コード例 #1
0
ファイル: tor-gencert.c プロジェクト: AllardJ/Tomato
static void
clear_passphrase(void)
{
  if (passphrase) {
    memwipe(passphrase, 0, passphrase_len);
    tor_free(passphrase);
  }
}
コード例 #2
0
ファイル: onion_tap.c プロジェクト: jfrazelle/tor
/** Given a router's 128 byte public key,
 * stores the following in onion_skin_out:
 *   - [42 bytes] OAEP padding
 *   - [16 bytes] Symmetric key for encrypting blob past RSA
 *   - [70 bytes] g^x part 1 (inside the RSA)
 *   - [58 bytes] g^x part 2 (symmetrically encrypted)
 *
 * Stores the DH private key into handshake_state_out for later completion
 * of the handshake.
 *
 * The meeting point/cookies and auth are zeroed out for now.
 */
int
onion_skin_TAP_create(crypto_pk_t *dest_router_key,
                  crypto_dh_t **handshake_state_out,
                  char *onion_skin_out) /* TAP_ONIONSKIN_CHALLENGE_LEN bytes */
{
  char challenge[DH1024_KEY_LEN];
  crypto_dh_t *dh = NULL;
  int dhbytes, pkbytes;

  tor_assert(dest_router_key);
  tor_assert(handshake_state_out);
  tor_assert(onion_skin_out);
  *handshake_state_out = NULL;
  memset(onion_skin_out, 0, TAP_ONIONSKIN_CHALLENGE_LEN);

  if (!(dh = crypto_dh_new(DH_TYPE_CIRCUIT)))
    goto err;

  dhbytes = crypto_dh_get_bytes(dh);
  pkbytes = (int) crypto_pk_keysize(dest_router_key);
  tor_assert(dhbytes == 128);
  tor_assert(pkbytes == 128);

  if (crypto_dh_get_public(dh, challenge, dhbytes))
    goto err;

  /* set meeting point, meeting cookie, etc here. Leave zero for now. */
  if (crypto_pk_obsolete_public_hybrid_encrypt(dest_router_key, onion_skin_out,
                                      TAP_ONIONSKIN_CHALLENGE_LEN,
                                      challenge, DH1024_KEY_LEN,
                                      PK_PKCS1_OAEP_PADDING, 1)<0)
    goto err;

  memwipe(challenge, 0, sizeof(challenge));
  *handshake_state_out = dh;

  return 0;
 err:
  /* LCOV_EXCL_START
   * We only get here if RSA encryption fails or DH keygen fails. Those
   * shouldn't be possible. */
  memwipe(challenge, 0, sizeof(challenge));
  if (dh) crypto_dh_free(dh);
  return -1;
  /* LCOV_EXCL_STOP */
}
コード例 #3
0
ファイル: crypto_format.c プロジェクト: 1234max/tor
/** Read a tagged-data file from <b>fname</b> into the
 * <b>data_out_len</b>-byte buffer in <b>data_out</b>. Check that the
 * typestring matches <b>typestring</b>; store the tag into a newly allocated
 * string in <b>tag_out</b>. Return -1 on failure, and the number of bytes of
 * data on success.  Preserves the errno from reading the file. */
ssize_t
crypto_read_tagged_contents_from_file(const char *fname,
                                      const char *typestring,
                                      char **tag_out,
                                      uint8_t *data_out,
                                      ssize_t data_out_len)
{
  char prefix[33];
  char *content = NULL;
  struct stat st;
  ssize_t r = -1;
  size_t st_size = 0;
  int saved_errno = 0;

  *tag_out = NULL;
  st.st_size = 0;
  content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  if (! content) {
    saved_errno = errno;
    goto end;
  }
  if (st.st_size < 32 || st.st_size > 32 + data_out_len) {
    saved_errno = EINVAL;
    goto end;
  }
  st_size = (size_t)st.st_size;

  memcpy(prefix, content, 32);
  prefix[32] = 0;
  /* Check type, extract tag. */
  if (strcmpstart(prefix, "== ") || strcmpend(prefix, " ==") ||
      ! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix))) {
    saved_errno = EINVAL;
    goto end;
  }

  if (strcmpstart(prefix+3, typestring) ||
      3+strlen(typestring) >= 32 ||
      strcmpstart(prefix+3+strlen(typestring), ": ")) {
    saved_errno = EINVAL;
    goto end;
  }

  *tag_out = tor_strndup(prefix+5+strlen(typestring),
                         strlen(prefix)-8-strlen(typestring));

  memcpy(data_out, content+32, st_size-32);
  r = st_size - 32;

 end:
  if (content)
    memwipe(content, 0, st_size);
  tor_free(content);
  if (saved_errno)
    errno = saved_errno;
  return r;
}
コード例 #4
0
ファイル: mempool.c プロジェクト: zhenfeizhang/ntru-tor-local
/** Free all space held in <b>pool</b>  This makes all pointers returned from
 * mp_pool_get(<b>pool</b>) invalid. */
