cipher.c 21 KB

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