tor-browser

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

crypto_kernel.c (17216B)


      1 /*
      2 * crypto_kernel.c
      3 *
      4 * header for the cryptographic kernel
      5 *
      6 * David A. McGrew
      7 * Cisco Systems, Inc.
      8 */
      9 /*
     10 *
     11 * Copyright(c) 2001-2017 Cisco Systems, Inc.
     12 * All rights reserved.
     13 *
     14 * Redistribution and use in source and binary forms, with or without
     15 * modification, are permitted provided that the following conditions
     16 * are met:
     17 *
     18 *   Redistributions of source code must retain the above copyright
     19 *   notice, this list of conditions and the following disclaimer.
     20 *
     21 *   Redistributions in binary form must reproduce the above
     22 *   copyright notice, this list of conditions and the following
     23 *   disclaimer in the documentation and/or other materials provided
     24 *   with the distribution.
     25 *
     26 *   Neither the name of the Cisco Systems, Inc. nor the names of its
     27 *   contributors may be used to endorse or promote products derived
     28 *   from this software without specific prior written permission.
     29 *
     30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     41 * OF THE POSSIBILITY OF SUCH DAMAGE.
     42 *
     43 */
     44 
     45 #ifdef HAVE_CONFIG_H
     46 #include <config.h>
     47 #endif
     48 
     49 #include "alloc.h"
     50 
     51 #include "crypto_kernel.h"
     52 #include "cipher_types.h"
     53 
     54 /* the debug module for the crypto_kernel */
     55 
     56 srtp_debug_module_t srtp_mod_crypto_kernel = {
     57    0,              /* debugging is off by default */
     58    "crypto kernel" /* printable name for module   */
     59 };
     60 
     61 /* crypto_kernel is a global variable, the only one of its datatype */
     62 
     63 static srtp_crypto_kernel_t crypto_kernel = {
     64    srtp_crypto_kernel_state_insecure, /* start off in insecure state */
     65    NULL,                              /* no cipher types yet         */
     66    NULL,                              /* no auth types yet           */
     67    NULL                               /* no debug modules yet        */
     68 };
     69 
     70 #define MAX_RNG_TRIALS 25
     71 
     72 srtp_err_status_t srtp_crypto_kernel_init(void)
     73 {
     74    srtp_err_status_t status;
     75 
     76    /* check the security state */
     77    if (crypto_kernel.state == srtp_crypto_kernel_state_secure) {
     78        /*
     79         * we're already in the secure state, but we've been asked to
     80         * re-initialize, so we just re-run the self-tests and then return
     81         */
     82        return srtp_crypto_kernel_status();
     83    }
     84 
     85    /* initialize error reporting system */
     86    status = srtp_err_reporting_init();
     87    if (status) {
     88        return status;
     89    }
     90 
     91    /* load debug modules */
     92    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_crypto_kernel);
     93    if (status) {
     94        return status;
     95    }
     96    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_auth);
     97    if (status) {
     98        return status;
     99    }
    100    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_cipher);
    101    if (status) {
    102        return status;
    103    }
    104    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_alloc);
    105    if (status) {
    106        return status;
    107    }
    108 
    109    /* load cipher types */
    110    status = srtp_crypto_kernel_load_cipher_type(&srtp_null_cipher,
    111                                                 SRTP_NULL_CIPHER);
    112    if (status) {
    113        return status;
    114    }
    115    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_128,
    116                                                 SRTP_AES_ICM_128);
    117    if (status) {
    118        return status;
    119    }
    120    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_256,
    121                                                 SRTP_AES_ICM_256);
    122    if (status) {
    123        return status;
    124    }
    125    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_icm);
    126    if (status) {
    127        return status;
    128    }
    129 #ifdef GCM
    130    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_192,
    131                                                 SRTP_AES_ICM_192);
    132    if (status) {
    133        return status;
    134    }
    135    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_128,
    136                                                 SRTP_AES_GCM_128);
    137    if (status) {
    138        return status;
    139    }
    140    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256,
    141                                                 SRTP_AES_GCM_256);
    142    if (status) {
    143        return status;
    144    }
    145    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_gcm);
    146    if (status) {
    147        return status;
    148    }
    149 #endif
    150 
    151    /* load auth func types */
    152    status = srtp_crypto_kernel_load_auth_type(&srtp_null_auth, SRTP_NULL_AUTH);
    153    if (status) {
    154        return status;
    155    }
    156    status = srtp_crypto_kernel_load_auth_type(&srtp_hmac, SRTP_HMAC_SHA1);
    157    if (status) {
    158        return status;
    159    }
    160    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_hmac);
    161    if (status) {
    162        return status;
    163    }
    164 
    165    /* change state to secure */
    166    crypto_kernel.state = srtp_crypto_kernel_state_secure;
    167 
    168    return srtp_err_status_ok;
    169 }
    170 
    171 srtp_err_status_t srtp_crypto_kernel_status(void)
    172 {
    173    srtp_err_status_t status;
    174    srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
    175    srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
    176 
    177    /* for each cipher type, describe and test */
    178    while (ctype != NULL) {
    179        srtp_err_report(srtp_err_level_info, "cipher: %s\n",
    180                        ctype->cipher_type->description);
    181        srtp_err_report(srtp_err_level_info, "  self-test: ");
    182        status = srtp_cipher_type_self_test(ctype->cipher_type);
    183        if (status) {
    184            srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
    185                            status);
    186            exit(status);
    187        }
    188        srtp_err_report(srtp_err_level_info, "passed\n");
    189        ctype = ctype->next;
    190    }
    191 
    192    /* for each auth type, describe and test */
    193    while (atype != NULL) {
    194        srtp_err_report(srtp_err_level_info, "auth func: %s\n",
    195                        atype->auth_type->description);
    196        srtp_err_report(srtp_err_level_info, "  self-test: ");
    197        status = srtp_auth_type_self_test(atype->auth_type);
    198        if (status) {
    199            srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
    200                            status);
    201            exit(status);
    202        }
    203        srtp_err_report(srtp_err_level_info, "passed\n");
    204        atype = atype->next;
    205    }
    206 
    207    srtp_crypto_kernel_list_debug_modules();
    208 
    209    return srtp_err_status_ok;
    210 }
    211 
    212 srtp_err_status_t srtp_crypto_kernel_list_debug_modules(void)
    213 {
    214    srtp_kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
    215 
    216    /* describe each debug module */
    217    srtp_err_report(srtp_err_level_info, "debug modules loaded:\n");
    218    while (dm != NULL) {
    219        srtp_err_report(srtp_err_level_info, "  %s ", dm->mod->name);
    220        if (dm->mod->on) {
    221            srtp_err_report(srtp_err_level_info, "(on)\n");
    222        } else {
    223            srtp_err_report(srtp_err_level_info, "(off)\n");
    224        }
    225        dm = dm->next;
    226    }
    227 
    228    return srtp_err_status_ok;
    229 }
    230 
    231 srtp_err_status_t srtp_crypto_kernel_shutdown(void)
    232 {
    233    /*
    234     * free dynamic memory used in crypto_kernel at present
    235     */
    236 
    237    /* walk down cipher type list, freeing memory */
    238    while (crypto_kernel.cipher_type_list != NULL) {
    239        srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
    240        crypto_kernel.cipher_type_list = ctype->next;
    241        debug_print(srtp_mod_crypto_kernel, "freeing memory for cipher %s",
    242                    ctype->cipher_type->description);
    243        srtp_crypto_free(ctype);
    244    }
    245 
    246    /* walk down authetication module list, freeing memory */
    247    while (crypto_kernel.auth_type_list != NULL) {
    248        srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
    249        crypto_kernel.auth_type_list = atype->next;
    250        debug_print(srtp_mod_crypto_kernel,
    251                    "freeing memory for authentication %s",
    252                    atype->auth_type->description);
    253        srtp_crypto_free(atype);
    254    }
    255 
    256    /* walk down debug module list, freeing memory */
    257    while (crypto_kernel.debug_module_list != NULL) {
    258        srtp_kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
    259        crypto_kernel.debug_module_list = kdm->next;
    260        debug_print(srtp_mod_crypto_kernel,
    261                    "freeing memory for debug module %s", kdm->mod->name);
    262        srtp_crypto_free(kdm);
    263    }
    264 
    265    /* return to insecure state */
    266    crypto_kernel.state = srtp_crypto_kernel_state_insecure;
    267 
    268    return srtp_err_status_ok;
    269 }
    270 
    271 static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type(
    272    const srtp_cipher_type_t *new_ct,
    273    srtp_cipher_type_id_t id,
    274    int replace)
    275 {
    276    srtp_kernel_cipher_type_t *ctype;
    277    srtp_kernel_cipher_type_t *new_ctype = NULL;
    278    srtp_err_status_t status;
    279 
    280    /* defensive coding */
    281    if (new_ct == NULL) {
    282        return srtp_err_status_bad_param;
    283    }
    284 
    285    if (new_ct->id != id) {
    286        return srtp_err_status_bad_param;
    287    }
    288 
    289    /* check cipher type by running self-test */
    290    status = srtp_cipher_type_self_test(new_ct);
    291    if (status) {
    292        return status;
    293    }
    294 
    295    /* walk down list, checking if this type is in the list already  */
    296    ctype = crypto_kernel.cipher_type_list;
    297    while (ctype != NULL) {
    298        if (id == ctype->id) {
    299            if (!replace) {
    300                return srtp_err_status_bad_param;
    301            }
    302            status =
    303                srtp_cipher_type_test(new_ct, ctype->cipher_type->test_data);
    304            if (status) {
    305                return status;
    306            }
    307            new_ctype = ctype;
    308            break;
    309        } else if (new_ct == ctype->cipher_type) {
    310            return srtp_err_status_bad_param;
    311        }
    312        ctype = ctype->next;
    313    }
    314 
    315    /* if not found, put new_ct at the head of the list */
    316    if (ctype == NULL) {
    317        /* allocate memory */
    318        new_ctype = (srtp_kernel_cipher_type_t *)srtp_crypto_alloc(
    319            sizeof(srtp_kernel_cipher_type_t));
    320        if (new_ctype == NULL) {
    321            return srtp_err_status_alloc_fail;
    322        }
    323        new_ctype->next = crypto_kernel.cipher_type_list;
    324 
    325        /* set head of list to new cipher type */
    326        crypto_kernel.cipher_type_list = new_ctype;
    327    }
    328 
    329    /* set fields */
    330    new_ctype->cipher_type = new_ct;
    331    new_ctype->id = id;
    332 
    333    return srtp_err_status_ok;
    334 }
    335 
    336 srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
    337    const srtp_cipher_type_t *new_ct,
    338    srtp_cipher_type_id_t id)
    339 {
    340    return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 0);
    341 }
    342 
    343 srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *new_ct,
    344                                           srtp_cipher_type_id_t id)
    345 {
    346    return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 1);
    347 }
    348 
    349 srtp_err_status_t srtp_crypto_kernel_do_load_auth_type(
    350    const srtp_auth_type_t *new_at,
    351    srtp_auth_type_id_t id,
    352    int replace)
    353 {
    354    srtp_kernel_auth_type_t *atype;
    355    srtp_kernel_auth_type_t *new_atype = NULL;
    356    srtp_err_status_t status;
    357 
    358    /* defensive coding */
    359    if (new_at == NULL) {
    360        return srtp_err_status_bad_param;
    361    }
    362 
    363    if (new_at->id != id) {
    364        return srtp_err_status_bad_param;
    365    }
    366 
    367    /* check auth type by running self-test */
    368    status = srtp_auth_type_self_test(new_at);
    369    if (status) {
    370        return status;
    371    }
    372 
    373    /* walk down list, checking if this type is in the list already  */
    374    atype = crypto_kernel.auth_type_list;
    375    while (atype != NULL) {
    376        if (id == atype->id) {
    377            if (!replace) {
    378                return srtp_err_status_bad_param;
    379            }
    380            status = srtp_auth_type_test(new_at, atype->auth_type->test_data);
    381            if (status) {
    382                return status;
    383            }
    384            new_atype = atype;
    385            break;
    386        } else if (new_at == atype->auth_type) {
    387            return srtp_err_status_bad_param;
    388        }
    389        atype = atype->next;
    390    }
    391 
    392    /* if not found, put new_at at the head of the list */
    393    if (atype == NULL) {
    394        /* allocate memory */
    395        new_atype = (srtp_kernel_auth_type_t *)srtp_crypto_alloc(
    396            sizeof(srtp_kernel_auth_type_t));
    397        if (new_atype == NULL) {
    398            return srtp_err_status_alloc_fail;
    399        }
    400 
    401        new_atype->next = crypto_kernel.auth_type_list;
    402        /* set head of list to new auth type */
    403        crypto_kernel.auth_type_list = new_atype;
    404    }
    405 
    406    /* set fields */
    407    new_atype->auth_type = new_at;
    408    new_atype->id = id;
    409 
    410    return srtp_err_status_ok;
    411 }
    412 
    413 srtp_err_status_t srtp_crypto_kernel_load_auth_type(
    414    const srtp_auth_type_t *new_at,
    415    srtp_auth_type_id_t id)
    416 {
    417    return srtp_crypto_kernel_do_load_auth_type(new_at, id, 0);
    418 }
    419 
    420 srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *new_at,
    421                                         srtp_auth_type_id_t id)
    422 {
    423    return srtp_crypto_kernel_do_load_auth_type(new_at, id, 1);
    424 }
    425 
    426 const srtp_cipher_type_t *srtp_crypto_kernel_get_cipher_type(
    427    srtp_cipher_type_id_t id)
    428 {
    429    srtp_kernel_cipher_type_t *ctype;
    430 
    431    /* walk down list, looking for id  */
    432    ctype = crypto_kernel.cipher_type_list;
    433    while (ctype != NULL) {
    434        if (id == ctype->id) {
    435            return ctype->cipher_type;
    436        }
    437        ctype = ctype->next;
    438    }
    439 
    440    /* haven't found the right one, indicate failure by returning NULL */
    441    return NULL;
    442 }
    443 
    444 srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id,
    445                                                  srtp_cipher_pointer_t *cp,
    446                                                  int key_len,
    447                                                  int tag_len)
    448 {
    449    const srtp_cipher_type_t *ct;
    450 
    451    /*
    452     * if the crypto_kernel is not yet initialized, we refuse to allocate
    453     * any ciphers - this is a bit extra-paranoid
    454     */
    455    if (crypto_kernel.state != srtp_crypto_kernel_state_secure) {
    456        return srtp_err_status_init_fail;
    457    }
    458 
    459    ct = srtp_crypto_kernel_get_cipher_type(id);
    460    if (!ct) {
    461        return srtp_err_status_fail;
    462    }
    463 
    464    return ((ct)->alloc(cp, key_len, tag_len));
    465 }
    466 
    467 const srtp_auth_type_t *srtp_crypto_kernel_get_auth_type(srtp_auth_type_id_t id)
    468 {
    469    srtp_kernel_auth_type_t *atype;
    470 
    471    /* walk down list, looking for id  */
    472    atype = crypto_kernel.auth_type_list;
    473    while (atype != NULL) {
    474        if (id == atype->id) {
    475            return atype->auth_type;
    476        }
    477        atype = atype->next;
    478    }
    479 
    480    /* haven't found the right one, indicate failure by returning NULL */
    481    return NULL;
    482 }
    483 
    484 srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id,
    485                                                srtp_auth_pointer_t *ap,
    486                                                int key_len,
    487                                                int tag_len)
    488 {
    489    const srtp_auth_type_t *at;
    490 
    491    /*
    492     * if the crypto_kernel is not yet initialized, we refuse to allocate
    493     * any auth functions - this is a bit extra-paranoid
    494     */
    495    if (crypto_kernel.state != srtp_crypto_kernel_state_secure) {
    496        return srtp_err_status_init_fail;
    497    }
    498 
    499    at = srtp_crypto_kernel_get_auth_type(id);
    500    if (!at) {
    501        return srtp_err_status_fail;
    502    }
    503 
    504    return ((at)->alloc(ap, key_len, tag_len));
    505 }
    506 
    507 srtp_err_status_t srtp_crypto_kernel_load_debug_module(
    508    srtp_debug_module_t *new_dm)
    509 {
    510    srtp_kernel_debug_module_t *kdm, *new;
    511 
    512    /* defensive coding */
    513    if (new_dm == NULL || new_dm->name == NULL) {
    514        return srtp_err_status_bad_param;
    515    }
    516 
    517    /* walk down list, checking if this type is in the list already  */
    518    kdm = crypto_kernel.debug_module_list;
    519    while (kdm != NULL) {
    520        if (strncmp(new_dm->name, kdm->mod->name, 64) == 0) {
    521            return srtp_err_status_bad_param;
    522        }
    523        kdm = kdm->next;
    524    }
    525 
    526    /* put new_dm at the head of the list */
    527    /* allocate memory */
    528    new = (srtp_kernel_debug_module_t *)srtp_crypto_alloc(
    529        sizeof(srtp_kernel_debug_module_t));
    530    if (new == NULL) {
    531        return srtp_err_status_alloc_fail;
    532    }
    533 
    534    /* set fields */
    535    new->mod = new_dm;
    536    new->next = crypto_kernel.debug_module_list;
    537 
    538    /* set head of list to new cipher type */
    539    crypto_kernel.debug_module_list = new;
    540 
    541    return srtp_err_status_ok;
    542 }
    543 
    544 srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *name, int on)
    545 {
    546    srtp_kernel_debug_module_t *kdm;
    547 
    548    /* walk down list, checking if this type is in the list already  */
    549    kdm = crypto_kernel.debug_module_list;
    550    while (kdm != NULL) {
    551        if (strncmp(name, kdm->mod->name, 64) == 0) {
    552            kdm->mod->on = on;
    553            return srtp_err_status_ok;
    554        }
    555        kdm = kdm->next;
    556    }
    557 
    558    return srtp_err_status_fail;
    559 }