Example #1
0
static void
bench_cell_ops(void)
{
  const int iters = 1<<16;
  int i;

  /* benchmarks for cell ops at relay. */
  or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
  cell_t *cell = tor_malloc(sizeof(cell_t));
  int outbound;
  uint64_t start, end;

  crypto_rand((char*)cell->payload, sizeof(cell->payload));

  /* Mock-up or_circuit_t */
  or_circ->base_.magic = OR_CIRCUIT_MAGIC;
  or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;

  /* Initialize crypto */
  char key1[CIPHER_KEY_LEN], key2[CIPHER_KEY_LEN];
  crypto_rand(key1, sizeof(key1));
  crypto_rand(key2, sizeof(key2));
  or_circ->p_crypto = crypto_cipher_new(key1);
  or_circ->n_crypto = crypto_cipher_new(key2);
  or_circ->p_digest = crypto_digest_new();
  or_circ->n_digest = crypto_digest_new();

  reset_perftime();

  for (outbound = 0; outbound <= 1; ++outbound) {
    cell_direction_t d = outbound ? CELL_DIRECTION_OUT : CELL_DIRECTION_IN;
    start = perftime();
    for (i = 0; i < iters; ++i) {
      char recognized = 0;
      crypt_path_t *layer_hint = NULL;
      relay_crypt(TO_CIRCUIT(or_circ), cell, d, &layer_hint, &recognized);
    }
    end = perftime();
    printf("%sbound cells: %.2f ns per cell. (%.2f ns per byte of payload)\n",
           outbound?"Out":" In",
           NANOCOUNT(start,end,iters),
           NANOCOUNT(start,end,iters*CELL_PAYLOAD_SIZE));
  }

  crypto_digest_free(or_circ->p_digest);
  crypto_digest_free(or_circ->n_digest);
  crypto_cipher_free(or_circ->p_crypto);
  crypto_cipher_free(or_circ->n_crypto);
  tor_free(or_circ);
  tor_free(cell);
}
Example #2
0
/** Run unit tests for our random number generation function and its wrappers.
 */
static void
test_crypto_rng(void *arg)
{
  int i, j, allok;
  char data1[100], data2[100];
  double d;
  char *h=NULL;

  /* Try out RNG. */
  (void)arg;
  tt_assert(! crypto_seed_rng());
  crypto_rand(data1, 100);
  crypto_rand(data2, 100);
  tt_mem_op(data1,OP_NE, data2,100);
  allok = 1;
  for (i = 0; i < 100; ++i) {
    uint64_t big;
    char *host;
    j = crypto_rand_int(100);
    if (j < 0 || j >= 100)
      allok = 0;
    big = crypto_rand_uint64(UINT64_C(1)<<40);
    if (big >= (UINT64_C(1)<<40))
      allok = 0;
    big = crypto_rand_uint64(UINT64_C(5));
    if (big >= 5)
      allok = 0;
    d = crypto_rand_double();
    tt_assert(d >= 0);
    tt_assert(d < 1.0);
    host = crypto_random_hostname(3,8,"www.",".onion");
    if (strcmpstart(host,"www.") ||
        strcmpend(host,".onion") ||
        strlen(host) < 13 ||
        strlen(host) > 18)
      allok = 0;
    tor_free(host);
  }

  /* Make sure crypto_random_hostname clips its inputs properly. */
  h = crypto_random_hostname(20000, 9000, "www.", ".onion");
  tt_assert(! strcmpstart(h,"www."));
  tt_assert(! strcmpend(h,".onion"));
  tt_int_op(63+4+6, OP_EQ, strlen(h));

  tt_assert(allok);
 done:
  tor_free(h);
}
Example #3
0
/** Implement the server side of the CREATE_FAST abbreviated handshake.  The
 * client has provided DIGEST_LEN key bytes in <b>key_in</b> ("x").  We
 * generate a reply of DIGEST_LEN*2 bytes in <b>key_out</b>, consisting of a
 * new random "y", followed by H(x|y) to check for correctness.  We set
 * <b>key_out_len</b> bytes of key material in <b>key_out</b>.
 * Return 0 on success, &lt;0 on failure.
 **/
