Back to index

tor  0.2.3.18-rc
Classes | Defines | Functions | Variables
crypto.c File Reference

Wrapper functions to present a consistent interface to public-key and symmetric cryptography operations from OpenSSL. More...

#include "orconfig.h"
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/rand.h>
#include <openssl/opensslv.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/conf.h>
#include <openssl/hmac.h>
#include "crypto.h"
#include "../common/torlog.h"
#include "aes.h"
#include "../common/util.h"
#include "container.h"
#include "compat.h"
#include "sha256.c"

Go to the source code of this file.

Classes

struct  crypto_pk_t
 A public key, or a public/private key-pair. More...
struct  crypto_cipher_t
 Key and stream information for a stream cipher. More...
struct  crypto_dh_t
 A structure to hold the first half (x, g^x) of a Diffie-Hellman handshake while we're waiting for the second. More...
struct  crypto_digest_t
 Intermediate information about the digest of a stream of data. More...
union  crypto_digest_t.d

Defines

#define CRYPTO_PRIVATE
#define MAX_DNS_LABEL_SIZE   63
 Longest recognized.
#define SHA256_Final(a, b)   sha256_done(b,a)
#define PUBLIC_KEY_OK(k)   ((k) && (k)->key && (k)->key->n)
 Macro: is k a valid RSA public or private key?
#define PRIVATE_KEY_OK(k)   ((k) && (k)->key && (k)->key->p)
 Macro: is k a valid RSA private key?
#define BLOCKSIZE   64
#define DIGESTSIZE   32
#define DH_GENERATOR   2
 Our DH 'g' parameter.
#define DH_PRIVATE_KEY_BITS   320
 Number of bits to use when choosing the x or y value in a Diffie-Hellman handshake.
#define MIN(a, b)   ((a)<(b)?(a):(b))
#define ADD_ENTROPY   32
 How many bytes of entropy we add at once.
#define RAND_POLL_IS_SAFE
 True iff it's safe to use RAND_poll after setup.
#define EXPBIAS   6
#define SHA256_CTX   sha256_state
 On OpenSSL versions before 0.9.8, there is no working SHA256 implementation, so we use Tom St Denis's nice speedy one, slightly adapted to our needs.
#define SHA256_Init   sha256_init
#define SHA256_Update   sha256_process
#define LTC_ARGCHK(x)   tor_assert(x)
#define X   255
 Special values used for the base64_decode_table.
#define SP   64
#define PAD   65

Functions

static unsigned char * SHA256 (const unsigned char *m, size_t len, unsigned char *d)
static int setup_openssl_threading (void)
static int tor_check_dh_key (int severity, BIGNUM *bn)
 Check for bad Diffie-Hellman public keys (g^x).
static INLINE int crypto_get_rsa_padding_overhead (int padding)
 Return the number of bytes added by padding method padding.
static INLINE int crypto_get_rsa_padding (int padding)
 Given a padding method padding, return the correct OpenSSL constant.
static void crypto_log_errors (int severity, const char *doing)
 Log all pending crypto errors at level severity.
static void log_engine (const char *fn, ENGINE *e)
 Log any OpenSSL engines we're using at NOTICE.
static ENGINE * try_load_engine (const char *path, const char *engine)
 Try to load an engine in a shared library via fully qualified path.
int crypto_global_init (int useAccel, const char *accelName, const char *accelDir)
 Initialize the crypto library.
void crypto_thread_cleanup (void)
 Free crypto resources held by this thread.
crypto_pk_t_crypto_new_pk_from_rsa (RSA *rsa)
 used by tortls.c: wrap an RSA* in a crypto_pk_t.
RSA * _crypto_pk_get_rsa (crypto_pk_t *env)
 Helper, used by tor-checkkey.c and tor-gencert.c.
EVP_PKEY * _crypto_pk_get_evp_pkey (crypto_pk_t *env, int private)
 used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t.
DH * _crypto_dh_get_dh (crypto_dh_t *dh)
 Used by tortls.c: Get the DH* from a crypto_dh_t.
crypto_pk_tcrypto_pk_new (void)
 Allocate and return storage for a public key.
void crypto_pk_free (crypto_pk_t *env)
 Release a reference to an asymmetric key; when all the references are released, free the key.
crypto_cipher_tcrypto_cipher_new_with_iv (const char *key, const char *iv)
 Allocate and return a new symmetric cipher using the provided key and iv.
crypto_cipher_tcrypto_cipher_new (const char *key)
 Return a new crypto_cipher_t with the provided key and an IV of all zero bytes.
void crypto_cipher_free (crypto_cipher_t *env)
 Free a symmetric cipher.
int crypto_pk_generate_key_with_bits (crypto_pk_t *env, int bits)
 Generate a bits-bit new public/private keypair in env.
int crypto_pk_read_private_key_from_string (crypto_pk_t *env, const char *s, ssize_t len)
 Read a PEM-encoded private key from the len-byte string s into env.
int crypto_pk_read_private_key_from_filename (crypto_pk_t *env, const char *keyfile)
 Read a PEM-encoded private key from the file named by keyfile into env.
static int crypto_pk_write_key_to_string_impl (crypto_pk_t *env, char **dest, size_t *len, int is_public)
 Helper function to implement crypto_pk_write_*_key_to_string.
int crypto_pk_write_public_key_to_string (crypto_pk_t *env, char **dest, size_t *len)
 PEM-encode the public key portion of env and write it to a newly allocated string.
int crypto_pk_write_private_key_to_string (crypto_pk_t *env, char **dest, size_t *len)
 PEM-encode the private key portion of env and write it to a newly allocated string.
int crypto_pk_read_public_key_from_string (crypto_pk_t *env, const char *src, size_t len)
 Read a PEM-encoded public key from the first len characters of src, and store the result in env.
int crypto_pk_write_private_key_to_filename (crypto_pk_t *env, const char *fname)
 Write the private key from env into the file named by fname, PEM-encoded.
int crypto_pk_check_key (crypto_pk_t *env)
 Return true iff env has a valid key.
int crypto_pk_key_is_private (const crypto_pk_t *key)
 Return true iff key contains the private-key portion of the RSA key.
int crypto_pk_public_exponent_ok (crypto_pk_t *env)
 Return true iff env contains a public key whose public exponent equals 65537.
int crypto_pk_cmp_keys (crypto_pk_t *a, crypto_pk_t *b)
 Compare the public-key components of a and b.
size_t crypto_pk_keysize (crypto_pk_t *env)
 Return the size of the public key modulus in env, in bytes.
int crypto_pk_num_bits (crypto_pk_t *env)
 Return the size of the public key modulus of env, in bits.
crypto_pk_tcrypto_pk_dup_key (crypto_pk_t *env)
 Increase the reference count of env, and return it.
crypto_pk_tcrypto_pk_copy_full (crypto_pk_t *env)
 Make a real honest-to-goodness copy of env, and return it.
int crypto_pk_public_encrypt (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding)
 Encrypt fromlen bytes from from with the public key in env, using the padding method padding.