void
mp_pool_destroy(mp_pool_t *pool)
{
    destroy_chunks(pool->empty_chunks);
    destroy_chunks(pool->used_chunks);
    destroy_chunks(pool->full_chunks);
    memwipe(pool, 0xe0, sizeof(mp_pool_t));
    FREE(pool);
}
コード例 #5
0
ファイル: crypto_ed25519.c プロジェクト: 1833183060/tor-1
/** Release all storage held for <b>kp</b>. */
void
ed25519_keypair_free(ed25519_keypair_t *kp)
{
  if (! kp)
    return;

  memwipe(kp, 0, sizeof(*kp));
  tor_free(kp);
}
コード例 #6
0
ファイル: test-memwipe.c プロジェクト: Archer-sys/tor
static unsigned
fill_heap_buffer_memwipe(void)
{
  char *buf = heap_buf = malloc(BUF_LEN);
  FILL_BUFFER_IMPL()
  memwipe(buf, 0, BUF_LEN);
  free(buf);
  return sum;
}
コード例 #7
0
ファイル: crypto_rand_fast.c プロジェクト: nmathewson/Tor
/**
 * Initialize and return a new fast PRNG, using a strong random seed.
 *
 * Note that this object is NOT thread-safe.  If you need a thread-safe
 * prng, use crypto_rand(), or wrap this in a mutex.
 **/
crypto_fast_rng_t *
crypto_fast_rng_new(void)
{
  uint8_t seed[SEED_LEN];
  crypto_strongest_rand(seed, sizeof(seed));
  crypto_fast_rng_t *result = crypto_fast_rng_new_from_seed(seed);
  memwipe(seed, 0, sizeof(seed));
  return result;
}
コード例 #8
0
ファイル: onion_tap.c プロジェクト: BenGant/tor
/** Given a router's 128 byte public key,
 * stores the following in onion_skin_out:
 *   - [42 bytes] OAEP padding
 *   - [16 bytes] Symmetric key for encrypting blob past RSA
 *   - [70 bytes] g^x part 1 (inside the RSA)
 *   - [58 bytes] g^x part 2 (symmetrically encrypted)
 *
 * Stores the DH private key into handshake_state_out for later completion
 * of the handshake.
 *
 * The meeting point/cookies and auth are zeroed out for now.
 */