int
fast_server_handshake(const uint8_t *key_in, /* DIGEST_LEN bytes */
                      uint8_t *handshake_reply_out, /* DIGEST_LEN*2 bytes */
                      uint8_t *key_out,
                      size_t key_out_len)
{
  uint8_t tmp[DIGEST_LEN+DIGEST_LEN];
  uint8_t *out = NULL;
  size_t out_len;
  int r = -1;

  crypto_rand((char*)handshake_reply_out, DIGEST_LEN);

  memcpy(tmp, key_in, 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))) {
    goto done; // LCOV_EXCL_LINE
  }
  memcpy(handshake_reply_out+DIGEST_LEN, out, DIGEST_LEN);
  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;
}
Example #4
0
/* Helper function: Send a well-formed v2 ESTABLISH_INTRO cell to
 * <b>intro_circ</b>. Return the public key advertised in the cell. */
static crypto_pk_t *
helper_establish_intro_v2(or_circuit_t *intro_circ)
{
  crypto_pk_t *key1 = NULL;
  int retval;
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  ssize_t cell_len = 0;
  char circ_nonce[DIGEST_LEN] = {0};

  tt_assert(intro_circ);

  /* Prepare the circuit for the incoming ESTABLISH_INTRO */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Send legacy establish_intro */
  key1 = pk_generate(0);

  /* Use old circ_nonce why not */
  cell_len = rend_service_encode_establish_intro_cell(
                                           (char*)cell_body,
                                           sizeof(cell_body), key1,
                                           circ_nonce);
  tt_int_op(cell_len, OP_GT, 0);

  /* Receive legacy establish_intro */
  retval = hs_intro_received_establish_intro(intro_circ,
                                             cell_body, (size_t) cell_len);
  tt_int_op(retval, OP_EQ, 0);

 done:
  return key1;
}
Example #5
0
/* Helper function: Send a well-formed v3 ESTABLISH_INTRO cell to
 * <b>intro_circ</b>. Return the cell. */
static trn_cell_establish_intro_t *
helper_establish_intro_v3(or_circuit_t *intro_circ)
{
  int retval;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  ssize_t cell_len = 0;
  trn_cell_establish_intro_t *cell = NULL;

  tt_assert(intro_circ);

  /* Prepare the circuit for the incoming ESTABLISH_INTRO */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
   * attempt to parse it. */
  cell_len = new_establish_intro_cell(circ_nonce, &cell);
  tt_i64_op(cell_len, OP_GT, 0);
  tt_assert(cell);
  cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
                                             cell);
  tt_int_op(cell_len, OP_GT, 0);

  /* Receive the cell */
  retval = hs_intro_received_establish_intro(intro_circ, cell_body,
                                             (size_t) cell_len);
  tt_int_op(retval, OP_EQ, 0);

 done:
  return cell;
}
Example #6
0
/* Send a legit ESTABLISH_INTRO cell but slightly change the signature. Should
 * fail. */
static void
test_establish_intro_wrong_sig(void *arg)
{
  int retval;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  ssize_t cell_len = 0;
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);

  (void) arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     attempt to parse it. */
  cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
  tt_i64_op(cell_len, OP_GT, 0);

  /* Mutate the last byte (signature)! :) */
  cell_body[cell_len - 1]++;

  /* Receive the cell. Should fail. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, cell_body,
                                             (size_t)cell_len);
  expect_log_msg_containing("Failed to verify ESTABLISH_INTRO cell.");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  circuit_free_(TO_CIRCUIT(intro_circ));
}
Example #7
0
/* Try sending an ESTABLISH_INTRO cell on a circuit that is already an intro
 * point. Should fail. */
