tor-browser

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

aes_icm_ossl.c (12457B)


      1 /*
      2 * aes_icm_ossl.c
      3 *
      4 * AES Integer Counter Mode
      5 *
      6 * John A. Foley
      7 * Cisco Systems, Inc.
      8 *
      9 * 2/24/2012:  This module was modified to use CiscoSSL for AES counter
     10 *             mode.  Eddy Lem contributed the code to allow this.
     11 *
     12 * 12/20/2012: Added support for AES-192 and AES-256.
     13 */
     14 
     15 /*
     16 *
     17 * Copyright (c) 2013-2017, Cisco Systems, Inc.
     18 * All rights reserved.
     19 *
     20 * Redistribution and use in source and binary forms, with or without
     21 * modification, are permitted provided that the following conditions
     22 * are met:
     23 *
     24 *   Redistributions of source code must retain the above copyright
     25 *   notice, this list of conditions and the following disclaimer.
     26 *
     27 *   Redistributions in binary form must reproduce the above
     28 *   copyright notice, this list of conditions and the following
     29 *   disclaimer in the documentation and/or other materials provided
     30 *   with the distribution.
     31 *
     32 *   Neither the name of the Cisco Systems, Inc. nor the names of its
     33 *   contributors may be used to endorse or promote products derived
     34 *   from this software without specific prior written permission.
     35 *
     36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     37 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     38 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     39 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     40 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     41 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     43 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     47 * OF THE POSSIBILITY OF SUCH DAMAGE.
     48 *
     49 */
     50 
     51 #ifdef HAVE_CONFIG_H
     52 #include <config.h>
     53 #endif
     54 
     55 #include <openssl/evp.h>
     56 #include "aes_icm_ext.h"
     57 #include "crypto_types.h"
     58 #include "err.h" /* for srtp_debug */
     59 #include "alloc.h"
     60 #include "cipher_types.h"
     61 #include "cipher_test_cases.h"
     62 
     63 srtp_debug_module_t srtp_mod_aes_icm = {
     64    0,             /* debugging is off by default */
     65    "aes icm ossl" /* printable module name       */
     66 };
     67 
     68 /*
     69 * integer counter mode works as follows:
     70 *
     71 * 16 bits
     72 * <----->
     73 * +------+------+------+------+------+------+------+------+
     74 * |           nonce           |    packet index    |  ctr |---+
     75 * +------+------+------+------+------+------+------+------+   |
     76 *                                                             |
     77 * +------+------+------+------+------+------+------+------+   v
     78 * |                      salt                      |000000|->(+)
     79 * +------+------+------+------+------+------+------+------+   |
     80 *                                                             |
     81 *                                                        +---------+
     82 *                                                        | encrypt |
     83 *                                                        +---------+
     84 *                                                             |
     85 * +------+------+------+------+------+------+------+------+   |
     86 * |                    keystream block                    |<--+
     87 * +------+------+------+------+------+------+------+------+
     88 *
     89 * All fields are big-endian
     90 *
     91 * ctr is the block counter, which increments from zero for
     92 * each packet (16 bits wide)
     93 *
     94 * packet index is distinct for each packet (48 bits wide)
     95 *
     96 * nonce can be distinct across many uses of the same key, or
     97 * can be a fixed value per key, or can be per-packet randomness
     98 * (64 bits)
     99 *
    100 */
    101 
    102 /*
    103 * This function allocates a new instance of this crypto engine.
    104 * The key_len parameter should be one of 30, 38, or 46 for
    105 * AES-128, AES-192, and AES-256 respectively.  Note, this key_len
    106 * value is inflated, as it also accounts for the 112 bit salt
    107 * value.  The tlen argument is for the AEAD tag length, which
    108 * isn't used in counter mode.
    109 */
    110 static srtp_err_status_t srtp_aes_icm_openssl_alloc(srtp_cipher_t **c,
    111                                                    int key_len,
    112                                                    int tlen)
    113 {
    114    srtp_aes_icm_ctx_t *icm;
    115    (void)tlen;
    116 
    117    debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
    118                key_len);
    119 
    120    /*
    121     * Verify the key_len is valid for one of: AES-128/192/256
    122     */
    123    if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
    124        key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
    125        key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
    126        return srtp_err_status_bad_param;
    127    }
    128 
    129    /* allocate memory a cipher of type aes_icm */
    130    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
    131    if (*c == NULL) {
    132        return srtp_err_status_alloc_fail;
    133    }
    134 
    135    icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
    136    if (icm == NULL) {
    137        srtp_crypto_free(*c);
    138        *c = NULL;
    139        return srtp_err_status_alloc_fail;
    140    }
    141 
    142    icm->ctx = EVP_CIPHER_CTX_new();
    143    if (icm->ctx == NULL) {
    144        srtp_crypto_free(icm);
    145        srtp_crypto_free(*c);
    146        *c = NULL;
    147        return srtp_err_status_alloc_fail;
    148    }
    149 
    150    /* set pointers */
    151    (*c)->state = icm;
    152 
    153    /* setup cipher parameters */
    154    switch (key_len) {
    155    case SRTP_AES_ICM_128_KEY_LEN_WSALT:
    156        (*c)->algorithm = SRTP_AES_ICM_128;
    157        (*c)->type = &srtp_aes_icm_128;
    158        icm->key_size = SRTP_AES_128_KEY_LEN;
    159        break;
    160    case SRTP_AES_ICM_192_KEY_LEN_WSALT:
    161        (*c)->algorithm = SRTP_AES_ICM_192;
    162        (*c)->type = &srtp_aes_icm_192;
    163        icm->key_size = SRTP_AES_192_KEY_LEN;
    164        break;
    165    case SRTP_AES_ICM_256_KEY_LEN_WSALT:
    166        (*c)->algorithm = SRTP_AES_ICM_256;
    167        (*c)->type = &srtp_aes_icm_256;
    168        icm->key_size = SRTP_AES_256_KEY_LEN;
    169        break;
    170    }
    171 
    172    /* set key size */
    173    (*c)->key_len = key_len;
    174 
    175    return srtp_err_status_ok;
    176 }
    177 
    178 /*
    179 * This function deallocates an instance of this engine
    180 */
    181 static srtp_err_status_t srtp_aes_icm_openssl_dealloc(srtp_cipher_t *c)
    182 {
    183    srtp_aes_icm_ctx_t *ctx;
    184 
    185    if (c == NULL) {
    186        return srtp_err_status_bad_param;
    187    }
    188 
    189    /*
    190     * Free the EVP context
    191     */
    192    ctx = (srtp_aes_icm_ctx_t *)c->state;
    193    if (ctx != NULL) {
    194        EVP_CIPHER_CTX_free(ctx->ctx);
    195        /* zeroize the key material */
    196        octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
    197        srtp_crypto_free(ctx);
    198    }
    199 
    200    /* free memory */
    201    srtp_crypto_free(c);
    202 
    203    return srtp_err_status_ok;
    204 }
    205 
    206 /*
    207 * aes_icm_openssl_context_init(...) initializes the aes_icm_context
    208 * using the value in key[].
    209 *
    210 * the key is the secret key
    211 *
    212 * the salt is unpredictable (but not necessarily secret) data which
    213 * randomizes the starting point in the keystream
    214 */
    215 static srtp_err_status_t srtp_aes_icm_openssl_context_init(void *cv,
    216                                                           const uint8_t *key)
    217 {
    218    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    219    const EVP_CIPHER *evp;
    220 
    221    /*
    222     * set counter and initial values to 'offset' value, being careful not to
    223     * go past the end of the key buffer
    224     */
    225    v128_set_to_zero(&c->counter);
    226    v128_set_to_zero(&c->offset);
    227    memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN);
    228    memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
    229 
    230    /* force last two octets of the offset to zero (for srtp compatibility) */
    231    c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
    232    c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
    233 
    234    debug_print(srtp_mod_aes_icm, "key:  %s",
    235                srtp_octet_string_hex_string(key, c->key_size));
    236    debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
    237 
    238    switch (c->key_size) {
    239    case SRTP_AES_256_KEY_LEN:
    240        evp = EVP_aes_256_ctr();
    241        break;
    242    case SRTP_AES_192_KEY_LEN:
    243        evp = EVP_aes_192_ctr();
    244        break;
    245    case SRTP_AES_128_KEY_LEN:
    246        evp = EVP_aes_128_ctr();
    247        break;
    248    default:
    249        return srtp_err_status_bad_param;
    250        break;
    251    }
    252 
    253    EVP_CIPHER_CTX_reset(c->ctx);
    254 
    255    if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) {
    256        return srtp_err_status_fail;
    257    }
    258 
    259    return srtp_err_status_ok;
    260 }
    261 
    262 /*
    263 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
    264 * the offset
    265 */
    266 static srtp_err_status_t srtp_aes_icm_openssl_set_iv(
    267    void *cv,
    268    uint8_t *iv,
    269    srtp_cipher_direction_t dir)
    270 {
    271    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    272    v128_t nonce;
    273    (void)dir;
    274 
    275    /* set nonce (for alignment) */
    276    v128_copy_octet_string(&nonce, iv);
    277 
    278    debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
    279 
    280    v128_xor(&c->counter, &c->offset, &nonce);
    281 
    282    debug_print(srtp_mod_aes_icm, "set_counter: %s",
    283                v128_hex_string(&c->counter));
    284 
    285    if (!EVP_EncryptInit_ex(c->ctx, NULL, NULL, NULL, c->counter.v8)) {
    286        return srtp_err_status_fail;
    287    }
    288 
    289    return srtp_err_status_ok;
    290 }
    291 
    292 /*
    293 * This function encrypts a buffer using AES CTR mode
    294 *
    295 * Parameters:
    296 *	c	Crypto context
    297 *	buf	data to encrypt
    298 *	enc_len	length of encrypt buffer
    299 */
    300 static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv,
    301                                                      unsigned char *buf,
    302                                                      unsigned int *enc_len)
    303 {
    304    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
    305    int len = 0;
    306 
    307    debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));
    308 
    309    if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) {
    310        return srtp_err_status_cipher_fail;
    311    }
    312    *enc_len = len;
    313 
    314    if (!EVP_EncryptFinal_ex(c->ctx, buf + len, &len)) {
    315        return srtp_err_status_cipher_fail;
    316    }
    317    *enc_len += len;
    318 
    319    return srtp_err_status_ok;
    320 }
    321 
    322 /*
    323 * Name of this crypto engine
    324 */
    325 static const char srtp_aes_icm_128_openssl_description[] =
    326    "AES-128 counter mode using openssl";
    327 static const char srtp_aes_icm_192_openssl_description[] =
    328    "AES-192 counter mode using openssl";
    329 static const char srtp_aes_icm_256_openssl_description[] =
    330    "AES-256 counter mode using openssl";
    331 
    332 /*
    333 * This is the function table for this crypto engine.
    334 * note: the encrypt function is identical to the decrypt function
    335 */
    336 const srtp_cipher_type_t srtp_aes_icm_128 = {
    337    srtp_aes_icm_openssl_alloc,           /* */
    338    srtp_aes_icm_openssl_dealloc,         /* */
    339    srtp_aes_icm_openssl_context_init,    /* */
    340    0,                                    /* set_aad */
    341    srtp_aes_icm_openssl_encrypt,         /* */
    342    srtp_aes_icm_openssl_encrypt,         /* */
    343    srtp_aes_icm_openssl_set_iv,          /* */
    344    0,                                    /* get_tag */
    345    srtp_aes_icm_128_openssl_description, /* */
    346    &srtp_aes_icm_128_test_case_0,        /* */
    347    SRTP_AES_ICM_128                      /* */
    348 };
    349 
    350 /*
    351 * This is the function table for this crypto engine.
    352 * note: the encrypt function is identical to the decrypt function
    353 */
    354 const srtp_cipher_type_t srtp_aes_icm_192 = {
    355    srtp_aes_icm_openssl_alloc,           /* */
    356    srtp_aes_icm_openssl_dealloc,         /* */
    357    srtp_aes_icm_openssl_context_init,    /* */
    358    0,                                    /* set_aad */
    359    srtp_aes_icm_openssl_encrypt,         /* */
    360    srtp_aes_icm_openssl_encrypt,         /* */
    361    srtp_aes_icm_openssl_set_iv,          /* */
    362    0,                                    /* get_tag */
    363    srtp_aes_icm_192_openssl_description, /* */
    364    &srtp_aes_icm_192_test_case_0,        /* */
    365    SRTP_AES_ICM_192                      /* */
    366 };
    367 
    368 /*
    369 * This is the function table for this crypto engine.
    370 * note: the encrypt function is identical to the decrypt function
    371 */
    372 const srtp_cipher_type_t srtp_aes_icm_256 = {
    373    srtp_aes_icm_openssl_alloc,           /* */
    374    srtp_aes_icm_openssl_dealloc,         /* */
    375    srtp_aes_icm_openssl_context_init,    /* */
    376    0,                                    /* set_aad */
    377    srtp_aes_icm_openssl_encrypt,         /* */
    378    srtp_aes_icm_openssl_encrypt,         /* */
    379    srtp_aes_icm_openssl_set_iv,          /* */
    380    0,                                    /* get_tag */
    381    srtp_aes_icm_256_openssl_description, /* */
    382    &srtp_aes_icm_256_test_case_0,        /* */
    383    SRTP_AES_ICM_256                      /* */
    384 };