int
onion_skin_TAP_create(crypto_pk_t *dest_router_key,
                  crypto_dh_t **handshake_state_out,
                  char *onion_skin_out) /* TAP_ONIONSKIN_CHALLENGE_LEN bytes */
{
  char challenge[DH_KEY_LEN];
  crypto_dh_t *dh = NULL;
  int dhbytes, pkbytes;

  tor_assert(dest_router_key);
  tor_assert(handshake_state_out);
  tor_assert(onion_skin_out);
  *handshake_state_out = NULL;
  memset(onion_skin_out, 0, TAP_ONIONSKIN_CHALLENGE_LEN);

  if (!(dh = crypto_dh_new(DH_TYPE_CIRCUIT)))
    goto err;

  dhbytes = crypto_dh_get_bytes(dh);
  pkbytes = (int) crypto_pk_keysize(dest_router_key);
  tor_assert(dhbytes == 128);
  tor_assert(pkbytes == 128);

  if (crypto_dh_get_public(dh, challenge, dhbytes))
    goto err;

  note_crypto_pk_op(ENC_ONIONSKIN);

  /* set meeting point, meeting cookie, etc here. Leave zero for now. */
  if (crypto_pk_public_hybrid_encrypt(dest_router_key, onion_skin_out,
                                      TAP_ONIONSKIN_CHALLENGE_LEN,
                                      challenge, DH_KEY_LEN,
                                      PK_PKCS1_OAEP_PADDING, 1)<0)
    goto err;

  memwipe(challenge, 0, sizeof(challenge));
  *handshake_state_out = dh;

  return 0;
 err:
  memwipe(challenge, 0, sizeof(challenge));
  if (dh) crypto_dh_free(dh);
  return -1;
}
コード例 #9
0
ファイル: routerkeys.c プロジェクト: CFFei/TorAnonPerf
int
write_encrypted_secret_key(const ed25519_secret_key_t *key,
                           const char *fname)
{
  int r = -1;
  char pwbuf0[256];
  uint8_t *encrypted_key = NULL;
  size_t encrypted_len = 0;

  if (do_getpass("Enter new passphrase:", pwbuf0, sizeof(pwbuf0), 1,
                 get_options()) < 0) {
    log_warn(LD_OR, "NO/failed passphrase");
    return -1;
  }

  if (strlen(pwbuf0) == 0) {
    if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_ON)
      return -1;
    else
      return 0;
  }

  if (crypto_pwbox(&encrypted_key, &encrypted_len,
                   key->seckey, sizeof(key->seckey),
                   pwbuf0, strlen(pwbuf0),  0) < 0) {
    log_warn(LD_OR, "crypto_pwbox failed!?");
    goto done;
  }
  if (crypto_write_tagged_contents_to_file(fname,
                                           ENC_KEY_HEADER,
                                           ENC_KEY_TAG,
                                           encrypted_key, encrypted_len) < 0)
    goto done;
  r = 1;
 done:
  if (encrypted_key) {
    memwipe(encrypted_key, 0, encrypted_len);
    tor_free(encrypted_key);
  }
  memwipe(pwbuf0, 0, sizeof(pwbuf0));
  return r;
}
コード例 #10
0
ファイル: hs_ntor.c プロジェクト: unixninja92/Tor
/* Public function: Do the appropriate ntor calculations and derive the keys
 * needed to decrypt and verify INTRODUCE1 cells. Return 0 and place the final
 * key material in <b>hs_ntor_intro_cell_keys_out</b> if everything went well,
 * otherwise return -1;
 *
 * The relevant calculations are as follows:
 *
 *    intro_secret_hs_input = EXP(X,b) | AUTH_KEY | X | B | PROTOID
 *    info = m_hsexpand | subcredential
 *    hs_keys = KDF(intro_secret_hs_input | t_hsenc | info, S_KEY_LEN+MAC_LEN)
 *    HS_DEC_KEY = hs_keys[0:S_KEY_LEN]
 *    HS_MAC_KEY = hs_keys[S_KEY_LEN:S_KEY_LEN+MAC_KEY_LEN]
 *
 * where:
 * <b>intro_auth_pubkey</b> is AUTH_KEY (introduction point auth key),
 * <b>intro_enc_keypair</b> is (b,B) (introduction point encryption keypair),
 * <b>client_ephemeral_enc_pubkey</b> is X (CLIENT_PK in INTRODUCE2 cell),
 * <b>subcredential</b> is the HS subcredential (of size DIGEST256_LEN) */