static void
test_establish_intro_wrong_purpose(void *arg)
{
  int retval;
  ssize_t cell_len = 0;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);

  (void)arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  memcpy(intro_circ->rend_circ_nonce, circ_nonce, DIGEST_LEN);

  /* Set a bad circuit purpose!! :) */
  circuit_change_purpose(TO_CIRCUIT(intro_circ), CIRCUIT_PURPOSE_INTRO_POINT);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     attempt to parse it. */
  cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
  tt_i64_op(cell_len, OP_GT, 0);

  /* Receive the cell. Should fail. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
  expect_log_msg_containing("Rejecting ESTABLISH_INTRO on non-OR circuit.");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  circuit_free_(TO_CIRCUIT(intro_circ));
}
Example #8
0
static void
bench_cell_aes(void)
{
  uint64_t start, end;
  const int len = 509;
  const int iters = (1<<16);
  const int max_misalign = 15;
  char *b = tor_malloc(len+max_misalign);
  crypto_cipher_t *c;
  int i, misalign;
  char key[CIPHER_KEY_LEN];
  crypto_rand(key, sizeof(key));
  c = crypto_cipher_new(key);

  reset_perftime();
  for (misalign = 0; misalign <= max_misalign; ++misalign) {
    start = perftime();
    for (i = 0; i < iters; ++i) {
      crypto_cipher_crypt_inplace(c, b+misalign, len);
    }
    end = perftime();
    printf("%d bytes, misaligned by %d: %.2f nsec per byte\n", len, misalign,
           NANOCOUNT(start, end, iters*len));
  }

  crypto_cipher_free(c);
  tor_free(b);
}
Example #9
0
/** We simulate a failure to create an ESTABLISH_INTRO cell */
static void
test_gen_establish_intro_cell_bad(void *arg)
{
  (void) arg;
  ssize_t cell_len = 0;
  trn_cell_establish_intro_t *cell = NULL;
  char circ_nonce[DIGEST_LEN] = {0};
  hs_service_intro_point_t *ip = NULL;

  MOCK(ed25519_sign_prefixed, mock_ed25519_sign_prefixed);

  crypto_rand(circ_nonce, sizeof(circ_nonce));

  setup_full_capture_of_logs(LOG_WARN);
  /* Easiest way to make that function fail is to mock the
     ed25519_sign_prefixed() function and make it fail. */
  cell = trn_cell_establish_intro_new();
  tt_assert(cell);
  ip = service_intro_point_new(NULL);
  cell_len = hs_cell_build_establish_intro(circ_nonce, ip, NULL);
  service_intro_point_free(ip);
  expect_log_msg_containing("Unable to make signature for "
                            "ESTABLISH_INTRO cell.");
  teardown_capture_of_logs();
  tt_i64_op(cell_len, OP_EQ, -1);

 done:
  trn_cell_establish_intro_free(cell);
  UNMOCK(ed25519_sign_prefixed);
}
Example #10
0
/** Implement the server side of the CREATE_FAST abbreviated handshake.  The
 * client has provided DIGEST_LEN key bytes in <b>key_in</b> ("x").  We
 * generate a reply of DIGEST_LEN*2 bytes in <b>key_out</b>, consisting of a
 * new random "y", followed by H(x|y) to check for correctness.  We set
 * <b>key_out_len</b> bytes of key material in <b>key_out</b>.
 * Return 0 on success, &lt;0 on failure.
 **/
int
fast_server_handshake(const char *key_in, /* DIGEST_LEN bytes */
                      char *handshake_reply_out, /* DIGEST_LEN*2 bytes */
                      char *key_out,
                      size_t key_out_len)
{
  char tmp[DIGEST_LEN+DIGEST_LEN];
  char *out = NULL;
  size_t out_len;
  int r = -1;

  if (crypto_rand(handshake_reply_out, DIGEST_LEN)<0)
    return -1;

  memcpy(tmp, key_in, DIGEST_LEN);
  memcpy(tmp+DIGEST_LEN, handshake_reply_out, DIGEST_LEN);
  out_len = key_out_len+DIGEST_LEN;
  out = tor_malloc(out_len);
  if (crypto_expand_key_material(tmp, sizeof(tmp), out, out_len)) {
    goto done;
  }
  memcpy(handshake_reply_out+DIGEST_LEN, out, DIGEST_LEN);
  memcpy(key_out, out+DIGEST_LEN, key_out_len);
  r = 0;
 done:
  memset(tmp, 0, sizeof(tmp));
  memset(out, 0, out_len);
  tor_free(out);
  return r;
}
Example #11
0
/** Test base32 decoding. */
static void
test_crypto_base32_decode(void)
{
  char plain[60], encoded[96 + 1], decoded[60];
  int res;
  crypto_rand(plain, 60);
  /* Encode and decode a random string. */
  base32_encode(encoded, 96 + 1, plain, 60);
  res = base32_decode(decoded, 60, encoded, 96);
  test_eq(res, 0);
  test_memeq(plain, decoded, 60);
  /* Encode, uppercase, and decode a random string. */
  base32_encode(encoded, 96 + 1, plain, 60);
  tor_strupper(encoded);
  res = base32_decode(decoded, 60, encoded, 96);
  test_eq(res, 0);
  test_memeq(plain, decoded, 60);
  /* Change encoded string and decode. */
  if (encoded[0] == 'A' || encoded[0] == 'a')
    encoded[0] = 'B';
  else
    encoded[0] = 'A';
  res = base32_decode(decoded, 60, encoded, 96);
  test_eq(res, 0);
  test_memneq(plain, decoded, 60);
  /* Bad encodings. */
  encoded[0] = '!';
  res = base32_decode(decoded, 60, encoded, 96);
  test_assert(res < 0);

 done:
  ;
}
Example #12
0
/** Send the establish-rendezvous cell along a rendezvous circuit. if
 * it fails, mark the circ for close and return -1. else return 0.
 */
