Пример #1
0
void measure(void)
{
  int i;
  int loop;
  int mlen;

  for (loop = 0;loop < LOOPS;++loop) {
    for (mlen = 0;mlen <= MAXTEST_BYTES;mlen += 1 + mlen / 8) {
      randombytes(k,crypto_secretbox_KEYBYTES);
      randombytes(n,crypto_secretbox_NONCEBYTES);
      randombytes(m + crypto_secretbox_ZEROBYTES,mlen);
      randombytes(c,mlen + crypto_secretbox_ZEROBYTES);
      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
	crypto_secretbox(c,m,mlen + crypto_secretbox_ZEROBYTES,n,k);
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"cycles",cycles,TIMINGS);
      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
	crypto_secretbox_open(m,c,mlen + crypto_secretbox_ZEROBYTES,n,k);
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"open_cycles",cycles,TIMINGS);
      ++c[crypto_secretbox_ZEROBYTES];
      for (i = 0;i <= TIMINGS;++i) {
        cycles[i] = cpucycles();
	crypto_secretbox_open(m,c,mlen + crypto_secretbox_ZEROBYTES,n,k);
      }
      for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
      printentry(mlen,"forgery_open_cycles",cycles,TIMINGS);
    }
  }
}
Пример #2
0
static ERL_NIF_TERM nacl_secretbox_open_padded(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
{
  ErlNifBinary key;
  ErlNifBinary nonce;
  ErlNifBinary padded_ciphertext;
  ErlNifBinary padded_message;
  
  if (!enif_inspect_iolist_as_binary(env, argv[0], &padded_ciphertext))
    return enif_make_badarg(env);

  if (!enif_inspect_iolist_as_binary(env, argv[1], &nonce))
    return enif_make_badarg(env);

  if (!enif_inspect_iolist_as_binary(env, argv[2], &key))
    return enif_make_badarg(env);

  if (key.size != crypto_secretbox_KEYBYTES) return enif_make_badarg(env);
  if (nonce.size !=  crypto_secretbox_NONCEBYTES) return enif_make_badarg(env);
  if (padded_ciphertext.size < crypto_secretbox_BOXZEROBYTES) return enif_make_badarg(env);

  if (!enif_alloc_binary(padded_ciphertext.size, &padded_message))
    return nacl_error_tuple(env, "alloc_failed");

  if (crypto_secretbox_open(padded_message.data, padded_ciphertext.data, padded_ciphertext.size,
			    nonce.data, key.data)) {
    return nacl_error_tuple(env, "crypto_failed");
  }

  return enif_make_sub_binary(env,
			      enif_make_binary(env, &padded_message),
			      crypto_secretbox_ZEROBYTES,
			      padded_ciphertext.size - crypto_secretbox_ZEROBYTES);
}
Пример #3
0
main()
{
  int mlen;
  int i;
  int caught;

  for (mlen = 0;mlen < 1000 && mlen + crypto_secretbox_ZEROBYTES < sizeof m;++mlen) {
    randombytes(k,crypto_secretbox_KEYBYTES);
    randombytes(n,crypto_secretbox_NONCEBYTES);
    randombytes(m + crypto_secretbox_ZEROBYTES,mlen);
    crypto_secretbox(c,m,mlen + crypto_secretbox_ZEROBYTES,n,k);
    caught = 0;
    while (caught < 10) {
      c[random() % (mlen + crypto_secretbox_ZEROBYTES)] = random();
      if (crypto_secretbox_open(m2,c,mlen + crypto_secretbox_ZEROBYTES,n,k) == 0) {
        for (i = 0;i < mlen + crypto_secretbox_ZEROBYTES;++i)
          if (m2[i] != m[i]) {
	    printf("forgery\n");
	    return 100;
	  }
      } else {
        ++caught;
      }
    }
  }
  return 0;
}
Пример #4
0
static nif_term_t
salt_secretbox_open(nif_heap_t *hp, int argc, const nif_term_t argv[])
{
	/* salt_secretbox_open(Cipher_text, Nonce, Secret_key) -> {ok, Plain_text} | forged_or_garbled. */
	nif_bin_t 		ct;
	nif_bin_t 		nc;
	nif_bin_t 		sk;
	nif_bin_t 		pt;
	nif_term_t 		raw;
	nif_term_t 		sub;
	nif_term_t 		tag;

	if (argc != 3)
		return (BADARG);

	/* Unpack arguments ensuring they're suitably typed. */
	if (! enif_inspect_iolist_as_binary(hp, argv[0], &ct))
		return (BADARG);

	if (! enif_inspect_binary(hp, argv[1], &nc))
		return (BADARG);

	if (! enif_inspect_binary(hp, argv[2], &sk))
		return (BADARG);

	/* Check constraints on size and zero prefixing. */
	if (ct.size < crypto_secretbox_BOXZEROBYTES || ct.size > SALT_MAX_MESSAGE_SIZE)
		return (BADARG);
	if (memcmp((const void *)ct.data, &salt_secretbox_boxzerobytes[0], crypto_secretbox_BOXZEROBYTES) != 0)
		return (BADARG);

	if (nc.size != crypto_secretbox_NONCEBYTES)
		return (BADARG);

	if (sk.size != crypto_secretbox_KEYBYTES)
		return (BADARG);

	/* Allocate space for plain text. NB: Passing ENOMEM as BADARG. */
	if (! enif_alloc_binary(ct.size, &pt))
		return (BADARG);

	/* Perform the crypto, strip leading zeros. */
	if (crypto_secretbox_open(pt.data, ct.data, ct.size, nc.data, sk.data) != 0) {
		enif_release_binary(&pt);

		return (enif_make_atom(hp, "forged_or_garbled"));
	}

	raw = enif_make_binary(hp, &pt);
	sub = enif_make_sub_binary(hp, raw, crypto_secretbox_ZEROBYTES, ct.size - crypto_secretbox_ZEROBYTES);
	tag = enif_make_atom(hp, "ok");

	return (enif_make_tuple2(hp, tag, sub));
}
Пример #5
0
String NaCl::secret_decrypt(String enc_msg)
{
    try
    {
        std::string encrypted_message = from_ruby<std::string>(enc_msg);
        std::string message = crypto_secretbox_open(encrypted_message, my_nonce, my_secret);
        return to_ruby<std::string>(message);
    }
    catch (int e)
    {
        return to_ruby<std::string>("");
    }
}
Пример #6
0
Message CryptoEngine::Decrypt(const std::vector<unsigned char> message_bytes) {

    // Parse from bytes to EcnryptedMessage object
    EncryptedMessage encrypted_msg = EncryptedMessage::FromBytes(message_bytes);

    // get the clear text, with the additional data prepended
    std::string clear_text_with_data(crypto_secretbox_open(encrypted_msg.message(), encrypted_msg.nonce(), secret_key_));

    // convert the string data to a real message: (version, type, clear_text)
    Message message = Message::FromBytesString(clear_text_with_data);

    return message;
}
Пример #7
0
bool decrypt_box(uint8_t *keys, box *outer, size_t len) {
    box *inner = (box *) outer->data;

    uint8_t *outer_key = keys;
    uint8_t *inner_key = keys + BOX_KEY_LEN;
    bool ok = false;

    if (decrypt_gcm(outer_key, outer->iv, outer->data, sizeof(box) + len, outer->tag)) {
        uint8_t *data = inner->tag;
        size_t inner_len = len + crypto_secretbox_ZEROBYTES;
        memset(data, 0, crypto_secretbox_BOXZEROBYTES);
        ok = crypto_secretbox_open(data, data, inner_len, inner->iv, inner_key) == 0;
    }

    return ok;
}
Пример #8
0
int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain)
{
    if (length <= crypto_secretbox_BOXZEROBYTES)
        return -1;

    uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES];
    uint8_t temp_encrypted[length + crypto_secretbox_BOXZEROBYTES];

    memset(temp_plain, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy(temp_encrypted + crypto_secretbox_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.

    if (crypto_secretbox_open(temp_plain, temp_encrypted, length + crypto_secretbox_BOXZEROBYTES, nonce, secret_key) == -1)
        return -1;

    memcpy(plain, temp_plain + crypto_secretbox_ZEROBYTES, length - crypto_secretbox_MACBYTES);
    return length - crypto_secretbox_MACBYTES;
}
Пример #9
0
PyObject *pycrypto_secretbox_open(PyObject *self, PyObject *args, PyObject *kw){
  char *c, *n, *k;
  Py_ssize_t csize=0, nsize=0, ksize=0;
  static const char *kwlist[] = {"c", "n", "k", 0};
  unsigned int i;
  PyObject *ret;
  size_t clen;
  unsigned char *mpad;
  unsigned char *cpad;

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#:crypto_secretbox_open", (char **) kwlist, &c, &csize, &n, &nsize, &k, &ksize)){
    return (PyObject *)0;}

  if (nsize != crypto_secretbox_NONCEBYTES) return Py_BuildValue("i", 0);
  if (ksize != crypto_secretbox_KEYBYTES) return Py_BuildValue("i", 0);

  clen = csize + crypto_secretbox_BOXZEROBYTES;
  mpad = PyMem_Malloc(clen);

  if (!mpad)
    return PyErr_NoMemory();

  cpad = PyMem_Malloc(clen);

  if (!cpad){
    PyMem_Free(mpad);
    return PyErr_NoMemory();}

  for (i = 0;i < crypto_secretbox_BOXZEROBYTES;++i) cpad[i] = 0;
  for (i = crypto_secretbox_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_secretbox_BOXZEROBYTES];

  if (crypto_secretbox_open(mpad, cpad, clen, (const unsigned char *) n, (const unsigned char *) k) != 0){
    PyMem_Free(mpad);
    PyMem_Free(cpad);
    return Py_BuildValue("i", 0);}

  if (clen < crypto_secretbox_ZEROBYTES){
    PyMem_Free(mpad);
    PyMem_Free(cpad);
    return Py_BuildValue("i", 0);}

  ret = PyBytes_FromStringAndSize((char *)mpad + crypto_secretbox_ZEROBYTES, clen - crypto_secretbox_ZEROBYTES);
  PyMem_Free(mpad);
  PyMem_Free(cpad);
  return ret;}