int
hs_ntor_service_get_introduce1_keys(
                    const ed25519_public_key_t *intro_auth_pubkey,
                    const curve25519_keypair_t *intro_enc_keypair,
                    const curve25519_public_key_t *client_ephemeral_enc_pubkey,
                    const uint8_t *subcredential,
                    hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
{
  int bad = 0;
  uint8_t secret_input[INTRO_SECRET_HS_INPUT_LEN];
  uint8_t dh_result[CURVE25519_OUTPUT_LEN];

  tor_assert(intro_auth_pubkey);
  tor_assert(intro_enc_keypair);
  tor_assert(client_ephemeral_enc_pubkey);
  tor_assert(subcredential);
  tor_assert(hs_ntor_intro_cell_keys_out);

  /* Compute EXP(X, b) */
  curve25519_handshake(dh_result,
                       &intro_enc_keypair->seckey,
                       client_ephemeral_enc_pubkey);
  bad |= safe_mem_is_zero(dh_result, CURVE25519_OUTPUT_LEN);

  /* Get intro_secret_hs_input */
  get_intro_secret_hs_input(dh_result, intro_auth_pubkey,
                            client_ephemeral_enc_pubkey,
                            &intro_enc_keypair->pubkey,
                            secret_input);
  bad |= safe_mem_is_zero(secret_input, CURVE25519_OUTPUT_LEN);

  /* Get ENC_KEY and MAC_KEY! */
  get_introduce1_key_material(secret_input, subcredential,
                              hs_ntor_intro_cell_keys_out);

  memwipe(secret_input,  0, sizeof(secret_input));
  if (bad) {
    memwipe(hs_ntor_intro_cell_keys_out, 0, sizeof(hs_ntor_intro_cell_keys_t));
  }

  return bad ? -1 : 0;
}
コード例 #11
0
ファイル: aes.c プロジェクト: themiron/asuswrt-merlin
/** Release storage held by <b>cipher</b>
 */
void
aes_cipher_free(aes_cnt_cipher_t *cipher)
{
  if (!cipher)
    return;
  if (cipher->using_evp) {
    EVP_CIPHER_CTX_cleanup(&cipher->key.evp);
  }
  memwipe(cipher, 0, sizeof(aes_cnt_cipher_t));
  tor_free(cipher);
}
コード例 #12
0
ファイル: onion_tap.c プロジェクト: jfrazelle/tor
/** Finish the client side of the DH handshake.
 * Given the 128 byte DH reply + 20 byte hash as generated by
 * onion_skin_server_handshake and the handshake state generated by
 * onion_skin_create, verify H(K) with the first 20 bytes of shared
 * key material, then generate key_out_len more bytes of shared key
 * material and store them in key_out.
 *
 * After the invocation, call crypto_dh_free on handshake_state.
 */
int
onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
            const char *handshake_reply, /* TAP_ONIONSKIN_REPLY_LEN bytes */
            char *key_out,
            size_t key_out_len,
            const char **msg_out)
{
  ssize_t len;
  char *key_material=NULL;
  size_t key_material_len;
  tor_assert(crypto_dh_get_bytes(handshake_state) == DH1024_KEY_LEN);

  key_material_len = DIGEST_LEN + key_out_len;
  key_material = tor_malloc(key_material_len);
  len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state,
                                 handshake_reply, DH1024_KEY_LEN, key_material,
                                 key_material_len);
  if (len < 0) {
    if (msg_out)
      *msg_out = "DH computation failed.";
    goto err;
  }

  if (tor_memneq(key_material, handshake_reply+DH1024_KEY_LEN, DIGEST_LEN)) {
    /* H(K) does *not* match. Something fishy. */
    if (msg_out)
      *msg_out = "Digest DOES NOT MATCH on onion handshake. Bug or attack.";
    goto err;
  }

  /* use the rest of the key material for our shared keys, digests, etc */
  memcpy(key_out, key_material+DIGEST_LEN, key_out_len);

  memwipe(key_material, 0, key_material_len);
  tor_free(key_material);
  return 0;
 err:
  memwipe(key_material, 0, key_material_len);
  tor_free(key_material);
  return -1;
}
コード例 #13
0
ファイル: ed25519_tor.c プロジェクト: 1234max/tor
int
ed25519_donna_seckey(unsigned char *sk)
{
  ed25519_secret_key seed;

  crypto_strongest_rand(seed, 32);

  ed25519_extsk(sk, seed);

  memwipe(seed, 0, sizeof(seed));

  return 0;
}
コード例 #14
0
ファイル: onion.c プロジェクト: BwRy/Astoria
/** Release all storage held in <b>keys</b>. */
void
server_onion_keys_free(server_onion_keys_t *keys)
{
  if (! keys)
    return;

  crypto_pk_free(keys->onion_key);
  crypto_pk_free(keys->last_onion_key);
  ntor_key_map_free(keys->curve25519_key_map);
  tor_free(keys->junk_keypair);
  memwipe(keys, 0, sizeof(server_onion_keys_t));
  tor_free(keys);
}
コード例 #15
0
ファイル: hs_ntor.c プロジェクト: unixninja92/Tor
/** Helper function: Compute the part of the HS ntor handshake that generates
 *  key material for creating and handling INTRODUCE1 cells. Function used
 *  by both client and service. Specifically, calculate the following:
 *
 *     info = m_hsexpand | subcredential
 *     hs_keys = KDF(intro_secret_hs_input | t_hsenc | info, S_KEY_LEN+MAC_LEN)
 *     ENC_KEY = hs_keys[0:S_KEY_LEN]
 *     MAC_KEY = hs_keys[S_KEY_LEN:S_KEY_LEN+MAC_KEY_LEN]
 *
 *  where intro_secret_hs_input is <b>secret_input</b> (of size
 *  INTRO_SECRET_HS_INPUT_LEN), and <b>subcredential</b> is of size
 *  DIGEST256_LEN.
 *
 * If everything went well, fill <b>hs_ntor_intro_cell_keys_out</b> with the
 * necessary key material, and return 0. */