int crypto_pk_private_decrypt (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
 Decrypt fromlen bytes from from with the private key in env, using the padding method padding.
int crypto_pk_public_checksig (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
 Check the signature in from (fromlen bytes long) with the public key in env, using PKCS1 padding.
int crypto_pk_public_checksig_digest (crypto_pk_t *env, const char *data, size_t datalen, const char *sig, size_t siglen)
 Check a siglen-byte long signature at sig against datalen bytes of data at data, using the public key in env.
int crypto_pk_private_sign (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
 Sign fromlen bytes of data from from with the private key in env, using PKCS1 padding.
int crypto_pk_private_sign_digest (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
 Compute a SHA1 digest of fromlen bytes of data stored at from; sign the data with the private key in env, and store it in to.
int crypto_pk_public_hybrid_encrypt (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int force)
 Perform a hybrid (public/secret) encryption on fromlen bytes of data from from, with padding type 'padding', storing the results on to.
int crypto_pk_private_hybrid_decrypt (crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
 Invert crypto_pk_public_hybrid_encrypt.
int crypto_pk_asn1_encode (crypto_pk_t *pk, char *dest, size_t dest_len)
 ASN.1-encode the public portion of pk into dest.
crypto_pk_tcrypto_pk_asn1_decode (const char *str, size_t len)
 Decode an ASN.1-encoded public key from str; return the result on success and NULL on failure.
int crypto_pk_get_digest (crypto_pk_t *pk, char *digest_out)
 Given a private or public key pk, put a SHA1 hash of the public key into digest_out (must have DIGEST_LEN bytes of space).
int crypto_pk_get_all_digests (crypto_pk_t *pk, digests_t *digests_out)
 Compute all digests of the DER encoding of pk, and store them in digests_out.
void add_spaces_to_fp (char *out, size_t outlen, const char *in)
 Copy in to the outlen-byte buffer out, adding spaces every four spaces.
int crypto_pk_get_fingerprint (crypto_pk_t *pk, char *fp_out, int add_space)
 Given a private or public key pk, put a fingerprint of the public key into fp_out (must have at least FINGERPRINT_LEN+1 bytes of space).
int crypto_pk_check_fingerprint_syntax (const char *s)
 Return true iff s is in the correct format for a fingerprint.
const char * crypto_cipher_get_key (crypto_cipher_t *env)
 Return a pointer to the key set for the cipher in env.
int crypto_cipher_encrypt (crypto_cipher_t *env, char *to, const char *from, size_t fromlen)
 Encrypt fromlen bytes from from using the cipher env; on success, store the result to to and return 0.
int crypto_cipher_decrypt (crypto_cipher_t *env, char *to, const char *from, size_t fromlen)
 Decrypt fromlen bytes from from using the cipher env; on success, store the result to to and return 0.
int crypto_cipher_crypt_inplace (crypto_cipher_t *env, char *buf, size_t len)
 Encrypt len bytes on from using the cipher in env; on success, return 0.
int crypto_cipher_encrypt_with_iv (const char *key, char *to, size_t tolen, const char *from, size_t fromlen)
 Encrypt fromlen bytes (at least 1) from from with the key in key to the buffer in to of length tolen.
int crypto_cipher_decrypt_with_iv (const char *key, char *to, size_t tolen, const char *from, size_t fromlen)
 Decrypt fromlen bytes (at least 1+CIPHER_IV_LEN) from from with the key in key to the buffer in to of length tolen.
int crypto_digest (char *digest, const char *m, size_t len)
 Compute the SHA1 digest of the len bytes on data stored in m.
int crypto_digest256 (char *digest, const char *m, size_t len, digest_algorithm_t algorithm)
 Compute a 256-bit digest of len bytes in data stored in m, using the algorithm algorithm.
int crypto_digest_all (digests_t *ds_out, const char *m, size_t len)
 Set the digests_t in ds_out to contain every digest on the len bytes in m that we know how to compute.
const char * crypto_digest_algorithm_get_name (digest_algorithm_t alg)
 Return the name of an algorithm, as used in directory documents.
int crypto_digest_algorithm_parse_name (const char *name)
 Given the name of a digest algorithm, return its integer value, or -1 if the name is not recognized.
crypto_digest_tcrypto_digest_new (void)
 Allocate and return a new digest object to compute SHA1 digests.
crypto_digest_tcrypto_digest256_new (digest_algorithm_t algorithm)
 Allocate and return a new digest object to compute 256-bit digests using algorithm.
void crypto_digest_free (crypto_digest_t *digest)
 Deallocate a digest object.
void crypto_digest_add_bytes (crypto_digest_t *digest, const char *data, size_t len)
 Add len bytes from data to the digest object.
void crypto_digest_get_digest (crypto_digest_t *digest, char *out, size_t out_len)
 Compute the hash of the data that has been passed to the digest object; write the first out_len bytes of the result to out.
crypto_digest_tcrypto_digest_dup (const crypto_digest_t *digest)
 Allocate and return a new digest object with the same state as digest
void crypto_digest_assign (crypto_digest_t *into, const crypto_digest_t *from)
 Replace the state of the digest object into with the state of the digest object from.
void crypto_hmac_sha1 (char *hmac_out, const char *key, size_t key_len, const char *msg, size_t msg_len)
 Compute the HMAC-SHA-1 of the msg_len bytes in msg, using the key of length key_len.
void crypto_hmac_sha256 (char *hmac_out, const char *key, size_t key_len, const char *msg, size_t msg_len)
 Compute the HMAC-SHA-256 of the msg_len bytes in msg, using the key of length key_len.
static BIGNUM * crypto_generate_dynamic_dh_modulus (void)
 Generate and return a reasonable and safe DH parameter p.
static int crypto_store_dynamic_dh_modulus (const char *fname)
 Store our dynamic DH modulus (and its group parameters) to fname for future use.
static BIGNUM * crypto_get_stored_dynamic_dh_modulus (const char *fname)
 Return the dynamic DH modulus stored in fname.
void crypto_set_tls_dh_prime (const char *dynamic_dh_modulus_fname)
 Set the global TLS Diffie-Hellman modulus.
static void init_dh_param (void)
 Initialize dh_param_p and dh_param_g if they are not already set.
crypto_dh_tcrypto_dh_new (int dh_type)
 Allocate and return a new DH object for a key exchange.
int crypto_dh_get_bytes (crypto_dh_t *dh)
 Return the length of the DH key in dh, in bytes.
int crypto_dh_generate_public (crypto_dh_t *dh)
 Generate <x,g^x> for our part of the key exchange.
int crypto_dh_get_public (crypto_dh_t *dh, char *pubkey, size_t pubkey_len)
 Generate g^x as necessary, and write the g^x for the key exchange as a pubkey_len-byte value into pubkey.
ssize_t crypto_dh_compute_secret (int severity, crypto_dh_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_bytes_out)
 Given a DH key exchange object, and our peer's value of g^y (as a pubkey_len-byte value in pubkey) generate secret_bytes_out bytes of shared key material and write them to secret_out.
int crypto_expand_key_material (const char *key_in, size_t key_in_len, char *key_out, size_t key_out_len)
 Given key_in_len bytes of negotiated randomness in key_in ("K"), expand it into key_out_len bytes of negotiated key material in key_out by taking the first key_out_len bytes of H(K | [00]) | H(K | [01]) | ....
void crypto_dh_free (crypto_dh_t *dh)
 Free a DH key exchange object.
static void seed_weak_rng (void)
 Set the seed of the weak RNG to a random value.
int crypto_seed_rng (int startup)
 Seed OpenSSL's random number generator with bytes from the operating system.
int crypto_rand (char *to, size_t n)
 Write n bytes of strong random data to to.
int crypto_rand_int (unsigned int max)
 Return a pseudorandom integer, chosen uniformly from the values between 0 and max-1 inclusive.
uint64_t crypto_rand_uint64 (uint64_t max)
 Return a pseudorandom 64-bit integer, chosen uniformly from the values between 0 and max-1.
double crypto_rand_double (void)
 Return a pseudorandom double d, chosen uniformly from the range 0.0 <= d < 1.0.
char * crypto_random_hostname (int min_rand_len, int max_rand_len, const char *prefix, const char *suffix)
 Generate and return a new random hostname starting with prefix, ending with suffix, and containing no fewer than min_rand_len and no more than max_rand_len random base32 characters between.
void * smartlist_choose (const smartlist_t *sl)
 Return a randomly chosen element of sl; or NULL if sl is empty.
void smartlist_shuffle (smartlist_t *sl)
 Scramble the elements of sl into a random order.
int base64_encode (char *dest, size_t destlen, const char *src, size_t srclen)
 Base-64 encode srclen bytes of data from src.
int base64_decode (char *dest, size_t destlen, const char *src, size_t srclen)
 Base-64 decode srclen bytes of data from src.
int digest_to_base64 (char *d64, const char *digest)
 Base-64 encode DIGEST_LINE bytes from digest, remove the trailing = and newline characters, and store the nul-terminated result in the first BASE64_DIGEST_LEN+1 bytes of d64.
int digest_from_base64 (char *digest, const char *d64)
 Given a base-64 encoded, nul-terminated digest in d64 (without trailing newline or = characters), decode it and store the result in the first DIGEST_LEN bytes at digest.
int digest256_to_base64 (char *d64, const char *digest)
 Base-64 encode DIGEST256_LINE bytes from digest, remove the trailing = and newline characters, and store the nul-terminated result in the first BASE64_DIGEST256_LEN+1 bytes of d64.
int digest256_from_base64 (char *digest, const char *d64)
 Given a base-64 encoded, nul-terminated digest in d64 (without trailing newline or = characters), decode it and store the result in the first DIGEST256_LEN bytes at digest.
void base32_encode (char *dest, size_t destlen, const char *src, size_t srclen)
 Implements base32 encoding as in rfc3548.
int base32_decode (char *dest, size_t destlen, const char *src, size_t srclen)
 Implements base32 decoding as in rfc3548.
void secret_to_key (char *key_out, size_t key_out_len, const char *secret, size_t secret_len, const char *s2k_specifier)
 Implement RFC2440-style iterated-salted S2K conversion: convert the secret_len-byte secret into a key_out_len byte key_out.
int crypto_global_cleanup (void)
 Uninitialize the crypto library.

Variables

static int _crypto_global_initialized = 0
 Boolean: has OpenSSL's crypto been initialized?
static BIGNUM * dh_param_p = NULL
 Shared P parameter for our circuit-crypto DH key exchanges.
static BIGNUM * dh_param_p_tls = NULL
 Shared P parameter for our TLS DH key exchanges.
static BIGNUM * dh_param_g = NULL
 Shared G parameter for our DH key exchanges.
static const uint8_t base64_decode_table [256]
 Internal table mapping byte values to what they represent in base64.

Detailed Description

Wrapper functions to present a consistent interface to public-key and symmetric cryptography operations from OpenSSL.

Definition in file crypto.c.


Class Documentation

struct crypto_pk_t

A public key, or a public/private key-pair.

Definition at line 110 of file crypto.c.

Class Members
RSA * key The key itself.
int refs reference count, so we don't have to copy keys
struct crypto_cipher_t

Key and stream information for a stream cipher.

Definition at line 117 of file crypto.c.

Class Members
aes_cnt_cipher_t * cipher The key in format usable for counter-mode AES encryption.
char iv The initial IV.
char key The raw key.
struct crypto_dh_t

A structure to hold the first half (x, g^x) of a Diffie-Hellman handshake while we're waiting for the second.

Definition at line 127 of file crypto.c.

Class Members
DH * dh The openssl DH object.
struct crypto_digest_t

Intermediate information about the digest of a stream of data.

Definition at line 1471 of file crypto.c.

Class Members
digest_algorithm_t algorithm: 8 Which algorithm is in use?
union crypto_digest_t d State for the digest we're using. Only one member of the union is usable, depending on the value of algorithm.
union crypto_digest_t.d

Definition at line 1472 of file crypto.c.

Class Members
SHA_CTX sha1 state for SHA1
SHA256_CTX sha2 state for SHA256

Define Documentation

#define ADD_ENTROPY   32

How many bytes of entropy we add at once.

This is how much entropy OpenSSL likes to add right now, so maybe it will work for us too.

Definition at line 2276 of file crypto.c.

#define BLOCKSIZE   64
#define CRYPTO_PRIVATE

Definition at line 52 of file crypto.c.

#define DH_GENERATOR   2

Our DH 'g' parameter.

Definition at line 1688 of file crypto.c.

#define DH_PRIVATE_KEY_BITS   320

Number of bits to use when choosing the x or y value in a Diffie-Hellman handshake.

Since we exponentiate by this value, choosing a smaller one lets our handhake go faster.

Definition at line 2021 of file crypto.c.

#define DIGESTSIZE   32
#define EXPBIAS   6
#define LTC_ARGCHK (   x)    tor_assert(x)

Definition at line 81 of file crypto.c.

#define MAX_DNS_LABEL_SIZE   63

Longest recognized.

Definition at line 70 of file crypto.c.

#define MIN (   a,
 
)    ((a)<(b)?(a):(b))

Definition at line 2158 of file crypto.c.

#define PAD   65

Definition at line 2554 of file crypto.c.

#define PRIVATE_KEY_OK (   k)    ((k) && (k)->key && (k)->key->p)

Macro: is k a valid RSA private key?

Definition at line 100 of file crypto.c.

#define PUBLIC_KEY_OK (   k)    ((k) && (k)->key && (k)->key->n)

Macro: is k a valid RSA public or private key?

Definition at line 98 of file crypto.c.

Value:
((OPENSSL_VERSION_NUMBER >= OPENSSL_V(0,9,7,'j') &&        \
    OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(0,9,8)) ||     \
   OPENSSL_VERSION_NUMBER >= OPENSSL_V(0,9,8,'c'))

True iff it's safe to use RAND_poll after setup.

Versions of OpenSSL prior to 0.9.7k and 0.9.8c had a bug where RAND_poll would allocate an fd_set on the stack, open a new file, and try to FD_SET that fd without checking whether it fit in the fd_set. Thus, if the system has not just been started up, it is unsafe to call

Definition at line 2284 of file crypto.c.

#define SHA256_CTX   sha256_state

On OpenSSL versions before 0.9.8, there is no working SHA256 implementation, so we use Tom St Denis's nice speedy one, slightly adapted to our needs.

These macros make it usable by us.

Definition at line 78 of file crypto.c.

#define SHA256_Final (   a,
 
)    sha256_done(b,a)

Definition at line 84 of file crypto.c.

#define SHA256_Init   sha256_init

Definition at line 79 of file crypto.c.

Definition at line 80 of file crypto.c.

#define SP   64

Definition at line 2553 of file crypto.c.

#define X   255

Special values used for the base64_decode_table.

Definition at line 2552 of file crypto.c.


Function Documentation

Used by tortls.c: Get the DH* from a crypto_dh_t.

Definition at line 346 of file crypto.c.

{
  return dh->dh;
}

Here is the caller graph for this function:

used by tortls.c: wrap an RSA* in a crypto_pk_t.

Definition at line 297 of file crypto.c.

{
  crypto_pk_t *env;
  tor_assert(rsa);
  env = tor_malloc(sizeof(crypto_pk_t));
  env->refs = 1;
  env->key = rsa;
  return env;
}

Here is the caller graph for this function:

EVP_PKEY* _crypto_pk_get_evp_pkey ( crypto_pk_t env,
int  private 
)

used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t.

Iff private is set, include the private-key portion of the key.

Definition at line 318 of file crypto.c.

{
  RSA *key = NULL;
  EVP_PKEY *pkey = NULL;
  tor_assert(env->key);
  if (private) {
    if (!(key = RSAPrivateKey_dup(env->key)))
      goto error;
  } else {
    if (!(key = RSAPublicKey_dup(env->key)))
      goto error;
  }
  if (!(pkey = EVP_PKEY_new()))
    goto error;
  if (!(EVP_PKEY_assign_RSA(pkey, key)))
    goto error;
  return pkey;
 error:
  if (pkey)
    EVP_PKEY_free(pkey);
  if (key)
    RSA_free(key);
  return NULL;
}

Here is the caller graph for this function:

Helper, used by tor-checkkey.c and tor-gencert.c.

Return the RSA from a crypto_pk_t.

Definition at line 310 of file crypto.c.

{
  return env->key;
}

Here is the caller graph for this function:

void add_spaces_to_fp ( char *  out,
size_t  outlen,
const char *  in 
)

Copy in to the outlen-byte buffer out, adding spaces every four spaces.

Definition at line 1221 of file crypto.c.

{
  int n = 0;
  char *end = out+outlen;
  tor_assert(outlen < SIZE_T_CEILING);

  while (*in && out<end) {
    *out++ = *in++;
    if (++n == 4 && *in && out<end) {
      n = 0;
      *out++ = ' ';
    }
  }
  tor_assert(out<end);
  *out = '\0';
}

Here is the caller graph for this function:

int base32_decode ( char *  dest,
size_t  destlen,
const char *  src,
size_t  srclen 
)

Implements base32 decoding as in rfc3548.

Limitation: Requires that srclen*5 is a multiple of 8. Returns 0 if successful, -1 otherwise.

Definition at line 2791 of file crypto.c.

{
  /* XXXX we might want to rewrite this along the lines of base64_decode, if
   * it ever shows up in the profile. */
  unsigned int i;
  size_t nbits, j, bit;
  char *tmp;
  nbits = srclen * 5;

  tor_assert(srclen < SIZE_T_CEILING / 5);
  tor_assert((nbits%8) == 0); /* We need an even multiple of 8 bits. */
  tor_assert((nbits/8) <= destlen); /* We need enough space. */
  tor_assert(destlen < SIZE_T_CEILING);

  /* Convert base32 encoded chars to the 5-bit values that they represent. */
  tmp = tor_malloc_zero(srclen);
  for (j = 0; j < srclen; ++j) {
    if (src[j] > 0x60 && src[j] < 0x7B) tmp[j] = src[j] - 0x61;
    else if (src[j] > 0x31 && src[j] < 0x38) tmp[j] = src[j] - 0x18;
    else if (src[j] > 0x40 && src[j] < 0x5B) tmp[j] = src[j] - 0x41;
    else {
      log_warn(LD_BUG, "illegal character in base32 encoded string");
      tor_free(tmp);
      return -1;
    }
  }

  /* Assemble result byte-wise by applying five possible cases. */
  for (i = 0, bit = 0; bit < nbits; ++i, bit += 8) {
    switch (bit % 40) {
    case 0:
      dest[i] = (((uint8_t)tmp[(bit/5)]) << 3) +
                (((uint8_t)tmp[(bit/5)+1]) >> 2);
      break;
    case 8:
      dest[i] = (((uint8_t)tmp[(bit/5)]) << 6) +
                (((uint8_t)tmp[(bit/5)+1]) << 1) +
                (((uint8_t)tmp[(bit/5)+2]) >> 4);
      break;
    case 16:
      dest[i] = (((uint8_t)tmp[(bit/5)]) << 4) +
                (((uint8_t)tmp[(bit/5)+1]) >> 1);
      break;
    case 24:
      dest[i] = (((uint8_t)tmp[(bit/5)]) << 7) +
                (((uint8_t)tmp[(bit/5)+1]) << 2) +
                (((uint8_t)tmp[(bit/5)+2]) >> 3);
      break;
    case 32:
      dest[i] = (((uint8_t)tmp[(bit/5)]) << 5) +
                ((uint8_t)tmp[(bit/5)+1]);
      break;
    }
  }

  memset(tmp, 0, srclen);
  tor_free(tmp);
  tmp = NULL;
  return 0;
}

Here is the caller graph for this function:

void base32_encode ( char *  dest,
size_t  destlen,
const char *  src,
size_t  srclen 
)

Implements base32 encoding as in rfc3548.

Limitation: Requires that srclen*8 is a multiple of 5.

Definition at line 2766 of file crypto.c.

{
  unsigned int i, v, u;
  size_t nbits = srclen * 8, bit;

  tor_assert(srclen < SIZE_T_CEILING/8);
  tor_assert((nbits%5) == 0); /* We need an even multiple of 5 bits. */
  tor_assert((nbits/5)+1 <= destlen); /* We need enough space. */
  tor_assert(destlen < SIZE_T_CEILING);

  for (i=0,bit=0; bit < nbits; ++i, bit+=5) {
    /* set v to the 16-bit value starting at src[bits/8], 0-padded. */
    v = ((uint8_t)src[bit/8]) << 8;
    if (bit+5<nbits) v += (uint8_t)src[(bit/8)+1];
    /* set u to the 5-bit value at the bit'th bit of src. */
    u = (v >> (11-(bit%8))) & 0x1F;
    dest[i] = BASE32_CHARS[u];
  }
  dest[i] = '\0';
}

Here is the caller graph for this function:

int base64_decode ( char *  dest,
size_t  destlen,
const char *  src,
size_t  srclen 
)

Base-64 decode srclen bytes of data from src.

Write the result into dest, if it will fit within destlen bytes. Return the number of bytes written on success; -1 if destlen is too short, or other failure.

NOTE 1: destlen is checked conservatively, as though srclen contained no spaces or padding.

NOTE 2: This implementation does not check for the correct number of padding "=" characters at the end of the string, and does not check for internal padding characters.

Definition at line 2592 of file crypto.c.

{
#ifdef USE_OPENSSL_BASE64
  EVP_ENCODE_CTX ctx;
  int len, ret;
  /* 64 bytes of input -> *up to* 48 bytes of output.
     Plus one more byte, in case I'm wrong.
  */
  if (destlen < ((srclen/64)+1)*49)
    return -1;
  if (destlen > SIZE_T_CEILING)
    return -1;

  EVP_DecodeInit(&ctx);
  EVP_DecodeUpdate(&ctx, (unsigned char*)dest, &len,
                   (unsigned char*)src, srclen);
  EVP_DecodeFinal(&ctx, (unsigned char*)dest, &ret);
  ret += len;
  return ret;
#else
  const char *eos = src+srclen;
  uint32_t n=0;
  int n_idx=0;
  char *dest_orig = dest;

  /* Max number of bits == srclen*6.
   * Number of bytes required to hold all bits == (srclen*6)/8.
   * Yes, we want to round down: anything that hangs over the end of a
   * byte is padding. */
  if (destlen < (srclen*3)/4)
    return -1;
  if (destlen > SIZE_T_CEILING)
    return -1;

  /* Iterate over all the bytes in src.  Each one will add 0 or 6 bits to the
   * value we're decoding.  Accumulate bits in <b>n</b>, and whenever we have
   * 24 bits, batch them into 3 bytes and flush those bytes to dest.
   */
  for ( ; src < eos; ++src) {
    unsigned char c = (unsigned char) *src;
    uint8_t v = base64_decode_table[c];
    switch (v) {
      case X:
        /* This character isn't allowed in base64. */
        return -1;
      case SP:
        /* This character is whitespace, and has no effect. */
        continue;
      case PAD:
        /* We've hit an = character: the data is over. */
        goto end_of_loop;
      default:
        /* We have an actual 6-bit value.  Append it to the bits in n. */
        n = (n<<6) | v;
        if ((++n_idx) == 4) {
          /* We've accumulated 24 bits in n. Flush them. */
          *dest++ = (n>>16);
          *dest++ = (n>>8) & 0xff;
          *dest++ = (n) & 0xff;
          n_idx = 0;
          n = 0;
        }
    }
  }
 end_of_loop:
  /* If we have leftover bits, we need to cope. */
  switch (n_idx) {
    case 0:
    default:
      /* No leftover bits.  We win. */
      break;
    case 1:
      /* 6 leftover bits. That's invalid; we can't form a byte out of that. */
      return -1;
    case 2:
      /* 12 leftover bits: The last 4 are padding and the first 8 are data. */
      *dest++ = n >> 4;
      break;
    case 3:
      /* 18 leftover bits: The last 2 are padding and the first 16 are data. */
      *dest++ = n >> 10;
      *dest++ = n >> 2;
  }

  tor_assert((dest-dest_orig) <= (ssize_t)destlen);
  tor_assert((dest-dest_orig) <= INT_MAX);

  return (int)(dest-dest_orig);
#endif
}

Here is the caller graph for this function:

int base64_encode ( char *  dest,
size_t  destlen,
const char *  src,
size_t  srclen 
)

Base-64 encode srclen bytes of data from src.

Write the result into dest, if it will fit within destlen bytes. Return the number of bytes written on success; -1 if destlen is too short, or other failure.

Definition at line 2526 of file crypto.c.

{
  /* FFFF we might want to rewrite this along the lines of base64_decode, if
   * it ever shows up in the profile. */
  EVP_ENCODE_CTX ctx;
  int len, ret;
  tor_assert(srclen < INT_MAX);

  /* 48 bytes of input -> 64 bytes of output plus newline.
     Plus one more byte, in case I'm wrong.
  */
  if (destlen < ((srclen/48)+1)*66)
    return -1;
  if (destlen > SIZE_T_CEILING)
    return -1;

  EVP_EncodeInit(&ctx);
  EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len,
                   (unsigned char*)src, (int)srclen);
  EVP_EncodeFinal(&ctx, (unsigned char*)(dest+len), &ret);
  ret += len;
  return ret;
}

Here is the caller graph for this function:

int crypto_cipher_crypt_inplace ( crypto_cipher_t env,
char *  buf,
size_t  len 
)

Encrypt len bytes on from using the cipher in env; on success, return 0.

On failure, return -1.

Definition at line 1332 of file crypto.c.

{
  tor_assert(len < SIZE_T_CEILING);
  aes_crypt_inplace(env->cipher, buf, len);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_cipher_decrypt ( crypto_cipher_t env,
char *  to,
const char *  from,
size_t  fromlen 
)

Decrypt fromlen bytes from from using the cipher env; on success, store the result to to and return 0.

On failure, return -1.

Definition at line 1316 of file crypto.c.

{
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen < SIZE_T_CEILING);

  aes_crypt(env->cipher, from, fromlen, to);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_cipher_decrypt_with_iv ( const char *  key,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen 
)

Decrypt fromlen bytes (at least 1+CIPHER_IV_LEN) from from with the key in key to the buffer in to of length tolen.

tolen must be at least fromlen minus CIPHER_IV_LEN bytes for the initialization vector. On success, return the number of bytes written, on failure, return -1.

Definition at line 1375 of file crypto.c.

{
  crypto_cipher_t *cipher;
  tor_assert(key);
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen < INT_MAX);

  if (fromlen <= CIPHER_IV_LEN)
    return -1;
  if (tolen < fromlen - CIPHER_IV_LEN)
    return -1;

  cipher = crypto_cipher_new_with_iv(key, from);

  crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
  crypto_cipher_free(cipher);
  return (int)(fromlen - CIPHER_IV_LEN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_cipher_encrypt ( crypto_cipher_t env,
char *  to,
const char *  from,
size_t  fromlen 
)

Encrypt fromlen bytes from from using the cipher env; on success, store the result to to and return 0.

On failure, return -1.

Definition at line 1297 of file crypto.c.

{
  tor_assert(env);
  tor_assert(env->cipher);
  tor_assert(from);
  tor_assert(fromlen);
  tor_assert(to);
  tor_assert(fromlen < SIZE_T_CEILING);

  aes_crypt(env->cipher, from, fromlen, to);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_cipher_encrypt_with_iv ( const char *  key,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen 
)

Encrypt fromlen bytes (at least 1) from from with the key in key to the buffer in to of length tolen.

tolen must be at least fromlen plus CIPHER_IV_LEN bytes for the initialization vector. On success, return the number of bytes written, on failure, return -1.

Definition at line 1346 of file crypto.c.

{
  crypto_cipher_t *cipher;
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen < INT_MAX);

  if (fromlen < 1)
    return -1;
  if (tolen < fromlen + CIPHER_IV_LEN)
    return -1;

  cipher = crypto_cipher_new_with_iv(key, NULL);

  memcpy(to, cipher->iv, CIPHER_IV_LEN);
  crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
  crypto_cipher_free(cipher);
  return (int)(fromlen + CIPHER_IV_LEN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Free a symmetric cipher.

Definition at line 421 of file crypto.c.

{
  if (!env)
    return;

  tor_assert(env->cipher);
  aes_cipher_free(env->cipher);
  memset(env, 0, sizeof(crypto_cipher_t));
  tor_free(env);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* crypto_cipher_get_key ( crypto_cipher_t env)

Return a pointer to the key set for the cipher in env.

Definition at line 1287 of file crypto.c.

{
  return env->key;
}

Here is the caller graph for this function:

crypto_cipher_t* crypto_cipher_new ( const char *  key)

Return a new crypto_cipher_t with the provided key and an IV of all zero bytes.

Definition at line 411 of file crypto.c.

{
  char zeroiv[CIPHER_IV_LEN];
  memset(zeroiv, 0, sizeof(zeroiv));
  return crypto_cipher_new_with_iv(key, zeroiv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

crypto_cipher_t* crypto_cipher_new_with_iv ( const char *  key,
const char *  iv 
)

Allocate and return a new symmetric cipher using the provided key and iv.

The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes. If you provide NULL in place of either one, it is generated at random.

Definition at line 388 of file crypto.c.

{
  crypto_cipher_t *env;

  env = tor_malloc_zero(sizeof(crypto_cipher_t));

  if (key == NULL)
    crypto_rand(env->key, CIPHER_KEY_LEN);
  else
    memcpy(env->key, key, CIPHER_KEY_LEN);
  if (iv == NULL)
    crypto_rand(env->iv, CIPHER_IV_LEN);
  else
    memcpy(env->iv, iv, CIPHER_IV_LEN);

  env->cipher = aes_new_cipher(env->key, env->iv);

  return env;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ssize_t crypto_dh_compute_secret ( int  severity,
crypto_dh_t dh,
const char *  pubkey,
size_t  pubkey_len,
char *  secret_out,
size_t  secret_bytes_out 
)

Given a DH key exchange object, and our peer's value of g^y (as a pubkey_len-byte value in pubkey) generate secret_bytes_out bytes of shared key material and write them to secret_out.

Return the number of bytes generated on success, or -1 on failure.

(We generate key material by computing SHA1( g^xy || "\x00" ) || SHA1( g^xy || "\x01" ) || ... where || is concatenation.)

Definition at line 2170 of file crypto.c.

{
  char *secret_tmp = NULL;
  BIGNUM *pubkey_bn = NULL;
  size_t secret_len=0, secret_tmp_len=0;
  int result=0;
  tor_assert(dh);
  tor_assert(secret_bytes_out/DIGEST_LEN <= 255);
  tor_assert(pubkey_len < INT_MAX);

  if (!(pubkey_bn = BN_bin2bn((const unsigned char*)pubkey,
                              (int)pubkey_len, NULL)))
    goto error;
  if (tor_check_dh_key(severity, pubkey_bn)<0) {
    /* Check for invalid public keys. */
    log_fn(severity, LD_CRYPTO,"Rejected invalid g^x");
    goto error;
  }
  secret_tmp_len = crypto_dh_get_bytes(dh);
  secret_tmp = tor_malloc(secret_tmp_len);
  result = DH_compute_key((unsigned char*)secret_tmp, pubkey_bn, dh->dh);
  if (result < 0) {
    log_warn(LD_CRYPTO,"DH_compute_key() failed.");
    goto error;
  }
  secret_len = result;
  if (crypto_expand_key_material(secret_tmp, secret_len,
                                 secret_out, secret_bytes_out)<0)
    goto error;
  secret_len = secret_bytes_out;

  goto done;
 error:
  result = -1;
 done:
  crypto_log_errors(LOG_WARN, "completing DH handshake");
  if (pubkey_bn)
    BN_free(pubkey_bn);
  if (secret_tmp) {
    memset(secret_tmp, 0, secret_tmp_len);
    tor_free(secret_tmp);
  }
  if (result < 0)
    return result;
  else
    return secret_len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void crypto_dh_free ( crypto_dh_t dh)

Free a DH key exchange object.

Definition at line 2261 of file crypto.c.

{
  if (!dh)
    return;
  tor_assert(dh->dh);
  DH_free(dh->dh);
  tor_free(dh);
}

Here is the caller graph for this function:

Generate <x,g^x> for our part of the key exchange.

Return 0 on success, -1 on failure.

Definition at line 2073 of file crypto.c.

{
 again:
  if (!DH_generate_key(dh->dh)) {
    crypto_log_errors(LOG_WARN, "generating DH key");
    return -1;
  }
  if (tor_check_dh_key(LOG_WARN, dh->dh->pub_key)<0) {
    log_warn(LD_CRYPTO, "Weird! Our own DH key was invalid.  I guess once-in-"
             "the-universe chances really do happen.  Trying again.");
    /* Free and clear the keys, so OpenSSL will actually try again. */
    BN_free(dh->dh->pub_key);
    BN_free(dh->dh->priv_key);
    dh->dh->pub_key = dh->dh->priv_key = NULL;
    goto again;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return the length of the DH key in dh, in bytes.

Definition at line 2063 of file crypto.c.

{
  tor_assert(dh);
  return DH_size(dh->dh);
}

Here is the caller graph for this function:

int crypto_dh_get_public ( crypto_dh_t dh,
char *  pubkey,
size_t  pubkey_len 
)

Generate g^x as necessary, and write the g^x for the key exchange as a pubkey_len-byte value into pubkey.

Return 0 on success, -1 on failure. pubkey_len must be >= DH_BYTES.

Definition at line 2097 of file crypto.c.

{
  int bytes;
  tor_assert(dh);
  if (!dh->dh->pub_key) {
    if (crypto_dh_generate_public(dh)<0)
      return -1;
  }

  tor_assert(dh->dh->pub_key);
  bytes = BN_num_bytes(dh->dh->pub_key);
  tor_assert(bytes >= 0);
  if (pubkey_len < (size_t)bytes) {
    log_warn(LD_CRYPTO,
             "Weird! pubkey_len (%d) was smaller than DH_BYTES (%d)",
             (int) pubkey_len, bytes);
    return -1;
  }

  memset(pubkey, 0, pubkey_len);
  BN_bn2bin(dh->dh->pub_key, (unsigned char*)(pubkey+(pubkey_len-bytes)));

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

crypto_dh_t* crypto_dh_new ( int  dh_type)

Allocate and return a new DH object for a key exchange.

Definition at line 2026 of file crypto.c.

{
  crypto_dh_t *res = tor_malloc_zero(sizeof(crypto_dh_t));

  tor_assert(dh_type == DH_TYPE_CIRCUIT || dh_type == DH_TYPE_TLS ||
             dh_type == DH_TYPE_REND);

  if (!dh_param_p)
    init_dh_param();

  if (!(res->dh = DH_new()))
    goto err;

  if (dh_type == DH_TYPE_TLS) {
    if (!(res->dh->p = BN_dup(dh_param_p_tls)))
      goto err;
  } else {
    if (!(res->dh->p = BN_dup(dh_param_p)))
      goto err;
  }

  if (!(res->dh->g = BN_dup(dh_param_g)))
    goto err;

  res->dh->length = DH_PRIVATE_KEY_BITS;

  return res;
 err:
  crypto_log_errors(LOG_WARN, "creating DH object");
  if (res->dh) DH_free(res->dh); /* frees p and g too */
  tor_free(res);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_digest ( char *  digest,
const char *  m,
size_t  len 
)

Compute the SHA1 digest of the len bytes on data stored in m.

Write the DIGEST_LEN byte result into digest. Return 0 on success, -1 on failure.

Definition at line 1404 of file crypto.c.

{
  tor_assert(m);
  tor_assert(digest);
  return (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
}

Here is the caller graph for this function:

int crypto_digest256 ( char *  digest,
const char *  m,
size_t  len,
digest_algorithm_t  algorithm 
)

Compute a 256-bit digest of len bytes in data stored in m, using the algorithm algorithm.

Write the DIGEST_LEN256-byte result into digest. Return 0 on success, -1 on failure.

Definition at line 1415 of file crypto.c.

{
  tor_assert(m);
  tor_assert(digest);
  tor_assert(algorithm == DIGEST_SHA256);
  return (SHA256((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Allocate and return a new digest object to compute 256-bit digests using algorithm.

Definition at line 1495 of file crypto.c.

{
  crypto_digest_t *r;
  tor_assert(algorithm == DIGEST_SHA256);
  r = tor_malloc(sizeof(crypto_digest_t));
  SHA256_Init(&r->d.sha2);
  r->algorithm = algorithm;
  return r;
}

Here is the caller graph for this function:

void crypto_digest_add_bytes ( crypto_digest_t digest,
const char *  data,
size_t  len 
)

Add len bytes from data to the digest object.

Definition at line 1519 of file crypto.c.

{
  tor_assert(digest);
  tor_assert(data);
  /* Using the SHA*_*() calls directly means we don't support doing
   * SHA in hardware. But so far the delay of getting the question
   * to the hardware, and hearing the answer, is likely higher than
   * just doing it ourselves. Hashes are fast.
   */
  switch (digest->algorithm) {
    case DIGEST_SHA1:
      SHA1_Update(&digest->d.sha1, (void*)data, len);
      break;
    case DIGEST_SHA256:
      SHA256_Update(&digest->d.sha2, (void*)data, len);
      break;
    default:
      tor_fragile_assert();
      break;
  }
}

Here is the caller graph for this function:

Return the name of an algorithm, as used in directory documents.

Definition at line 1444 of file crypto.c.

{
  switch (alg) {
    case DIGEST_SHA1:
      return "sha1";
    case DIGEST_SHA256:
      return "sha256";
    default:
      tor_fragile_assert();
      return "??unknown_digest??";
  }
}

Here is the caller graph for this function:

int crypto_digest_algorithm_parse_name ( const char *  name)

Given the name of a digest algorithm, return its integer value, or -1 if the name is not recognized.

Definition at line 1460 of file crypto.c.

{
  if (!strcmp(name, "sha1"))
    return DIGEST_SHA1;
  else if (!strcmp(name, "sha256"))
    return DIGEST_SHA256;
  else
    return -1;
}

Here is the caller graph for this function:

int crypto_digest_all ( digests_t ds_out,
const char *  m,
size_t  len 
)

Set the digests_t in ds_out to contain every digest on the len bytes in m that we know how to compute.

Return 0 on success, -1 on failure.

Definition at line 1428 of file crypto.c.

{
  digest_algorithm_t i;
  tor_assert(ds_out);
  memset(ds_out, 0, sizeof(*ds_out));
  if (crypto_digest(ds_out->d[DIGEST_SHA1], m, len) < 0)
    return -1;
  for (i = DIGEST_SHA256; i < N_DIGEST_ALGORITHMS; ++i) {
    if (crypto_digest256(ds_out->d[i], m, len, i) < 0)
      return -1;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void crypto_digest_assign ( crypto_digest_t into,
const crypto_digest_t from 
)

Replace the state of the digest object into with the state of the digest object from.

Definition at line 1594 of file crypto.c.

{
  tor_assert(into);
  tor_assert(from);
  memcpy(into,from,sizeof(crypto_digest_t));
}

Here is the caller graph for this function:

Allocate and return a new digest object with the same state as digest

Definition at line 1581 of file crypto.c.

{
  crypto_digest_t *r;
  tor_assert(digest);
  r = tor_malloc(sizeof(crypto_digest_t));
  memcpy(r,digest,sizeof(crypto_digest_t));
  return r;
}

Here is the caller graph for this function:

void crypto_digest_free ( crypto_digest_t digest)

Deallocate a digest object.

Definition at line 1508 of file crypto.c.

{
  if (!digest)
    return;
  memset(digest, 0, sizeof(crypto_digest_t));
  tor_free(digest);
}

Here is the caller graph for this function:

void crypto_digest_get_digest ( crypto_digest_t digest,
char *  out,
size_t  out_len 
)

Compute the hash of the data that has been passed to the digest object; write the first out_len bytes of the result to out.

out_len must be <= DIGEST256_LEN.

Definition at line 1547 of file crypto.c.

{
  unsigned char r[DIGEST256_LEN];
  crypto_digest_t tmpenv;
  tor_assert(digest);
  tor_assert(out);
  /* memcpy into a temporary ctx, since SHA*_Final clears the context */
  memcpy(&tmpenv, digest, sizeof(crypto_digest_t));
  switch (digest->algorithm) {
    case DIGEST_SHA1:
      tor_assert(out_len <= DIGEST_LEN);
      SHA1_Final(r, &tmpenv.d.sha1);
      break;
    case DIGEST_SHA256:
      tor_assert(out_len <= DIGEST256_LEN);
      SHA256_Final(r, &tmpenv.d.sha2);
      break;
    default:
      log_warn(LD_BUG, "Called with unknown algorithm %d", digest->algorithm);
      /* If fragile_assert is not enabled, then we should at least not
       * leak anything. */
      memset(r, 0xff, sizeof(r));
      tor_fragile_assert();
      break;
  }
  memcpy(out, r, out_len);
  memset(r, 0, sizeof(r));
}

Here is the caller graph for this function:

Allocate and return a new digest object to compute SHA1 digests.

Definition at line 1483 of file crypto.c.

{
  crypto_digest_t *r;
  r = tor_malloc(sizeof(crypto_digest_t));
  SHA1_Init(&r->d.sha1);
  r->algorithm = DIGEST_SHA1;
  return r;
}

Here is the caller graph for this function:

int crypto_expand_key_material ( const char *  key_in,
size_t  key_in_len,
char *  key_out,
size_t  key_out_len 
)

Given key_in_len bytes of negotiated randomness in key_in ("K"), expand it into key_out_len bytes of negotiated key material in key_out by taking the first key_out_len bytes of H(K | [00]) | H(K | [01]) | ....

Return 0 on success, -1 on failure.

Definition at line 2228 of file crypto.c.

{
  int i;
  char *cp, *tmp = tor_malloc(key_in_len+1);
  char digest[DIGEST_LEN];

  /* If we try to get more than this amount of key data, we'll repeat blocks.*/
  tor_assert(key_out_len <= DIGEST_LEN*256);

  memcpy(tmp, key_in, key_in_len);
  for (cp = key_out, i=0; cp < key_out+key_out_len;
       ++i, cp += DIGEST_LEN) {
    tmp[key_in_len] = i;
    if (crypto_digest(digest, tmp, key_in_len+1))
      goto err;
    memcpy(cp, digest, MIN(DIGEST_LEN, key_out_len-(cp-key_out)));
  }
  memset(tmp, 0, key_in_len+1);
  tor_free(tmp);
  memset(digest, 0, sizeof(digest));
  return 0;

 err:
  memset(tmp, 0, key_in_len+1);
  tor_free(tmp);
  memset(digest, 0, sizeof(digest));
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static BIGNUM* crypto_generate_dynamic_dh_modulus ( void  ) [static]

Generate and return a reasonable and safe DH parameter p.

Definition at line 1699 of file crypto.c.

{
  BIGNUM *dynamic_dh_modulus;
  DH *dh_parameters;
  int r, dh_codes;
  char *s;

  dynamic_dh_modulus = BN_new();
  tor_assert(dynamic_dh_modulus);

  dh_parameters = DH_generate_parameters(DH_BYTES*8, DH_GENERATOR, NULL, NULL);
  tor_assert(dh_parameters);

  r = DH_check(dh_parameters, &dh_codes);
  tor_assert(r && !dh_codes);

  BN_copy(dynamic_dh_modulus, dh_parameters->p);
  tor_assert(dynamic_dh_modulus);

  DH_free(dh_parameters);

  { /* log the dynamic DH modulus: */
    s = BN_bn2hex(dynamic_dh_modulus);
    tor_assert(s);
    log_info(LD_OR, "Dynamic DH modulus generated: [%s]", s);
    OPENSSL_free(s);
  }

  return dynamic_dh_modulus;
}

Here is the caller graph for this function:

static INLINE int crypto_get_rsa_padding ( int  padding) [static]

Given a padding method padding, return the correct OpenSSL constant.

Definition at line 150 of file crypto.c.

{
  switch (padding)
    {
    case PK_PKCS1_PADDING: return RSA_PKCS1_PADDING;
    case PK_PKCS1_OAEP_PADDING: return RSA_PKCS1_OAEP_PADDING;
    default: tor_assert(0); return -1;
    }
}

Here is the caller graph for this function:

static INLINE int crypto_get_rsa_padding_overhead ( int  padding) [static]

Return the number of bytes added by padding method padding.

Definition at line 137 of file crypto.c.

{
  switch (padding)
    {
    case RSA_PKCS1_OAEP_PADDING: return 42;
    case RSA_PKCS1_PADDING: return 11;
    default: tor_assert(0); return -1;
    }
}

Here is the caller graph for this function:

static BIGNUM* crypto_get_stored_dynamic_dh_modulus ( const char *  fname) [static]

Return the dynamic DH modulus stored in fname.

If there is no dynamic DH modulus stored in fname, return NULL.

Definition at line 1806 of file crypto.c.

{
  int retval;
  char *contents = NULL;
  const char *contents_tmp = NULL;
  int dh_codes;
  DH *stored_dh = NULL;
  BIGNUM *dynamic_dh_modulus = NULL;
  int length = 0;
  unsigned char *base64_decoded_dh = NULL;
  const unsigned char *cp = NULL;

  tor_assert(fname);

  contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
  if (!contents) {
    log_info(LD_CRYPTO, "Could not open file '%s'", fname);
    goto done; /*usually means that ENOENT. don't try to move file to broken.*/
  }

  /* skip the file header */
  contents_tmp = eat_whitespace(contents);
  if (!*contents_tmp) {
    log_warn(LD_CRYPTO, "Stored dynamic DH modulus file "
             "seems corrupted (eat_whitespace).");
    goto err;
  }

  /* 'fname' contains the DH parameters stored in base64-ed DER
   *  format. We are only interested in the DH modulus.
   *  NOTE: We allocate more storage here than we need. Since we're already
   *  doing that, we can also add 1 byte extra to appease Coverity's
   *  scanner. */

  cp = base64_decoded_dh = tor_malloc_zero(strlen(contents_tmp) + 1);
  length = base64_decode((char *)base64_decoded_dh, strlen(contents_tmp),
                         contents_tmp, strlen(contents_tmp));
  if (length < 0) {
    log_warn(LD_CRYPTO, "Stored dynamic DH modulus seems corrupted (base64).");
    goto err;
  }

  stored_dh = d2i_DHparams(NULL, &cp, length);
  if ((!stored_dh) || (cp - base64_decoded_dh != length)) {
    log_warn(LD_CRYPTO, "Stored dynamic DH modulus seems corrupted (d2i).");
    goto err;
  }

  { /* check the cryptographic qualities of the stored dynamic DH modulus: */
    retval = DH_check(stored_dh, &dh_codes);
    if (!retval || dh_codes) {
      log_warn(LD_CRYPTO, "Stored dynamic DH modulus is not a safe prime.");
      goto err;
    }

    retval = DH_size(stored_dh);
    if (retval < DH_BYTES) {
      log_warn(LD_CRYPTO, "Stored dynamic DH modulus is smaller "
               "than '%d' bits.", DH_BYTES*8);
      goto err;
    }

    if (!BN_is_word(stored_dh->g, 2)) {
      log_warn(LD_CRYPTO, "Stored dynamic DH parameters do not use '2' "
               "as the group generator.");
      goto err;
    }
  }

  { /* log the dynamic DH modulus: */
    char *s = BN_bn2hex(stored_dh->p);
    tor_assert(s);
    log_info(LD_OR, "Found stored dynamic DH modulus: [%s]", s);
    OPENSSL_free(s);
  }

  goto done;

 err:

  {
    /* move broken prime to $filename.broken */
    char *fname_new=NULL;
    tor_asprintf(&fname_new, "%s.broken", fname);

    log_warn(LD_CRYPTO, "Moving broken dynamic DH prime to '%s'.", fname_new);

    if (replace_file(fname, fname_new))
      log_notice(LD_CRYPTO, "Error while moving '%s' to '%s'.",
                 fname, fname_new);

    tor_free(fname_new);
  }

  if (stored_dh) {
    DH_free(stored_dh);
    stored_dh = NULL;
  }

 done:
  tor_free(contents);
  tor_free(base64_decoded_dh);

  if (stored_dh) {
    dynamic_dh_modulus = BN_dup(stored_dh->p);
    DH_free(stored_dh);
  }

  return dynamic_dh_modulus;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_global_cleanup ( void  )

Uninitialize the crypto library.

Return 0 on success, -1 on failure.

Definition at line 2989 of file crypto.c.

{
  EVP_cleanup();
  ERR_remove_state(0);
  ERR_free_strings();

  if (dh_param_p)
    BN_free(dh_param_p);
  if (dh_param_p_tls)
    BN_free(dh_param_p_tls);
  if (dh_param_g)
    BN_free(dh_param_g);

#ifndef DISABLE_ENGINES
  ENGINE_cleanup();
#endif

  CONF_modules_unload(1);
  CRYPTO_cleanup_all_ex_data();
#ifdef TOR_IS_MULTITHREADED
  if (_n_openssl_mutexes) {
    int n = _n_openssl_mutexes;
    tor_mutex_t **ms = _openssl_mutexes;
    int i;
    _openssl_mutexes = NULL;
    _n_openssl_mutexes = 0;
    for (i=0;i<n;++i) {
      tor_mutex_free(ms[i]);
    }
    tor_free(ms);
  }
#endif
  return 0;
}

Here is the caller graph for this function:

int crypto_global_init ( int  useAccel,
const char *  accelName,
const char *  accelDir 
)

Initialize the crypto library.

Return 0 on success, -1 on failure.

Definition at line 227 of file crypto.c.

{
  if (!_crypto_global_initialized) {
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    _crypto_global_initialized = 1;
    setup_openssl_threading();
    if (useAccel > 0) {
#ifdef DISABLE_ENGINES
      (void)accelName;
      (void)accelDir;
      log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
#else
      ENGINE *e = NULL;

      log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
      ENGINE_load_builtin_engines();
      ENGINE_register_all_complete();

      if (accelName) {
        if (accelDir) {
          log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\""
                   " via path \"%s\".", accelName, accelDir);
          e = try_load_engine(accelName, accelDir);
        } else {
          log_info(LD_CRYPTO, "Initializing dynamic OpenSSL engine \"%s\""
                   " acceleration support.", accelName);
          e = ENGINE_by_id(accelName);
        }
        if (!e) {
          log_warn(LD_CRYPTO, "Unable to load dynamic OpenSSL engine \"%s\".",
                   accelName);
        } else {
          log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".",
                   accelName);
        }
      }
      if (e) {
        log_info(LD_CRYPTO, "Loaded OpenSSL hardware acceleration engine,"
                 " setting default ciphers.");
        ENGINE_set_default(e, ENGINE_METHOD_ALL);
      }
      log_engine("RSA", ENGINE_get_default_RSA());
      log_engine("DH", ENGINE_get_default_DH());
      log_engine("RAND", ENGINE_get_default_RAND());
      log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
      log_engine("3DES", ENGINE_get_cipher_engine(NID_des_ede3_ecb));
      log_engine("AES", ENGINE_get_cipher_engine(NID_aes_128_ecb));
#endif
    } else {
      log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
    }

    evaluate_evp_for_aes(-1);
    evaluate_ctr_for_aes();

    return crypto_seed_rng(1);
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void crypto_hmac_sha1 ( char *  hmac_out,
const char *  key,
size_t  key_len,
const char *  msg,
size_t  msg_len 
)

Compute the HMAC-SHA-1 of the msg_len bytes in msg, using the key of length key_len.

Store the DIGEST_LEN-byte result in hmac_out.

Definition at line 1607 of file crypto.c.

{
  tor_assert(key_len < INT_MAX);
  tor_assert(msg_len < INT_MAX);
  HMAC(EVP_sha1(), key, (int)key_len, (unsigned char*)msg, (int)msg_len,
       (unsigned char*)hmac_out, NULL);
}

Here is the caller graph for this function:

void crypto_hmac_sha256 ( char *  hmac_out,
const char *  key,
size_t  key_len,
const char *  msg,
size_t  msg_len 
)

Compute the HMAC-SHA-256 of the msg_len bytes in msg, using the key of length key_len.

Store the DIGEST256_LEN-byte result in hmac_out.

Definition at line 1622 of file crypto.c.

{
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(0,9,8)
  /* If we've got OpenSSL >=0.9.8 we can use its hmac implementation. */
  tor_assert(key_len < INT_MAX);
  tor_assert(msg_len < INT_MAX);
  HMAC(EVP_sha256(), key, (int)key_len, (unsigned char*)msg, (int)msg_len,
       (unsigned char*)hmac_out, NULL);
#else
  /* OpenSSL doesn't have an EVP implementation for SHA256. We'll need
     to do HMAC on our own.

     HMAC isn't so hard: To compute HMAC(key, msg):
      1. If len(key) > blocksize, key = H(key).
      2. If len(key) < blocksize, right-pad key up to blocksize with 0 bytes.
      3. let ipad = key xor 0x363636363636....36
         let opad = key xor 0x5c5c5c5c5c5c....5c
         The result is H(opad | H( ipad | msg ) )
  */
#define BLOCKSIZE 64
#define DIGESTSIZE 32
  uint8_t k[BLOCKSIZE];
  uint8_t pad[BLOCKSIZE];
  uint8_t d[DIGESTSIZE];
  int i;
  SHA256_CTX st;

  tor_assert(key_len < INT_MAX);
  tor_assert(msg_len < INT_MAX);

  if (key_len <= BLOCKSIZE) {
    memset(k, 0, sizeof(k));
    memcpy(k, key, key_len); /* not time invariant in key_len */
  } else {
    SHA256((const uint8_t *)key, key_len, k);
    memset(k+DIGESTSIZE, 0, sizeof(k)-DIGESTSIZE);
  }
  for (i = 0; i < BLOCKSIZE; ++i)
    pad[i] = k[i] ^ 0x36;
  SHA256_Init(&st);
  SHA256_Update(&st, pad, BLOCKSIZE);
  SHA256_Update(&st, (uint8_t*)msg, msg_len);
  SHA256_Final(d, &st);

  for (i = 0; i < BLOCKSIZE; ++i)
    pad[i] = k[i] ^ 0x5c;
  SHA256_Init(&st);
  SHA256_Update(&st, pad, BLOCKSIZE);
  SHA256_Update(&st, d, DIGESTSIZE);
  SHA256_Final((uint8_t*)hmac_out, &st);

  /* Now clear everything. */
  memset(k, 0, sizeof(k));
  memset(pad, 0, sizeof(pad));
  memset(d, 0, sizeof(d));
  memset(&st, 0, sizeof(st));
#undef BLOCKSIZE
#undef DIGESTSIZE
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void crypto_log_errors ( int  severity,
const char *  doing 
) [static]

Log all pending crypto errors at level severity.

Use doing to describe our current activities.

Definition at line 167 of file crypto.c.

{
  unsigned long err;
  const char *msg, *lib, *func;
  while ((err = ERR_get_error()) != 0) {
    msg = (const char*)ERR_reason_error_string(err);
    lib = (const char*)ERR_lib_error_string(err);
    func = (const char*)ERR_func_error_string(err);
    if (!msg) msg = "(null)";
    if (!lib) lib = "(null)";
    if (!func) func = "(null)";
    if (doing) {
      log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
          doing, msg, lib, func);
    } else {
      log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)", msg, lib, func);
    }
  }
}

Here is the caller graph for this function:

crypto_pk_t* crypto_pk_asn1_decode ( const char *  str,
size_t  len 
)

Decode an ASN.1-encoded public key from str; return the result on success and NULL on failure.

Definition at line 1148 of file crypto.c.

{
  RSA *rsa;
  unsigned char *buf;
  const unsigned char *cp;
  cp = buf = tor_malloc(len);
  memcpy(buf,str,len);
  rsa = d2i_RSAPublicKey(NULL, &cp, len);
  tor_free(buf);
  if (!rsa) {
    crypto_log_errors(LOG_WARN,"decoding public key");
    return NULL;
  }
  return _crypto_new_pk_from_rsa(rsa);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_asn1_encode ( crypto_pk_t pk,
char *  dest,
size_t  dest_len 
)

ASN.1-encode the public portion of pk into dest.

Return -1 on error, or the number of characters used on success.

Definition at line 1122 of file crypto.c.

{
  int len;
  unsigned char *buf, *cp;
  len = i2d_RSAPublicKey(pk->key, NULL);
  if (len < 0 || (size_t)len > dest_len || dest_len > SIZE_T_CEILING)
    return -1;
  cp = buf = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &cp);
  if (len < 0) {
    crypto_log_errors(LOG_WARN,"encoding public key");
    tor_free(buf);
    return -1;
  }
  /* We don't encode directly into 'dest', because that would be illegal
   * type-punning.  (C99 is smarter than me, C99 is smarter than me...)
   */
  memcpy(dest,buf,len);
  tor_free(buf);
  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_check_fingerprint_syntax ( const char *  s)

Return true iff s is in the correct format for a fingerprint.

Definition at line 1268 of file crypto.c.

{
  int i;
  for (i = 0; i < FINGERPRINT_LEN; ++i) {
    if ((i%5) == 4) {
      if (!TOR_ISSPACE(s[i])) return 0;
    } else {
      if (!TOR_ISXDIGIT(s[i])) return 0;
    }
  }
  if (s[FINGERPRINT_LEN]) return 0;
  return 1;
}

Here is the caller graph for this function:

Return true iff env has a valid key.

Definition at line 682 of file crypto.c.

{
  int r;
  tor_assert(env);

  r = RSA_check_key(env->key);
  if (r <= 0)
    crypto_log_errors(LOG_WARN,"checking RSA key");
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_cmp_keys ( crypto_pk_t a,
crypto_pk_t b 
)

Compare the public-key components of a and b.

Return -1 if a<b, 0 if a==b, and 1 if a>b.

Definition at line 718 of file crypto.c.

{
  int result;

  if (!a || !b)
    return -1;

  if (!a->key || !b->key)
    return -1;

  tor_assert(PUBLIC_KEY_OK(a));
  tor_assert(PUBLIC_KEY_OK(b));
  result = BN_cmp((a->key)->n, (b->key)->n);
  if (result)
    return result;
  return BN_cmp((a->key)->e, (b->key)->e);
}

Here is the caller graph for this function:

Make a real honest-to-goodness copy of env, and return it.

Definition at line 771 of file crypto.c.

{
  RSA *new_key;
  int privatekey = 0;
  tor_assert(env);
  tor_assert(env->key);

  if (PRIVATE_KEY_OK(env)) {
    new_key = RSAPrivateKey_dup(env->key);
    privatekey = 1;
  } else {
    new_key = RSAPublicKey_dup(env->key);
  }
  if (!new_key) {
    log_err(LD_CRYPTO, "Unable to duplicate a %s key: openssl failed.",
            privatekey?"private":"public");
    crypto_log_errors(LOG_ERR,
                      privatekey ? "Duplicating a private key" :
                      "Duplicating a public key");
    tor_fragile_assert();
    return NULL;
  }

  return _crypto_new_pk_from_rsa(new_key);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Increase the reference count of env, and return it.

Definition at line 760 of file crypto.c.

{
  tor_assert(env);
  tor_assert(env->key);

  env->refs++;
  return env;
}

Here is the caller graph for this function:

void crypto_pk_free ( crypto_pk_t env)

Release a reference to an asymmetric key; when all the references are released, free the key.

Definition at line 368 of file crypto.c.

{
  if (!env)
    return;

  if (--env->refs > 0)
    return;
  tor_assert(env->refs == 0);

  if (env->key)
    RSA_free(env->key);

  tor_free(env);
}

Here is the caller graph for this function:

int crypto_pk_generate_key_with_bits ( crypto_pk_t env,
int  bits 
)

Generate a bits-bit new public/private keypair in env.

Return 0 on success, -1 on failure.

Definition at line 438 of file crypto.c.

{
  tor_assert(env);

  if (env->key)
    RSA_free(env->key);
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(0,9,8)
  /* In OpenSSL 0.9.7, RSA_generate_key is all we have. */
  env->key = RSA_generate_key(bits, 65537, NULL, NULL);
#else
  /* In OpenSSL 0.9.8, RSA_generate_key is deprecated. */
  {
    BIGNUM *e = BN_new();
    RSA *r = NULL;
    if (!e)
      goto done;
    if (! BN_set_word(e, 65537))
      goto done;
    r = RSA_new();
    if (!r)
      goto done;
    if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
      goto done;

    env->key = r;
    r = NULL;
  done:
    if (e)
      BN_free(e);
    if (r)
      RSA_free(r);
    }
#endif
  if (!env->key) {
    crypto_log_errors(LOG_WARN, "generating RSA key");
    return -1;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_get_all_digests ( crypto_pk_t pk,
digests_t digests_out 
)

Compute all digests of the DER encoding of pk, and store them in digests_out.

Return 0 on success, -1 on failure.

Definition at line 1195 of file crypto.c.

{
  unsigned char *buf, *bufp;
  int len;

  len = i2d_RSAPublicKey(pk->key, NULL);
  if (len < 0)
    return -1;
  buf = bufp = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &bufp);
  if (len < 0) {
    crypto_log_errors(LOG_WARN,"encoding public key");
    tor_free(buf);
    return -1;
  }
  if (crypto_digest_all(digests_out, (char*)buf, len) < 0) {
    tor_free(buf);
    return -1;
  }
  tor_free(buf);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_get_digest ( crypto_pk_t pk,
char *  digest_out 
)

Given a private or public key pk, put a SHA1 hash of the public key into digest_out (must have DIGEST_LEN bytes of space).

Return 0 on success, -1 on failure.

Definition at line 1169 of file crypto.c.

{
  unsigned char *buf, *bufp;
  int len;

  len = i2d_RSAPublicKey(pk->key, NULL);
  if (len < 0)
    return -1;
  buf = bufp = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &bufp);
  if (len < 0) {
    crypto_log_errors(LOG_WARN,"encoding public key");
    tor_free(buf);
    return -1;
  }
  if (crypto_digest(digest_out, (char*)buf, len) < 0) {
    tor_free(buf);
    return -1;
  }
  tor_free(buf);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_get_fingerprint ( crypto_pk_t pk,
char *  fp_out,
int  add_space 
)

Given a private or public key pk, put a fingerprint of the public key into fp_out (must have at least FINGERPRINT_LEN+1 bytes of space).

Return 0 on success, -1 on failure.

Fingerprints are computed as the SHA1 digest of the ASN.1 encoding of the public key, converted to hexadecimal, in upper case, with a space after every four digits.

If add_space is false, omit the spaces.

Definition at line 1249 of file crypto.c.

{
  char digest[DIGEST_LEN];
  char hexdigest[HEX_DIGEST_LEN+1];
  if (crypto_pk_get_digest(pk, digest)) {
    return -1;
  }
  base16_encode(hexdigest,sizeof(hexdigest),digest,DIGEST_LEN);
  if (add_space) {
    add_spaces_to_fp(fp_out, FINGERPRINT_LEN+1, hexdigest);
  } else {
    strncpy(fp_out, hexdigest, HEX_DIGEST_LEN+1);
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_key_is_private ( const crypto_pk_t key)

Return true iff key contains the private-key portion of the RSA key.

Definition at line 696 of file crypto.c.

{
  tor_assert(key);
  return PRIVATE_KEY_OK(key);
}

Here is the caller graph for this function:

size_t crypto_pk_keysize ( crypto_pk_t env)

Return the size of the public key modulus in env, in bytes.

Definition at line 738 of file crypto.c.

{
  tor_assert(env);
  tor_assert(env->key);

  return (size_t) RSA_size(env->key);
}

Here is the caller graph for this function:

Allocate and return storage for a public key.

The key itself will not yet be set.

Definition at line 355 of file crypto.c.

{
  RSA *rsa;

  rsa = RSA_new();
  tor_assert(rsa);
  return _crypto_new_pk_from_rsa(rsa);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return the size of the public key modulus of env, in bits.

Definition at line 748 of file crypto.c.

{
  tor_assert(env);
  tor_assert(env->key);
  tor_assert(env->key->n);

  return BN_num_bits(env->key->n);
}

Here is the caller graph for this function:

int crypto_pk_private_decrypt ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen,
int  padding,
int  warnOnFailure 
)

Decrypt fromlen bytes from from with the private key in env, using the padding method padding.

On success, write the result to to, and return the number of bytes written. On failure, return -1.

tolen is the number of writable bytes in to, and must be at least the length of the modulus of env.

Definition at line 835 of file crypto.c.

{
  int r;
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(env->key);
  tor_assert(fromlen<INT_MAX);
  tor_assert(tolen >= crypto_pk_keysize(env));
  if (!env->key->p)
    /* Not a private key */
    return -1;

  r = RSA_private_decrypt((int)fromlen,
                          (unsigned char*)from, (unsigned char*)to,
                          env->key, crypto_get_rsa_padding(padding));

  if (r<0) {
    crypto_log_errors(warnOnFailure?LOG_WARN:LOG_DEBUG,
                      "performing RSA decryption");
    return -1;
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_private_hybrid_decrypt ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen,
int  padding,
int  warnOnFailure 
)

Invert crypto_pk_public_hybrid_encrypt.

Definition at line 1063 of file crypto.c.

{
  int outlen, r;
  size_t pkeylen;
  crypto_cipher_t *cipher = NULL;
  char *buf = NULL;

  tor_assert(fromlen < SIZE_T_CEILING);
  pkeylen = crypto_pk_keysize(env);

  if (fromlen <= pkeylen) {
    return crypto_pk_private_decrypt(env,to,tolen,from,fromlen,padding,
                                     warnOnFailure);
  }

  buf = tor_malloc(pkeylen);
  outlen = crypto_pk_private_decrypt(env,buf,pkeylen,from,pkeylen,padding,
                                     warnOnFailure);
  if (outlen<0) {
    log_fn(warnOnFailure?LOG_WARN:LOG_DEBUG, LD_CRYPTO,
           "Error decrypting public-key data");
    goto err;
  }
  if (outlen < CIPHER_KEY_LEN) {
    log_fn(warnOnFailure?LOG_WARN:LOG_INFO, LD_CRYPTO,
           "No room for a symmetric key");
    goto err;
  }
  cipher = crypto_cipher_new(buf);
  if (!cipher) {
    goto err;
  }
  memcpy(to,buf+CIPHER_KEY_LEN,outlen-CIPHER_KEY_LEN);
  outlen -= CIPHER_KEY_LEN;
  tor_assert(tolen - outlen >= fromlen - pkeylen);
  r = crypto_cipher_decrypt(cipher, to+outlen, from+pkeylen, fromlen-pkeylen);
  if (r<0)
    goto err;
  memset(buf,0,pkeylen);
  tor_free(buf);
  crypto_cipher_free(cipher);
  tor_assert(outlen + fromlen < INT_MAX);
  return (int)(outlen + (fromlen-pkeylen));
 err:
  memset(buf,0,pkeylen);
  tor_free(buf);
  crypto_cipher_free(cipher);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_private_sign ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen 
)

Sign fromlen bytes of data from from with the private key in env, using PKCS1 padding.

On success, write the signature to to, and return the number of bytes written. On failure, return -1.

tolen is the number of writable bytes in to, and must be at least the length of the modulus of env.

Definition at line 944 of file crypto.c.

{
  int r;
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen < INT_MAX);
  tor_assert(tolen >= crypto_pk_keysize(env));
  if (!env->key->p)
    /* Not a private key */
    return -1;

  r = RSA_private_encrypt((int)fromlen,
                          (unsigned char*)from, (unsigned char*)to,
                          env->key, RSA_PKCS1_PADDING);
  if (r<0) {
    crypto_log_errors(LOG_WARN, "generating RSA signature");
    return -1;
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_private_sign_digest ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen 
)

Compute a SHA1 digest of fromlen bytes of data stored at from; sign the data with the private key in env, and store it in to.

Return the number of bytes written on success, and -1 on failure.

tolen is the number of writable bytes in to, and must be at least the length of the modulus of env.

Definition at line 976 of file crypto.c.

{
  int r;
  char digest[DIGEST_LEN];
  if (crypto_digest(digest,from,fromlen)<0)
    return -1;
  r = crypto_pk_private_sign(env,to,tolen,digest,DIGEST_LEN);
  memset(digest, 0, sizeof(digest));
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_public_checksig ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen 
)

Check the signature in from (fromlen bytes long) with the public key in env, using PKCS1 padding.

On success, write the signed data to to, and return the number of bytes written. On failure, return -1.

tolen is the number of writable bytes in to, and must be at least the length of the modulus of env.

Definition at line 872 of file crypto.c.

{
  int r;
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen < INT_MAX);
  tor_assert(tolen >= crypto_pk_keysize(env));
  r = RSA_public_decrypt((int)fromlen,
                         (unsigned char*)from, (unsigned char*)to,
                         env->key, RSA_PKCS1_PADDING);

  if (r<0) {
    crypto_log_errors(LOG_WARN, "checking RSA signature");
    return -1;
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_public_checksig_digest ( crypto_pk_t env,
const char *  data,
size_t  datalen,
const char *  sig,
size_t  siglen 
)

Check a siglen-byte long signature at sig against datalen bytes of data at data, using the public key in env.

Return 0 if sig is a correct signature for SHA1(data). Else return -1.

Definition at line 899 of file crypto.c.

{
  char digest[DIGEST_LEN];
  char *buf;
  size_t buflen;
  int r;

  tor_assert(env);
  tor_assert(data);
  tor_assert(sig);
  tor_assert(datalen < SIZE_T_CEILING);
  tor_assert(siglen < SIZE_T_CEILING);

  if (crypto_digest(digest,data,datalen)<0) {
    log_warn(LD_BUG, "couldn't compute digest");
    return -1;
  }
  buflen = crypto_pk_keysize(env);
  buf = tor_malloc(buflen);
  r = crypto_pk_public_checksig(env,buf,buflen,sig,siglen);
  if (r != DIGEST_LEN) {
    log_warn(LD_CRYPTO, "Invalid signature");
    tor_free(buf);
    return -1;
  }
  if (tor_memneq(buf, digest, DIGEST_LEN)) {
    log_warn(LD_CRYPTO, "Signature mismatched with digest.");
    tor_free(buf);
    return -1;
  }
  tor_free(buf);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_public_encrypt ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen,
int  padding 
)

Encrypt fromlen bytes from from with the public key in env, using the padding method padding.

On success, write the result to to, and return the number of bytes written. On failure, return -1.

tolen is the number of writable bytes in to, and must be at least the length of the modulus of env.

Definition at line 806 of file crypto.c.

{
  int r;
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen<INT_MAX);
  tor_assert(tolen >= crypto_pk_keysize(env));

  r = RSA_public_encrypt((int)fromlen,
                         (unsigned char*)from, (unsigned char*)to,
                         env->key, crypto_get_rsa_padding(padding));
  if (r<0) {
    crypto_log_errors(LOG_WARN, "performing RSA encryption");
    return -1;
  }
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return true iff env contains a public key whose public exponent equals 65537.

Definition at line 706 of file crypto.c.

{
  tor_assert(env);
  tor_assert(env->key);

  return BN_is_word(env->key->e, 65537);
}

Here is the caller graph for this function:

int crypto_pk_public_hybrid_encrypt ( crypto_pk_t env,
char *  to,
size_t  tolen,
const char *  from,
size_t  fromlen,
int  padding,
int  force 
)

Perform a hybrid (public/secret) encryption on fromlen bytes of data from from, with padding type 'padding', storing the results on to.

Returns the number of bytes written on success, -1 on failure.

The encrypted data consists of:

  • The source data, padded and encrypted with the public key, if the padded source data is no longer than the public key, and force is false, OR
  • The beginning of the source data prefixed with a 16-byte symmetric key, padded and encrypted with the public key; followed by the rest of the source data encrypted in AES-CTR mode with the symmetric key.

Definition at line 1003 of file crypto.c.

{
  int overhead, outlen, r;
  size_t pkeylen, symlen;
  crypto_cipher_t *cipher = NULL;
  char *buf = NULL;

  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(fromlen < SIZE_T_CEILING);

  overhead = crypto_get_rsa_padding_overhead(crypto_get_rsa_padding(padding));
  pkeylen = crypto_pk_keysize(env);

  if (!force && fromlen+overhead <= pkeylen) {
    /* It all fits in a single encrypt. */
    return crypto_pk_public_encrypt(env,to,
                                    tolen,
                                    from,fromlen,padding);
  }
  tor_assert(tolen >= fromlen + overhead + CIPHER_KEY_LEN);
  tor_assert(tolen >= pkeylen);

  cipher = crypto_cipher_new(NULL); /* generate a new key. */

  buf = tor_malloc(pkeylen+1);
  memcpy(buf, cipher->key, CIPHER_KEY_LEN);
  memcpy(buf+CIPHER_KEY_LEN, from, pkeylen-overhead-CIPHER_KEY_LEN);

  /* Length of symmetrically encrypted data. */
  symlen = fromlen-(pkeylen-overhead-CIPHER_KEY_LEN);

  outlen = crypto_pk_public_encrypt(env,to,tolen,buf,pkeylen-overhead,padding);
  if (outlen!=(int)pkeylen) {
    goto err;
  }
  r = crypto_cipher_encrypt(cipher, to+outlen,
                            from+pkeylen-overhead-CIPHER_KEY_LEN, symlen);

  if (r<0) goto err;
  memset(buf, 0, pkeylen);
  tor_free(buf);
  crypto_cipher_free(cipher);
  tor_assert(outlen+symlen < INT_MAX);
  return (int)(outlen + symlen);
 err:

  memset(buf, 0, pkeylen);
  tor_free(buf);
  crypto_cipher_free(cipher);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_read_private_key_from_filename ( crypto_pk_t env,
const char *  keyfile 
)

Read a PEM-encoded private key from the file named by keyfile into env.

Return 0 on success, -1 on failure.

Definition at line 517 of file crypto.c.

{
  char *contents;
  int r;

  /* Read the file into a string. */
  contents = read_file_to_str(keyfile, 0, NULL);
  if (!contents) {
    log_warn(LD_CRYPTO, "Error reading private key from \"%s\"", keyfile);
    return -1;
  }

  /* Try to parse it. */
  r = crypto_pk_read_private_key_from_string(env, contents, -1);
  memset(contents, 0, strlen(contents));
  tor_free(contents);
  if (r)
    return -1; /* read_private_key_from_string already warned, so we don't.*/

  /* Make sure it's valid. */
  if (crypto_pk_check_key(env) <= 0)
    return -1;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_read_private_key_from_string ( crypto_pk_t env,
const char *  s,
ssize_t  len 
)

Read a PEM-encoded private key from the len-byte string s into env.

Return 0 on success, -1 on failure. If len is -1, the string is nul-terminated.

Definition at line 485 of file crypto.c.

{
  BIO *b;

  tor_assert(env);
  tor_assert(s);
  tor_assert(len < INT_MAX && len < SSIZE_T_CEILING);

  /* Create a read-only memory BIO, backed by the string 's' */
  b = BIO_new_mem_buf((char*)s, (int)len);
  if (!b)
    return -1;

  if (env->key)
    RSA_free(env->key);

  env->key = PEM_read_bio_RSAPrivateKey(b,NULL,NULL,NULL);

  BIO_free(b);

  if (!env->key) {
    crypto_log_errors(LOG_WARN, "Error parsing private key");
    return -1;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_read_public_key_from_string ( crypto_pk_t env,
const char *  src,
size_t  len 
)

Read a PEM-encoded public key from the first len characters of src, and store the result in env.

Return 0 on success, -1 on failure.

Definition at line 617 of file crypto.c.

{
  BIO *b;

  tor_assert(env);
  tor_assert(src);
  tor_assert(len<INT_MAX);

  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
  if (!b)
    return -1;

  BIO_write(b, src, (int)len);

  if (env->key)
    RSA_free(env->key);
  env->key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
  BIO_free(b);
  if (!env->key) {
    crypto_log_errors(LOG_WARN, "reading public key from string");
    return -1;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int crypto_pk_write_key_to_string_impl ( crypto_pk_t env,
char **  dest,
size_t *  len,
int  is_public 
) [static]

Helper function to implement crypto_pk_write_*_key_to_string.

Definition at line 546 of file crypto.c.

{
  BUF_MEM *buf;
  BIO *b;
  int r;

  tor_assert(env);
  tor_assert(env->key);
  tor_assert(dest);

  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
  if (!b)
    return -1;

  /* Now you can treat b as if it were a file.  Just use the
   * PEM_*_bio_* functions instead of the non-bio variants.
   */
  if (is_public)
    r = PEM_write_bio_RSAPublicKey(b, env->key);
  else
    r = PEM_write_bio_RSAPrivateKey(b, env->key, NULL,NULL,0,NULL,NULL);

  if (!r) {
    crypto_log_errors(LOG_WARN, "writing RSA key to string");
    BIO_free(b);
    return -1;
  }

  BIO_get_mem_ptr(b, &buf);
  (void)BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
  BIO_free(b);

  *dest = tor_malloc(buf->length+1);
  memcpy(*dest, buf->data, buf->length);
  (*dest)[buf->length] = 0; /* nul terminate it */
  *len = buf->length;
  BUF_MEM_free(buf);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_write_private_key_to_filename ( crypto_pk_t env,
const char *  fname 
)

Write the private key from env into the file named by fname, PEM-encoded.

Return 0 on success, -1 on failure.

Definition at line 648 of file crypto.c.

{
  BIO *bio;
  char *cp;
  long len;
  char *s;
  int r;

  tor_assert(PRIVATE_KEY_OK(env));

  if (!(bio = BIO_new(BIO_s_mem())))
    return -1;
  if (PEM_write_bio_RSAPrivateKey(bio, env->key, NULL,NULL,0,NULL,NULL)
      == 0) {
    crypto_log_errors(LOG_WARN, "writing private key");
    BIO_free(bio);
    return -1;
  }
  len = BIO_get_mem_data(bio, &cp);
  tor_assert(len >= 0);
  s = tor_malloc(len+1);
  memcpy(s, cp, len);
  s[len]='\0';
  r = write_str_to_file(fname, s, 0);
  BIO_free(bio);
  memset(s, 0, strlen(s));
  tor_free(s);
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_write_private_key_to_string ( crypto_pk_t env,
char **  dest,
size_t *  len 
)

PEM-encode the private key portion of env and write it to a newly allocated string.

On success, set *dest to the new string, *len to the string's length, and return 0. On failure, return -1.

Definition at line 606 of file crypto.c.

{
  return crypto_pk_write_key_to_string_impl(env, dest, len, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_pk_write_public_key_to_string ( crypto_pk_t env,
char **  dest,
size_t *  len 
)

PEM-encode the public key portion of env and write it to a newly allocated string.

On success, set *dest to the new string, *len to the string's length, and return 0. On failure, return -1.

Definition at line 594 of file crypto.c.

{
  return crypto_pk_write_key_to_string_impl(env, dest, len, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_rand ( char *  to,
size_t  n 
)

Write n bytes of strong random data to to.

Return 0 on success, -1 on failure.

Definition at line 2377 of file crypto.c.

{
  int r;
  tor_assert(n < INT_MAX);
  tor_assert(to);
  r = RAND_bytes((unsigned char*)to, (int)n);
  if (r == 0)
    crypto_log_errors(LOG_WARN, "generating random data");
  return (r == 1) ? 0 : -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

double crypto_rand_double ( void  )

Return a pseudorandom double d, chosen uniformly from the range 0.0 <= d < 1.0.

Definition at line 2437 of file crypto.c.

{
  /* We just use an unsigned int here; we don't really care about getting
   * more than 32 bits of resolution */
  unsigned int uint;
  crypto_rand((char*)&uint, sizeof(uint));
#if SIZEOF_INT == 4
#define UINT_MAX_AS_DOUBLE 4294967296.0
#elif SIZEOF_INT == 8
#define UINT_MAX_AS_DOUBLE 1.8446744073709552e+19
#else
#error SIZEOF_INT is neither 4 nor 8
#endif
  return ((double)uint) / UINT_MAX_AS_DOUBLE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_rand_int ( unsigned int  max)

Return a pseudorandom integer, chosen uniformly from the values between 0 and max-1 inclusive.

max must be between 1 and INT_MAX+1, inclusive.

Definition at line 2392 of file crypto.c.

{
  unsigned int val;
  unsigned int cutoff;
  tor_assert(max <= ((unsigned int)INT_MAX)+1);
  tor_assert(max > 0); /* don't div by 0 */

  /* We ignore any values that are >= 'cutoff,' to avoid biasing the
   * distribution with clipping at the upper end of unsigned int's
   * range.
   */
  cutoff = UINT_MAX - (UINT_MAX%max);
  while (1) {
    crypto_rand((char*)&val, sizeof(val));
    if (val < cutoff)
      return val % max;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

uint64_t crypto_rand_uint64 ( uint64_t  max)

Return a pseudorandom 64-bit integer, chosen uniformly from the values between 0 and max-1.

Definition at line 2414 of file crypto.c.

{
  uint64_t val;
  uint64_t cutoff;
  tor_assert(max < UINT64_MAX);
  tor_assert(max > 0); /* don't div by 0 */

  /* We ignore any values that are >= 'cutoff,' to avoid biasing the
   * distribution with clipping at the upper end of unsigned int's
   * range.
   */
  cutoff = UINT64_MAX - (UINT64_MAX%max);
  while (1) {
    crypto_rand((char*)&val, sizeof(val));
    if (val < cutoff)
      return val % max;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* crypto_random_hostname ( int  min_rand_len,
int  max_rand_len,
const char *  prefix,
const char *  suffix 
)

Generate and return a new random hostname starting with prefix, ending with suffix, and containing no fewer than min_rand_len and no more than max_rand_len random base32 characters between.

Clip max_rand_len to MAX_DNS_LABEL_SIZE.

Definition at line 2461 of file crypto.c.

{
  char *result, *rand_bytes;
  int randlen, rand_bytes_len;
  size_t resultlen, prefixlen;

  if (max_rand_len > MAX_DNS_LABEL_SIZE)
    max_rand_len = MAX_DNS_LABEL_SIZE;
  if (min_rand_len > max_rand_len)
    min_rand_len = max_rand_len;

  randlen = min_rand_len + crypto_rand_int(max_rand_len - min_rand_len + 1);

  prefixlen = strlen(prefix);
  resultlen = prefixlen + strlen(suffix) + randlen + 16;

  rand_bytes_len = ((randlen*5)+7)/8;
  if (rand_bytes_len % 5)
    rand_bytes_len += 5 - (rand_bytes_len%5);
  rand_bytes = tor_malloc(rand_bytes_len);
  crypto_rand(rand_bytes, rand_bytes_len);

  result = tor_malloc(resultlen);
  memcpy(result, prefix, prefixlen);
  base32_encode(result+prefixlen, resultlen-prefixlen,
                rand_bytes, rand_bytes_len);
  tor_free(rand_bytes);
  strlcpy(result+prefixlen+randlen, suffix, resultlen-(prefixlen+randlen));

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int crypto_seed_rng ( int  startup)

Seed OpenSSL's random number generator with bytes from the operating system.

startup should be true iff we have just started Tor and have not yet allocated a bunch of fds. Return 0 on success, -1 on failure.

Definition at line 2303 of file crypto.c.

{
  int rand_poll_status = 0;

  /* local variables */
#ifdef _WIN32
  unsigned char buf[ADD_ENTROPY];
  static int provider_set = 0;
  static HCRYPTPROV provider;
#else
  char buf[ADD_ENTROPY];
  static const char *filenames[] = {
    "/dev/srandom", "/dev/urandom", "/dev/random", NULL
  };
  int fd, i;
  size_t n;
#endif

  /* OpenSSL has a RAND_poll function that knows about more kinds of
   * entropy than we do.  We'll try calling that, *and* calling our own entropy
   * functions.  If one succeeds, we'll accept the RNG as seeded. */
  if (startup || RAND_POLL_IS_SAFE) {
    rand_poll_status = RAND_poll();
    if (rand_poll_status == 0)
      log_warn(LD_CRYPTO, "RAND_poll() failed.");
  }

#ifdef _WIN32
  if (!provider_set) {
    if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
                             CRYPT_VERIFYCONTEXT)) {
      if ((unsigned long)GetLastError() != (unsigned long)NTE_BAD_KEYSET) {
        log_warn(LD_CRYPTO, "Can't get CryptoAPI provider [1]");
        return rand_poll_status ? 0 : -1;
      }
    }
    provider_set = 1;
  }
  if (!CryptGenRandom(provider, sizeof(buf), buf)) {
    log_warn(LD_CRYPTO, "Can't get entropy from CryptoAPI.");
    return rand_poll_status ? 0 : -1;
  }
  RAND_seed(buf, sizeof(buf));
  memset(buf, 0, sizeof(buf));
  seed_weak_rng();
  return 0;
#else
  for (i = 0; filenames[i]; ++i) {
    fd = open(filenames[i], O_RDONLY, 0);
    if (fd<0) continue;
    log_info(LD_CRYPTO, "Seeding RNG from \"%s\"", filenames[i]);
    n = read_all(fd, buf, sizeof(buf), 0);
    close(fd);
    if (n != sizeof(buf)) {
      log_warn(LD_CRYPTO,
               "Error reading from entropy source (read only %lu bytes).",
               (unsigned long)n);
      return -1;
    }
    RAND_seed(buf, (int)sizeof(buf));
    memset(buf, 0, sizeof(buf));
    seed_weak_rng();
    return 0;
  }

  log_warn(LD_CRYPTO, "Cannot seed RNG -- no entropy source found.");
  return rand_poll_status ? 0 : -1;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void crypto_set_tls_dh_prime ( const char *  dynamic_dh_modulus_fname)

Set the global TLS Diffie-Hellman modulus.

If dynamic_dh_modulus_fname is set, try to read a dynamic DH modulus off it and use it as the DH modulus. If that's not possible, generate a new dynamic DH modulus. If dynamic_dh_modulus_fname is NULL, use the Apache mod_ssl DH modulus.

Definition at line 1924 of file crypto.c.

{
  BIGNUM *tls_prime = NULL;
  int store_dh_prime_afterwards = 0;
  int r;

  /* If the space is occupied, free the previous TLS DH prime */
  if (dh_param_p_tls) {
    BN_free(dh_param_p_tls);
    dh_param_p_tls = NULL;
  }

  if (dynamic_dh_modulus_fname) { /* use dynamic DH modulus: */
    log_info(LD_OR, "Using stored dynamic DH modulus.");
    tls_prime = crypto_get_stored_dynamic_dh_modulus(dynamic_dh_modulus_fname);

    if (!tls_prime) {
      log_notice(LD_OR, "Generating fresh dynamic DH modulus. "
                 "This might take a while...");
      tls_prime = crypto_generate_dynamic_dh_modulus();

      store_dh_prime_afterwards++;
    }
  } else { /* use the static DH prime modulus used by Apache in mod_ssl: */
    tls_prime = BN_new();
    tor_assert(tls_prime);

    /* This is the 1024-bit safe prime that Apache uses for its DH stuff; see
     * modules/ssl/ssl_engine_dh.c; Apache also uses a generator of 2 with this
     * prime.
     */
    r =BN_hex2bn(&tls_prime,
                 "D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98"
                 "BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A"
                 "467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7"
                 "DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68"
                 "B0E7393E0F24218EB3");
    tor_assert(r);
  }

  tor_assert(tls_prime);

  dh_param_p_tls = tls_prime;

  if (store_dh_prime_afterwards)
    /* save the new dynamic DH modulus to disk. */
    if (crypto_store_dynamic_dh_modulus(dynamic_dh_modulus_fname)) {
      log_notice(LD_CRYPTO, "Failed while storing dynamic DH modulus. "
                 "Make sure your data directory is sane.");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int crypto_store_dynamic_dh_modulus ( const char *  fname) [static]

Store our dynamic DH modulus (and its group parameters) to fname for future use.

Definition at line 1733 of file crypto.c.

{
  int len, new_len;
  DH *dh = NULL;
  unsigned char *dh_string_repr = NULL, *cp = NULL;
  char *base64_encoded_dh = NULL;
  char *file_string = NULL;
  int retval = -1;
  static const char file_header[] = "# This file contains stored Diffie-"
    "Hellman parameters for future use.\n# You *do not* need to edit this "
    "file.\n\n";

  tor_assert(fname);

  if (!dh_param_p_tls) {
    log_info(LD_CRYPTO, "Tried to store a DH modulus that does not exist.");
    goto done;
  }

  if (!(dh = DH_new()))
    goto done;
  if (!(dh->p = BN_dup(dh_param_p_tls)))
    goto done;
  if (!(dh->g = BN_new()))
    goto done;
  if (!BN_set_word(dh->g, DH_GENERATOR))
    goto done;

  len = i2d_DHparams(dh, NULL);
  if (len < 0) {
    log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (1).");
    goto done;
  }

  cp = dh_string_repr = tor_malloc_zero(len+1);
  len = i2d_DHparams(dh, &cp);
  if ((len < 0) || ((cp - dh_string_repr) != len)) {
    log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (2).");
    goto done;
  }

  base64_encoded_dh = tor_malloc_zero(len * 2); /* should be enough */
  new_len = base64_encode(base64_encoded_dh, len * 2,
                          (char *)dh_string_repr, len);
  if (new_len < 0) {
    log_warn(LD_CRYPTO, "Error occured while base64-encoding DH modulus.");
    goto done;
  }

  /* concatenate file header and the dh parameters blob */
  new_len = tor_asprintf(&file_string, "%s%s", file_header, base64_encoded_dh);

  /* write to file */
  if (write_bytes_to_new_file(fname, file_string, new_len, 0) < 0) {
    log_info(LD_CRYPTO, "'%s' was already occupied.", fname);
    goto done;
  }

  retval = 0;

 done:
  if (dh)
    DH_free(dh);
  tor_free(dh_string_repr);
  tor_free(base64_encoded_dh);
  tor_free(file_string);

  return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void crypto_thread_cleanup ( void  )

Free crypto resources held by this thread.

Definition at line 290 of file crypto.c.

{
  ERR_remove_state(0);
}

Here is the caller graph for this function:

int digest256_from_base64 ( char *  digest,
const char *  d64 
)

Given a base-64 encoded, nul-terminated digest in d64 (without trailing newline or = characters), decode it and store the result in the first DIGEST256_LEN bytes at digest.

Definition at line 2741 of file crypto.c.

{
#ifdef USE_OPENSSL_BASE64
  char buf_in[BASE64_DIGEST256_LEN+3];
  char buf[256];
  if (strlen(d64) != BASE64_DIGEST256_LEN)
    return -1;
  memcpy(buf_in, d64, BASE64_DIGEST256_LEN);
  memcpy(buf_in+BASE64_DIGEST256_LEN, "=\n\0", 3);
  if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST256_LEN)
    return -1;
  memcpy(digest, buf, DIGEST256_LEN);
  return 0;
#else
  if (base64_decode(digest, DIGEST256_LEN, d64, strlen(d64)) == DIGEST256_LEN)
    return 0;
  else
    return -1;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int digest256_to_base64 ( char *  d64,
const char *  digest 
)

Base-64 encode DIGEST256_LINE bytes from digest, remove the trailing = and newline characters, and store the nul-terminated result in the first BASE64_DIGEST256_LEN+1 bytes of d64.

Definition at line 2728 of file crypto.c.

{
  char buf[256];
  base64_encode(buf, sizeof(buf), digest, DIGEST256_LEN);
  buf[BASE64_DIGEST256_LEN] = '\0';
  memcpy(d64, buf, BASE64_DIGEST256_LEN+1);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int digest_from_base64 ( char *  digest,
const char *  d64 
)

Given a base-64 encoded, nul-terminated digest in d64 (without trailing newline or = characters), decode it and store the result in the first DIGEST_LEN bytes at digest.

Definition at line 2703 of file crypto.c.

{
#ifdef USE_OPENSSL_BASE64
  char buf_in[BASE64_DIGEST_LEN+3];
  char buf[256];
  if (strlen(d64) != BASE64_DIGEST_LEN)
    return -1;
  memcpy(buf_in, d64, BASE64_DIGEST_LEN);
  memcpy(buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
  if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST_LEN)
    return -1;
  memcpy(digest, buf, DIGEST_LEN);
  return 0;
#else
  if (base64_decode(digest, DIGEST_LEN, d64, strlen(d64)) == DIGEST_LEN)
    return 0;
  else
    return -1;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int digest_to_base64 ( char *  d64,
const char *  digest 
)

Base-64 encode DIGEST_LINE bytes from digest, remove the trailing = and newline characters, and store the nul-terminated result in the first BASE64_DIGEST_LEN+1 bytes of d64.

Definition at line 2690 of file crypto.c.

{
  char buf[256];
  base64_encode(buf, sizeof(buf), digest, DIGEST_LEN);
  buf[BASE64_DIGEST_LEN] = '\0';
  memcpy(d64, buf, BASE64_DIGEST_LEN+1);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_dh_param ( void  ) [static]

Initialize dh_param_p and dh_param_g if they are not already set.

Definition at line 1979 of file crypto.c.

{
  BIGNUM *circuit_dh_prime, *generator;
  int r;
  if (dh_param_p && dh_param_g)
    return;

  circuit_dh_prime = BN_new();
  generator = BN_new();
  tor_assert(circuit_dh_prime && generator);

  /* Set our generator for all DH parameters */
  r = BN_set_word(generator, DH_GENERATOR);
  tor_assert(r);

  /* This is from rfc2409, section 6.2.  It's a safe prime, and
     supposedly it equals:
        2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
  */
  r = BN_hex2bn(&circuit_dh_prime,
                "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
                "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
                "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
                "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
                "49286651ECE65381FFFFFFFFFFFFFFFF");
  tor_assert(r);

  /* Set the new values as the global DH parameters. */
  dh_param_p = circuit_dh_prime;
  dh_param_g = generator;

  /* Ensure that we have TLS DH parameters set up, too, even if we're
     going to change them soon. */
  if (!dh_param_p_tls) {
    crypto_set_tls_dh_prime(NULL);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void log_engine ( const char *  fn,
ENGINE *  e 
) [static]

Log any OpenSSL engines we're using at NOTICE.

Definition at line 190 of file crypto.c.

{
  if (e) {
    const char *name, *id;
    name = ENGINE_get_name(e);
    id = ENGINE_get_id(e);
    log(LOG_NOTICE, LD_CRYPTO, "Using OpenSSL engine %s [%s] for %s",
        name?name:"?", id?id:"?", fn);
  } else {
    log(LOG_INFO, LD_CRYPTO, "Using default implementation for %s", fn);
  }
}

Here is the caller graph for this function:

void secret_to_key ( char *  key_out,
size_t  key_out_len,
const char *  secret,
size_t  secret_len,
const char *  s2k_specifier 
)

Implement RFC2440-style iterated-salted S2K conversion: convert the secret_len-byte secret into a key_out_len byte key_out.

As in RFC2440, the first 8 bytes of s2k_specifier are a salt; the 9th byte describes how much iteration to do. Does not support key_out_len > DIGEST_LEN.

Definition at line 2859 of file crypto.c.

{
  crypto_digest_t *d;
  uint8_t c;
  size_t count, tmplen;
  char *tmp;
  tor_assert(key_out_len < SIZE_T_CEILING);

#define EXPBIAS 6
  c = s2k_specifier[8];
  count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
#undef EXPBIAS

  tor_assert(key_out_len <= DIGEST_LEN);

  d = crypto_digest_new();
  tmplen = 8+secret_len;
  tmp = tor_malloc(tmplen);
  memcpy(tmp,s2k_specifier,8);
  memcpy(tmp+8,secret,secret_len);
  secret_len += 8;
  while (count) {
    if (count >= secret_len) {
      crypto_digest_add_bytes(d, tmp, secret_len);
      count -= secret_len;
    } else {
      crypto_digest_add_bytes(d, tmp, count);
      count = 0;
    }
  }
  crypto_digest_get_digest(d, key_out, key_out_len);
  memset(tmp, 0, tmplen);
  tor_free(tmp);
  crypto_digest_free(d);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void seed_weak_rng ( void  ) [static]

Set the seed of the weak RNG to a random value.

Definition at line 2291 of file crypto.c.

{
  unsigned seed;
  crypto_rand((void*)&seed, sizeof(seed));
  tor_init_weak_random(seed);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int setup_openssl_threading ( void  ) [static]

Definition at line 2980 of file crypto.c.

{
  return 0;
}

Here is the caller graph for this function:

static unsigned char* SHA256 ( const unsigned char *  m,
size_t  len,
unsigned char *  d 
) [static]

Definition at line 87 of file crypto.c.

{
  SHA256_CTX ctx;
  SHA256_Init(&ctx);
  SHA256_Update(&ctx, m, len);
  SHA256_Final(d, &ctx);
  return d;
}

Here is the caller graph for this function:

void* smartlist_choose ( const smartlist_t sl)

Return a randomly chosen element of sl; or NULL if sl is empty.

Definition at line 2497 of file crypto.c.

{
  int len = smartlist_len(sl);
  if (len)
    return smartlist_get(sl,crypto_rand_int(len));
  return NULL; /* no elements to choose from */
}

Here is the call graph for this function:

Here is the caller graph for this function:

Scramble the elements of sl into a random order.

Definition at line 2507 of file crypto.c.

{
  int i;
  /* From the end of the list to the front, choose at random from the
     positions we haven't looked at yet, and swap that position into the
     current position.  Remember to give "no swap" the same probability as
     any other swap. */
  for (i = smartlist_len(sl)-1; i > 0; --i) {
    int j = crypto_rand_int(i+1);
    smartlist_swap(sl, i, j);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int tor_check_dh_key ( int  severity,
BIGNUM *  bn 
) [static]

Check for bad Diffie-Hellman public keys (g^x).

Return 0 if the key is okay (in the subgroup [2,p-2]), or -1 if it's bad. See http://www.cl.cam.ac.uk/ftp/users/rja14/psandqs.ps.gz for some tips.

Definition at line 2127 of file crypto.c.

{
  BIGNUM *x;
  char *s;
  tor_assert(bn);
  x = BN_new();
  tor_assert(x);
  if (!dh_param_p)
    init_dh_param();
  BN_set_word(x, 1);
  if (BN_cmp(bn,x)<=0) {
    log_fn(severity, LD_CRYPTO, "DH key must be at least 2.");
    goto err;
  }
  BN_copy(x,dh_param_p);
  BN_sub_word(x, 1);
  if (BN_cmp(bn,x)>=0) {
    log_fn(severity, LD_CRYPTO, "DH key must be at most p-2.");
    goto err;
  }
  BN_free(x);
  return 0;
 err:
  BN_free(x);
  s = BN_bn2hex(bn);
  log_fn(severity, LD_CRYPTO, "Rejecting insecure DH key [%s]", s);
  OPENSSL_free(s);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ENGINE* try_load_engine ( const char *  path,
const char *  engine 
) [static]

Try to load an engine in a shared library via fully qualified path.

Definition at line 208 of file crypto.c.

{
  ENGINE *e = ENGINE_by_id("dynamic");
  if (e) {
    if (!ENGINE_ctrl_cmd_string(e, "ID", engine, 0) ||
        !ENGINE_ctrl_cmd_string(e, "DIR_LOAD", "2", 0) ||
        !ENGINE_ctrl_cmd_string(e, "DIR_ADD", path, 0) ||
        !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
      ENGINE_free(e);
      e = NULL;
    }
  }
  return e;
}

Here is the caller graph for this function:


Variable Documentation

int _crypto_global_initialized = 0 [static]

Boolean: has OpenSSL's crypto been initialized?

Definition at line 161 of file crypto.c.

const uint8_t base64_decode_table[256] [static]
Initial value:
 {
  X, X, X, X, X, X, X, X, X, SP, SP, SP, X, SP, X, X, 
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  SP, X, X, X, X, X, X, X, X, X, X, 62, X, X, X, 63,
  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, X, X, X, PAD, X, X,
  X, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, X, X, X, X, X,
  X, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
  X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
}

Internal table mapping byte values to what they represent in base64.

Numbers 0..63 are 6-bit integers. SPs are spaces, and should be skipped. Xs are invalid and must not appear in base64. PAD indicates end-of-string.

Definition at line 2560 of file crypto.c.

BIGNUM* dh_param_g = NULL [static]

Shared G parameter for our DH key exchanges.

Definition at line 1695 of file crypto.c.

BIGNUM* dh_param_p = NULL [static]

Shared P parameter for our circuit-crypto DH key exchanges.

Definition at line 1691 of file crypto.c.

BIGNUM* dh_param_p_tls = NULL [static]

Shared P parameter for our TLS DH key exchanges.

Definition at line 1693 of file crypto.c.