Пример #10
0
int main(void)
{
  int mlen;
  int i;

  for (mlen = 0;mlen < 1000 && mlen + crypto_secretbox_ZEROBYTES < sizeof m;++mlen) {
    randombytes(k,crypto_secretbox_KEYBYTES);
    randombytes(n,crypto_secretbox_NONCEBYTES);
    randombytes(m + crypto_secretbox_ZEROBYTES,mlen);
    crypto_secretbox(c,m,mlen + crypto_secretbox_ZEROBYTES,n,k);
    if (crypto_secretbox_open(m2,c,mlen + crypto_secretbox_ZEROBYTES,n,k) == 0) {
      for (i = 0;i < mlen + crypto_secretbox_ZEROBYTES;++i)
        if (m2[i] != m[i]) {
	  printf("bad decryption\n");
	  break;
	}
    } else {
      printf("ciphertext fails verification\n");
    }
  }
  return 0;
}
Пример #11
0
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
    if (msg_->size () < 225) {
        errno = EPROTO;
        return -1;
    }

    const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
    if (memcmp (initiate, "INITIATE\0", 9)) {
        errno = EPROTO;
        return -1;
    }

    uint8_t cookie_nonce [crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext [crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_box [crypto_secretbox_BOXZEROBYTES + 80];

    //  Open Box [C' + s'](t)
    memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);

    memcpy (cookie_nonce, "COOKIE--", 8);
    memcpy (cookie_nonce + 8, initiate + 9, 16);

    int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
                                    sizeof cookie_box,
                                    cookie_nonce, cookie_key);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    //  Check cookie plain text is as expected [C' + s']
    if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES,
                cn_client, 32)
    ||  memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32,
                cn_secret, 32)) {
        errno = EAGAIN;
        return -1;
    }

    const size_t clen = (msg_->size () - 113) + crypto_box_BOXZEROBYTES;

    uint8_t initiate_nonce [crypto_box_NONCEBYTES];
    uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 96 + 256];
    uint8_t initiate_box [crypto_box_BOXZEROBYTES + 112 + 256];

    //  Open Box [C + vouch + metadata](C'->S')
    memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (initiate_box + crypto_box_BOXZEROBYTES,
            initiate + 113, clen - crypto_box_BOXZEROBYTES);

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    memcpy (initiate_nonce + 16, initiate + 105, 8);

    rc = crypto_box_open (initiate_plaintext, initiate_box,
                          clen, initiate_nonce, cn_client, cn_secret);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    const uint8_t *client_key = initiate_plaintext + crypto_box_ZEROBYTES;

    uint8_t vouch_nonce [crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 32];
    uint8_t vouch_box [crypto_box_BOXZEROBYTES + 48];

    //  Open Box [C'](C->S) and check contents
    memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (vouch_box + crypto_box_BOXZEROBYTES,
            initiate_plaintext + crypto_box_ZEROBYTES + 48, 48);

    memcpy (vouch_nonce, "VOUCH---", 8);
    memcpy (vouch_nonce + 8,
            initiate_plaintext + crypto_box_ZEROBYTES + 32, 16);

    rc = crypto_box_open (vouch_plaintext, vouch_box,
                          sizeof vouch_box,
                          vouch_nonce, client_key, secret_key);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    //  What we decrypted must be the client's short-term public key
    if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, cn_client, 32)) {
        errno = EPROTO;
        return -1;
    }

    //  Precompute connection secret from client key
    rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret);
    zmq_assert (rc == 0);

    //  Use ZAP protocol (RFC 27) to authenticate the user.
    rc = session->zap_connect ();
    if (rc == 0) {
        send_zap_request (client_key);
        rc = receive_and_process_zap_reply ();
        if (rc != 0) {
            if (errno != EAGAIN)
                return -1;
            expecting_zap_reply = true;
        }
    }

    return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 96,
                           clen - crypto_box_ZEROBYTES - 96);
}
Пример #12
0
bool unit_test_crypto_secretbox(){
  // Global length
  uint64_t len = HACL_UNIT_TESTS_SIZE * sizeof(uint8_t);
  // Scratch buffers
  uint8_t hacl_cipher[HACL_UNIT_TESTS_SIZE + 32], expected_cipher[HACL_UNIT_TESTS_SIZE + 32];
  // Shared key
  uint8_t key[32];
  // Random plaintext
  uint8_t *plaintext = malloc((HACL_UNIT_TESTS_SIZE + crypto_secretbox_ZEROBYTES) * sizeof (uint8_t));
  READ_RANDOM_BYTES(len, plaintext + crypto_secretbox_ZEROBYTES);
  for (int i = 0; i < crypto_secretbox_ZEROBYTES; i++) plaintext[i] = 0;
  // Random plaintext
  uint8_t nonce[24];
  READ_RANDOM_BYTES(24, nonce);
  // Test 1
  int a;
  bool pass = true;
  for (int i = 0; i < 256; i++){
    tweet_crypto_secretbox(expected_cipher, plaintext, crypto_secretbox_ZEROBYTES + i, nonce, key);
    crypto_secretbox(hacl_cipher, plaintext, crypto_secretbox_ZEROBYTES + i, nonce, key);
    a = memcmp(hacl_cipher, expected_cipher, (crypto_secretbox_ZEROBYTES + i) * sizeof (uint8_t));
    if (a != 0){
      pass = false;
      break;
    }
    /* a = crypto_secretbox_open_detached(hacl_cipher/\* +32 *\/, expected_cipher/\* +32 *\/, expected_cipher + 16, i, nonce, key); */
    a = crypto_secretbox_open(hacl_cipher, expected_cipher, crypto_secretbox_ZEROBYTES + i, nonce, key);
    if (a != 0) {
      pass = false;
      printf("SECRETBOX OPEN ******* failed to verify on input of size %d\n", i);
      break;
    }
    a = memcmp(hacl_cipher, plaintext, (crypto_secretbox_ZEROBYTES + i) * sizeof (uint8_t));
    if (a != 0) {
      pass = false;
      printf("SECRETBOX OPEN failed on input of size %d\n", i);
      break;
    }
  }
  if (!pass) return pass;

  // Test 2
  tweet_crypto_secretbox(expected_cipher, plaintext, crypto_secretbox_ZEROBYTES + HACL_UNIT_TESTS_SIZE, nonce, key);
  crypto_secretbox(hacl_cipher, plaintext, crypto_secretbox_ZEROBYTES + HACL_UNIT_TESTS_SIZE, nonce, key);
  a = memcmp(hacl_cipher, expected_cipher, (crypto_secretbox_ZEROBYTES + HACL_UNIT_TESTS_SIZE) * sizeof (uint8_t));
  if (a != 0){
    pass = false;
    printf("SECRETBOX failed on input of size %d\n.", HACL_UNIT_TESTS_SIZE);
  }
  a = crypto_secretbox_open(hacl_cipher, expected_cipher, HACL_UNIT_TESTS_SIZE + crypto_secretbox_ZEROBYTES, nonce, key);
  if (a != 0) {
    pass = false;
    printf("SECRETBOX OPEN failed to verify on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }
  a = memcmp(hacl_cipher, plaintext, (crypto_secretbox_ZEROBYTES + HACL_UNIT_TESTS_SIZE) * sizeof (uint8_t));
  if (a != 0) {
    pass = false;
    printf("SECRETBOX OPEN failed on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }

  free(plaintext);

  return pass;
}
Пример #13
0
const char *checksum_compute(void)
{
  long long i;
  long long j;

  for (j = 0;j < crypto_secretbox_ZEROBYTES;++j) m[j] = 0;

  for (i = 0;i < CHECKSUM_BYTES;++i) {
    long long mlen = i + crypto_secretbox_ZEROBYTES;
    long long tlen = i + crypto_secretbox_ZEROBYTES;
    long long clen = i + crypto_secretbox_ZEROBYTES;

    for (j = -16;j < 0;++j) k[j] = rand();
    for (j = -16;j < 0;++j) n[j] = rand();
    for (j = -16;j < 0;++j) m[j] = rand();
    for (j = klen;j < klen + 16;++j) k[j] = rand();
    for (j = nlen;j < nlen + 16;++j) n[j] = rand();
    for (j = mlen;j < mlen + 16;++j) m[j] = rand();
    for (j = -16;j < klen + 16;++j) k2[j] = k[j];
    for (j = -16;j < nlen + 16;++j) n2[j] = n[j];
    for (j = -16;j < mlen + 16;++j) m2[j] = m[j];
    for (j = -16;j < clen + 16;++j) c2[j] = c[j] = rand();

    if (crypto_secretbox(c,m,mlen,n,k) != 0) return "crypto_secretbox returns nonzero";

    for (j = -16;j < mlen + 16;++j) if (m2[j] != m[j]) return "crypto_secretbox overwrites m";
    for (j = -16;j < nlen + 16;++j) if (n2[j] != n[j]) return "crypto_secretbox overwrites n";
    for (j = -16;j < klen + 16;++j) if (k2[j] != k[j]) return "crypto_secretbox overwrites k";
    for (j = -16;j < 0;++j) if (c2[j] != c[j]) return "crypto_secretbox writes before output";
    for (j = clen;j < clen + 16;++j) if (c2[j] != c[j]) return "crypto_secretbox writes after output";
    for (j = 0;j < crypto_secretbox_BOXZEROBYTES;++j)
      if (c[j] != 0) return "crypto_secretbox does not clear extra bytes";

    for (j = -16;j < 0;++j) c[j] = rand();
    for (j = clen;j < clen + 16;++j) c[j] = rand();
    for (j = -16;j < clen + 16;++j) c2[j] = c[j];
    for (j = -16;j < tlen + 16;++j) t2[j] = t[j] = rand();

    if (crypto_secretbox_open(t,c,clen,n,k) != 0) return "crypto_secretbox_open returns nonzero";

    for (j = -16;j < clen + 16;++j) if (c2[j] != c[j]) return "crypto_secretbox_open overwrites c";
    for (j = -16;j < nlen + 16;++j) if (n2[j] != n[j]) return "crypto_secretbox_open overwrites n";
    for (j = -16;j < klen + 16;++j) if (k2[j] != k[j]) return "crypto_secretbox_open overwrites k";
    for (j = -16;j < 0;++j) if (t2[j] != t[j]) return "crypto_secretbox_open writes before output";
    for (j = tlen;j < tlen + 16;++j) if (t2[j] != t[j]) return "crypto_secretbox_open writes after output";
    for (j = 0;j < crypto_secretbox_ZEROBYTES;++j)
      if (t[j] != 0) return "crypto_secretbox_open does not clear extra bytes";

    for (j = 0;j < i;++j) if (t[j] != m[j]) return "plaintext does not match";

    for (j = 0;j < i;++j)
      k[j % klen] ^= c[j + crypto_secretbox_BOXZEROBYTES];
    crypto_secretbox(c,m,mlen,n,k);
    for (j = 0;j < i;++j)
      n[j % nlen] ^= c[j + crypto_secretbox_BOXZEROBYTES];
    crypto_secretbox(c,m,mlen,n,k);
    if (i == 0) m[crypto_secretbox_ZEROBYTES + 0] = 0;
    m[crypto_secretbox_ZEROBYTES + i] = m[crypto_secretbox_ZEROBYTES + 0];
    for (j = 0;j < i;++j)
      m[j + crypto_secretbox_ZEROBYTES] ^= c[j + crypto_secretbox_BOXZEROBYTES];
  }

  sodium_bin2hex(checksum, sizeof checksum, k, klen);

  return 0;
}
Пример #14
0
void doit(void)
{
  crypto_secretbox(c,m,TUNE_BYTES + crypto_secretbox_ZEROBYTES,n,k);
  crypto_secretbox_open(t,c,TUNE_BYTES + crypto_secretbox_ZEROBYTES,n,k);
}
Пример #15
0
static int _handle_initiate (struct curvecpr_server *server, struct curvecpr_session *s, void *priv, const struct curvecpr_packet_initiate *p, const unsigned char *buf, size_t num)
{
    const struct curvecpr_server_cf *cf = &server->cf;

    unsigned char nonce[24];
    unsigned char data[sizeof(struct curvecpr_packet_initiate_box) + 640];

    if (s != NULL) {
        /* Update existing client. */
        crypto_uint64 unpacked_nonce = curvecpr_bytes_unpack_uint64(p->nonce);
        if (unpacked_nonce <= s->their_session_nonce)
            return -EINVAL;

        curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16);
        curvecpr_bytes_copy(nonce + 16, p->nonce, 8);

        curvecpr_bytes_zero(data, 16);
        curvecpr_bytes_copy(data + 16, buf, num);

        if (crypto_box_open_afternm(data, data, num + 16, nonce, s->my_session_their_session_key))
            return -EINVAL;

        s->their_session_nonce = unpacked_nonce;
        curvecpr_session_set_priv(s, priv);

        if (cf->ops.recv(server, s, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box)))
            return -EINVAL;

        return 0;
    } else {
        struct curvecpr_session s_new, *s_new_stored;
        const struct curvecpr_packet_initiate_box *p_box;

        /* Register new client. */
        curvecpr_bytes_copy(nonce, "minute-k", 8);
        curvecpr_bytes_copy(nonce + 8, p->cookie, 16);

        /* We can reuse data; the cookie will fit into it. */
        curvecpr_bytes_zero(data, 16);
        curvecpr_bytes_copy(data + 16, p->cookie + 16, 80);

        /* Validate cookie. */
        if (crypto_secretbox_open(data, data, 96, nonce, server->my_temporal_key)) {
            curvecpr_bytes_zero(data, 16);
            curvecpr_bytes_copy(data + 16, p->cookie + 16, 80);
            if (crypto_secretbox_open(data, data, 96, nonce, server->my_last_temporal_key))
                return -EINVAL;
        }

        if (!curvecpr_bytes_equal(p->client_session_pk, data + 32, 32))
            return -EINVAL;

        /* Cookie is valid; set up keys. */
        curvecpr_session_new(&s_new);

        curvecpr_bytes_copy(s_new.their_session_pk, data + 32, 32);
        curvecpr_bytes_copy(s_new.my_session_sk, data + 64, 32);

        crypto_box_beforenm(s_new.my_session_their_session_key, s_new.their_session_pk, s_new.my_session_sk);

        curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16);
        curvecpr_bytes_copy(nonce + 16, p->nonce, 8);

        curvecpr_bytes_zero(data, 16);
        curvecpr_bytes_copy(data + 16, buf, num);

        if (crypto_box_open_afternm(data, data, num + 16, nonce, s_new.my_session_their_session_key))
            return -EINVAL;

        p_box = (struct curvecpr_packet_initiate_box *)data;

        /* Attempt to validate this client. */
        {
            unsigned char vouch[64];

            curvecpr_bytes_copy(s_new.their_global_pk, p_box->client_global_pk, 32);
            crypto_box_beforenm(s_new.my_global_their_global_key, s_new.their_global_pk, cf->my_global_sk);

            curvecpr_bytes_copy(nonce, "CurveCPV", 8);
            curvecpr_bytes_copy(nonce + 8, p_box->nonce, 16);

            curvecpr_bytes_zero(vouch, 16);
            curvecpr_bytes_copy(vouch + 16, p_box->vouch, 48);

            if (crypto_box_afternm(vouch, vouch, 64, nonce, s_new.my_global_their_global_key))
                return -EINVAL;

            if (!curvecpr_bytes_equal(vouch + 32, s_new.their_session_pk, 32))
                return -EINVAL;
        }

        /* All good, we can go ahead and submit the client for registration. */
        s_new.their_session_nonce = curvecpr_bytes_unpack_uint64(p->nonce);
        curvecpr_bytes_copy(s_new.my_domain_name, p_box->server_domain_name, 256);
        curvecpr_session_set_priv(&s_new, priv);

        if (cf->ops.put_session(server, &s_new, &s_new_stored))
            return -EINVAL; /* This can fail for a variety of reasons that are up to
                               the delegate to determine, but two typical ones will be
                               too many connections or an invalid domain name. */

        /* Now the session is registered; we can send the encapsulated message. */
        if (cf->ops.recv(server, s_new_stored, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box)))
            return -EINVAL;

        return 0;
    }
}
Пример #16
0
static int crypto_read(const char *path, char *buf, size_t size,
                       off_t off, struct fuse_file_info *inf){
  size_t red = 0;

  while(size > 0) {
    int idx = off / (block_size - crypto_PADDING);
    size_t delta = off % (block_size - crypto_PADDING);
    size_t bsize = block_size, fudge = 0;

    if(size < block_size - crypto_PADDING) {
      // We have to check that we aren't in partial block land, when reading from
      // the end of the file by stating the file and checking that the requested
      // offset isn't a slice of a partial block.
      struct stat st = {0};
      int staterr = crypto_getattr(path, &st);
      if(staterr < 0) return staterr;
      size_t next_block = (idx + 1) * (block_size - crypto_PADDING);
      if(st.st_size < next_block)
        next_block = st.st_size;

      if(next_block - off > size)
        fudge = next_block - off - size;
    }

    if(bsize > block_size)
      printf("bzize: %zu size: %zu delta: %zu\n", bsize, size, delta);

    char block[bsize];
    int res = pread(inf->fh, block, bsize, block_size * idx);
    if(res == -1)
      return -errno;

    if(res == 0)
      return red;

    unsigned char nonce[crypto_secretbox_NONCEBYTES];
    memcpy(nonce, block, crypto_secretbox_NONCEBYTES);

    size_t csize = res - crypto_secretbox_NONCEBYTES + crypto_secretbox_BOXZEROBYTES;
    unsigned char cpad[csize];
    memset(cpad, 0, csize);
    memcpy(cpad + crypto_secretbox_BOXZEROBYTES, block + crypto_secretbox_NONCEBYTES, csize);

    unsigned char mpad[csize];
    memset(mpad, 0, csize);

    int ruroh = crypto_secretbox_open(mpad, cpad, csize, nonce, key);
    if(ruroh == -1) {
      printf("error at index: %i offset: %llu read: %i size: %zu path: %s\n", idx, off, res, bsize, path);
      return -ENXIO;
    }

    memcpy(buf + red, mpad + delta + crypto_secretbox_ZEROBYTES, csize - delta - fudge - crypto_secretbox_ZEROBYTES);

    size -= res - crypto_PADDING - fudge - delta;
    red  += res - crypto_PADDING - fudge - delta;
    off  += res - crypto_PADDING - fudge - delta;
  }

  return red;
}
Пример #17
0
int main(){


	int s,b,on=1,i;
	
	struct sockaddr_in channel, server;
	unsigned char buf[BUF_SIZE];
     	unsigned char k[crypto_secretbox_KEYBYTES];
     	unsigned char n[crypto_secretbox_NONCEBYTES];
     	unsigned char m[BUF_SIZE]; unsigned long long mlen = BUF_SIZE;
     	unsigned char c[BUF_SIZE];




/* Address structure */

	memset(&channel,0,sizeof(channel));
	channel.sin_family = AF_INET;
	channel.sin_addr.s_addr = htonl(INADDR_ANY);
	channel.sin_port = htons(CLIENT_PORT);

/* Build socket and Bind */

	s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); /* Create socket */
	if(s<0)
		fatal("Failed to create socket!");

	setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on));	//Osäker på denna

	b = bind(s,(struct sockaddr *)&channel,sizeof(channel));
	if(b<0){
		fatal("Bind failed ");
	}
	
	//Setting up server address
	
	memset(&server,0,sizeof(server));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 	//INADDR_LOOPBACK är denna datorns ip i.e 127.0.0.1 //inet_addr(serverIP); <- får användas över nätverk där serverIP ges som klassisk xxx.xxx.xxx.xxx
	server.sin_port = htons(SERVER_PORT);			//Serverns portnummer
	

	/*  Time to start sending  */

	if(connect(s,(struct sockaddr *)&server,sizeof(server))){
		fatal("Could not connect to server");
	}
		
	//usleep(1000);		//Ska tydligen ge server tid fast det funkar utan detta, iallafall när localhost-localhost




	// Här börjar diffie-hellman *************************************************************************


	if(!dh(k,crypto_secretbox_KEYBYTES,n,crypto_secretbox_NONCEBYTES,s)){
		fatal("Diffie-hellman fail!");
	}	

	// S**t på diffie-hellman *********************************************************

	// Här Börjar symetrisk krytering *************************************************
	
	while(1){						//Infinite message chain loop

		for(i=0;i<BUF_SIZE;i++){			//Reset message
			m[i] = 0;
		}
		i = crypto_secretbox_ZEROBYTES;			//Begin message at byte 32
		printf("\nWrite your message(q/Q to quit):\n");
		fgets((char *)&m[i],200,stdin);			// Get message from user max 200 charachters (should be enough)

		if((m[i] =='q' || m[i] == 'Q') && strlen((char *)&m[i]) == 2){
			break;
		}

		if(VISIBLE){
			printf("\n\n******  Symmetric encryption/decryption echo begin  ******\n\n");
			printf("\nClient plaintext:\n%s\n",&m[i]);
		}
	
		if(crypto_secretbox(c,m,mlen,n,k)!=0){
			fatal("Cryptobox fail!");
		}
		
		inc_nonce(n);

		if(VISIBLE){
			printf("\nClient ciphertext:\n%s\n",&c[crypto_secretbox_ZEROBYTES]); //Kolla om detta borde stämma
		}

		if(write(s,c,BUF_SIZE)==-1){		// Skriver meddelandet till server. _!check!_ check funkar ej  pröva annat (send)!
			fatal("Server not responding");
		}

		for(i=0;i<BUF_SIZE;i++){
			buf[i] = 0;
		}

		read(s,c,BUF_SIZE);				// Läser in svar _!check!_

		if(VISIBLE){
			printf("\nServer ciphertext:\n%s\n",&c[crypto_secretbox_ZEROBYTES]);
		}

		if(crypto_secretbox_open(buf,c,BUF_SIZE,n,k)==-1){
			fatal("Decryption fail!");
		}
		
		inc_nonce(n);

		if(VISIBLE){
			printf("\nServer plaintext:\n%s\n",&buf[crypto_secretbox_ZEROBYTES]);
			printf("\n\n******  Symmetric encrytion/decryption echo end  ******\n\n");
		}

		printf("\n\n");
		printf("Server says: %s\n", &buf[32]);
	}

	close(s);
	printf("Exiting program!\n");
	return 0;

}
Пример #18
0
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
    if (msg_->size () < 257) {
        //  Temporary support for security debugging
        puts ("CURVE I: client INITIATE is not correct size");
        errno = EPROTO;
        return -1;
    }

    const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
    if (memcmp (initiate, "\x08INITIATE", 9)) {
        //  Temporary support for security debugging
        puts ("CURVE I: client INITIATE has invalid command name");
        errno = EPROTO;
        return -1;
    }

    uint8_t cookie_nonce [crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext [crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_box [crypto_secretbox_BOXZEROBYTES + 80];

    //  Open Box [C' + s'](t)
    memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);

    memcpy (cookie_nonce, "COOKIE--", 8);
    memcpy (cookie_nonce + 8, initiate + 9, 16);

    int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
                                    sizeof cookie_box,
                                    cookie_nonce, cookie_key);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client INITIATE cookie");
        errno = EPROTO;
        return -1;
    }

    //  Check cookie plain text is as expected [C' + s']
    if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, cn_client, 32)
    ||  memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, cn_secret, 32)) {
        //  Temporary support for security debugging
        puts ("CURVE I: client INITIATE cookie is not valid");
        errno = EPROTO;
        return -1;
    }

    const size_t clen = (msg_->size () - 113) + crypto_box_BOXZEROBYTES;

    uint8_t initiate_nonce [crypto_box_NONCEBYTES];
    uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
    uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256];

    //  Open Box [C + vouch + metadata](C'->S')
    memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (initiate_box + crypto_box_BOXZEROBYTES,
            initiate + 113, clen - crypto_box_BOXZEROBYTES);

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    memcpy (initiate_nonce + 16, initiate + 105, 8);
    cn_peer_nonce = get_uint64(initiate + 105);

    rc = crypto_box_open (initiate_plaintext, initiate_box,
                          clen, initiate_nonce, cn_client, cn_secret);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client INITIATE");
        errno = EPROTO;
        return -1;
    }

    const uint8_t *client_key = initiate_plaintext + crypto_box_ZEROBYTES;

    uint8_t vouch_nonce [crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];

    //  Open Box Box [C',S](C->S') and check contents
    memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (vouch_box + crypto_box_BOXZEROBYTES,
            initiate_plaintext + crypto_box_ZEROBYTES + 48, 80);

    memcpy (vouch_nonce, "VOUCH---", 8);
    memcpy (vouch_nonce + 8,
            initiate_plaintext + crypto_box_ZEROBYTES + 32, 16);

    rc = crypto_box_open (vouch_plaintext, vouch_box,
                          sizeof vouch_box,
                          vouch_nonce, client_key, cn_secret);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client INITIATE vouch");
        errno = EPROTO;
        return -1;
    }

    //  What we decrypted must be the client's short-term public key
    if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, cn_client, 32)) {
        //  Temporary support for security debugging
        puts ("CURVE I: invalid handshake from client (public key)");
        errno = EPROTO;
        return -1;
    }

    //  Precompute connection secret from client key
    rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret);
    zmq_assert (rc == 0);

    //  Use ZAP protocol (RFC 27) to authenticate the user.
    rc = session->zap_connect ();
    if (rc == 0) {
        send_zap_request (client_key);
        rc = receive_and_process_zap_reply ();
        if (rc == 0)
            state = status_code == "200"
                ? send_ready
                : send_error;
        else
        if (errno == EAGAIN)
            state = expect_zap_reply;
        else
            return -1;
    }
    else
        state = send_ready;

    return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 128,
                           clen - crypto_box_ZEROBYTES - 128);
}
Пример #19
0
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
    int rc = check_basic_command_structure (msg_);
    if (rc == -1)
        return -1;

    const size_t size = msg_->size ();
    const uint8_t *initiate = static_cast<uint8_t *> (msg_->data ());

    if (size < 9 || memcmp (initiate, "\x08INITIATE", 9)) {
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
        errno = EPROTO;
        return -1;
    }

    if (size < 257) {
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (),
          ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
        errno = EPROTO;
        return -1;
    }

    uint8_t cookie_nonce[crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext[crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_box[crypto_secretbox_BOXZEROBYTES + 80];

    //  Open Box [C' + s'](t)
    memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);

    memcpy (cookie_nonce, "COOKIE--", 8);
    memcpy (cookie_nonce + 8, initiate + 9, 16);

    rc = crypto_secretbox_open (cookie_plaintext, cookie_box, sizeof cookie_box,
                                cookie_nonce, _cookie_key);
    if (rc != 0) {
        // CURVE I: cannot open client INITIATE cookie
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
        errno = EPROTO;
        return -1;
    }

    //  Check cookie plain text is as expected [C' + s']
    if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, _cn_client, 32)
        || memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32,
                   _cn_secret, 32)) {
        // TODO this case is very hard to test, as it would require a modified
        //  client that knows the server's secret temporary cookie key

        // CURVE I: client INITIATE cookie is not valid
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
        errno = EPROTO;
        return -1;
    }

    const size_t clen = (size - 113) + crypto_box_BOXZEROBYTES;

    uint8_t initiate_nonce[crypto_box_NONCEBYTES];
    uint8_t initiate_plaintext[crypto_box_ZEROBYTES + 128 + 256];
    uint8_t initiate_box[crypto_box_BOXZEROBYTES + 144 + 256];

    //  Open Box [C + vouch + metadata](C'->S')
    memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (initiate_box + crypto_box_BOXZEROBYTES, initiate + 113,
            clen - crypto_box_BOXZEROBYTES);

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    memcpy (initiate_nonce + 16, initiate + 105, 8);
    cn_peer_nonce = get_uint64 (initiate + 105);

    rc = crypto_box_open (initiate_plaintext, initiate_box, clen,
                          initiate_nonce, _cn_client, _cn_secret);
    if (rc != 0) {
        // CURVE I: cannot open client INITIATE
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
        errno = EPROTO;
        return -1;
    }

    const uint8_t *client_key = initiate_plaintext + crypto_box_ZEROBYTES;

    uint8_t vouch_nonce[crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext[crypto_box_ZEROBYTES + 64];
    uint8_t vouch_box[crypto_box_BOXZEROBYTES + 80];

    //  Open Box Box [C',S](C->S') and check contents
    memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (vouch_box + crypto_box_BOXZEROBYTES,
            initiate_plaintext + crypto_box_ZEROBYTES + 48, 80);

    memcpy (vouch_nonce, "VOUCH---", 8);
    memcpy (vouch_nonce + 8, initiate_plaintext + crypto_box_ZEROBYTES + 32,
            16);

    rc = crypto_box_open (vouch_plaintext, vouch_box, sizeof vouch_box,
                          vouch_nonce, client_key, _cn_secret);
    if (rc != 0) {
        // CURVE I: cannot open client INITIATE vouch
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
        errno = EPROTO;
        return -1;
    }

    //  What we decrypted must be the client's short-term public key
    if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, _cn_client, 32)) {
        // TODO this case is very hard to test, as it would require a modified
        //  client that knows the server's secret short-term key

        // CURVE I: invalid handshake from client (public key)
        session->get_socket ()->event_handshake_failed_protocol (
          session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE);
        errno = EPROTO;
        return -1;
    }

    //  Precompute connection secret from client key
    rc = crypto_box_beforenm (cn_precom, _cn_client, _cn_secret);
    zmq_assert (rc == 0);

    //  Given this is a backward-incompatible change, it's behind a socket
    //  option disabled by default.
    if (zap_required () || !options.zap_enforce_domain) {
        //  Use ZAP protocol (RFC 27) to authenticate the user.
        rc = session->zap_connect ();
        if (rc == 0) {
            send_zap_request (client_key);
            state = waiting_for_zap_reply;

            //  TODO actually, it is quite unlikely that we can read the ZAP
            //  reply already, but removing this has some strange side-effect
            //  (probably because the pipe's in_active flag is true until a read
            //  is attempted)
            rc = receive_and_process_zap_reply ();
            if (rc == -1)
                return -1;
        } else if (!options.zap_enforce_domain) {
            //  This supports the Stonehouse pattern (encryption without
            //  authentication) in legacy mode (domain set but no handler).
            state = sending_ready;
        } else {
            session->get_socket ()->event_handshake_failed_no_detail (
              session->get_endpoint (), EFAULT);
            return -1;
        }
    } else {
        //  This supports the Stonehouse pattern (encryption without authentication).
        state = sending_ready;
    }

    return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 128,
                           clen - crypto_box_ZEROBYTES - 128);
}