static void
get_introduce1_key_material(const uint8_t *secret_input,
                        const uint8_t *subcredential,
                        hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
{
  uint8_t keystream[CIPHER256_KEY_LEN + DIGEST256_LEN];
  uint8_t info_blob[INFO_BLOB_LEN];
  uint8_t kdf_input[KDF_INPUT_LEN];
  crypto_xof_t *xof;
  uint8_t *ptr;

  /* Let's build info */
  ptr = info_blob;
  APPEND(ptr, M_HSEXPAND, strlen(M_HSEXPAND));
  APPEND(ptr, subcredential, DIGEST256_LEN);
  tor_assert(ptr == info_blob + sizeof(info_blob));

  /* Let's build the input to the KDF */
  ptr = kdf_input;
  APPEND(ptr, secret_input, INTRO_SECRET_HS_INPUT_LEN);
  APPEND(ptr, T_HSENC, strlen(T_HSENC));
  APPEND(ptr, info_blob, sizeof(info_blob));
  tor_assert(ptr == kdf_input + sizeof(kdf_input));

  /* Now we need to run kdf_input over SHAKE-256 */
  xof = crypto_xof_new();
  crypto_xof_add_bytes(xof, kdf_input, sizeof(kdf_input));
  crypto_xof_squeeze_bytes(xof, keystream, sizeof(keystream)) ;
  crypto_xof_free(xof);

  { /* Get the keys */
    memcpy(&hs_ntor_intro_cell_keys_out->enc_key, keystream,CIPHER256_KEY_LEN);
    memcpy(&hs_ntor_intro_cell_keys_out->mac_key,
           keystream+CIPHER256_KEY_LEN, DIGEST256_LEN);
  }

  memwipe(keystream,  0, sizeof(keystream));
  memwipe(kdf_input,  0, sizeof(kdf_input));
}
コード例 #16
0
ファイル: crypto_ed25519.c プロジェクト: Zex/tor
/**
 * Initialize a new ed25519 secret key in <b>seckey_out</b>.  If
 * <b>extra_strong</b>, take the RNG inputs directly from the operating
 * system.  Return 0 on success, -1 on failure.
 */
int
ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
                        int extra_strong)
{
  int r;
  uint8_t seed[32];
  if (! extra_strong || crypto_strongest_rand(seed, sizeof(seed)) < 0)
    crypto_rand((char*)seed, sizeof(seed));

  r = get_ed_impl()->seckey_expand(seckey_out->seckey, seed);
  memwipe(seed, 0, sizeof(seed));

  return r < 0 ? -1 : 0;
}
コード例 #17
0
int
crypto_sign_seckey(unsigned char *sk)
{
  unsigned char seed[32];

  if (randombytes(seed,32) < 0)
    return -1;

  crypto_sign_seckey_expand(sk, seed);

  memwipe(seed, 0, 32);

  return 0;
}
コード例 #18
0
ファイル: onion_fast.c プロジェクト: Samdney/tor
/** Implement the second half of the client side of the CREATE_FAST handshake.
 * We sent the server <b>handshake_state</b> ("x") already, and the server
 * told us <b>handshake_reply_out</b> (y|H(x|y)).  Make sure that the hash is
 * correct, and generate key material in <b>key_out</b>.  Return 0 on success,
 * true on failure.
 *
 * NOTE: The "CREATE_FAST" handshake path is distinguishable from regular
 * "onionskin" handshakes, and is not secure if an adversary can see or modify
 * the messages.  Therefore, it should only be used by clients, and only as
 * the first hop of a circuit (since the first hop is already authenticated
 * and protected by TLS).
 */
