tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cipher.c (22597B)


      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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 */
    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 */
    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 */
    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_print0(srtp_mod_cipher, "testing encryption");
    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_print0(srtp_mod_cipher, "testing decryption");
    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 */
    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 */
    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    uint32_t tag_len = SRTP_MAX_TAG_LEN;
    636    unsigned char aad[4] = { 0, 0, 0, 0 };
    637    uint32_t aad_len = 4;
    638 
    639    enc_buf = (unsigned char *)srtp_crypto_alloc(octets_in_buffer + tag_len);
    640    if (enc_buf == NULL) {
    641        return 0; /* indicate bad parameters by returning null */
    642    }
    643    /* time repeated trials */
    644    v128_set_to_zero(&nonce);
    645    timer = clock();
    646    for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
    647        // Set IV
    648        if (srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt) !=
    649            srtp_err_status_ok) {
    650            srtp_crypto_free(enc_buf);
    651            return 0;
    652        }
    653 
    654        // Set (empty) AAD if supported by the cipher
    655        if (c->type->set_aad) {
    656            if (srtp_cipher_set_aad(c, aad, aad_len) != srtp_err_status_ok) {
    657                srtp_crypto_free(enc_buf);
    658                return 0;
    659            }
    660        }
    661 
    662        // Encrypt the buffer
    663        if (srtp_cipher_encrypt(c, enc_buf, &len) != srtp_err_status_ok) {
    664            srtp_crypto_free(enc_buf);
    665            return 0;
    666        }
    667 
    668        // Get tag if supported by the cipher
    669        if (c->type->get_tag) {
    670            if (srtp_cipher_get_tag(c, (uint8_t *)(enc_buf + len), &tag_len) !=
    671                srtp_err_status_ok) {
    672                srtp_crypto_free(enc_buf);
    673                return 0;
    674            }
    675        }
    676    }
    677    timer = clock() - timer;
    678 
    679    srtp_crypto_free(enc_buf);
    680 
    681    if (timer == 0) {
    682        /* Too fast! */
    683        return 0;
    684    }
    685 
    686    return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
    687 }