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

Side by Side Diff: crypto/cipher/cipher.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 | « crypto/cipher/aes_icm_ossl.c ('k') | crypto/cipher/null_cipher.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 * cipher.c
3 *
4 * cipher meta-functions
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 *
9 */
10
11 /*
12 *
13 * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 *
20 * Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 *
23 * Redistributions in binary form must reproduce the above
24 * copyright notice, this list of conditions and the following
25 * disclaimer in the documentation and/or other materials provided
26 * with the distribution.
27 *
28 * Neither the name of the Cisco Systems, Inc. nor the names of its
29 * contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
36 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43 * OF THE POSSIBILITY OF SUCH DAMAGE.
44 *
45 */
46
47 #ifdef HAVE_CONFIG_H
48 #include <config.h>
49 #endif
50
51 #include "cipher.h"
52 #include "crypto_types.h"
53 #include "err.h" /* for srtp_debug */
54 #include "alloc.h" /* for crypto_alloc(), crypto_free() */
55
56 srtp_debug_module_t srtp_mod_cipher = {
57 0, /* debugging is off by default */
58 "cipher" /* printable module name */
59 };
60
61 srtp_err_status_t srtp_cipher_type_alloc (const srtp_cipher_type_t *ct, srtp_cip her_t **c, int key_len, int tlen)
62 {
63 if (!ct || !ct->alloc) {
64 return (srtp_err_status_bad_param);
65 }
66 return ((ct)->alloc((c), (key_len), (tlen)));
67 }
68
69 srtp_err_status_t srtp_cipher_dealloc (srtp_cipher_t *c)
70 {
71 if (!c || !c->type) {
72 return (srtp_err_status_bad_param);
73 }
74 return (((c)->type)->dealloc(c));
75 }
76
77 srtp_err_status_t srtp_cipher_init (srtp_cipher_t *c, const uint8_t *key)
78 {
79 if (!c || !c->type || !c->state) {
80 return (srtp_err_status_bad_param);
81 }
82 return (((c)->type)->init(((c)->state), (key)));
83 }
84
85
86 srtp_err_status_t srtp_cipher_set_iv (srtp_cipher_t *c, uint8_t *iv, int directi on)
87 {
88 if (!c || !c->type || !c->state) {
89 return (srtp_err_status_bad_param);
90 }
91
92 return (((c)->type)->set_iv(((c)->state), iv, direction));
93 }
94
95 srtp_err_status_t srtp_cipher_output (srtp_cipher_t *c, uint8_t *buffer, uint32_ t *num_octets_to_output)
96 {
97
98 /* zeroize the buffer */
99 octet_string_set_to_zero(buffer, *num_octets_to_output);
100
101 /* exor keystream into buffer */
102 return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
103 }
104
105 srtp_err_status_t srtp_cipher_encrypt (srtp_cipher_t *c, uint8_t *buffer, uint32 _t *num_octets_to_output)
106 {
107 if (!c || !c->type || !c->state) {
108 return (srtp_err_status_bad_param);
109 }
110
111 return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
112 }
113
114 srtp_err_status_t srtp_cipher_decrypt (srtp_cipher_t *c, uint8_t *buffer, uint32 _t *num_octets_to_output)
115 {
116 if (!c || !c->type || !c->state) {
117 return (srtp_err_status_bad_param);
118 }
119
120 return (((c)->type)->decrypt(((c)->state), buffer, num_octets_to_output));
121 }
122
123 srtp_err_status_t srtp_cipher_get_tag (srtp_cipher_t *c, uint8_t *buffer, uint32 _t *tag_len)
124 {
125 if (!c || !c->type || !c->state) {
126 return (srtp_err_status_bad_param);
127 }
128 if (!((c)->type)->get_tag) {
129 return (srtp_err_status_no_such_op);
130 }
131
132 return (((c)->type)->get_tag(((c)->state), buffer, tag_len));
133 }
134
135 srtp_err_status_t srtp_cipher_set_aad (srtp_cipher_t *c, const uint8_t *aad, uin t32_t aad_len)
136 {
137 if (!c || !c->type || !c->state) {
138 return (srtp_err_status_bad_param);
139 }
140 if (!((c)->type)->set_aad) {
141 return (srtp_err_status_no_such_op);
142 }
143
144 return (((c)->type)->set_aad(((c)->state), aad, aad_len));
145 }
146
147 /* some bookkeeping functions */
148
149 int srtp_cipher_get_key_length (const srtp_cipher_t *c)
150 {
151 return c->key_len;
152 }
153
154
155 /*
156 * A trivial platform independent random source. The random
157 * data is used for some of the cipher self-tests.
158 */
159 static srtp_err_status_t srtp_cipher_rand (void *dest, uint32_t len)
160 {
161 #if defined(HAVE_RAND_S)
162 uint8_t *dst = (uint8_t *)dest;
163 while (len)
164 {
165 unsigned int val;
166 errno_t err = rand_s(&val);
167
168 if (err != 0)
169 return srtp_err_status_fail;
170
171 *dst++ = val & 0xff;
172 len--;
173 }
174 #else
175 /* Generic C-library (rand()) version */
176 /* This is a random source of last resort */
177 uint8_t *dst = (uint8_t *)dest;
178 while (len)
179 {
180 int val = rand();
181 /* rand() returns 0-32767 (ugh) */
182 /* Is this a good enough way to get random bytes?
183 It is if it passes FIPS-140... */
184 *dst++ = val & 0xff;
185 len--;
186 }
187 #endif
188 return srtp_err_status_ok;
189 }
190
191 #define SELF_TEST_BUF_OCTETS 128
192 #define NUM_RAND_TESTS 128
193 #define MAX_KEY_LEN 64
194 /*
195 * srtp_cipher_type_test(ct, test_data) tests a cipher of type ct against
196 * test cases provided in a list test_data of values of key, salt, iv,
197 * plaintext, and ciphertext that is known to be good
198 */
199 srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt p_cipher_test_case_t *test_data)
200 {
201 const srtp_cipher_test_case_t *test_case = test_data;
202 srtp_cipher_t *c;
203 srtp_err_status_t status;
204 uint8_t buffer[SELF_TEST_BUF_OCTETS];
205 uint8_t buffer2[SELF_TEST_BUF_OCTETS];
206 uint32_t tag_len;
207 unsigned int len;
208 int i, j, case_num = 0;
209
210 debug_print(srtp_mod_cipher, "running self-test for cipher %s",
211 ct->description);
212
213 /*
214 * check to make sure that we have at least one test case, and
215 * return an error if we don't - we need to be paranoid here
216 */
217 if (test_case == NULL) {
218 return srtp_err_status_cant_check;
219 }
220
221 /*
222 * loop over all test cases, perform known-answer tests of both the
223 * encryption and decryption functions
224 */
225 while (test_case != NULL) {
226 /* allocate cipher */
227 status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, te st_case->tag_length_octets);
228 if (status) {
229 return status;
230 }
231
232 /*
233 * test the encrypt function
234 */
235 debug_print(srtp_mod_cipher, "testing encryption", NULL);
236
237 /* initialize cipher */
238 status = srtp_cipher_init(c, test_case->key);
239 if (status) {
240 srtp_cipher_dealloc(c);
241 return status;
242 }
243
244 /* copy plaintext into test buffer */
245 if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
246 srtp_cipher_dealloc(c);
247 return srtp_err_status_bad_param;
248 }
249 for (i = 0; i < test_case->plaintext_length_octets; i++) {
250 buffer[i] = test_case->plaintext[i];
251 }
252
253 debug_print(srtp_mod_cipher, "plaintext: %s",
254 srtp_octet_string_hex_string(buffer,
255 test_case->plaintext_length_oct ets));
256
257 /* set the initialization vector */
258 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_ encrypt);
259 if (status) {
260 srtp_cipher_dealloc(c);
261 return status;
262 }
263
264 if (c->algorithm == SRTP_AES_128_GCM || c->algorithm == SRTP_AES_256_GCM ) {
265 debug_print(srtp_mod_cipher, "IV: %s",
266 srtp_octet_string_hex_string(test_case->idx, 12));
267
268 /*
269 * Set the AAD
270 */
271 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_lengt h_octets);
272 if (status) {
273 srtp_cipher_dealloc(c);
274 return status;
275 }
276 debug_print(srtp_mod_cipher, "AAD: %s",
277 srtp_octet_string_hex_string(test_case->aad,
278 test_case->aad_length_octet s));
279 }
280
281 /* encrypt */
282 len = test_case->plaintext_length_octets;
283 status = srtp_cipher_encrypt(c, buffer, &len);
284 if (status) {
285 srtp_cipher_dealloc(c);
286 return status;
287 }
288
289 if (c->algorithm == SRTP_AES_128_GCM || c->algorithm == SRTP_AES_256_GCM ) {
290 /*
291 * Get the GCM tag
292 */
293 status = srtp_cipher_get_tag(c, buffer + len, &tag_len);
294 if (status) {
295 srtp_cipher_dealloc(c);
296 return status;
297 }
298 len += tag_len;
299 }
300
301 debug_print(srtp_mod_cipher, "ciphertext: %s",
302 srtp_octet_string_hex_string(buffer,
303 test_case->ciphertext_length_oc tets));
304
305 /* compare the resulting ciphertext with that in the test case */
306 if (len != test_case->ciphertext_length_octets) {
307 return srtp_err_status_algo_fail;
308 }
309 status = srtp_err_status_ok;
310 for (i = 0; i < test_case->ciphertext_length_octets; i++) {
311 if (buffer[i] != test_case->ciphertext[i]) {
312 status = srtp_err_status_algo_fail;
313 debug_print(srtp_mod_cipher, "test case %d failed", case_num);
314 debug_print(srtp_mod_cipher, "(failure at byte %d)", i);
315 break;
316 }
317 }
318 if (status) {
319
320 debug_print(srtp_mod_cipher, "c computed: %s",
321 srtp_octet_string_hex_string(buffer,
322 2 * test_case->plaintext_le ngth_octets));
323 debug_print(srtp_mod_cipher, "c expected: %s",
324 srtp_octet_string_hex_string(test_case->ciphertext,
325 2 * test_case->plaintext_le ngth_octets));
326
327 srtp_cipher_dealloc(c);
328 return srtp_err_status_algo_fail;
329 }
330
331 /*
332 * test the decrypt function
333 */
334 debug_print(srtp_mod_cipher, "testing decryption", NULL);
335
336 /* re-initialize cipher for decryption */
337 status = srtp_cipher_init(c, test_case->key);
338 if (status) {
339 srtp_cipher_dealloc(c);
340 return status;
341 }
342
343 /* copy ciphertext into test buffer */
344 if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
345 srtp_cipher_dealloc(c);
346 return srtp_err_status_bad_param;
347 }
348 for (i = 0; i < test_case->ciphertext_length_octets; i++) {
349 buffer[i] = test_case->ciphertext[i];
350 }
351
352 debug_print(srtp_mod_cipher, "ciphertext: %s",
353 srtp_octet_string_hex_string(buffer,
354 test_case->plaintext_length_oct ets));
355
356 /* set the initialization vector */
357 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_ decrypt);
358 if (status) {
359 srtp_cipher_dealloc(c);
360 return status;
361 }
362
363 if (c->algorithm == SRTP_AES_128_GCM || c->algorithm == SRTP_AES_256_GCM ) {
364 /*
365 * Set the AAD
366 */
367 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_lengt h_octets);
368 if (status) {
369 srtp_cipher_dealloc(c);
370 return status;
371 }
372 debug_print(srtp_mod_cipher, "AAD: %s",
373 srtp_octet_string_hex_string(test_case->aad,
374 test_case->aad_length_octet s));
375 }
376
377 /* decrypt */
378 len = test_case->ciphertext_length_octets;
379 status = srtp_cipher_decrypt(c, buffer, &len);
380 if (status) {
381 srtp_cipher_dealloc(c);
382 return status;
383 }
384
385 debug_print(srtp_mod_cipher, "plaintext: %s",
386 srtp_octet_string_hex_string(buffer,
387 test_case->plaintext_length_oct ets));
388
389 /* compare the resulting plaintext with that in the test case */
390 if (len != test_case->plaintext_length_octets) {
391 return srtp_err_status_algo_fail;
392 }
393 status = srtp_err_status_ok;
394 for (i = 0; i < test_case->plaintext_length_octets; i++) {
395 if (buffer[i] != test_case->plaintext[i]) {
396 status = srtp_err_status_algo_fail;
397 debug_print(srtp_mod_cipher, "test case %d failed", case_num);
398 debug_print(srtp_mod_cipher, "(failure at byte %d)", i);
399 }
400 }
401 if (status) {
402
403 debug_print(srtp_mod_cipher, "p computed: %s",
404 srtp_octet_string_hex_string(buffer,
405 2 * test_case->plaintext_le ngth_octets));
406 debug_print(srtp_mod_cipher, "p expected: %s",
407 srtp_octet_string_hex_string(test_case->plaintext,
408 2 * test_case->plaintext_le ngth_octets));
409
410 srtp_cipher_dealloc(c);
411 return srtp_err_status_algo_fail;
412 }
413
414 /* deallocate the cipher */
415 status = srtp_cipher_dealloc(c);
416 if (status) {
417 return status;
418 }
419
420 /*
421 * the cipher passed the test case, so move on to the next test
422 * case in the list; if NULL, we'l proceed to the next test
423 */
424 test_case = test_case->next_test_case;
425 ++case_num;
426 }
427
428 /* now run some random invertibility tests */
429
430 /* allocate cipher, using paramaters from the first test case */
431 test_case = test_data;
432 status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, test_c ase->tag_length_octets);
433 if (status) {
434 return status;
435 }
436
437 for (j = 0; j < NUM_RAND_TESTS; j++) {
438 unsigned length;
439 int plaintext_len;
440 uint8_t key[MAX_KEY_LEN];
441 uint8_t iv[MAX_KEY_LEN];
442
443 /* choose a length at random (leaving room for IV and padding) */
444 length = rand() % (SELF_TEST_BUF_OCTETS - 64);
445 debug_print(srtp_mod_cipher, "random plaintext length %d\n", length);
446 status = srtp_cipher_rand(buffer, length);
447 if (status) {
448 return status;
449 }
450
451 debug_print(srtp_mod_cipher, "plaintext: %s",
452 srtp_octet_string_hex_string(buffer, length));
453
454 /* copy plaintext into second buffer */
455 for (i = 0; (unsigned int)i < length; i++) {
456 buffer2[i] = buffer[i];
457 }
458
459 /* choose a key at random */
460 if (test_case->key_length_octets > MAX_KEY_LEN) {
461 return srtp_err_status_cant_check;
462 }
463 status = srtp_cipher_rand(key, test_case->key_length_octets);
464 if (status) {
465 return status;
466 }
467
468 /* chose a random initialization vector */
469 status = srtp_cipher_rand(iv, MAX_KEY_LEN);
470 if (status) {
471 return status;
472 }
473
474 /* initialize cipher */
475 status = srtp_cipher_init(c, key);
476 if (status) {
477 srtp_cipher_dealloc(c);
478 return status;
479 }
480
481 /* set initialization vector */
482 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_ encrypt);
483 if (status) {
484 srtp_cipher_dealloc(c);
485 return status;
486 }
487
488 if (c->algorithm == SRTP_AES_128_GCM || c->algorithm == SRTP_AES_256_GCM ) {
489 /*
490 * Set the AAD
491 */
492 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_lengt h_octets);
493 if (status) {
494 srtp_cipher_dealloc(c);
495 return status;
496 }
497 debug_print(srtp_mod_cipher, "AAD: %s",
498 srtp_octet_string_hex_string(test_case->aad,
499 test_case->aad_length_octet s));
500 }
501
502 /* encrypt buffer with cipher */
503 plaintext_len = length;
504 status = srtp_cipher_encrypt(c, buffer, &length);
505 if (status) {
506 srtp_cipher_dealloc(c);
507 return status;
508 }
509 if (c->algorithm == SRTP_AES_128_GCM || c->algorithm == SRTP_AES_256_GCM ) {
510 /*
511 * Get the GCM tag
512 */
513 status = srtp_cipher_get_tag(c, buffer + length, &tag_len);
514 if (status) {
515 srtp_cipher_dealloc(c);
516 return status;
517 }
518 length += tag_len;
519 }
520 debug_print(srtp_mod_cipher, "ciphertext: %s",
521 srtp_octet_string_hex_string(buffer, length));
522
523 /*
524 * re-initialize cipher for decryption, re-set the iv, then
525 * decrypt the ciphertext
526 */
527 status = srtp_cipher_init(c, key);
528 if (status) {
529 srtp_cipher_dealloc(c);
530 return status;
531 }
532 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_ decrypt);
533 if (status) {
534 srtp_cipher_dealloc(c);
535 return status;
536 }
537 if (c->algorithm == SRTP_AES_128_GCM || c->algorithm == SRTP_AES_256_GCM ) {
538 /*
539 * Set the AAD
540 */
541 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_lengt h_octets);
542 if (status) {
543 srtp_cipher_dealloc(c);
544 return status;
545 }
546 debug_print(srtp_mod_cipher, "AAD: %s",
547 srtp_octet_string_hex_string(test_case->aad,
548 test_case->aad_length_octet s));
549 }
550 status = srtp_cipher_decrypt(c, buffer, &length);
551 if (status) {
552 srtp_cipher_dealloc(c);
553 return status;
554 }
555
556 debug_print(srtp_mod_cipher, "plaintext[2]: %s",
557 srtp_octet_string_hex_string(buffer, length));
558
559 /* compare the resulting plaintext with the original one */
560 if (length != plaintext_len) {
561 return srtp_err_status_algo_fail;
562 }
563 status = srtp_err_status_ok;
564 for (i = 0; i < plaintext_len; i++) {
565 if (buffer[i] != buffer2[i]) {
566 status = srtp_err_status_algo_fail;
567 debug_print(srtp_mod_cipher, "random test case %d failed", case_ num);
568 debug_print(srtp_mod_cipher, "(failure at byte %d)", i);
569 }
570 }
571 if (status) {
572 srtp_cipher_dealloc(c);
573 return srtp_err_status_algo_fail;
574 }
575
576 }
577
578 status = srtp_cipher_dealloc(c);
579 if (status) {
580 return status;
581 }
582
583 return srtp_err_status_ok;
584 }
585
586
587 /*
588 * srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's interna l
589 * list of test data.
590 */
591 srtp_err_status_t srtp_cipher_type_self_test (const srtp_cipher_type_t *ct)
592 {
593 return srtp_cipher_type_test(ct, ct->test_data);
594 }
595
596 /*
597 * cipher_bits_per_second(c, l, t) computes (an estimate of) the
598 * number of bits that a cipher implementation can encrypt in a second
599 *
600 * c is a cipher (which MUST be allocated and initialized already), l
601 * is the length in octets of the test data to be encrypted, and t is
602 * the number of trials
603 *
604 * if an error is encountered, the value 0 is returned
605 */
606 uint64_t srtp_cipher_bits_per_second (srtp_cipher_t *c, int octets_in_buffer, in t num_trials)
607 {
608 int i;
609 v128_t nonce;
610 clock_t timer;
611 unsigned char *enc_buf;
612 unsigned int len = octets_in_buffer;
613
614 enc_buf = (unsigned char*)srtp_crypto_alloc(octets_in_buffer);
615 if (enc_buf == NULL) {
616 return 0; /* indicate bad parameters by returning null */
617
618 }
619 /* time repeated trials */
620 v128_set_to_zero(&nonce);
621 timer = clock();
622 for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
623 srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt);
624 srtp_cipher_encrypt(c, enc_buf, &len);
625 }
626 timer = clock() - timer;
627
628 srtp_crypto_free(enc_buf);
629
630 if (timer == 0) {
631 /* Too fast! */
632 return 0;
633 }
634
635 return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
636 }
OLDNEW
« no previous file with comments | « crypto/cipher/aes_icm_ossl.c ('k') | crypto/cipher/null_cipher.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698