int
fast_client_handshake(const fast_handshake_state_t *handshake_state,
                      const uint8_t *handshake_reply_out,/*DIGEST_LEN*2 bytes*/
                      uint8_t *key_out,
                      size_t key_out_len,
                      const char **msg_out)
{
  uint8_t tmp[DIGEST_LEN+DIGEST_LEN];
  uint8_t *out;
  size_t out_len;
  int r = -1;

  memcpy(tmp, handshake_state->state, DIGEST_LEN);
  memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
  out_len = key_out_len+DIGEST_LEN;
  out = tor_malloc(out_len);
  if (BUG(crypto_expand_key_material_TAP(tmp, sizeof(tmp), out, out_len))) {
    /* LCOV_EXCL_START */
    if (msg_out)
      *msg_out = "Failed to expand key material";
    goto done;
    /* LCOV_EXCL_STOP */
  }
  if (tor_memneq(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
    /* H(K) does *not* match. Something fishy. */
    if (msg_out)
      *msg_out = "Digest DOES NOT MATCH on fast handshake. Bug or attack.";
    goto done;
  }
  memcpy(key_out, out+DIGEST_LEN, key_out_len);
  r = 0;
 done:
  memwipe(tmp, 0, sizeof(tmp));
  memwipe(out, 0, out_len);
  tor_free(out);
  return r;
}
コード例 #19
0
ファイル: circuitlist.c プロジェクト: jenpocheng/tor-0.2.3.25
/** Deallocate space associated with the cpath node <b>victim</b>. */
static void
circuit_free_cpath_node(crypt_path_t *victim)
{
  if (!victim)
    return;

  crypto_cipher_free(victim->f_crypto);
  crypto_cipher_free(victim->b_crypto);
  crypto_digest_free(victim->f_digest);
  crypto_digest_free(victim->b_digest);
  crypto_dh_free(victim->dh_handshake_state);
  extend_info_free(victim->extend_info);

  memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
  tor_free(victim);
}
コード例 #20
0
ファイル: tor-gencert.c プロジェクト: grubWare/hibernate
/** Read the passphrase from the passphrase fd. */
static int
load_passphrase(void)
{
  char *cp;
  char buf[1024]; /* "Ought to be enough for anybody." */
  ssize_t n = read_all(passphrase_fd, buf, sizeof(buf), 0);
  if (n < 0) {
    log_err(LD_GENERAL, "Couldn't read from passphrase fd: %s",
            strerror(errno));
    return -1;
  }
  cp = memchr(buf, '\n', n);
  passphrase_len = cp-buf;
  passphrase = tor_strndup(buf, passphrase_len);
  memwipe(buf, 0, sizeof(buf));
  return 0;
}
コード例 #21
0
ファイル: crypto_curve25519.c プロジェクト: Zex/tor
/**
 * Generate CURVE25519_SECKEY_LEN random bytes in <b>out</b>. If
 * <b>extra_strong</b> is true, this key is possibly going to get used more
 * than once, so use a better-than-usual RNG. Return 0 on success, -1 on
 * failure.
 *
 * This function does not adjust the output of the RNG at all; the will caller
 * will need to clear or set the appropriate bits to make curve25519 work.
 */
int
curve25519_rand_seckey_bytes(uint8_t *out, int extra_strong)
{
  uint8_t k_tmp[CURVE25519_SECKEY_LEN];

  if (crypto_rand((char*)out, CURVE25519_SECKEY_LEN) < 0)
    return -1;
  if (extra_strong && !crypto_strongest_rand(k_tmp, CURVE25519_SECKEY_LEN)) {
    /* If they asked for extra-strong entropy and we have some, use it as an
     * HMAC key to improve not-so-good entropy rather than using it directly,
     * just in case the extra-strong entropy is less amazing than we hoped. */
    crypto_hmac_sha256((char*) out,
                       (const char *)k_tmp, sizeof(k_tmp),
                       (const char *)out, CURVE25519_SECKEY_LEN);
  }
  memwipe(k_tmp, 0, sizeof(k_tmp));
  return 0;
}
コード例 #22
0
ファイル: hs_circuit.c プロジェクト: ageis/tor
/* For a given introduction point and an introduction circuit, send the
 * ESTABLISH_INTRO cell. The service object is used for logging. This can fail
 * and if so, the circuit is closed and the intro point object is flagged
 * that the circuit is not established anymore which is important for the
 * retry mechanism. */
static void
send_establish_intro(const hs_service_t *service,
                     hs_service_intro_point_t *ip, origin_circuit_t *circ)
{
  ssize_t cell_len;
  uint8_t payload[RELAY_PAYLOAD_SIZE];

  tor_assert(service);
  tor_assert(ip);
  tor_assert(circ);

  /* Encode establish intro cell. */
  cell_len = hs_cell_build_establish_intro(circ->cpath->prev->rend_circ_nonce,
                                           ip, payload);
  if (cell_len < 0) {
    log_warn(LD_REND, "Unable to encode ESTABLISH_INTRO cell for service %s "
                      "on circuit %u. Closing circuit.",
             safe_str_client(service->onion_address),
             TO_CIRCUIT(circ)->n_circ_id);
    goto err;
  }

  /* Send the cell on the circuit. */
  if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ),
                                   RELAY_COMMAND_ESTABLISH_INTRO,
                                   (char *) payload, cell_len,
                                   circ->cpath->prev) < 0) {
    log_info(LD_REND, "Unable to send ESTABLISH_INTRO cell for service %s "
                      "on circuit %u.",
             safe_str_client(service->onion_address),
             TO_CIRCUIT(circ)->n_circ_id);
    /* On error, the circuit has been closed. */
    goto done;
  }

  /* Record the attempt to use this circuit. */
  pathbias_count_use_attempt(circ);
  goto done;

 err:
  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
 done:
  memwipe(payload, 0, sizeof(payload));
}
コード例 #23
0
ファイル: hs_circuit.c プロジェクト: ageis/tor
/* We are a v2 legacy HS client: Create and return a crypt path for the hidden
 * service on the other side of the rendezvous circuit <b>circ</b>. Initialize
 * the crypt path crypto using the body of the RENDEZVOUS1 cell at
 * <b>rend_cell_body</b> (which must be at least DH_KEY_LEN+DIGEST_LEN bytes).
 */
