• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2017 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 "cipher_priv.h"
53 #include "crypto_types.h"
54 #include "err.h"   /* for srtp_debug */
55 #include "alloc.h" /* for crypto_alloc(), crypto_free()  */
56 
57 srtp_debug_module_t srtp_mod_cipher = {
58     0,       /* debugging is off by default */
59     "cipher" /* printable module name       */
60 };
61 
srtp_cipher_type_alloc(const srtp_cipher_type_t * ct,srtp_cipher_t ** c,int key_len,int tlen)62 srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct,
63                                          srtp_cipher_t **c,
64                                          int key_len,
65                                          int tlen)
66 {
67     if (!ct || !ct->alloc) {
68         return (srtp_err_status_bad_param);
69     }
70     return ((ct)->alloc((c), (key_len), (tlen)));
71 }
72 
srtp_cipher_dealloc(srtp_cipher_t * c)73 srtp_err_status_t srtp_cipher_dealloc(srtp_cipher_t *c)
74 {
75     if (!c || !c->type) {
76         return (srtp_err_status_bad_param);
77     }
78     return (((c)->type)->dealloc(c));
79 }
80 
srtp_cipher_init(srtp_cipher_t * c,const uint8_t * key)81 srtp_err_status_t srtp_cipher_init(srtp_cipher_t *c, const uint8_t *key)
82 {
83     if (!c || !c->type || !c->state) {
84         return (srtp_err_status_bad_param);
85     }
86     return (((c)->type)->init(((c)->state), (key)));
87 }
88 
srtp_cipher_set_iv(srtp_cipher_t * c,uint8_t * iv,int direction)89 srtp_err_status_t srtp_cipher_set_iv(srtp_cipher_t *c,
90                                      uint8_t *iv,
91                                      int direction)
92 {
93     if (!c || !c->type || !c->state) {
94         return (srtp_err_status_bad_param);
95     }
96 
97     return (((c)->type)->set_iv(((c)->state), iv, direction));
98 }
99 
srtp_cipher_output(srtp_cipher_t * c,uint8_t * buffer,uint32_t * num_octets_to_output)100 srtp_err_status_t srtp_cipher_output(srtp_cipher_t *c,
101                                      uint8_t *buffer,
102                                      uint32_t *num_octets_to_output)
103 {
104     /* zeroize the buffer */
105     octet_string_set_to_zero(buffer, *num_octets_to_output);
106 
107     /* exor keystream into buffer */
108     return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
109 }
110 
srtp_cipher_encrypt(srtp_cipher_t * c,uint8_t * buffer,uint32_t * num_octets_to_output)111 srtp_err_status_t srtp_cipher_encrypt(srtp_cipher_t *c,
112                                       uint8_t *buffer,
113                                       uint32_t *num_octets_to_output)
114 {
115     if (!c || !c->type || !c->state) {
116         return (srtp_err_status_bad_param);
117     }
118 
119     return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
120 }
121 
srtp_cipher_decrypt(srtp_cipher_t * c,uint8_t * buffer,uint32_t * num_octets_to_output)122 srtp_err_status_t srtp_cipher_decrypt(srtp_cipher_t *c,
123                                       uint8_t *buffer,
124                                       uint32_t *num_octets_to_output)
125 {
126     if (!c || !c->type || !c->state) {
127         return (srtp_err_status_bad_param);
128     }
129 
130     return (((c)->type)->decrypt(((c)->state), buffer, num_octets_to_output));
131 }
132 
srtp_cipher_get_tag(srtp_cipher_t * c,uint8_t * buffer,uint32_t * tag_len)133 srtp_err_status_t srtp_cipher_get_tag(srtp_cipher_t *c,
134                                       uint8_t *buffer,
135                                       uint32_t *tag_len)
136 {
137     if (!c || !c->type || !c->state) {
138         return (srtp_err_status_bad_param);
139     }
140     if (!((c)->type)->get_tag) {
141         return (srtp_err_status_no_such_op);
142     }
143 
144     return (((c)->type)->get_tag(((c)->state), buffer, tag_len));
145 }
146 
srtp_cipher_set_aad(srtp_cipher_t * c,const uint8_t * aad,uint32_t aad_len)147 srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c,
148                                       const uint8_t *aad,
149                                       uint32_t aad_len)
150 {
151     if (!c || !c->type || !c->state) {
152         return (srtp_err_status_bad_param);
153     }
154     if (!((c)->type)->set_aad) {
155         return (srtp_err_status_no_such_op);
156     }
157 
158     return (((c)->type)->set_aad(((c)->state), aad, aad_len));
159 }
160 
161 /* some bookkeeping functions */
162 
srtp_cipher_get_key_length(const srtp_cipher_t * c)163 int srtp_cipher_get_key_length(const srtp_cipher_t *c)
164 {
165     return c->key_len;
166 }
167 
168 /*
169  * A trivial platform independent random source.
170  * For use in test only.
171  */
srtp_cipher_rand_for_tests(void * dest,uint32_t len)172 void srtp_cipher_rand_for_tests(void *dest, uint32_t len)
173 {
174     /* Generic C-library (rand()) version */
175     /* This is a random source of last resort */
176     uint8_t *dst = (uint8_t *)dest;
177     while (len) {
178         int val = rand();
179         /* rand() returns 0-32767 (ugh) */
180         /* Is this a good enough way to get random bytes?
181            It is if it passes FIPS-140... */
182         *dst++ = val & 0xff;
183         len--;
184     }
185 }
186 
187 /*
188  * A trivial platform independent 32 bit random number.
189  * For use in test only.
190  */
srtp_cipher_rand_u32_for_tests(void)191 uint32_t srtp_cipher_rand_u32_for_tests(void)
192 {
193     uint32_t r;
194     srtp_cipher_rand_for_tests(&r, sizeof(r));
195     return r;
196 }
197 
198 #define SELF_TEST_BUF_OCTETS 128
199 #define NUM_RAND_TESTS 128
200 #define MAX_KEY_LEN 64
201 /*
202  * srtp_cipher_type_test(ct, test_data) tests a cipher of type ct against
203  * test cases provided in a list test_data of values of key, salt, iv,
204  * plaintext, and ciphertext that is known to be good
205  */
srtp_cipher_type_test(const srtp_cipher_type_t * ct,const srtp_cipher_test_case_t * test_data)206 srtp_err_status_t srtp_cipher_type_test(
207     const srtp_cipher_type_t *ct,
208     const srtp_cipher_test_case_t *test_data)
209 {
210     const srtp_cipher_test_case_t *test_case = test_data;
211     srtp_cipher_t *c;
212     srtp_err_status_t status;
213     uint8_t buffer[SELF_TEST_BUF_OCTETS];
214     uint8_t buffer2[SELF_TEST_BUF_OCTETS];
215     uint32_t tag_len;
216     unsigned int len;
217     int i, j, case_num = 0;
218     unsigned k = 0;
219 
220     debug_print(srtp_mod_cipher, "running self-test for cipher %s",
221                 ct->description);
222 
223     /*
224      * check to make sure that we have at least one test case, and
225      * return an error if we don't - we need to be paranoid here
226      */
227     if (test_case == NULL) {
228         return srtp_err_status_cant_check;
229     }
230 
231     /*
232      * loop over all test cases, perform known-answer tests of both the
233      * encryption and decryption functions
234      */
235     while (test_case != NULL) {
236         /* allocate cipher */
237         status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets,
238                                         test_case->tag_length_octets);
239         if (status) {
240             return status;
241         }
242 
243         /*
244          * test the encrypt function
245          */
246         debug_print(srtp_mod_cipher, "testing encryption", NULL);
247 
248         /* initialize cipher */
249         status = srtp_cipher_init(c, test_case->key);
250         if (status) {
251             srtp_cipher_dealloc(c);
252             return status;
253         }
254 
255         /* copy plaintext into test buffer */
256         if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
257             srtp_cipher_dealloc(c);
258             return srtp_err_status_bad_param;
259         }
260         for (k = 0; k < test_case->plaintext_length_octets; k++) {
261             buffer[k] = test_case->plaintext[k];
262         }
263 
264         debug_print(srtp_mod_cipher, "plaintext:    %s",
265                     srtp_octet_string_hex_string(
266                         buffer, test_case->plaintext_length_octets));
267 
268         /* set the initialization vector */
269         status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
270                                     srtp_direction_encrypt);
271         if (status) {
272             srtp_cipher_dealloc(c);
273             return status;
274         }
275 
276         if (c->algorithm == SRTP_AES_GCM_128 ||
277             c->algorithm == SRTP_AES_GCM_256) {
278             debug_print(srtp_mod_cipher, "IV:    %s",
279                         srtp_octet_string_hex_string(test_case->idx, 12));
280 
281             /*
282              * Set the AAD
283              */
284             status = srtp_cipher_set_aad(c, test_case->aad,
285                                          test_case->aad_length_octets);
286             if (status) {
287                 srtp_cipher_dealloc(c);
288                 return status;
289             }
290             debug_print(srtp_mod_cipher, "AAD:    %s",
291                         srtp_octet_string_hex_string(
292                             test_case->aad, test_case->aad_length_octets));
293         }
294 
295         /* encrypt */
296         len = test_case->plaintext_length_octets;
297         status = srtp_cipher_encrypt(c, buffer, &len);
298         if (status) {
299             srtp_cipher_dealloc(c);
300             return status;
301         }
302 
303         if (c->algorithm == SRTP_AES_GCM_128 ||
304             c->algorithm == SRTP_AES_GCM_256) {
305             /*
306              * Get the GCM tag
307              */
308             status = srtp_cipher_get_tag(c, buffer + len, &tag_len);
309             if (status) {
310                 srtp_cipher_dealloc(c);
311                 return status;
312             }
313             len += tag_len;
314         }
315 
316         debug_print(srtp_mod_cipher, "ciphertext:   %s",
317                     srtp_octet_string_hex_string(
318                         buffer, test_case->ciphertext_length_octets));
319 
320         /* compare the resulting ciphertext with that in the test case */
321         if (len != test_case->ciphertext_length_octets) {
322             srtp_cipher_dealloc(c);
323             return srtp_err_status_algo_fail;
324         }
325         status = srtp_err_status_ok;
326         for (k = 0; k < test_case->ciphertext_length_octets; k++) {
327             if (buffer[k] != test_case->ciphertext[k]) {
328                 status = srtp_err_status_algo_fail;
329                 debug_print(srtp_mod_cipher, "test case %d failed", case_num);
330                 debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
331                 break;
332             }
333         }
334         if (status) {
335             debug_print(srtp_mod_cipher, "c computed: %s",
336                         srtp_octet_string_hex_string(
337                             buffer, 2 * test_case->plaintext_length_octets));
338             debug_print(srtp_mod_cipher, "c expected: %s",
339                         srtp_octet_string_hex_string(
340                             test_case->ciphertext,
341                             2 * test_case->plaintext_length_octets));
342 
343             srtp_cipher_dealloc(c);
344             return srtp_err_status_algo_fail;
345         }
346 
347         /*
348          * test the decrypt function
349          */
350         debug_print(srtp_mod_cipher, "testing decryption", NULL);
351 
352         /* re-initialize cipher for decryption */
353         status = srtp_cipher_init(c, test_case->key);
354         if (status) {
355             srtp_cipher_dealloc(c);
356             return status;
357         }
358 
359         /* copy ciphertext into test buffer */
360         if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
361             srtp_cipher_dealloc(c);
362             return srtp_err_status_bad_param;
363         }
364         for (k = 0; k < test_case->ciphertext_length_octets; k++) {
365             buffer[k] = test_case->ciphertext[k];
366         }
367 
368         debug_print(srtp_mod_cipher, "ciphertext:    %s",
369                     srtp_octet_string_hex_string(
370                         buffer, test_case->plaintext_length_octets));
371 
372         /* set the initialization vector */
373         status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
374                                     srtp_direction_decrypt);
375         if (status) {
376             srtp_cipher_dealloc(c);
377             return status;
378         }
379 
380         if (c->algorithm == SRTP_AES_GCM_128 ||
381             c->algorithm == SRTP_AES_GCM_256) {
382             /*
383              * Set the AAD
384              */
385             status = srtp_cipher_set_aad(c, test_case->aad,
386                                          test_case->aad_length_octets);
387             if (status) {
388                 srtp_cipher_dealloc(c);
389                 return status;
390             }
391             debug_print(srtp_mod_cipher, "AAD:    %s",
392                         srtp_octet_string_hex_string(
393                             test_case->aad, test_case->aad_length_octets));
394         }
395 
396         /* decrypt */
397         len = test_case->ciphertext_length_octets;
398         status = srtp_cipher_decrypt(c, buffer, &len);
399         if (status) {
400             srtp_cipher_dealloc(c);
401             return status;
402         }
403 
404         debug_print(srtp_mod_cipher, "plaintext:   %s",
405                     srtp_octet_string_hex_string(
406                         buffer, test_case->plaintext_length_octets));
407 
408         /* compare the resulting plaintext with that in the test case */
409         if (len != test_case->plaintext_length_octets) {
410             srtp_cipher_dealloc(c);
411             return srtp_err_status_algo_fail;
412         }
413         status = srtp_err_status_ok;
414         for (k = 0; k < test_case->plaintext_length_octets; k++) {
415             if (buffer[k] != test_case->plaintext[k]) {
416                 status = srtp_err_status_algo_fail;
417                 debug_print(srtp_mod_cipher, "test case %d failed", case_num);
418                 debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
419             }
420         }
421         if (status) {
422             debug_print(srtp_mod_cipher, "p computed: %s",
423                         srtp_octet_string_hex_string(
424                             buffer, 2 * test_case->plaintext_length_octets));
425             debug_print(srtp_mod_cipher, "p expected: %s",
426                         srtp_octet_string_hex_string(
427                             test_case->plaintext,
428                             2 * test_case->plaintext_length_octets));
429 
430             srtp_cipher_dealloc(c);
431             return srtp_err_status_algo_fail;
432         }
433 
434         /* deallocate the cipher */
435         status = srtp_cipher_dealloc(c);
436         if (status) {
437             return status;
438         }
439 
440         /*
441          * the cipher passed the test case, so move on to the next test
442          * case in the list; if NULL, we'l proceed to the next test
443          */
444         test_case = test_case->next_test_case;
445         ++case_num;
446     }
447 
448     /* now run some random invertibility tests */
449 
450     /* allocate cipher, using paramaters from the first test case */
451     test_case = test_data;
452     status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets,
453                                     test_case->tag_length_octets);
454     if (status) {
455         return status;
456     }
457 
458     for (j = 0; j < NUM_RAND_TESTS; j++) {
459         unsigned int length;
460         unsigned int plaintext_len;
461         uint8_t key[MAX_KEY_LEN];
462         uint8_t iv[MAX_KEY_LEN];
463 
464         /* choose a length at random (leaving room for IV and padding) */
465         length = srtp_cipher_rand_u32_for_tests() % (SELF_TEST_BUF_OCTETS - 64);
466         debug_print(srtp_mod_cipher, "random plaintext length %d\n", length);
467         srtp_cipher_rand_for_tests(buffer, length);
468 
469         debug_print(srtp_mod_cipher, "plaintext:    %s",
470                     srtp_octet_string_hex_string(buffer, length));
471 
472         /* copy plaintext into second buffer */
473         for (i = 0; (unsigned int)i < length; i++) {
474             buffer2[i] = buffer[i];
475         }
476 
477         /* choose a key at random */
478         if (test_case->key_length_octets > MAX_KEY_LEN) {
479             srtp_cipher_dealloc(c);
480             return srtp_err_status_cant_check;
481         }
482         srtp_cipher_rand_for_tests(key, test_case->key_length_octets);
483 
484         /* chose a random initialization vector */
485         srtp_cipher_rand_for_tests(iv, MAX_KEY_LEN);
486 
487         /* initialize cipher */
488         status = srtp_cipher_init(c, key);
489         if (status) {
490             srtp_cipher_dealloc(c);
491             return status;
492         }
493 
494         /* set initialization vector */
495         status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
496                                     srtp_direction_encrypt);
497         if (status) {
498             srtp_cipher_dealloc(c);
499             return status;
500         }
501 
502         if (c->algorithm == SRTP_AES_GCM_128 ||
503             c->algorithm == SRTP_AES_GCM_256) {
504             /*
505              * Set the AAD
506              */
507             status = srtp_cipher_set_aad(c, test_case->aad,
508                                          test_case->aad_length_octets);
509             if (status) {
510                 srtp_cipher_dealloc(c);
511                 return status;
512             }
513             debug_print(srtp_mod_cipher, "AAD:    %s",
514                         srtp_octet_string_hex_string(
515                             test_case->aad, test_case->aad_length_octets));
516         }
517 
518         /* encrypt buffer with cipher */
519         plaintext_len = length;
520         status = srtp_cipher_encrypt(c, buffer, &length);
521         if (status) {
522             srtp_cipher_dealloc(c);
523             return status;
524         }
525         if (c->algorithm == SRTP_AES_GCM_128 ||
526             c->algorithm == SRTP_AES_GCM_256) {
527             /*
528              * Get the GCM tag
529              */
530             status = srtp_cipher_get_tag(c, buffer + length, &tag_len);
531             if (status) {
532                 srtp_cipher_dealloc(c);
533                 return status;
534             }
535             length += tag_len;
536         }
537         debug_print(srtp_mod_cipher, "ciphertext:   %s",
538                     srtp_octet_string_hex_string(buffer, length));
539 
540         /*
541          * re-initialize cipher for decryption, re-set the iv, then
542          * decrypt the ciphertext
543          */
544         status = srtp_cipher_init(c, key);
545         if (status) {
546             srtp_cipher_dealloc(c);
547             return status;
548         }
549         status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
550                                     srtp_direction_decrypt);
551         if (status) {
552             srtp_cipher_dealloc(c);
553             return status;
554         }
555         if (c->algorithm == SRTP_AES_GCM_128 ||
556             c->algorithm == SRTP_AES_GCM_256) {
557             /*
558              * Set the AAD
559              */
560             status = srtp_cipher_set_aad(c, test_case->aad,
561                                          test_case->aad_length_octets);
562             if (status) {
563                 srtp_cipher_dealloc(c);
564                 return status;
565             }
566             debug_print(srtp_mod_cipher, "AAD:    %s",
567                         srtp_octet_string_hex_string(
568                             test_case->aad, test_case->aad_length_octets));
569         }
570         status = srtp_cipher_decrypt(c, buffer, &length);
571         if (status) {
572             srtp_cipher_dealloc(c);
573             return status;
574         }
575 
576         debug_print(srtp_mod_cipher, "plaintext[2]: %s",
577                     srtp_octet_string_hex_string(buffer, length));
578 
579         /* compare the resulting plaintext with the original one */
580         if (length != plaintext_len) {
581             srtp_cipher_dealloc(c);
582             return srtp_err_status_algo_fail;
583         }
584         status = srtp_err_status_ok;
585         for (k = 0; k < plaintext_len; k++) {
586             if (buffer[k] != buffer2[k]) {
587                 status = srtp_err_status_algo_fail;
588                 debug_print(srtp_mod_cipher, "random test case %d failed",
589                             case_num);
590                 debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
591             }
592         }
593         if (status) {
594             srtp_cipher_dealloc(c);
595             return srtp_err_status_algo_fail;
596         }
597     }
598 
599     status = srtp_cipher_dealloc(c);
600     if (status) {
601         return status;
602     }
603 
604     return srtp_err_status_ok;
605 }
606 
607 /*
608  * srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's
609  * internal list of test data.
610  */
srtp_cipher_type_self_test(const srtp_cipher_type_t * ct)611 srtp_err_status_t srtp_cipher_type_self_test(const srtp_cipher_type_t *ct)
612 {
613     return srtp_cipher_type_test(ct, ct->test_data);
614 }
615 
616 /*
617  * cipher_bits_per_second(c, l, t) computes (an estimate of) the
618  * number of bits that a cipher implementation can encrypt in a second
619  *
620  * c is a cipher (which MUST be allocated and initialized already), l
621  * is the length in octets of the test data to be encrypted, and t is
622  * the number of trials
623  *
624  * if an error is encountered, the value 0 is returned
625  */
srtp_cipher_bits_per_second(srtp_cipher_t * c,int octets_in_buffer,int num_trials)626 uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c,
627                                      int octets_in_buffer,
628                                      int num_trials)
629 {
630     int i;
631     v128_t nonce;
632     clock_t timer;
633     unsigned char *enc_buf;
634     unsigned int len = octets_in_buffer;
635 
636     enc_buf = (unsigned char *)srtp_crypto_alloc(octets_in_buffer);
637     if (enc_buf == NULL) {
638         return 0; /* indicate bad parameters by returning null */
639     }
640     /* time repeated trials */
641     v128_set_to_zero(&nonce);
642     timer = clock();
643     for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
644         if (srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt) !=
645             srtp_err_status_ok) {
646             srtp_crypto_free(enc_buf);
647             return 0;
648         }
649         if (srtp_cipher_encrypt(c, enc_buf, &len) != srtp_err_status_ok) {
650             srtp_crypto_free(enc_buf);
651             return 0;
652         }
653     }
654     timer = clock() - timer;
655 
656     srtp_crypto_free(enc_buf);
657 
658     if (timer == 0) {
659         /* Too fast! */
660         return 0;
661     }
662 
663     return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
664 }
665