tor-browser

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

aes_gcm_mbedtls.c (12561B)


      1 /*
      2 * aes_gcm_mbedtls.c
      3 *
      4 * AES Galois Counter Mode
      5 *
      6 * YongCheng Yang
      7 *
      8 */
      9 
     10 /*
     11 *
     12 * Copyright (c) 2013-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 
     46 #ifdef HAVE_CONFIG_H
     47 #include <config.h>
     48 #endif
     49 #include <mbedtls/gcm.h>
     50 #include "aes_gcm.h"
     51 #include "alloc.h"
     52 #include "err.h" /* for srtp_debug */
     53 #include "crypto_types.h"
     54 #include "cipher_types.h"
     55 #include "cipher_test_cases.h"
     56 
     57 srtp_debug_module_t srtp_mod_aes_gcm = {
     58    0,                /* debugging is off by default */
     59    "aes gcm mbedtls" /* printable module name       */
     60 };
     61 
     62 /**
     63 * SRTP IV Formation for AES-GCM
     64 * https://tools.ietf.org/html/rfc7714#section-8.1
     65 *   0  0  0  0  0  0  0  0  0  0  1  1
     66 *   0  1  2  3  4  5  6  7  8  9  0  1
     67 *  +--+--+--+--+--+--+--+--+--+--+--+--+
     68 *  |00|00| SSRC      | ROC       | SEQ |---+
     69 *  +--+--+--+--+--+--+--+--+--+--+--+--+   |
     70 *  |
     71 *  +--+--+--+--+--+--+--+--+--+--+--+--+   |
     72 *  | Encryption Salt                   |->(+)
     73 *  +--+--+--+--+--+--+--+--+--+--+--+--+   |
     74 *                                          |
     75 *  +--+--+--+--+--+--+--+--+--+--+--+--+   |
     76 *  | Initialization Vector             |<--+
     77 *  +--+--+--+--+--+--+--+--+--+--+--+--+
     78 *
     79 * SRTCP IV Formation for AES-GCM
     80 * https://tools.ietf.org/html/rfc7714#section-9.1
     81 *
     82 */
     83 
     84 /*
     85 * For now we only support 8 and 16 octet tags.  The spec allows for
     86 * optional 12 byte tag, which may be supported in the future.
     87 */
     88 #define GCM_IV_LEN 12
     89 #define GCM_AUTH_TAG_LEN 16
     90 #define GCM_AUTH_TAG_LEN_8 8
     91 
     92 #define FUNC_ENTRY() debug_print(srtp_mod_aes_gcm, "%s entry", __func__);
     93 /*
     94 * This function allocates a new instance of this crypto engine.
     95 * The key_len parameter should be one of 28 or 44 for
     96 * AES-128-GCM or AES-256-GCM respectively.  Note that the
     97 * key length includes the 14 byte salt value that is used when
     98 * initializing the KDF.
     99 */
    100 static srtp_err_status_t srtp_aes_gcm_mbedtls_alloc(srtp_cipher_t **c,
    101                                                    int key_len,
    102                                                    int tlen)
    103 {
    104    FUNC_ENTRY();
    105    srtp_aes_gcm_ctx_t *gcm;
    106 
    107    debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d",
    108                key_len);
    109    debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
    110 
    111    /*
    112     * Verify the key_len is valid for one of: AES-128/256
    113     */
    114    if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
    115        key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
    116        return (srtp_err_status_bad_param);
    117    }
    118 
    119    if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
    120        return (srtp_err_status_bad_param);
    121    }
    122 
    123    /* allocate memory a cipher of type aes_gcm */
    124    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
    125    if (*c == NULL) {
    126        return (srtp_err_status_alloc_fail);
    127    }
    128 
    129    gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t));
    130    if (gcm == NULL) {
    131        srtp_crypto_free(*c);
    132        *c = NULL;
    133        return (srtp_err_status_alloc_fail);
    134    }
    135 
    136    gcm->ctx =
    137        (mbedtls_gcm_context *)srtp_crypto_alloc(sizeof(mbedtls_gcm_context));
    138    if (gcm->ctx == NULL) {
    139        srtp_crypto_free(gcm);
    140        srtp_crypto_free(*c);
    141        *c = NULL;
    142        return srtp_err_status_alloc_fail;
    143    }
    144    mbedtls_gcm_init(gcm->ctx);
    145 
    146    /* set pointers */
    147    (*c)->state = gcm;
    148 
    149    /* setup cipher attributes */
    150    switch (key_len) {
    151    case SRTP_AES_GCM_128_KEY_LEN_WSALT:
    152        (*c)->type = &srtp_aes_gcm_128;
    153        (*c)->algorithm = SRTP_AES_GCM_128;
    154        gcm->key_size = SRTP_AES_128_KEY_LEN;
    155        gcm->tag_len = tlen;
    156        break;
    157    case SRTP_AES_GCM_256_KEY_LEN_WSALT:
    158        (*c)->type = &srtp_aes_gcm_256;
    159        (*c)->algorithm = SRTP_AES_GCM_256;
    160        gcm->key_size = SRTP_AES_256_KEY_LEN;
    161        gcm->tag_len = tlen;
    162        break;
    163    }
    164 
    165    /* set key size        */
    166    (*c)->key_len = key_len;
    167 
    168    return (srtp_err_status_ok);
    169 }
    170 
    171 /*
    172 * This function deallocates a GCM session
    173 */
    174 static srtp_err_status_t srtp_aes_gcm_mbedtls_dealloc(srtp_cipher_t *c)
    175 {
    176    srtp_aes_gcm_ctx_t *ctx;
    177    FUNC_ENTRY();
    178    ctx = (srtp_aes_gcm_ctx_t *)c->state;
    179    if (ctx) {
    180        mbedtls_gcm_free(ctx->ctx);
    181        srtp_crypto_free(ctx->ctx);
    182        /* zeroize the key material */
    183        octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
    184        srtp_crypto_free(ctx);
    185    }
    186 
    187    /* free memory */
    188    srtp_crypto_free(c);
    189 
    190    return (srtp_err_status_ok);
    191 }
    192 
    193 static srtp_err_status_t srtp_aes_gcm_mbedtls_context_init(void *cv,
    194                                                           const uint8_t *key)
    195 {
    196    FUNC_ENTRY();
    197    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
    198    uint32_t key_len_in_bits;
    199    int errCode = 0;
    200    c->dir = srtp_direction_any;
    201    c->aad_size = 0;
    202 
    203    debug_print(srtp_mod_aes_gcm, "key:  %s",
    204                srtp_octet_string_hex_string(key, c->key_size));
    205    key_len_in_bits = (c->key_size << 3);
    206    switch (c->key_size) {
    207    case SRTP_AES_256_KEY_LEN:
    208    case SRTP_AES_128_KEY_LEN:
    209        break;
    210    default:
    211        return (srtp_err_status_bad_param);
    212        break;
    213    }
    214 
    215    errCode = mbedtls_gcm_setkey(c->ctx, MBEDTLS_CIPHER_ID_AES,
    216                                 (const unsigned char *)key, key_len_in_bits);
    217    if (errCode != 0) {
    218        debug_print(srtp_mod_aes_gcm, "mbedtls error code:  %d", errCode);
    219        return srtp_err_status_init_fail;
    220    }
    221 
    222    return (srtp_err_status_ok);
    223 }
    224 
    225 static srtp_err_status_t srtp_aes_gcm_mbedtls_set_iv(
    226    void *cv,
    227    uint8_t *iv,
    228    srtp_cipher_direction_t direction)
    229 {
    230    FUNC_ENTRY();
    231    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
    232 
    233    if (direction != srtp_direction_encrypt &&
    234        direction != srtp_direction_decrypt) {
    235        return (srtp_err_status_bad_param);
    236    }
    237    c->dir = direction;
    238 
    239    debug_print(srtp_mod_aes_gcm, "setting iv: %s",
    240                srtp_octet_string_hex_string(iv, GCM_IV_LEN));
    241    c->iv_len = GCM_IV_LEN;
    242    memcpy(c->iv, iv, c->iv_len);
    243    return (srtp_err_status_ok);
    244 }
    245 
    246 /*
    247 * This function processes the AAD
    248 *
    249 * Parameters:
    250 *	c	Crypto context
    251 *	aad	Additional data to process for AEAD cipher suites
    252 *	aad_len	length of aad buffer
    253 */
    254 static srtp_err_status_t srtp_aes_gcm_mbedtls_set_aad(void *cv,
    255                                                      const uint8_t *aad,
    256                                                      uint32_t aad_len)
    257 {
    258    FUNC_ENTRY();
    259    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
    260 
    261    debug_print(srtp_mod_aes_gcm, "setting AAD: %s",
    262                srtp_octet_string_hex_string(aad, aad_len));
    263 
    264    if (aad_len + c->aad_size > MAX_AD_SIZE) {
    265        return srtp_err_status_bad_param;
    266    }
    267 
    268    memcpy(c->aad + c->aad_size, aad, aad_len);
    269    c->aad_size += aad_len;
    270 
    271    return (srtp_err_status_ok);
    272 }
    273 
    274 /*
    275 * This function encrypts a buffer using AES GCM mode
    276 *
    277 * Parameters:
    278 *	c	Crypto context
    279 *	buf	data to encrypt
    280 *	enc_len	length of encrypt buffer
    281 */
    282 static srtp_err_status_t srtp_aes_gcm_mbedtls_encrypt(void *cv,
    283                                                      unsigned char *buf,
    284                                                      unsigned int *enc_len)
    285 {
    286    FUNC_ENTRY();
    287    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
    288    int errCode = 0;
    289 
    290    if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
    291        return (srtp_err_status_bad_param);
    292    }
    293 
    294    errCode = mbedtls_gcm_crypt_and_tag(c->ctx, MBEDTLS_GCM_ENCRYPT, *enc_len,
    295                                        c->iv, c->iv_len, c->aad, c->aad_size,
    296                                        buf, buf, c->tag_len, c->tag);
    297 
    298    c->aad_size = 0;
    299    if (errCode != 0) {
    300        debug_print(srtp_mod_aes_gcm, "mbedtls error code:  %d", errCode);
    301        return srtp_err_status_bad_param;
    302    }
    303 
    304    return (srtp_err_status_ok);
    305 }
    306 
    307 /*
    308 * This function calculates and returns the GCM tag for a given context.
    309 * This should be called after encrypting the data.  The *len value
    310 * is increased by the tag size.  The caller must ensure that *buf has
    311 * enough room to accept the appended tag.
    312 *
    313 * Parameters:
    314 *	c	Crypto context
    315 *	buf	data to encrypt
    316 *	len	length of encrypt buffer
    317 */
    318 static srtp_err_status_t srtp_aes_gcm_mbedtls_get_tag(void *cv,
    319                                                      uint8_t *buf,
    320                                                      uint32_t *len)
    321 {
    322    FUNC_ENTRY();
    323    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
    324    debug_print(srtp_mod_aes_gcm, "appended tag size:  %d", c->tag_len);
    325    *len = c->tag_len;
    326    memcpy(buf, c->tag, c->tag_len);
    327    return (srtp_err_status_ok);
    328 }
    329 
    330 /*
    331 * This function decrypts a buffer using AES GCM mode
    332 *
    333 * Parameters:
    334 *	c	Crypto context
    335 *	buf	data to encrypt
    336 *	enc_len	length of encrypt buffer
    337 */
    338 static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv,
    339                                                      unsigned char *buf,
    340                                                      unsigned int *enc_len)
    341 {
    342    FUNC_ENTRY();
    343    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
    344    int errCode = 0;
    345 
    346    if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
    347        return (srtp_err_status_bad_param);
    348    }
    349 
    350    debug_print(srtp_mod_aes_gcm, "AAD: %s",
    351                srtp_octet_string_hex_string(c->aad, c->aad_size));
    352 
    353    errCode = mbedtls_gcm_auth_decrypt(
    354        c->ctx, (*enc_len - c->tag_len), c->iv, c->iv_len, c->aad, c->aad_size,
    355        buf + (*enc_len - c->tag_len), c->tag_len, buf, buf);
    356    c->aad_size = 0;
    357    if (errCode != 0) {
    358        return (srtp_err_status_auth_fail);
    359    }
    360 
    361    /*
    362     * Reduce the buffer size by the tag length since the tag
    363     * is not part of the original payload
    364     */
    365    *enc_len -= c->tag_len;
    366 
    367    return (srtp_err_status_ok);
    368 }
    369 
    370 /*
    371 * Name of this crypto engine
    372 */
    373 static const char srtp_aes_gcm_128_mbedtls_description[] =
    374    "AES-128 GCM using mbedtls";
    375 static const char srtp_aes_gcm_256_mbedtls_description[] =
    376    "AES-256 GCM using mbedtls";
    377 
    378 /*
    379 * This is the vector function table for this crypto engine.
    380 */
    381 const srtp_cipher_type_t srtp_aes_gcm_128 = {
    382    srtp_aes_gcm_mbedtls_alloc,
    383    srtp_aes_gcm_mbedtls_dealloc,
    384    srtp_aes_gcm_mbedtls_context_init,
    385    srtp_aes_gcm_mbedtls_set_aad,
    386    srtp_aes_gcm_mbedtls_encrypt,
    387    srtp_aes_gcm_mbedtls_decrypt,
    388    srtp_aes_gcm_mbedtls_set_iv,
    389    srtp_aes_gcm_mbedtls_get_tag,
    390    srtp_aes_gcm_128_mbedtls_description,
    391    &srtp_aes_gcm_128_test_case_0,
    392    SRTP_AES_GCM_128
    393 };
    394 
    395 /*
    396 * This is the vector function table for this crypto engine.
    397 */
    398 const srtp_cipher_type_t srtp_aes_gcm_256 = {
    399    srtp_aes_gcm_mbedtls_alloc,
    400    srtp_aes_gcm_mbedtls_dealloc,
    401    srtp_aes_gcm_mbedtls_context_init,
    402    srtp_aes_gcm_mbedtls_set_aad,
    403    srtp_aes_gcm_mbedtls_encrypt,
    404    srtp_aes_gcm_mbedtls_decrypt,
    405    srtp_aes_gcm_mbedtls_set_iv,
    406    srtp_aes_gcm_mbedtls_get_tag,
    407    srtp_aes_gcm_256_mbedtls_description,
    408    &srtp_aes_gcm_256_test_case_0,
    409    SRTP_AES_GCM_256
    410 };