static crypt_path_t *
create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
{
  crypt_path_t *hop = NULL;
  char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN];

  /* first DH_KEY_LEN bytes are g^y from the service. Finish the dh
   * handshake...*/
  tor_assert(circ->build_state);
  tor_assert(circ->build_state->pending_final_cpath);
  hop = circ->build_state->pending_final_cpath;

  tor_assert(hop->rend_dh_handshake_state);
  if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->rend_dh_handshake_state,
                               (char*)rend_cell_body, DH_KEY_LEN,
                               keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
    log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
    goto err;
  }
  /* ... and set up cpath. */
  if (circuit_init_cpath_crypto(hop,
                                keys+DIGEST_LEN, sizeof(keys)-DIGEST_LEN,
                                0, 0) < 0)
    goto err;

  /* Check whether the digest is right... */
  if (tor_memneq(keys, rend_cell_body+DH_KEY_LEN, DIGEST_LEN)) {
    log_warn(LD_PROTOCOL, "Incorrect digest of key material.");
    goto err;
  }

  /* clean up the crypto stuff we just made */
  crypto_dh_free(hop->rend_dh_handshake_state);
  hop->rend_dh_handshake_state = NULL;

  goto done;

 err:
  hop = NULL;

 done:
  memwipe(keys, 0, sizeof(keys));
  return hop;
}
コード例 #24
0
ファイル: crypto_ed25519.c プロジェクト: 1833183060/tor-1
/**
 * Given an ed25519 keypair in <b>inp</b>, generate a corresponding
 * ed25519 keypair in <b>out</b>, blinded by the corresponding 32-byte input
 * in 'param'.
 *
 * Tor uses key blinding for the "next-generation" hidden services design:
 * service descriptors are encrypted with a key derived from the service's
 * long-term public key, and then signed with (and stored at a position
 * indexed by) a short-term key derived by blinding the long-term keys.
 */
int
ed25519_keypair_blind(ed25519_keypair_t *out,
                      const ed25519_keypair_t *inp,
                      const uint8_t *param)
{
  ed25519_public_key_t pubkey_check;

  get_ed_impl()->blind_secret_key(out->seckey.seckey,
                                  inp->seckey.seckey, param);

  ed25519_public_blind(&pubkey_check, &inp->pubkey, param);
  ed25519_public_key_generate(&out->pubkey, &out->seckey);

  tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));

  memwipe(&pubkey_check, 0, sizeof(pubkey_check));

  return 0;
}
コード例 #25
0
ファイル: routerkeys.c プロジェクト: CFFei/TorAnonPerf
/** Construct cross-certification for the master identity key with
 * the ntor onion key. Store the sign of the corresponding ed25519 public key
 * in *<b>sign_out</b>. */
tor_cert_t *
make_ntor_onion_key_crosscert(const curve25519_keypair_t *onion_key,
      const ed25519_public_key_t *master_id_key, time_t now, time_t lifetime,
      int *sign_out)
{
  tor_cert_t *cert = NULL;
  ed25519_keypair_t ed_onion_key;

  if (ed25519_keypair_from_curve25519_keypair(&ed_onion_key, sign_out,
                                              onion_key) < 0)
    goto end;

  cert = tor_cert_create(&ed_onion_key, CERT_TYPE_ONION_ID, master_id_key,
      now, lifetime, 0);

 end:
  memwipe(&ed_onion_key, 0, sizeof(ed_onion_key));
  return cert;
}
コード例 #26
0
ファイル: crypto_curve25519.c プロジェクト: 1234max/tor
STATIC int
curve25519_impl(uint8_t *output, const uint8_t *secret,
                const uint8_t *basepoint)
{
  uint8_t bp[CURVE25519_PUBKEY_LEN];
  int r;
  memcpy(bp, basepoint, CURVE25519_PUBKEY_LEN);
  /* Clear the high bit, in case our backend foolishly looks at it. */
  bp[31] &= 0x7f;
#ifdef USE_CURVE25519_DONNA
  r = curve25519_donna(output, secret, bp);
#elif defined(USE_CURVE25519_NACL)
  r = crypto_scalarmult_curve25519(output, secret, bp);
#else
#error "No implementation of curve25519 is available."
#endif
  memwipe(bp, 0, sizeof(bp));
  return r;
}
コード例 #27
0
ファイル: crypto_rand_fast.c プロジェクト: nmathewson/Tor
/**
 * Extract <b>n</b> bytes from <b>rng</b> into the buffer at <b>out</b>.
 **/