static int
rend_client_send_establish_rendezvous(origin_circuit_t *circ)
{
  tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
  tor_assert(circ->rend_data);
  log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");

  crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN);

  /* Set timestamp_dirty, because circuit_expire_building expects it,
   * and the rend cookie also means we've used the circ. */
  circ->base_.timestamp_dirty = time(NULL);

  /* We've attempted to use this circuit. Probe it if we fail */
  pathbias_count_use_attempt(circ);

  if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
                                   RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
                                   circ->rend_data->rend_cookie,
                                   REND_COOKIE_LEN,
                                   circ->cpath->prev)<0) {
    /* circ is already marked for close */
    log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell");
    return -1;
  }

  return 0;
}
Example #13
0
static void
test_routerlist_launch_descriptor_downloads(void *arg)
{
  smartlist_t *downloadable = smartlist_new();
  time_t now = time(NULL);
  char *cp;
  (void)arg;

  for (int i = 0; i < 100; i++) {
    cp = tor_malloc(DIGEST256_LEN);
    tt_assert(cp);
    crypto_rand(cp, DIGEST256_LEN);
    smartlist_add(downloadable, cp);
  }

  MOCK(initiate_descriptor_downloads, mock_initiate_descriptor_downloads);
  launch_descriptor_downloads(DIR_PURPOSE_FETCH_MICRODESC, downloadable,
                              NULL, now);
  tt_int_op(3, ==, count);
  UNMOCK(initiate_descriptor_downloads);

 done:
  SMARTLIST_FOREACH(downloadable, char *, cp1, tor_free(cp1));
  smartlist_free(downloadable);
}
Example #14
0
static void
test_buffers_tls_read_mocked(void *arg)
{
  uint8_t *mem;
  buf_t *buf;
  (void)arg;

  mem = tor_malloc(64*1024);
  crypto_rand((char*)mem, 64*1024);
  tls_read_ptr = mem;
  n_remaining = 64*1024;

  MOCK(tor_tls_read, mock_tls_read);

  buf = buf_new();

  next_reply_val[0] = 1024;
  tt_int_op(128, ==, read_to_buf_tls(NULL, 128, buf));

  next_reply_val[0] = 5000;
  next_reply_val[1] = 5000;
  tt_int_op(6000, ==, read_to_buf_tls(NULL, 6000, buf));

 done:
  UNMOCK(tor_tls_read);
  tor_free(mem);
  buf_free(buf);
}
Example #15
0
/** Run AES performance benchmarks. */
static void
bench_aes(void)
{
  int len, i;
  char *b1, *b2;
  crypto_cipher_t *c;
  uint64_t start, end;
  const int bytes_per_iter = (1<<24);
  reset_perftime();
  char key[CIPHER_KEY_LEN];
  crypto_rand(key, sizeof(key));
  c = crypto_cipher_new(key);

  for (len = 1; len <= 8192; len *= 2) {
    int iters = bytes_per_iter / len;
    b1 = tor_malloc_zero(len);
    b2 = tor_malloc_zero(len);
    start = perftime();
    for (i = 0; i < iters; ++i) {
      crypto_cipher_encrypt(c, b1, b2, len);
    }
    end = perftime();
    tor_free(b1);
    tor_free(b2);
    printf("%d bytes: %.2f nsec per byte\n", len,
           NANOCOUNT(start, end, iters*len));
  }
  crypto_cipher_free(c);
}
Example #16
0
/** Send the establish-rendezvous cell along a rendezvous circuit. if
 * it fails, mark the circ for close and return -1. else return 0.
 */
