tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

crypto_dh.c (3585B)


      1 /* Copyright (c) 2001, Matej Pfajfar.
      2 * Copyright (c) 2001-2004, Roger Dingledine.
      3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * \file crypto_dh.c
      9 * \brief Block of functions related with DH utilities and operations.
     10 *    over Z_p.  We aren't using this for any new crypto -- EC is more
     11 *    efficient.
     12 **/
     13 
     14 #include "lib/crypt_ops/compat_openssl.h"
     15 #include "lib/crypt_ops/crypto_dh.h"
     16 #include "lib/crypt_ops/crypto_digest.h"
     17 #include "lib/crypt_ops/crypto_hkdf.h"
     18 #include "lib/crypt_ops/crypto_util.h"
     19 #include "lib/log/log.h"
     20 #include "lib/log/util_bug.h"
     21 
     22 /** Our DH 'g' parameter */
     23 const unsigned DH_GENERATOR = 2;
     24 /** This is ffdhe2048 from RFC 7919.
     25 */
     26 const char TLS_DH_PRIME[] =
     27  "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
     28  "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
     29  "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
     30  "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
     31  "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
     32  "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
     33  "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
     34  "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
     35  "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
     36  "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
     37  "886B423861285C97FFFFFFFFFFFFFFFF";
     38 /**
     39 * This is from rfc2409, section 6.2.  It's a safe prime, and
     40 * supposedly it equals:
     41 * 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
     42 */
     43 const char OAKLEY_PRIME_2[] =
     44  "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
     45  "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
     46  "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
     47  "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
     48  "49286651ECE65381FFFFFFFFFFFFFFFF";
     49 
     50 void
     51 crypto_dh_init(void)
     52 {
     53 #ifdef ENABLE_OPENSSL
     54  crypto_dh_init_openssl();
     55 #endif
     56 #ifdef ENABLE_NSS
     57  crypto_dh_init_nss();
     58 #endif
     59 }
     60 
     61 void
     62 crypto_dh_free_all(void)
     63 {
     64 #ifdef ENABLE_OPENSSL
     65  crypto_dh_free_all_openssl();
     66 #endif
     67 #ifdef ENABLE_NSS
     68  crypto_dh_free_all_nss();
     69 #endif
     70 }
     71 
     72 /** Given a DH key exchange object, and our peer's value of g^y (as a
     73 * <b>pubkey_len</b>-byte value in <b>pubkey</b>) generate
     74 * <b>secret_bytes_out</b> bytes of shared key material and write them
     75 * to <b>secret_out</b>.  Return the number of bytes generated on success,
     76 * or -1 on failure.
     77 *
     78 * (We generate key material by computing
     79 *         SHA1( g^xy || "\x00" ) || SHA1( g^xy || "\x01" ) || ...
     80 * where || is concatenation.)
     81 */
     82 ssize_t
     83 crypto_dh_compute_secret(int severity, crypto_dh_t *dh,
     84                         const char *pubkey, size_t pubkey_len,
     85                         char *secret_out, size_t secret_bytes_out)
     86 {
     87  tor_assert(secret_bytes_out/DIGEST_LEN <= 255);
     88 
     89  unsigned char *secret_tmp = NULL;
     90  size_t secret_len=0, secret_tmp_len=0;
     91  secret_tmp_len = crypto_dh_get_bytes(dh);
     92  secret_tmp = tor_malloc(secret_tmp_len);
     93 
     94  ssize_t result = crypto_dh_handshake(severity, dh, pubkey, pubkey_len,
     95                                   secret_tmp, secret_tmp_len);
     96  if (result < 0)
     97    goto error;
     98 
     99  secret_len = result;
    100  if (crypto_expand_key_material_TAP(secret_tmp, secret_len,
    101                                     (uint8_t*)secret_out, secret_bytes_out)<0)
    102    goto error;
    103  secret_len = secret_bytes_out;
    104 
    105  goto done;
    106 error:
    107  result = -1;
    108 done:
    109  if (secret_tmp) {
    110    memwipe(secret_tmp, 0, secret_tmp_len);
    111    tor_free(secret_tmp);
    112  }
    113  if (result < 0)
    114    return result;
    115  else
    116    return secret_len;
    117 }