void
crypto_fast_rng_getbytes(crypto_fast_rng_t *rng, uint8_t *out, size_t n)
{
  if (PREDICT_UNLIKELY(n > BUFLEN)) {
    /* The user has asked for a lot of output; generate it from a stream
     * cipher seeded by the PRNG rather than by pulling it out of the PRNG
     * directly.
     */
    uint8_t seed[SEED_LEN];
    crypto_fast_rng_getbytes_impl(rng, seed, SEED_LEN);
    crypto_cipher_t *c = cipher_from_seed(seed);
    memset(out, 0, n);
    crypto_cipher_crypt_inplace(c, (char*)out, n);
    crypto_cipher_free(c);
    memwipe(seed, 0, sizeof(seed));
    return;
  }

  crypto_fast_rng_getbytes_impl(rng, out, n);
}
コード例 #28
0
ファイル: crypto_curve25519.c プロジェクト: 1234max/tor
/* DOCDOC */
int
curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
                                 const char *fname,
                                 const char *tag)
{
  uint8_t contents[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
  int r;

  memcpy(contents, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN);
  memcpy(contents+CURVE25519_SECKEY_LEN,
         keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN);

  r = crypto_write_tagged_contents_to_file(fname,
                                           "c25519v1",
                                           tag,
                                           contents,
                                           sizeof(contents));

  memwipe(contents, 0, sizeof(contents));
  return r;
}
コード例 #29
0
ファイル: shared_random.c プロジェクト: Samdney/tor
/* Encode a reveal element using a given commit object to dst which is a
 * buffer large enough to put the base64-encoded reveal construction. The
 * format is as follow:
 *     REVEAL = base64-encode( TIMESTAMP || H(RN) )
 * Return base64 encoded length on success else a negative value.
 */
STATIC int
reveal_encode(const sr_commit_t *commit, char *dst, size_t len)
{
  int ret;
  size_t offset = 0;
  char buf[SR_REVEAL_LEN] = {0};

  tor_assert(commit);
  tor_assert(dst);

  set_uint64(buf, tor_htonll(commit->reveal_ts));
  offset += sizeof(uint64_t);
  memcpy(buf + offset, commit->random_number,
         sizeof(commit->random_number));

  /* Let's clean the buffer and then b64 encode it. */
  memset(dst, 0, len);
  ret = base64_encode(dst, len, buf, sizeof(buf), 0);
  /* Wipe this buffer because it contains our random value. */
  memwipe(buf, 0, sizeof(buf));
  return ret;
}
コード例 #30
0
ファイル: relay_crypto.c プロジェクト: nmathewson/Tor
/** Does the digest for this circuit indicate that this cell is for us?
 *
 * Update digest from the payload of cell (with the integrity part set
 * to 0). If the integrity part is valid, return 1, else restore digest
 * and cell to their original state and return 0.
 */
static int
relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
{
  uint32_t received_integrity, calculated_integrity;
  relay_header_t rh;
  crypto_digest_checkpoint_t backup_digest;

  crypto_digest_checkpoint(&backup_digest, digest);

  relay_header_unpack(&rh, cell->payload);
  memcpy(&received_integrity, rh.integrity, 4);
  memset(rh.integrity, 0, 4);
  relay_header_pack(cell->payload, &rh);

//  log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
//    received_integrity[0], received_integrity[1],
//    received_integrity[2], received_integrity[3]);

  crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);

  int rv = 1;

  if (calculated_integrity != received_integrity) {
//    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
// (%d vs %d).", received_integrity, calculated_integrity);
    /* restore digest to its old form */
    crypto_digest_restore(digest, &backup_digest);
    /* restore the relay header */
    memcpy(rh.integrity, &received_integrity, 4);
    relay_header_pack(cell->payload, &rh);
    rv = 0;
  }

  memwipe(&backup_digest, 0, sizeof(backup_digest));
  return rv;
}