static int
rend_client_send_establish_rendezvous(origin_circuit_t *circ)
{
  tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
  tor_assert(circ->rend_data);
  log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");

  if (crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN) < 0) {
    log_warn(LD_BUG, "Internal error: Couldn't produce random cookie.");
    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
    return -1;
  }

  /* Set timestamp_dirty, because circuit_expire_building expects it,
   * and the rend cookie also means we've used the circ. */
  circ->base_.timestamp_dirty = time(NULL);

  if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
                                   RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
                                   circ->rend_data->rend_cookie,
                                   REND_COOKIE_LEN,
                                   circ->cpath->prev)<0) {
    /* circ is already marked for close */
    log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell");
    return -1;
  }

  return 0;
}
Example #17
0
/** Return a filename with a random suffix, relative to our testing temporary
 * directory. If name is NULL, return the name of the testing temporary
 * directory, without any suffix. */
const char *
get_fname_rnd(const char *name)
{
  char rnd[256], rnd32[256];
  crypto_rand(rnd, RAND_PATH_BYTES);
  base32_encode(rnd32, sizeof(rnd32), rnd, RAND_PATH_BYTES);
  return get_fname_suffix(name, rnd32);
}
int
randombytes(char *out, size_t num_bytes)
{
  if (crypto_rand(out, num_bytes) < 0)
  {
    DRBG_RET(DRBG_ENTROPY_FAIL);
  }
  DRBG_RET(DRBG_OK);
}
Example #19
0
/**
 * Initialize the system that tells which ewma tick we are in.
 */
STATIC void
cell_ewma_initialize_ticks(void)
{
  if (ewma_ticks_initialized)
    return;
  monotime_coarse_get(&start_of_current_tick);
  crypto_rand((char*)&current_tick_num, sizeof(current_tick_num));
  ewma_ticks_initialized = 1;
}
Example #20
0
/**
 * 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)
{
  if (extra_strong)
    crypto_strongest_rand(out, CURVE25519_SECKEY_LEN);
  else
    crypto_rand((char*)out, CURVE25519_SECKEY_LEN);

  return 0;
}
Example #21
0
/** Create the state needed to perform a CREATE_FAST handshake. Return 0
 * on success, -1 on failure. */
int
fast_onionskin_create(fast_handshake_state_t **handshake_state_out,
                      uint8_t *handshake_out)
{
  fast_handshake_state_t *s;
  *handshake_state_out = s = tor_malloc(sizeof(fast_handshake_state_t));
  crypto_rand((char*)s->state, sizeof(s->state));
  memcpy(handshake_out, s->state, DIGEST_LEN);
  return 0;
}
Example #22
0
static void
add_bytes_to_buf(generic_buffer_t *buf, size_t n_bytes)
{
  char b[3000];

  while (n_bytes) {
    size_t this_add = n_bytes > sizeof(b) ? sizeof(b) : n_bytes;
    crypto_rand(b, this_add);
    generic_buffer_add(buf, b, this_add);
    n_bytes -= this_add;
  }
}
Example #23
0
/** Run unit tests for our random number generation function and its wrappers.
 */
static void
test_crypto_rng(void)
{
  int i, j, allok;
  char data1[100], data2[100];
  double d;

  /* Try out RNG. */
  test_assert(! crypto_seed_rng(0));
  crypto_rand(data1, 100);
  crypto_rand(data2, 100);
  test_memneq(data1,data2,100);
  allok = 1;
  for (i = 0; i < 100; ++i) {
    uint64_t big;
    char *host;
    j = crypto_rand_int(100);
    if (j < 0 || j >= 100)
      allok = 0;
    big = crypto_rand_uint64(U64_LITERAL(1)<<40);
    if (big >= (U64_LITERAL(1)<<40))
      allok = 0;
    big = crypto_rand_uint64(U64_LITERAL(5));
    if (big >= 5)
      allok = 0;
    d = crypto_rand_double();
    test_assert(d >= 0);
    test_assert(d < 1.0);
    host = crypto_random_hostname(3,8,"www.",".onion");
    if (strcmpstart(host,"www.") ||
        strcmpend(host,".onion") ||
        strlen(host) < 13 ||
        strlen(host) > 18)
      allok = 0;
    tor_free(host);
  }
  test_assert(allok);
 done:
  ;
}
Example #24
0
/** Run unit tests for digest set code (implemented as a hashtable or as a
 * bloom filter) */
