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

Side by Side Diff: srtp/crypto/ae_xfm/xfm.c

Issue 889083003: Update libsrtp to upstream 1.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libsrtp@master
Patch Set: Updated to libsrtp 1.5.1 Created 5 years, 10 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/Makefile.in ('k') | srtp/crypto/cipher/aes.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 * xfm.c
3 *
4 * Crypto transform implementation
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 #include "cryptoalg.h"
46 #include "aes_cbc.h"
47 #include "hmac.h"
48 #include "crypto_kernel.h" /* for crypto_get_random() */
49
50 #define KEY_LEN 16
51 #define ENC_KEY_LEN 16
52 #define MAC_KEY_LEN 16
53 #define IV_LEN 16
54 #define TAG_LEN 12
55 #define MAX_EXPAND 27
56
57 err_status_t
58 aes_128_cbc_hmac_sha1_96_func(void *key,
59 void *clear,
60 unsigned clear_len,
61 void *iv,
62 void *opaque,
63 unsigned *opaque_len,
64 void *auth_tag) {
65 aes_cbc_ctx_t aes_ctx;
66 hmac_ctx_t hmac_ctx;
67 unsigned char enc_key[ENC_KEY_LEN];
68 unsigned char mac_key[MAC_KEY_LEN];
69 err_status_t status;
70
71 /* check if we're doing authentication only */
72 if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
73
74 /* perform authentication only */
75
76 } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
77
78 /*
79 * bad parameter - we expect either all three pointers to be NULL,
80 * or none of those pointers to be NULL
81 */
82 return err_status_fail;
83
84 } else {
85
86 /* derive encryption and authentication keys from the input key */
87 status = hmac_init(&hmac_ctx, key, KEY_LEN);
88 if (status) return status;
89 status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
90 if (status) return status;
91
92 status = hmac_init(&hmac_ctx, key, KEY_LEN);
93 if (status) return status;
94 status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
95 if (status) return status;
96
97
98 /* perform encryption and authentication */
99
100 /* set aes key */
101 status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt) ;
102 if (status) return status;
103
104 /* set iv */
105 status = crypto_get_random(iv, IV_LEN);
106 if (status) return status;
107 status = aes_cbc_set_iv(&aes_ctx, iv);
108
109 /* encrypt the opaque data */
110 status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
111 if (status) return status;
112
113 /* authenticate clear and opaque data */
114 status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
115 if (status) return status;
116
117 status = hmac_start(&hmac_ctx);
118 if (status) return status;
119
120 status = hmac_update(&hmac_ctx, clear, clear_len);
121 if (status) return status;
122
123 status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
124 if (status) return status;
125
126 }
127
128 return err_status_ok;
129 }
130
131 err_status_t
132 aes_128_cbc_hmac_sha1_96_inv(void *key,
133 void *clear,
134 unsigned clear_len,
135 void *iv,
136 void *opaque,
137 unsigned *opaque_len,
138 void *auth_tag) {
139 aes_cbc_ctx_t aes_ctx;
140 hmac_ctx_t hmac_ctx;
141 unsigned char enc_key[ENC_KEY_LEN];
142 unsigned char mac_key[MAC_KEY_LEN];
143 unsigned char tmp_tag[TAG_LEN];
144 unsigned char *tag = auth_tag;
145 err_status_t status;
146 int i;
147
148 /* check if we're doing authentication only */
149 if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
150
151 /* perform authentication only */
152
153 } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
154
155 /*
156 * bad parameter - we expect either all three pointers to be NULL,
157 * or none of those pointers to be NULL
158 */
159 return err_status_fail;
160
161 } else {
162
163 /* derive encryption and authentication keys from the input key */
164 status = hmac_init(&hmac_ctx, key, KEY_LEN);
165 if (status) return status;
166 status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
167 if (status) return status;
168
169 status = hmac_init(&hmac_ctx, key, KEY_LEN);
170 if (status) return status;
171 status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
172 if (status) return status;
173
174 /* perform encryption and authentication */
175
176 /* set aes key */
177 status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt) ;
178 if (status) return status;
179
180 /* set iv */
181 status = rand_source_get_octet_string(iv, IV_LEN);
182 if (status) return status;
183 status = aes_cbc_set_iv(&aes_ctx, iv);
184
185 /* encrypt the opaque data */
186 status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);
187 if (status) return status;
188
189 /* authenticate clear and opaque data */
190 status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
191 if (status) return status;
192
193 status = hmac_start(&hmac_ctx);
194 if (status) return status;
195
196 status = hmac_update(&hmac_ctx, clear, clear_len);
197 if (status) return status;
198
199 status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);
200 if (status) return status;
201
202 /* compare the computed tag with the one provided as input */
203 for (i=0; i < TAG_LEN; i++)
204 if (tmp_tag[i] != tag[i])
205 return err_status_auth_fail;
206
207 }
208
209 return err_status_ok;
210 }
211
212
213 #define ENC 1
214
215 #define DEBUG 0
216
217 err_status_t
218 aes_128_cbc_hmac_sha1_96_enc(void *key,
219 const void *clear,
220 unsigned clear_len,
221 void *iv,
222 void *opaque,
223 unsigned *opaque_len) {
224 aes_cbc_ctx_t aes_ctx;
225 hmac_ctx_t hmac_ctx;
226 unsigned char enc_key[ENC_KEY_LEN];
227 unsigned char mac_key[MAC_KEY_LEN];
228 unsigned char *auth_tag;
229 err_status_t status;
230
231 /* check if we're doing authentication only */
232 if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
233
234 /* perform authentication only */
235
236 } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
237
238 /*
239 * bad parameter - we expect either all three pointers to be NULL,
240 * or none of those pointers to be NULL
241 */
242 return err_status_fail;
243
244 } else {
245
246 #if DEBUG
247 printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
248 #endif
249
250 /* derive encryption and authentication keys from the input key */
251 status = hmac_init(&hmac_ctx, key, KEY_LEN);
252 if (status) return status;
253 status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
254 if (status) return status;
255
256 status = hmac_init(&hmac_ctx, key, KEY_LEN);
257 if (status) return status;
258 status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
259 if (status) return status;
260
261
262 /* perform encryption and authentication */
263
264 /* set aes key */
265 status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt) ;
266 if (status) return status;
267
268 /* set iv */
269 status = rand_source_get_octet_string(iv, IV_LEN);
270 if (status) return status;
271 status = aes_cbc_set_iv(&aes_ctx, iv);
272 if (status) return status;
273
274 #if DEBUG
275 printf("plaintext len: %d\n", *opaque_len);
276 printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
277 printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len));
278 #endif
279
280 #if ENC
281 /* encrypt the opaque data */
282 status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
283 if (status) return status;
284 #endif
285
286 #if DEBUG
287 printf("ciphertext len: %d\n", *opaque_len);
288 printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
289 #endif
290
291 /*
292 * authenticate clear and opaque data, then write the
293 * authentication tag to the location immediately following the
294 * ciphertext
295 */
296 status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
297 if (status) return status;
298
299 status = hmac_start(&hmac_ctx);
300 if (status) return status;
301
302 status = hmac_update(&hmac_ctx, clear, clear_len);
303 if (status) return status;
304 #if DEBUG
305 printf("hmac input: %s\n",
306 octet_string_hex_string(clear, clear_len));
307 #endif
308 auth_tag = (unsigned char *)opaque;
309 auth_tag += *opaque_len;
310 status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
311 if (status) return status;
312 #if DEBUG
313 printf("hmac input: %s\n",
314 octet_string_hex_string(opaque, *opaque_len));
315 #endif
316 /* bump up the opaque_len to reflect the authentication tag */
317 *opaque_len += TAG_LEN;
318
319 #if DEBUG
320 printf("prot data len: %d\n", *opaque_len);
321 printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
322 #endif
323 }
324
325 return err_status_ok;
326 }
327
328 err_status_t
329 aes_128_cbc_hmac_sha1_96_dec(void *key,
330 const void *clear,
331 unsigned clear_len,
332 void *iv,
333 void *opaque,
334 unsigned *opaque_len) {
335 aes_cbc_ctx_t aes_ctx;
336 hmac_ctx_t hmac_ctx;
337 unsigned char enc_key[ENC_KEY_LEN];
338 unsigned char mac_key[MAC_KEY_LEN];
339 unsigned char tmp_tag[TAG_LEN];
340 unsigned char *auth_tag;
341 unsigned ciphertext_len;
342 err_status_t status;
343 int i;
344
345 /* check if we're doing authentication only */
346 if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
347
348 /* perform authentication only */
349
350 } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
351
352 /*
353 * bad parameter - we expect either all three pointers to be NULL,
354 * or none of those pointers to be NULL
355 */
356 return err_status_fail;
357
358 } else {
359 #if DEBUG
360 printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
361 #endif
362
363 /* derive encryption and authentication keys from the input key */
364 status = hmac_init(&hmac_ctx, key, KEY_LEN);
365 if (status) return status;
366 status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
367 if (status) return status;
368
369 status = hmac_init(&hmac_ctx, key, KEY_LEN);
370 if (status) return status;
371 status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
372 if (status) return status;
373
374 #if DEBUG
375 printf("prot data len: %d\n", *opaque_len);
376 printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
377 #endif
378
379 /*
380 * set the protected data length to that of the ciphertext, by
381 * subtracting out the length of the authentication tag
382 */
383 ciphertext_len = *opaque_len - TAG_LEN;
384
385 #if DEBUG
386 printf("ciphertext len: %d\n", ciphertext_len);
387 #endif
388 /* verify the authentication tag */
389
390 /*
391 * compute the authentication tag for the clear and opaque data,
392 * and write it to a temporary location
393 */
394 status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
395 if (status) return status;
396
397 status = hmac_start(&hmac_ctx);
398 if (status) return status;
399
400 status = hmac_update(&hmac_ctx, clear, clear_len);
401 if (status) return status;
402
403 #if DEBUG
404 printf("hmac input: %s\n",
405 octet_string_hex_string(clear, clear_len));
406 #endif
407
408 status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);
409 if (status) return status;
410
411 #if DEBUG
412 printf("hmac input: %s\n",
413 octet_string_hex_string(opaque, ciphertext_len));
414 #endif
415
416 /*
417 * compare the computed tag with the one provided as input (which
418 * immediately follows the ciphertext)
419 */
420 auth_tag = (unsigned char *)opaque;
421 auth_tag += ciphertext_len;
422 #if DEBUG
423 printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN));
424 printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN));
425 #endif
426 for (i=0; i < TAG_LEN; i++) {
427 if (tmp_tag[i] != auth_tag[i])
428 return err_status_auth_fail;
429 }
430
431 /* bump down the opaque_len to reflect the authentication tag */
432 *opaque_len -= TAG_LEN;
433
434 /* decrypt the confidential data */
435 status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt) ;
436 if (status) return status;
437 status = aes_cbc_set_iv(&aes_ctx, iv);
438 if (status) return status;
439
440 #if DEBUG
441 printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
442 printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
443 #endif
444
445 #if ENC
446 status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);
447 if (status) return status;
448 #endif
449
450 #if DEBUG
451 printf("plaintext len: %d\n", ciphertext_len);
452 printf("plaintext: %s\n",
453 octet_string_hex_string(opaque, ciphertext_len));
454 #endif
455
456 /* indicate the length of the plaintext */
457 *opaque_len = ciphertext_len;
458 }
459
460 return err_status_ok;
461 }
462
463 cryptoalg_ctx_t cryptoalg_ctx = {
464 aes_128_cbc_hmac_sha1_96_enc,
465 aes_128_cbc_hmac_sha1_96_dec,
466 KEY_LEN,
467 IV_LEN,
468 TAG_LEN,
469 MAX_EXPAND,
470 };
471
472 cryptoalg_t cryptoalg = &cryptoalg_ctx;
473
474 #define NULL_TAG_LEN 12
475
476 err_status_t
477 null_enc(void *key,
478 const void *clear,
479 unsigned clear_len,
480 void *iv,
481 void *opaque,
482 unsigned *opaque_len) {
483 int i;
484 unsigned char *auth_tag;
485 unsigned char *init_vec = iv;
486
487 /* check if we're doing authentication only */
488 if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
489
490 /* perform authentication only */
491
492 } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
493
494 /*
495 * bad parameter - we expect either all three pointers to be NULL,
496 * or none of those pointers to be NULL
497 */
498 return err_status_fail;
499
500 } else {
501
502 #if DEBUG
503 printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
504 printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN);
505 printf("plaintext len: %d\n", *opaque_len);
506 #endif
507 for (i=0; i < IV_LEN; i++)
508 init_vec[i] = i + (i * 16);
509 #if DEBUG
510 printf("iv: %s\n",
511 octet_string_hex_string(iv, IV_LEN));
512 printf("plaintext: %s\n",
513 octet_string_hex_string(opaque, *opaque_len));
514 #endif
515 auth_tag = opaque;
516 auth_tag += *opaque_len;
517 for (i=0; i < NULL_TAG_LEN; i++)
518 auth_tag[i] = i + (i * 16);
519 *opaque_len += NULL_TAG_LEN;
520 #if DEBUG
521 printf("protected data len: %d\n", *opaque_len);
522 printf("protected data: %s\n",
523 octet_string_hex_string(opaque, *opaque_len));
524 #endif
525
526 }
527
528 return err_status_ok;
529 }
530
531 err_status_t
532 null_dec(void *key,
533 const void *clear,
534 unsigned clear_len,
535 void *iv,
536 void *opaque,
537 unsigned *opaque_len) {
538 unsigned char *auth_tag;
539
540 /* check if we're doing authentication only */
541 if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
542
543 /* perform authentication only */
544
545 } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
546
547 /*
548 * bad parameter - we expect either all three pointers to be NULL,
549 * or none of those pointers to be NULL
550 */
551 return err_status_fail;
552
553 } else {
554
555 #if DEBUG
556 printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
557
558 printf("protected data len: %d\n", *opaque_len);
559 printf("protected data: %s\n",
560 octet_string_hex_string(opaque, *opaque_len));
561 #endif
562 auth_tag = opaque;
563 auth_tag += (*opaque_len - NULL_TAG_LEN);
564 #if DEBUG
565 printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
566 #endif
567 *opaque_len -= NULL_TAG_LEN;
568 #if DEBUG
569 printf("plaintext len: %d\n", *opaque_len);
570 printf("plaintext: %s\n",
571 octet_string_hex_string(opaque, *opaque_len));
572 #endif
573 }
574
575 return err_status_ok;
576 }
577
578 cryptoalg_ctx_t null_cryptoalg_ctx = {
579 null_enc,
580 null_dec,
581 KEY_LEN,
582 IV_LEN,
583 NULL_TAG_LEN,
584 MAX_EXPAND,
585 };
586
587 cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;
588
589 int
590 cryptoalg_get_id(cryptoalg_t c) {
591 if (c == cryptoalg)
592 return 1;
593 return 0;
594 }
595
596 cryptoalg_t
597 cryptoalg_find_by_id(int id) {
598 switch(id) {
599 case 1:
600 return cryptoalg;
601 default:
602 break;
603 }
604 return 0;
605 }
OLDNEW
« no previous file with comments | « srtp/crypto/Makefile.in ('k') | srtp/crypto/cipher/aes.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698