Changeset 5614 for pjproject/trunk/third_party/srtp/crypto/cipher/cipher.c
- Timestamp:
- Jul 4, 2017 5:22:51 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/third_party/srtp/crypto/cipher/cipher.c
r5261 r5614 6 6 * David A. McGrew 7 7 * Cisco Systems, Inc. 8 * 8 * 9 9 */ 10 10 11 11 /* 12 * 13 * Copyright (c) 2001-20 06,2013Cisco Systems, Inc.12 * 13 * Copyright (c) 2001-2017 Cisco Systems, Inc. 14 14 * All rights reserved. 15 * 15 * 16 16 * Redistribution and use in source and binary forms, with or without 17 17 * modification, are permitted provided that the following conditions 18 18 * are met: 19 * 19 * 20 20 * Redistributions of source code must retain the above copyright 21 21 * notice, this list of conditions and the following disclaimer. 22 * 22 * 23 23 * Redistributions in binary form must reproduce the above 24 24 * copyright notice, this list of conditions and the following 25 25 * disclaimer in the documentation and/or other materials provided 26 26 * with the distribution. 27 * 27 * 28 28 * Neither the name of the Cisco Systems, Inc. nor the names of its 29 29 * contributors may be used to endorse or promote products derived 30 30 * from this software without specific prior written permission. 31 * 31 * 32 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT … … 51 51 #include "cipher.h" 52 52 #include "crypto_types.h" 53 #include " rand_source.h" /* used in invertibiltiy tests*/53 #include "err.h" /* for srtp_debug */ 54 54 #include "alloc.h" /* for crypto_alloc(), crypto_free() */ 55 55 56 debug_module_tmod_cipher = {57 0,/* debugging is off by default */58 "cipher"/* printable module name */56 srtp_debug_module_t srtp_mod_cipher = { 57 0, /* debugging is off by default */ 58 "cipher" /* printable module name */ 59 59 }; 60 60 61 err_status_t 62 cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) { 61 srtp_err_status_t srtp_cipher_type_alloc (const srtp_cipher_type_t *ct, srtp_cipher_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 direction) 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, uint32_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; 63 170 64 /* zeroize the buffer */ 65 octet_string_set_to_zero(buffer, num_octets_to_output); 66 67 /* exor keystream into buffer */ 68 return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output); 69 } 70 71 /* some bookkeeping functions */ 72 73 int 74 cipher_get_key_length(const cipher_t *c) { 75 return c->key_len; 76 } 77 78 /* 79 * cipher_type_test(ct, test_data) tests a cipher of type ct against 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 80 196 * test cases provided in a list test_data of values of key, salt, iv, 81 197 * plaintext, and ciphertext that is known to be good 82 198 */ 83 84 #define SELF_TEST_BUF_OCTETS 128 85 #define NUM_RAND_TESTS 128 86 #define MAX_KEY_LEN 64 87 88 err_status_t 89 cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) { 90 const cipher_test_case_t *test_case = test_data; 91 cipher_t *c; 92 err_status_t status; 93 uint8_t buffer[SELF_TEST_BUF_OCTETS]; 94 uint8_t buffer2[SELF_TEST_BUF_OCTETS]; 95 int tag_len; 96 unsigned int len; 97 int i, j, case_num = 0; 98 99 debug_print(mod_cipher, "running self-test for cipher %s", 100 ct->description); 101 102 /* 103 * check to make sure that we have at least one test case, and 104 * return an error if we don't - we need to be paranoid here 105 */ 106 if (test_case == NULL) 107 return err_status_cant_check; 108 109 /* 110 * loop over all test cases, perform known-answer tests of both the 111 * encryption and decryption functions 112 */ 113 while (test_case != NULL) { 114 /* allocate cipher */ 115 status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 116 if (status) 117 return status; 118 199 srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srtp_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 119 213 /* 120 * test the encrypt function 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 121 216 */ 122 debug_print(mod_cipher, "testing encryption", NULL); 123 124 /* initialize cipher */ 125 status = cipher_init(c, test_case->key); 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, test_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_octets)); 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_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 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_length_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_octets)); 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_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 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_octets)); 304 305 /* compare the resulting ciphertext with that in the test case */ 306 if (len != test_case->ciphertext_length_octets) { 307 srtp_cipher_dealloc(c); 308 return srtp_err_status_algo_fail; 309 } 310 status = srtp_err_status_ok; 311 for (i = 0; i < test_case->ciphertext_length_octets; i++) { 312 if (buffer[i] != test_case->ciphertext[i]) { 313 status = srtp_err_status_algo_fail; 314 debug_print(srtp_mod_cipher, "test case %d failed", case_num); 315 debug_print(srtp_mod_cipher, "(failure at byte %d)", i); 316 break; 317 } 318 } 319 if (status) { 320 321 debug_print(srtp_mod_cipher, "c computed: %s", 322 srtp_octet_string_hex_string(buffer, 323 2 * test_case->plaintext_length_octets)); 324 debug_print(srtp_mod_cipher, "c expected: %s", 325 srtp_octet_string_hex_string(test_case->ciphertext, 326 2 * test_case->plaintext_length_octets)); 327 328 srtp_cipher_dealloc(c); 329 return srtp_err_status_algo_fail; 330 } 331 332 /* 333 * test the decrypt function 334 */ 335 debug_print(srtp_mod_cipher, "testing decryption", NULL); 336 337 /* re-initialize cipher for decryption */ 338 status = srtp_cipher_init(c, test_case->key); 339 if (status) { 340 srtp_cipher_dealloc(c); 341 return status; 342 } 343 344 /* copy ciphertext into test buffer */ 345 if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 346 srtp_cipher_dealloc(c); 347 return srtp_err_status_bad_param; 348 } 349 for (i = 0; i < test_case->ciphertext_length_octets; i++) { 350 buffer[i] = test_case->ciphertext[i]; 351 } 352 353 debug_print(srtp_mod_cipher, "ciphertext: %s", 354 srtp_octet_string_hex_string(buffer, 355 test_case->plaintext_length_octets)); 356 357 /* set the initialization vector */ 358 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_decrypt); 359 if (status) { 360 srtp_cipher_dealloc(c); 361 return status; 362 } 363 364 if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 365 /* 366 * Set the AAD 367 */ 368 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 369 if (status) { 370 srtp_cipher_dealloc(c); 371 return status; 372 } 373 debug_print(srtp_mod_cipher, "AAD: %s", 374 srtp_octet_string_hex_string(test_case->aad, 375 test_case->aad_length_octets)); 376 } 377 378 /* decrypt */ 379 len = test_case->ciphertext_length_octets; 380 status = srtp_cipher_decrypt(c, buffer, &len); 381 if (status) { 382 srtp_cipher_dealloc(c); 383 return status; 384 } 385 386 debug_print(srtp_mod_cipher, "plaintext: %s", 387 srtp_octet_string_hex_string(buffer, 388 test_case->plaintext_length_octets)); 389 390 /* compare the resulting plaintext with that in the test case */ 391 if (len != test_case->plaintext_length_octets) { 392 srtp_cipher_dealloc(c); 393 return srtp_err_status_algo_fail; 394 } 395 status = srtp_err_status_ok; 396 for (i = 0; i < test_case->plaintext_length_octets; i++) { 397 if (buffer[i] != test_case->plaintext[i]) { 398 status = srtp_err_status_algo_fail; 399 debug_print(srtp_mod_cipher, "test case %d failed", case_num); 400 debug_print(srtp_mod_cipher, "(failure at byte %d)", i); 401 } 402 } 403 if (status) { 404 405 debug_print(srtp_mod_cipher, "p computed: %s", 406 srtp_octet_string_hex_string(buffer, 407 2 * test_case->plaintext_length_octets)); 408 debug_print(srtp_mod_cipher, "p expected: %s", 409 srtp_octet_string_hex_string(test_case->plaintext, 410 2 * test_case->plaintext_length_octets)); 411 412 srtp_cipher_dealloc(c); 413 return srtp_err_status_algo_fail; 414 } 415 416 /* deallocate the cipher */ 417 status = srtp_cipher_dealloc(c); 418 if (status) { 419 return status; 420 } 421 422 /* 423 * the cipher passed the test case, so move on to the next test 424 * case in the list; if NULL, we'l proceed to the next test 425 */ 426 test_case = test_case->next_test_case; 427 ++case_num; 428 } 429 430 /* now run some random invertibility tests */ 431 432 /* allocate cipher, using paramaters from the first test case */ 433 test_case = test_data; 434 status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 126 435 if (status) { 127 cipher_dealloc(c); 128 return status; 129 } 130 131 /* copy plaintext into test buffer */ 132 if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 133 cipher_dealloc(c); 134 return err_status_bad_param; 135 } 136 for (i=0; i < test_case->plaintext_length_octets; i++) 137 buffer[i] = test_case->plaintext[i]; 138 139 debug_print(mod_cipher, "plaintext: %s", 140 octet_string_hex_string(buffer, 141 test_case->plaintext_length_octets)); 142 143 /* set the initialization vector */ 144 status = cipher_set_iv(c, test_case->idx, direction_encrypt); 436 return status; 437 } 438 439 for (j = 0; j < NUM_RAND_TESTS; j++) { 440 unsigned length; 441 int plaintext_len; 442 uint8_t key[MAX_KEY_LEN]; 443 uint8_t iv[MAX_KEY_LEN]; 444 445 /* choose a length at random (leaving room for IV and padding) */ 446 length = rand() % (SELF_TEST_BUF_OCTETS - 64); 447 debug_print(srtp_mod_cipher, "random plaintext length %d\n", length); 448 status = srtp_cipher_rand(buffer, length); 449 if (status) { 450 srtp_cipher_dealloc(c); 451 return status; 452 } 453 454 debug_print(srtp_mod_cipher, "plaintext: %s", 455 srtp_octet_string_hex_string(buffer, length)); 456 457 /* copy plaintext into second buffer */ 458 for (i = 0; (unsigned int)i < length; i++) { 459 buffer2[i] = buffer[i]; 460 } 461 462 /* choose a key at random */ 463 if (test_case->key_length_octets > MAX_KEY_LEN) { 464 srtp_cipher_dealloc(c); 465 return srtp_err_status_cant_check; 466 } 467 status = srtp_cipher_rand(key, test_case->key_length_octets); 468 if (status) { 469 srtp_cipher_dealloc(c); 470 return status; 471 } 472 473 /* chose a random initialization vector */ 474 status = srtp_cipher_rand(iv, MAX_KEY_LEN); 475 if (status) { 476 srtp_cipher_dealloc(c); 477 return status; 478 } 479 480 /* initialize cipher */ 481 status = srtp_cipher_init(c, key); 482 if (status) { 483 srtp_cipher_dealloc(c); 484 return status; 485 } 486 487 /* set initialization vector */ 488 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_encrypt); 489 if (status) { 490 srtp_cipher_dealloc(c); 491 return status; 492 } 493 494 if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 495 /* 496 * Set the AAD 497 */ 498 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 499 if (status) { 500 srtp_cipher_dealloc(c); 501 return status; 502 } 503 debug_print(srtp_mod_cipher, "AAD: %s", 504 srtp_octet_string_hex_string(test_case->aad, 505 test_case->aad_length_octets)); 506 } 507 508 /* encrypt buffer with cipher */ 509 plaintext_len = length; 510 status = srtp_cipher_encrypt(c, buffer, &length); 511 if (status) { 512 srtp_cipher_dealloc(c); 513 return status; 514 } 515 if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 516 /* 517 * Get the GCM tag 518 */ 519 status = srtp_cipher_get_tag(c, buffer + length, &tag_len); 520 if (status) { 521 srtp_cipher_dealloc(c); 522 return status; 523 } 524 length += tag_len; 525 } 526 debug_print(srtp_mod_cipher, "ciphertext: %s", 527 srtp_octet_string_hex_string(buffer, length)); 528 529 /* 530 * re-initialize cipher for decryption, re-set the iv, then 531 * decrypt the ciphertext 532 */ 533 status = srtp_cipher_init(c, key); 534 if (status) { 535 srtp_cipher_dealloc(c); 536 return status; 537 } 538 status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_decrypt); 539 if (status) { 540 srtp_cipher_dealloc(c); 541 return status; 542 } 543 if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) { 544 /* 545 * Set the AAD 546 */ 547 status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets); 548 if (status) { 549 srtp_cipher_dealloc(c); 550 return status; 551 } 552 debug_print(srtp_mod_cipher, "AAD: %s", 553 srtp_octet_string_hex_string(test_case->aad, 554 test_case->aad_length_octets)); 555 } 556 status = srtp_cipher_decrypt(c, buffer, &length); 557 if (status) { 558 srtp_cipher_dealloc(c); 559 return status; 560 } 561 562 debug_print(srtp_mod_cipher, "plaintext[2]: %s", 563 srtp_octet_string_hex_string(buffer, length)); 564 565 /* compare the resulting plaintext with the original one */ 566 if (length != plaintext_len) { 567 srtp_cipher_dealloc(c); 568 return srtp_err_status_algo_fail; 569 } 570 status = srtp_err_status_ok; 571 for (i = 0; i < plaintext_len; i++) { 572 if (buffer[i] != buffer2[i]) { 573 status = srtp_err_status_algo_fail; 574 debug_print(srtp_mod_cipher, "random test case %d failed", case_num); 575 debug_print(srtp_mod_cipher, "(failure at byte %d)", i); 576 } 577 } 578 if (status) { 579 srtp_cipher_dealloc(c); 580 return srtp_err_status_algo_fail; 581 } 582 583 } 584 585 status = srtp_cipher_dealloc(c); 145 586 if (status) { 146 cipher_dealloc(c); 147 return status; 148 } 149 150 if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 151 debug_print(mod_cipher, "IV: %s", 152 octet_string_hex_string(test_case->idx, 12)); 153 154 /* 155 * Set the AAD 156 */ 157 status = cipher_set_aad(c, test_case->aad, 158 test_case->aad_length_octets); 159 if (status) { 160 cipher_dealloc(c); 161 return status; 162 } 163 debug_print(mod_cipher, "AAD: %s", 164 octet_string_hex_string(test_case->aad, 165 test_case->aad_length_octets)); 166 } 167 168 /* encrypt */ 169 len = test_case->plaintext_length_octets; 170 status = cipher_encrypt(c, buffer, &len); 171 if (status) { 172 cipher_dealloc(c); 173 return status; 174 } 175 176 if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 177 /* 178 * Get the GCM tag 179 */ 180 status = cipher_get_tag(c, buffer + len, &tag_len); 181 if (status) { 182 cipher_dealloc(c); 183 return status; 184 } 185 len += tag_len; 186 } 187 188 debug_print(mod_cipher, "ciphertext: %s", 189 octet_string_hex_string(buffer, 190 test_case->ciphertext_length_octets)); 191 192 /* compare the resulting ciphertext with that in the test case */ 193 if (len != test_case->ciphertext_length_octets) 194 return err_status_algo_fail; 195 status = err_status_ok; 196 for (i=0; i < test_case->ciphertext_length_octets; i++) 197 if (buffer[i] != test_case->ciphertext[i]) { 198 status = err_status_algo_fail; 199 debug_print(mod_cipher, "test case %d failed", case_num); 200 debug_print(mod_cipher, "(failure at byte %d)", i); 201 break; 202 } 203 if (status) { 204 205 debug_print(mod_cipher, "c computed: %s", 206 octet_string_hex_string(buffer, 207 2*test_case->plaintext_length_octets)); 208 debug_print(mod_cipher, "c expected: %s", 209 octet_string_hex_string(test_case->ciphertext, 210 2*test_case->plaintext_length_octets)); 211 212 cipher_dealloc(c); 213 return err_status_algo_fail; 214 } 215 216 /* 217 * test the decrypt function 218 */ 219 debug_print(mod_cipher, "testing decryption", NULL); 220 221 /* re-initialize cipher for decryption */ 222 status = cipher_init(c, test_case->key); 223 if (status) { 224 cipher_dealloc(c); 225 return status; 226 } 227 228 /* copy ciphertext into test buffer */ 229 if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) { 230 cipher_dealloc(c); 231 return err_status_bad_param; 232 } 233 for (i=0; i < test_case->ciphertext_length_octets; i++) 234 buffer[i] = test_case->ciphertext[i]; 235 236 debug_print(mod_cipher, "ciphertext: %s", 237 octet_string_hex_string(buffer, 238 test_case->plaintext_length_octets)); 239 240 /* set the initialization vector */ 241 status = cipher_set_iv(c, test_case->idx, direction_decrypt); 242 if (status) { 243 cipher_dealloc(c); 244 return status; 245 } 246 247 if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 248 /* 249 * Set the AAD 250 */ 251 status = cipher_set_aad(c, test_case->aad, 252 test_case->aad_length_octets); 253 if (status) { 254 cipher_dealloc(c); 255 return status; 256 } 257 debug_print(mod_cipher, "AAD: %s", 258 octet_string_hex_string(test_case->aad, 259 test_case->aad_length_octets)); 260 } 261 262 /* decrypt */ 263 len = test_case->ciphertext_length_octets; 264 status = cipher_decrypt(c, buffer, &len); 265 if (status) { 266 cipher_dealloc(c); 267 return status; 268 } 269 270 debug_print(mod_cipher, "plaintext: %s", 271 octet_string_hex_string(buffer, 272 test_case->plaintext_length_octets)); 273 274 /* compare the resulting plaintext with that in the test case */ 275 if (len != test_case->plaintext_length_octets) 276 return err_status_algo_fail; 277 status = err_status_ok; 278 for (i=0; i < test_case->plaintext_length_octets; i++) 279 if (buffer[i] != test_case->plaintext[i]) { 280 status = err_status_algo_fail; 281 debug_print(mod_cipher, "test case %d failed", case_num); 282 debug_print(mod_cipher, "(failure at byte %d)", i); 283 } 284 if (status) { 285 286 debug_print(mod_cipher, "p computed: %s", 287 octet_string_hex_string(buffer, 288 2*test_case->plaintext_length_octets)); 289 debug_print(mod_cipher, "p expected: %s", 290 octet_string_hex_string(test_case->plaintext, 291 2*test_case->plaintext_length_octets)); 292 293 cipher_dealloc(c); 294 return err_status_algo_fail; 295 } 296 297 /* deallocate the cipher */ 298 status = cipher_dealloc(c); 299 if (status) 300 return status; 301 302 /* 303 * the cipher passed the test case, so move on to the next test 304 * case in the list; if NULL, we'l proceed to the next test 305 */ 306 test_case = test_case->next_test_case; 307 ++case_num; 308 } 309 310 /* now run some random invertibility tests */ 311 312 /* allocate cipher, using paramaters from the first test case */ 313 test_case = test_data; 314 status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets); 315 if (status) 316 return status; 317 318 rand_source_init(); 319 320 for (j=0; j < NUM_RAND_TESTS; j++) { 321 unsigned length; 322 int plaintext_len; 323 uint8_t key[MAX_KEY_LEN]; 324 uint8_t iv[MAX_KEY_LEN]; 325 326 /* choose a length at random (leaving room for IV and padding) */ 327 length = rand() % (SELF_TEST_BUF_OCTETS - 64); 328 debug_print(mod_cipher, "random plaintext length %d\n", length); 329 status = rand_source_get_octet_string(buffer, length); 330 if (status) return status; 331 332 debug_print(mod_cipher, "plaintext: %s", 333 octet_string_hex_string(buffer, length)); 334 335 /* copy plaintext into second buffer */ 336 for (i=0; (unsigned int)i < length; i++) 337 buffer2[i] = buffer[i]; 338 339 /* choose a key at random */ 340 if (test_case->key_length_octets > MAX_KEY_LEN) 341 return err_status_cant_check; 342 status = rand_source_get_octet_string(key, test_case->key_length_octets); 343 if (status) return status; 344 345 /* chose a random initialization vector */ 346 status = rand_source_get_octet_string(iv, MAX_KEY_LEN); 347 if (status) return status; 348 349 /* initialize cipher */ 350 status = cipher_init(c, key); 351 if (status) { 352 cipher_dealloc(c); 353 return status; 354 } 355 356 /* set initialization vector */ 357 status = cipher_set_iv(c, test_case->idx, direction_encrypt); 358 if (status) { 359 cipher_dealloc(c); 360 return status; 361 } 362 363 if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 364 /* 365 * Set the AAD 366 */ 367 status = cipher_set_aad(c, test_case->aad, 368 test_case->aad_length_octets); 369 if (status) { 370 cipher_dealloc(c); 371 return status; 372 } 373 debug_print(mod_cipher, "AAD: %s", 374 octet_string_hex_string(test_case->aad, 375 test_case->aad_length_octets)); 376 } 377 378 /* encrypt buffer with cipher */ 379 plaintext_len = length; 380 status = cipher_encrypt(c, buffer, &length); 381 if (status) { 382 cipher_dealloc(c); 383 return status; 384 } 385 if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 386 /* 387 * Get the GCM tag 388 */ 389 status = cipher_get_tag(c, buffer + length, &tag_len); 390 if (status) { 391 cipher_dealloc(c); 392 return status; 393 } 394 length += tag_len; 395 } 396 debug_print(mod_cipher, "ciphertext: %s", 397 octet_string_hex_string(buffer, length)); 398 399 /* 400 * re-initialize cipher for decryption, re-set the iv, then 401 * decrypt the ciphertext 402 */ 403 status = cipher_init(c, key); 404 if (status) { 405 cipher_dealloc(c); 406 return status; 407 } 408 status = cipher_set_iv(c, test_case->idx, direction_decrypt); 409 if (status) { 410 cipher_dealloc(c); 411 return status; 412 } 413 if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) { 414 /* 415 * Set the AAD 416 */ 417 status = cipher_set_aad(c, test_case->aad, 418 test_case->aad_length_octets); 419 if (status) { 420 cipher_dealloc(c); 421 return status; 422 } 423 debug_print(mod_cipher, "AAD: %s", 424 octet_string_hex_string(test_case->aad, 425 test_case->aad_length_octets)); 426 } 427 status = cipher_decrypt(c, buffer, &length); 428 if (status) { 429 cipher_dealloc(c); 430 return status; 431 } 432 433 debug_print(mod_cipher, "plaintext[2]: %s", 434 octet_string_hex_string(buffer, length)); 435 436 /* compare the resulting plaintext with the original one */ 437 if (length != plaintext_len) { 438 return err_status_algo_fail; 439 } 440 status = err_status_ok; 441 for (i=0; i < plaintext_len; i++) 442 if (buffer[i] != buffer2[i]) { 443 status = err_status_algo_fail; 444 debug_print(mod_cipher, "random test case %d failed", case_num); 445 debug_print(mod_cipher, "(failure at byte %d)", i); 446 } 447 if (status) { 448 cipher_dealloc(c); 449 return err_status_algo_fail; 450 } 451 452 } 453 454 status = cipher_dealloc(c); 455 if (status) 456 return status; 457 458 return err_status_ok; 459 } 460 461 462 /* 463 * cipher_type_self_test(ct) performs cipher_type_test on ct's internal 587 return status; 588 } 589 590 return srtp_err_status_ok; 591 } 592 593 594 /* 595 * srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's internal 464 596 * list of test data. 465 597 */ 466 467 err_status_t 468 cipher_type_self_test(const cipher_type_t *ct) { 469 return cipher_type_test(ct, ct->test_data); 598 srtp_err_status_t srtp_cipher_type_self_test (const srtp_cipher_type_t *ct) 599 { 600 return srtp_cipher_type_test(ct, ct->test_data); 470 601 } 471 602 … … 473 604 * cipher_bits_per_second(c, l, t) computes (an estimate of) the 474 605 * number of bits that a cipher implementation can encrypt in a second 475 * 606 * 476 607 * c is a cipher (which MUST be allocated and initialized already), l 477 608 * is the length in octets of the test data to be encrypted, and t is … … 480 611 * if an error is encountered, the value 0 is returned 481 612 */ 482 483 uint64_t 484 cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) { 485 int i; 486 v128_t nonce; 487 clock_t timer; 488 unsigned char *enc_buf; 489 unsigned int len = octets_in_buffer; 490 491 enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer); 492 if (enc_buf == NULL) 493 return 0; /* indicate bad parameters by returning null */ 494 495 /* time repeated trials */ 496 v128_set_to_zero(&nonce); 497 timer = clock(); 498 for(i=0; i < num_trials; i++, nonce.v32[3] = i) { 499 cipher_set_iv(c, &nonce, direction_encrypt); 500 cipher_encrypt(c, enc_buf, &len); 501 } 502 timer = clock() - timer; 503 504 crypto_free(enc_buf); 505 506 if (timer == 0) { 507 /* Too fast! */ 508 return 0; 509 } 510 511 return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; 512 } 613 uint64_t srtp_cipher_bits_per_second (srtp_cipher_t *c, int octets_in_buffer, int num_trials) 614 { 615 int i; 616 v128_t nonce; 617 clock_t timer; 618 unsigned char *enc_buf; 619 unsigned int len = octets_in_buffer; 620 621 enc_buf = (unsigned char*)srtp_crypto_alloc(octets_in_buffer); 622 if (enc_buf == NULL) { 623 return 0; /* indicate bad parameters by returning null */ 624 625 } 626 /* time repeated trials */ 627 v128_set_to_zero(&nonce); 628 timer = clock(); 629 for (i = 0; i < num_trials; i++, nonce.v32[3] = i) { 630 if (srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt) != srtp_err_status_ok) { 631 srtp_crypto_free(enc_buf); 632 return 0; 633 } 634 if (srtp_cipher_encrypt(c, enc_buf, &len) != srtp_err_status_ok) { 635 srtp_crypto_free(enc_buf); 636 return 0; 637 } 638 } 639 timer = clock() - timer; 640 641 srtp_crypto_free(enc_buf); 642 643 if (timer == 0) { 644 /* Too fast! */ 645 return 0; 646 } 647 648 return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer; 649 }
Note: See TracChangeset
for help on using the changeset viewer.