static void
test_container_digestset(void *arg)
{
  smartlist_t *included = smartlist_new();
  char d[DIGEST_LEN];
  int i;
  int ok = 1;
  int false_positives = 0;
  digestset_t *set = NULL;

  (void)arg;
  for (i = 0; i < 1000; ++i) {
    crypto_rand(d, DIGEST_LEN);
    smartlist_add(included, tor_memdup(d, DIGEST_LEN));
  }
  set = digestset_new(1000);
  SMARTLIST_FOREACH(included, const char *, cp,
                    if (digestset_contains(set, cp))
                      ok = 0);
  tt_assert(ok);
  SMARTLIST_FOREACH(included, const char *, cp,
                    digestset_add(set, cp));
  SMARTLIST_FOREACH(included, const char *, cp,
                    if (!digestset_contains(set, cp))
                      ok = 0);
  tt_assert(ok);
  for (i = 0; i < 1000; ++i) {
    crypto_rand(d, DIGEST_LEN);
    if (digestset_contains(set, d))
      ++false_positives;
  }
  tt_int_op(50, OP_GT, false_positives); /* Should be far lower. */

 done:
  if (set)
    digestset_free(set);
  SMARTLIST_FOREACH(included, char *, cp, tor_free(cp));
  smartlist_free(included);
}
Example #25
0
static circuit_t *
dummy_or_circuit_new(int n_p_cells, int n_n_cells)
{
  or_circuit_t *circ = or_circuit_new(0, NULL);
  int i;
  cell_t cell;

  for (i=0; i < n_p_cells; ++i) {
    crypto_rand((void*)&cell, sizeof(cell));
    cell_queue_append_packed_copy(TO_CIRCUIT(circ), &circ->p_chan_cells,
                                  0, &cell, 1, 0);
  }

  for (i=0; i < n_n_cells; ++i) {
    crypto_rand((void*)&cell, sizeof(cell));
    cell_queue_append_packed_copy(TO_CIRCUIT(circ),
                                  &TO_CIRCUIT(circ)->n_chan_cells,
                                  1, &cell, 1, 0);
  }

  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_OR;
  return TO_CIRCUIT(circ);
}
Example #26
0
static workqueue_entry_t *
add_work(threadpool_t *tp)
{
  int add_rsa =
    opt_ratio_rsa == 0 ||
    tor_weak_random_range(&weak_rng, opt_ratio_rsa) == 0;

  if (add_rsa) {
    rsa_work_t *w = tor_malloc_zero(sizeof(*w));
    w->serial = n_sent++;
    crypto_rand((char*)w->msg, 20);
    w->msglen = 20;
    ++rsa_sent;
    return threadpool_queue_work(tp, workqueue_do_rsa, handle_reply, w);
  } else {
    ecdh_work_t *w = tor_malloc_zero(sizeof(*w));
    w->serial = n_sent++;
    /* Not strictly right, but this is just for benchmarks. */
    crypto_rand((char*)w->u.pk.public_key, 32);
    ++ecdh_sent;
    return threadpool_queue_work(tp, workqueue_do_ecdh, handle_reply, w);
  }
}
Example #27
0
/**
 * 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;
}
Example #28
0
/** We simulate the creation of an outgoing ESTABLISH_INTRO cell, and then we
 *  parse it from the receiver side. */
static void
test_gen_establish_intro_cell(void *arg)
{
  (void) arg;
  ssize_t ret;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t buf[RELAY_PAYLOAD_SIZE];
  trn_cell_establish_intro_t *cell_in = NULL;

  crypto_rand(circ_nonce, sizeof(circ_nonce));

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     attempt to parse it. */
  {
    /* We only need the auth key pair here. */
    hs_service_intro_point_t *ip = service_intro_point_new(NULL);
    /* Auth key pair is generated in the constructor so we are all set for
     * using this IP object. */
    ret = hs_cell_build_establish_intro(circ_nonce, ip, buf);
    service_intro_point_free(ip);
    tt_u64_op(ret, OP_GT, 0);
  }

  /* Check the contents of the cell */
  {
    /* First byte is the auth key type: make sure its correct */
    tt_int_op(buf[0], OP_EQ, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
    /* Next two bytes is auth key len */
    tt_int_op(ntohs(get_uint16(buf+1)), OP_EQ, ED25519_PUBKEY_LEN);
    /* Skip to the number of extensions: no extensions */
    tt_int_op(buf[35], OP_EQ, 0);
    /* Skip to the sig len. Make sure it's the size of an ed25519 sig */
    tt_int_op(ntohs(get_uint16(buf+35+1+32)), OP_EQ, ED25519_SIG_LEN);
  }

  /* Parse it as the receiver */
  {
    ret = trn_cell_establish_intro_parse(&cell_in, buf, sizeof(buf));
    tt_u64_op(ret, OP_GT, 0);

    ret = verify_establish_intro_cell(cell_in,
                                      (const uint8_t *) circ_nonce,
                                      sizeof(circ_nonce));
    tt_u64_op(ret, OP_EQ, 0);
  }

 done:
  trn_cell_establish_intro_free(cell_in);
}
Example #29
0
static void
test_buffers_zlib_impl(int finalize_with_nil)
{
  char *msg = NULL;
  char *contents = NULL;
  char *expanded = NULL;
  buf_t *buf = NULL;
  tor_zlib_state_t *zlib_state = NULL;
  size_t out_len, in_len;
  int done;

  buf = buf_new_with_capacity(128); /* will round up */
  zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION);

  msg = tor_malloc(512);
  crypto_rand(msg, 512);
  tt_int_op(write_to_buf_zlib(buf, zlib_state, msg, 128, 0), OP_EQ, 0);
  tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+128, 128, 0), OP_EQ, 0);
  tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+256, 256, 0), OP_EQ, 0);
  done = !finalize_with_nil;
  tt_int_op(write_to_buf_zlib(buf, zlib_state, "all done", 9, done), OP_EQ, 0);
  if (finalize_with_nil) {
    tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0);
  }

  in_len = buf_datalen(buf);
  contents = tor_malloc(in_len);

  tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0);

  tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len,
                                       contents, in_len,
                                       ZLIB_METHOD, 1,
                                       LOG_WARN));

  tt_int_op(out_len, OP_GE, 128);
  tt_mem_op(msg, OP_EQ, expanded, 128);
  tt_int_op(out_len, OP_GE, 512);
  tt_mem_op(msg, OP_EQ, expanded, 512);
  tt_int_op(out_len, OP_EQ, 512+9);
  tt_mem_op("all done", OP_EQ, expanded+512, 9);

 done:
  buf_free(buf);
  tor_zlib_free(zlib_state);
  tor_free(contents);
  tor_free(expanded);
  tor_free(msg);
}
Example #30
0
/** Select and create the temporary directory we'll use to run our unit tests.
 * Store it in <b>temp_dir</b>.  Exit immediately if we can't create it.
 * idempotent. */
static void
setup_directory(void)
{
  static int is_setup = 0;
  int r;
  char rnd[256], rnd32[256];
  if (is_setup) return;

/* Due to base32 limitation needs to be a multiple of 5. */
#define RAND_PATH_BYTES 5
  crypto_rand(rnd, RAND_PATH_BYTES);
  base32_encode(rnd32, sizeof(rnd32), rnd, RAND_PATH_BYTES);

#ifdef _WIN32
  {
    char buf[MAX_PATH];
    const char *tmp = buf;
    const char *extra_backslash = "";
    /* If this fails, we're probably screwed anyway */
    if (!GetTempPathA(sizeof(buf),buf))
      tmp = "c:\\windows\\temp\\";
    if (strcmpend(tmp, "\\")) {
      /* According to MSDN, it should be impossible for GetTempPath to give us
       * an answer that doesn't end with \.  But let's make sure. */
      extra_backslash = "\\";
    }
    tor_snprintf(temp_dir, sizeof(temp_dir),
                 "%s%stor_test_%d_%s", tmp, extra_backslash,
                 (int)getpid(), rnd32);
    r = mkdir(temp_dir);
  }
#else
  tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d_%s",
               (int) getpid(), rnd32);
  r = mkdir(temp_dir, 0700);
  if (!r) {
    /* undo sticky bit so tests don't get confused. */
    r = chown(temp_dir, getuid(), getgid());
  }
#endif
  if (r) {
    fprintf(stderr, "Can't create directory %s:", temp_dir);
    perror("");
    exit(1);
  }
  is_setup = 1;
  temp_dir_setup_in_pid = getpid();
}