Beispiel #1
0
int main()
{
    auto print = [&](unsigned char* c) {
        for (int i = 16;i < 163;++i) {
            printf(",0x%02x",(unsigned int) c[i]);
            if (i % 8 == 7) printf("\n");
        }
        printf("\n");
    };

    crypto_box(c,m,163,nonce,bobpk,alicesk);
    print(c);


    int constexpr s = 163;
    Message mm(m , s);
    crypto_array<u8,s> mc;
    auto n = Nonce::wrap(nonce);
    auto pk = Key::wrap(bobpk);
    auto sk = Key::wrap(alicesk);
    auto out = Message(mc.p(), s);

    crypto_box(out, mm, n, pk, sk);

    print(mc.p());

    return 0;
}
Beispiel #2
0
/* encrypts plain of length length to encrypted of length + 16 using the 
   public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
   return -1 if there was a problem.
   return length of encrypted data if everything was fine. */
int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, 
                                       uint8_t * plain, uint32_t length, uint8_t * encrypted)
{
    if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0)
    {
        return -1;
    }
    
    uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0};
    uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES];
    uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0};
    
    memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */
    
    crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key);
    
    /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */
    if(memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0)
    {
        return -1;
    }
    /* unpad the encrypted message */
    memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
    return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES;
}
Beispiel #3
0
int main(void)
{
  size_t mlen;
  size_t i;
  int caught;

  for (mlen = 0;mlen < 1000 && mlen + crypto_box_ZEROBYTES < sizeof m;++mlen) {
    crypto_box_keypair(alicepk,alicesk);
    crypto_box_keypair(bobpk,bobsk);
    randombytes(n,crypto_box_NONCEBYTES);
    randombytes(m + crypto_box_ZEROBYTES,mlen);
    crypto_box(c,m,mlen + crypto_box_ZEROBYTES,n,bobpk,alicesk);
    caught = 0;
    while (caught < 10) {
      c[rand() % (mlen + crypto_box_ZEROBYTES)] = rand();
      if (crypto_box_open(m2,c,mlen + crypto_box_ZEROBYTES,n,alicepk,bobsk) == 0) {
        for (i = 0;i < mlen + crypto_box_ZEROBYTES;++i)
          if (m2[i] != m[i]) {
            printf("forgery\n");
            return 100;
          }
      } else {
        ++caught;
      }
    }
  }
  return 0;
}
Beispiel #4
0
int main(int argc, char **argv)
{
	int rc;
	uint8_t client_pub[32], client_sec[32];
	uint8_t server_pub[32], server_sec[32];
	uint8_t cipher[512], plain[512];
	uint8_t nonce[24];

	/* initialize memory */
	memset(cipher, 0, 512);
	memset(plain, 0, 512);

	/* "generate" nonce */
	memset(nonce, 0, 24);

	/* "generate" keys */
	memcpy(client_pub, CLIENT_PUB, 32);
	memcpy(client_sec, CLIENT_SEC, 32);
	memcpy(server_pub, SERVER_PUB, 32);
	memcpy(server_sec, SERVER_SEC, 32);

	/* assemble plaintext */
	memcpy(plain, MESSAGE, MESSAGE_LEN);
	dump("plaintext, before encryption", plain, MESSAGE_LEN);

	/* encipher message from client to server */
	rc = crypto_box(cipher, plain, MESSAGE_LEN,
	                nonce, server_pub, client_sec);
	dump("ciphertext", cipher, MESSAGE_LEN);
	assert(rc == 0);

	return 0;
}
Beispiel #5
0
// TODO: This should probably be refactored so that the indices and stuff are more sane; to prevent
//       memory issues.
size_t tunnel_buildPacket(struct tunnel *t, uint8_t *packet, uint8_t *message, size_t messageSize) {
  const bool      sendingPublickey = t->state == TUNNEL_STATE_CLIENT_PRE_HANDSHAKE;
  const uint64_t  tidWithFlags     = t->tid | (sendingPublickey ? PUBLICKEY_FLAG : 0);
  const size_t    headerSize       = sizeof tidWithFlags +
                                     sizeof t->nonce +
                                     (sendingPublickey ? sizeof t->localPublickey : 0);

  writeUint64LE(packet, tidWithFlags);
  memcpy(&packet[sizeof tidWithFlags], t->nonce, sizeof t->nonce);

  if (sendingPublickey) {
    t->state = TUNNEL_STATE_NORMAL;
    memcpy(&packet[sizeof tidWithFlags + sizeof t->nonce],
           t->localPublickey,
           sizeof t->localPublickey);
  }

  uint8_t crypted[crypto_box_ZEROBYTES + messageSize];

  memset(crypted, 0, crypto_box_ZEROBYTES);
  memcpy(&crypted[crypto_box_ZEROBYTES], message, messageSize);

  crypto_box(crypted, crypted, sizeof crypted, t->nonce, t->remotePublickey, t->localSecretkey);

  memcpy(&packet[headerSize],
         &crypted[crypto_box_BOXZEROBYTES],
         sizeof crypted - crypto_box_BOXZEROBYTES);

  return headerSize + sizeof crypted - crypto_box_BOXZEROBYTES;
}
Beispiel #6
0
int
main(int argc, const char **argv)
{
	unsigned char *sk, *pk, *n, *m, *c;
	size_t mlen, clen;

	if (argc < 2) {
		puts("usage: cbox SK PK NONCE");
		return 1;
	}

	if (strlen(argv[1]) != crypto_box_SECRETKEYBYTES * 2)
		errx(1, "bad SK length");
	sk = decodehex(argv[1]);

	if (strlen(argv[2]) != crypto_box_PUBLICKEYBYTES * 2)
		errx(1, "bad PK length");
	pk = decodehex(argv[2]);

	if (strlen(argv[3]) != crypto_box_NONCEBYTES * 2)
		errx(1, "bad NONCE length");
	n = decodehex(argv[3]);

	mlen = readmsg(&m);
	if ((c = calloc(mlen, 1)) == NULL)
		err(1, NULL);

	crypto_box(c, m, mlen, n, pk, sk);
	c += crypto_box_BOXZEROBYTES;
	clen = mlen - crypto_box_BOXZEROBYTES;

	if (fwrite(c, 1, clen, stdout) != clen)
		err(1, NULL);
	return 0;
}
Beispiel #7
0
int zmq::curve_server_t::produce_welcome (msg_t *msg_)
{
    uint8_t cookie_nonce [crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext [crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_ciphertext [crypto_secretbox_BOXZEROBYTES + 80];

    //  Create full nonce for encryption
    //  8-byte prefix plus 16-byte random nonce
    memcpy (cookie_nonce, "COOKIE--", 8);
    randombytes (cookie_nonce + 8, 16);

    //  Generate cookie = Box [C' + s'](t)
    memset (cookie_plaintext, 0, crypto_secretbox_ZEROBYTES);
    memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES,
            cn_client, 32);
    memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32,
            cn_secret, 32);

    //  Generate fresh cookie key
    randombytes (cookie_key, crypto_secretbox_KEYBYTES);

    //  Encrypt using symmetric cookie key
    int rc = crypto_secretbox (cookie_ciphertext, cookie_plaintext,
                               sizeof cookie_plaintext,
                               cookie_nonce, cookie_key);
    zmq_assert (rc == 0);

    uint8_t welcome_nonce [crypto_box_NONCEBYTES];
    uint8_t welcome_plaintext [crypto_box_ZEROBYTES + 128];
    uint8_t welcome_ciphertext [crypto_box_BOXZEROBYTES + 144];

    //  Create full nonce for encryption
    //  8-byte prefix plus 16-byte random nonce
    memcpy (welcome_nonce, "WELCOME-", 8);
    randombytes (welcome_nonce + 8, crypto_box_NONCEBYTES - 8);

    //  Create 144-byte Box [S' + cookie](S->C')
    memset (welcome_plaintext, 0, crypto_box_ZEROBYTES);
    memcpy (welcome_plaintext + crypto_box_ZEROBYTES, cn_public, 32);
    memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 32,
            cookie_nonce + 8, 16);
    memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 48,
            cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80);

    rc = crypto_box (welcome_ciphertext, welcome_plaintext,
                     sizeof welcome_plaintext,
                     welcome_nonce, cn_client, secret_key);
    if (rc == -1)
        return -1;

    rc = msg_->init_size (168);
    errno_assert (rc == 0);

    uint8_t * const welcome = static_cast <uint8_t *> (msg_->data ());
    memcpy (welcome, "\x07WELCOME", 8);
    memcpy (welcome + 8, welcome_nonce + 8, 16);
    memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144);

    return 0;
}
Beispiel #8
0
static void test_hacl_01(void)
{
    int res;

    /* Creating keypair ALICE... */
    crypto_box_keypair(alice_pk, alice_sk);

    /* Creating keypair BOB... */
    crypto_box_keypair(bob_pk, bob_sk);

    memset(m, 0, crypto_box_ZEROBYTES);
    memcpy(m + crypto_box_ZEROBYTES, message, MLEN - crypto_box_ZEROBYTES);

    /* Encrypting using pk_bob... */
    crypto_box(c, m, MLEN, n, bob_pk, alice_sk);

    memset(result, '\0', sizeof(result));

    /* Decrypting... */
    res = crypto_box_open(result, c, MLEN, n, alice_pk, bob_sk);

    TEST_ASSERT_EQUAL_INT(0, res);

    memset(r, 0, sizeof(r));
    memcpy(r, result + crypto_box_ZEROBYTES, MLEN - crypto_box_ZEROBYTES);

    TEST_ASSERT_EQUAL_STRING((const char*)message, (const char*)r);
}
Beispiel #9
0
/* encrypts plain of length length to encrypted of length + 16 using the
   public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
   return -1 if there was a problem.
   return length of encrypted data if everything was fine. */
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
                 uint8_t *plain, uint32_t length, uint8_t *encrypted)
{
    if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0)
        return -1;

    uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0};
    uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES];

    memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */

    crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key);

    /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero
       apparently memcmp should not be used so we do this instead:*/
    uint32_t i;
    uint32_t check = 0;
    for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) {
            check |= temp_encrypted[i] ^ 0;
    }
    if(check != 0)
        return -1;

    /* unpad the encrypted message */
    memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
    return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES;
}
Beispiel #10
0
static ERL_NIF_TERM nacl_box_padded(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
{
  ErlNifBinary padded_msg;
  ErlNifBinary nonce;
  ErlNifBinary pk;
  ErlNifBinary sk;
  ErlNifBinary result;

  if (!enif_inspect_iolist_as_binary(env, argv[0], &padded_msg))
    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], &pk))
    return enif_make_badarg(env);

  if (!enif_inspect_iolist_as_binary(env, argv[3], &sk))
    return enif_make_badarg(env);

  if (nonce.size != crypto_box_NONCEBYTES) return enif_make_badarg(env);
  if (pk.size != crypto_box_PUBLICKEYBYTES) return enif_make_badarg(env);
  if (sk.size != crypto_box_SECRETKEYBYTES) return enif_make_badarg(env);
  if (padded_msg.size < crypto_box_ZEROBYTES) return enif_make_badarg(env);

  if (!enif_alloc_binary(padded_msg.size, &result))
    return nacl_error_tuple(env, "alloc_failed");

  crypto_box(result.data, padded_msg.data, padded_msg.size, nonce.data, pk.data, sk.data);

  return enif_make_sub_binary(env,
			      enif_make_binary(env, &result),
			      crypto_box_BOXZEROBYTES,
			      padded_msg.size - crypto_box_BOXZEROBYTES);
}
Beispiel #11
0
int main() {
	unsigned char n[crypto_box_NONCEBYTES];
	unsigned char m[32+crypto_box_ZEROBYTES];
	unsigned char c[32+crypto_box_ZEROBYTES];

	unsigned char pk[crypto_box_PUBLICKEYBYTES];
	unsigned char sk[crypto_box_SECRETKEYBYTES];
	//crypto_box_keypair(pk, sk);
	//randombytes(sk,32);
	sk[0]=1;
	crypto_scalarmult_curve25519_base(pk,sk);


	int r;

	unsigned char* buffer1offset = m + crypto_box_ZEROBYTES;

	strcpy(buffer1offset, "hello world");
	printf("in=$s\n", buffer1offset);
	memset(m, 0, crypto_box_ZEROBYTES);
	r=crypto_box(c, m, 32+crypto_box_ZEROBYTES, n, pk, sk);
	printf("ret=%d\n", r);

	memset(c, 0, crypto_box_BOXZEROBYTES);
	r=crypto_box_open(m, c, 32+crypto_box_ZEROBYTES, n, pk, sk);
	printf("ret=%d\n", r);
	printf("out=$s\n", buffer1offset);
}
Beispiel #12
0
EncryptedMessage CryptoEngine::EncryptWithPublicKeyAndSign(const Message &message, const VerificationEngine &ver_engine) {

    // check the public key
    if (ver_engine.public_key().empty()) {
        std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (ver_engine.signing_public_key().empty()) {
        std::cout << "The recipient signing public key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (private_key_.empty()) {
        std::cout << "The secret key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (nonce_master_key_.empty()) {
        std::cout << "The master key for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (context_.empty()) {
        std::cout << "The context identifier for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (salt_.empty()) {
        std::cout << "The salt for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    // means the current crypto engine and the recipient crypto engine have the same public keys !
    // This is NOT SAFE - stop immediately
    if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()),
                         reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) {
        std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    // derive the nonce
    std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_);

    // calculate the hash of the data
    std::string hash(crypto_hash(message.ToBytesString()));

    // calculate the signature on the hash
    std::string signed_hash = crypto_sign(hash, sign_private_key_);

    // prepend the signature+hash to the message
    std::string signed_message_string = signed_hash + message.ToBytesString();

    // encrypt with the recipient public key
    std::string cipher_text = crypto_box(signed_message_string, nonce, ver_engine.public_key(), private_key_);

    return EncryptedMessage(nonce, cipher_text);
}
Beispiel #13
0
int main(int argc, char *argv[]) {
    if (argc != 5) error(2,
                             "Usage: tweetnacl-encrypt send-key.sec recv-key.pub text.txt text.enc");

    // This will also erroneously fail if the file "-" exists
    if (file_exists(argv[4])) errorf(1, "File <%s> exists", argv[4]);

    // Alice is sending to Bob, not surprisingly
    unsigned char a_secret_key[crypto_box_SECRETKEYBYTES];
    unsigned char b_public_key[crypto_box_PUBLICKEYBYTES];

    read_key(argv[1], a_secret_key, crypto_box_SECRETKEYBYTES);
    read_key(argv[2], b_public_key, crypto_box_PUBLICKEYBYTES);

    unsigned char nonce[crypto_box_NONCEBYTES];
    randombytes(nonce, sizeof(nonce));

    FILE *out;
    if (strcmp(argv[4], "-") != 0) {
        out = create_file(argv[4]);
        fwrite(nonce, sizeof(nonce), 1, out);
    } else {
        out = stdout;
        fwrite(bytes_to_hex(nonce, sizeof(nonce)), sizeof(nonce) * 2, 1, out);
        fputs("\n", out);
    }

    // Input
    // unsigned char *message = read_file(argv[3]);
    Content c = read_file(argv[3]);
    long psize = crypto_box_ZEROBYTES + c.size;
    unsigned char *padded = malloc(psize);
    if (padded == NULL) error(1, "Malloc failed!");
    memset(padded, 0, crypto_box_ZEROBYTES);
    memcpy(padded + crypto_box_ZEROBYTES, c.bytes, c.size);
    free(c.bytes);

    // Output
    unsigned char *encrypted = calloc(psize, sizeof(unsigned char));
    if (encrypted == NULL) error(1, "Calloc failed!");

    // Encrypt
    crypto_box(encrypted, padded, psize, nonce, b_public_key, a_secret_key);
    free(padded);

    if (out != stdout) {
        fwrite(encrypted + crypto_box_BOXZEROBYTES,
               psize - crypto_box_BOXZEROBYTES, 1, out);
    } else {
        fwrite(bytes_to_hex(encrypted + crypto_box_BOXZEROBYTES,
                            psize - crypto_box_BOXZEROBYTES),
               (psize - crypto_box_BOXZEROBYTES) * 2, 1, out);
        fputs("\n", out);
    }
    free(encrypted);
    return 0;
}
Beispiel #14
0
static nif_term_t
salt_box(nif_heap_t *hp, int argc, const nif_term_t argv[])
{
	/* salt_box(Plain_text, Nonce, Public_key, Secret_key) -> Cipher_text. */
	nif_bin_t 		pt;
	nif_bin_t 		nc;
	nif_bin_t 		pk;
	nif_bin_t 		sk;
	nif_bin_t 		ct;
	nif_term_t 		raw;
	nif_term_t 		sub;

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

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

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

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

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

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

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

	if (pk.size != crypto_box_PUBLICKEYBYTES)
		return (BADARG);

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

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

	/* Perform the crypto, strip leading zeros. */
	(void)crypto_box(ct.data, pt.data, pt.size, nc.data, pk.data, sk.data);

	raw = enif_make_binary(hp, &ct);
	sub = enif_make_sub_binary(hp, raw, crypto_box_BOXZEROBYTES, ct.size - crypto_box_BOXZEROBYTES);

	return (sub);
}
Beispiel #15
0
int main() {
	char * padded_message;
	int padded_mlen;
	u8 sk[PRIV_KEY_LEN] = {0};
	u8 pk[PUB_KEY_LEN] = {0};
	u8 sk2[PRIV_KEY_LEN] = {0};
	u8 pk2[PUB_KEY_LEN] = {0};
	u8 nonce[NONCE_LEN] = {0};
	char* message = "This is a cross-platform test of crypto_box/crypto_box_open in TweetNaCl.";
	u8 * ciphertext;
	char *decryptedmessage;

	// randomize nonce
	randombytes(nonce, NONCE_LEN);
	printf("Nonce: \n");
	hexdump((char*)nonce, NONCE_LEN);

	crypto_box_keypair(pk, sk);
	crypto_box_keypair(pk2, sk2);
	
	printf("Public key: \n");
	hexdump((char*)pk, PUB_KEY_LEN);
	printf("\nSecret key: \n");
	hexdump((char*)sk, PRIV_KEY_LEN);
	printf("Public key2: \n");
	hexdump((char*)pk2, PUB_KEY_LEN);
	printf("\nSecret key2: \n");
	hexdump((char*)sk2, PRIV_KEY_LEN);

	padded_mlen = strlen(message) + PADDING_LEN;
	padded_message = (char*) malloc(padded_mlen);
	memset(padded_message, 0, PADDING_LEN);
	memcpy(padded_message + PADDING_LEN, message, strlen(message));

	ciphertext = (u8*) malloc(padded_mlen);

	// we have a string so add 1 byte and NUL it so we can print it
	decryptedmessage = (char*) malloc(padded_mlen+1);
	decryptedmessage[padded_mlen] = '\0';

	printf("crypto_box returned: %d\n",crypto_box(ciphertext, (u8*)padded_message,  padded_mlen, nonce, pk2, sk));

	free(padded_message);
	
	printf("\nCipher text: \n");
	hexdump((char*)ciphertext, padded_mlen);
	printf("crypto_box_open returned: %d\n", crypto_box_open((u8*)decryptedmessage, ciphertext, padded_mlen, nonce, pk, sk2));
	free(ciphertext);
	printf("\nDecrypted text: \n");
	hexdump((char*)decryptedmessage, padded_mlen);

	printf("%s\n", decryptedmessage+32);
	free(decryptedmessage);
	return 0;
}
Beispiel #16
0
int main(void)
{
    unsigned char k[crypto_box_BEFORENMBYTES];
    int i;
    int ret;

    ret = crypto_box(c, m, 163, nonce, bobpk, alicesk);
    assert(ret == 0);
    for (i = 16; i < 163; ++i) {
        printf(",0x%02x", (unsigned int)c[i]);
        if (i % 8 == 7)
            printf("\n");
    }
    printf("\n");

    memset(c, 0, sizeof c);
    ret = crypto_box_beforenm(k, bobpk, alicesk);
    assert(ret == 0);
    crypto_box_afternm(c, m, 163, nonce, k);
    for (i = 16; i < 163; ++i) {
        printf(",0x%02x", (unsigned int)c[i]);
        if (i % 8 == 7)
            printf("\n");
    }
    printf("\n");

    assert(crypto_box_seedbytes() > 0U);
    assert(crypto_box_publickeybytes() > 0U);
    assert(crypto_box_secretkeybytes() > 0U);
    assert(crypto_box_beforenmbytes() > 0U);
    assert(crypto_box_noncebytes() > 0U);
    assert(crypto_box_zerobytes() > 0U);
    assert(crypto_box_boxzerobytes() > 0U);
    assert(crypto_box_macbytes() > 0U);
    assert(strcmp(crypto_box_primitive(), "curve25519xsalsa20poly1305") == 0);
    assert(crypto_box_curve25519xsalsa20poly1305_seedbytes()
           == crypto_box_seedbytes());
    assert(crypto_box_curve25519xsalsa20poly1305_publickeybytes()
           == crypto_box_publickeybytes());
    assert(crypto_box_curve25519xsalsa20poly1305_secretkeybytes()
           == crypto_box_secretkeybytes());
    assert(crypto_box_curve25519xsalsa20poly1305_beforenmbytes()
           == crypto_box_beforenmbytes());
    assert(crypto_box_curve25519xsalsa20poly1305_noncebytes()
           == crypto_box_noncebytes());
    assert(crypto_box_curve25519xsalsa20poly1305_zerobytes()
           == crypto_box_zerobytes());
    assert(crypto_box_curve25519xsalsa20poly1305_boxzerobytes()
           == crypto_box_boxzerobytes());
    assert(crypto_box_curve25519xsalsa20poly1305_macbytes()
           == crypto_box_macbytes());

    return 0;
}
Beispiel #17
0
// Decrypt with the same key but from the message bytes
EncryptedMessage CryptoEngine::EncryptWithPublicKey(const Message &message, const VerificationEngine &ver_engine) {

    // check the public key
    if (ver_engine.public_key().empty()) {
        std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (private_key_.empty()) {
        std::cout << "The secret key is empty. Cannot encrypt here." << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (nonce_master_key_.empty()) {
        std::cout << "The master key for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (context_.empty()) {
        std::cout << "The context identifier for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    if (salt_.empty()) {
        std::cout << "The salt for deriving the nonce is not valid" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    // means the current crypto engine and the recipient crypto engine have the same public keys !
    // This is NOT SAFE - stop immediately
    if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()),
                         reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) {
        std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl;
        throw g_crypto_engine_encryption_failure;
    }

    try {
        // derive the nonce
        std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_);

        // Add the additional data (tcp_verion, type, message) to the string
        std::string full_clear_text(message.ToBytesString());

        // encrypt with the recipient public key
        std::string cipher_text = crypto_box(full_clear_text, nonce, ver_engine.public_key(), private_key_);

        return EncryptedMessage(nonce, cipher_text);
    } catch (std::exception& e) {
        std::cout << "CryptoEngine::Encrypt exception: " << e.what() << std::endl;
        throw g_crypto_engine_encryption_failure;
    }
}
Beispiel #18
0
String NaCl::public_encrypt(String msg)
{
    try
    {
        std::string message = from_ruby<std::string>(msg);
        std::string encrypted_message = crypto_box(message, remote_nonce, remote_pk, my_sk);
        return to_ruby<std::string>(encrypted_message);
    }
    catch (int e)
    {
        return to_ruby<std::string>("");
    }
}
Beispiel #19
0
/**
 *  Encrypt data without making it a packet.
 *  @src: source of the data
 *  @len: length of the data
 *  @pk: public key to encrypt the data for
 *  @sk: secret key to encrypt the data with
 *  @dest: destination for ciphertext, must be as big as len + PREFIX
 */
void crypto_encipher_data (const void *src, int len, const unsigned char *pek,
                           const unsigned char *sek, void *dest)
{
        unsigned char m[crypto_box_ZEROBYTES + len];

        memset(m, 0, crypto_box_ZEROBYTES + len);
        memset(dest, 0, PREFIX + len);
        memcpy(m + crypto_box_ZEROBYTES, src, len);
        randombytes_buf(dest, crypto_box_NONCEBYTES);

        crypto_box((unsigned char *)dest + crypto_box_NONCEBYTES, m,
                   crypto_box_ZEROBYTES + len, dest, pek, sek);
}
Beispiel #20
0
int main(int argc, char **argv)
{
	int rc;
	uint8_t client_pub[32], client_sec[32];
	uint8_t server_pub[32], server_sec[32];
	uint8_t cipher[512], plain[512];
	uint8_t nonce[24];

	/* initialize memory */
	memset(cipher, 0, 512);
	memset(plain, 0, 512);

	/* "generate" nonce */
	memset(nonce, 0, 24);

	/* "generate" keys */
	memcpy(client_pub, CLIENT_PUB, 32);
	memcpy(client_sec, CLIENT_SEC, 32);
	memcpy(server_pub, SERVER_PUB, 32);
	memcpy(server_sec, SERVER_SEC, 32);

	/* assemble plaintext */
	memset(plain, 0, 32);                    /* first 32 octest are ZERO */
	memcpy(plain+32, MESSAGE, MESSAGE_LEN);  /* then comes the real data */
	dump("plaintext, before encryption", plain, MESSAGE_LEN+32);

	/* encipher message from client to server */
	rc = crypto_box(cipher, plain, MESSAGE_LEN+32,
	                nonce, server_pub, client_sec);
	dump("ciphertext", cipher, MESSAGE_LEN);
	assert(rc == 0);

	/* erase all trace of plaintext */
	memset(plain, 0, 512);

	/* decipher message as server, using client's public key */
	rc = crypto_box_open(plain, cipher, MESSAGE_LEN+32,
	                     nonce, client_pub, server_sec);
	dump("plaintext, after decryption", plain, MESSAGE_LEN+32);
	assert(rc == 0);
	assert(memcmp(MESSAGE, plain, MESSAGE_LEN) == 0);

	plain[MESSAGE_LEN+1] = '\0';
	printf("%s\n", plain);

	return 0;
}
Beispiel #21
0
// encrypted_bytes = crypto_box(clear_bytes, nonce, pk_other, sk_self);
static int tweetnacl_crypto_box( lua_State* L )
{
  unsigned int msg_len;
  const char* msg = luaL_checklstring(L,1,&msg_len);
  if(msg_len < 1)
    return luaL_error( L, "len(message)=%d, too short", msg_len);

  unsigned int nonce_len;
  const char* nonce = luaL_checklstring(L,2,&nonce_len);
  if(nonce_len != crypto_box_NONCEBYTES)
    return luaL_error( L, "len(nonce)=%d, should be %d", nonce_len, crypto_box_NONCEBYTES);

  unsigned int pk_len;
  const char* pk_other = luaL_checklstring(L,3,&pk_len);
  if(pk_len != crypto_box_PUBLICKEYBYTES)
    return luaL_error( L, "len(pk)=%d, should be %d", pk_len, crypto_box_PUBLICKEYBYTES);

  unsigned int sk_len;
  const char* sk_self = luaL_checklstring(L,4,&sk_len);
  if(sk_len != crypto_box_SECRETKEYBYTES)
    return luaL_error( L, "len(sk)=%d, should be %d", sk_len, crypto_box_SECRETKEYBYTES);

  unsigned int cmsg_len = msg_len + crypto_box_ZEROBYTES;
  char *cmsg = (char *)c_malloc(cmsg_len);
  if(!cmsg)
    return luaL_error( L, "malloc failed, %d bytes", cmsg_len);

  int i;
  for(i=0;i<crypto_box_ZEROBYTES;i++) cmsg[i] = 0;
  for(;i<cmsg_len;i++) cmsg[i] = msg[i-crypto_box_ZEROBYTES];

  unsigned int emsg_len = cmsg_len;
  char *emsg = (char *)c_malloc(emsg_len);
  if(!emsg)
  {
    c_free(cmsg);
    return luaL_error( L, "malloc failed, %d bytes", emsg_len);
  }

  crypto_box(emsg, cmsg, cmsg_len, nonce, pk_other, sk_self);
  lua_pushlstring(L, emsg+crypto_box_BOXZEROBYTES, emsg_len-crypto_box_BOXZEROBYTES);
  c_free(cmsg);
  c_free(emsg);
  return 1;
}
Beispiel #22
0
Connection::Connection(CryptoIdentity& ci, Path path, ConnectionPool& cp, ConnectionHandler& ch)
  : Forwarding(randint64())
  , _ci(&ci)
  , _cp(cp)
  , _ch(ch)
  , _naclsession( std::get<1>(path.at(path.size()-1))->enc_key() )
  , _their_id(      std::get<1>(path.at(path.size()-1))->id() )
  , _route_id( bytes( id() ) )
  , _authenticated(false)
  , _request_packet(new std::string)
  , _packet_queue(new std::vector<std::string>)
  , _nonces(nullptr)
  {
  _request_packet->push_back('\1');

  std::string nonce = _route_id + randomstring(8);
  _request_packet->append(nonce);
  nonce.resize(crypto_box_NONCEBYTES,'\0');

  RoutingRequest rq;
  rq.set_enc_algo(enumval(PkencAlgo::CURVE25519XSALSA20POLY1305));
  rq.set_sender_pubkey(_naclsession.our_pk());
  Hop hop;
  {
    hop.set_type(Hop::UP);
    hop.set_nonce_algo(Hop::XTEA32);
    rq.set_details(_naclsession.encrypt(hop.SerializeAsString(), nonce));
  }

  hop.Clear();
  hop.set_type(Hop::SIMPLE);
  hop.set_next(_their_id);
  for (signed int i=path.size()-2; i>=0; --i) {
    auto dev = std::get<1>(path[i]);
    hop.set_details(rq.details());
    rq.set_details( crypto_box( hop.SerializeAsString(), nonce,
                                dev->enc_key(), _naclsession.our_sk()) );
    hop.set_next(dev->id());
  }

  rq.AppendToString(_request_packet.get());
}
Beispiel #23
0
int zmq::curve_client_t::produce_hello (msg_t *msg_)
{
    uint8_t hello_nonce [crypto_box_NONCEBYTES];
    uint8_t hello_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t hello_box [crypto_box_BOXZEROBYTES + 80];

    //  Prepare the full nonce
    memcpy (hello_nonce, "CurveZMQHELLO---", 16);
    put_uint64 (hello_nonce + 16, cn_nonce);

    //  Create Box [64 * %x0](C'->S)
    memset (hello_plaintext, 0, sizeof hello_plaintext);

    int rc = crypto_box (hello_box, hello_plaintext,
                         sizeof hello_plaintext,
                         hello_nonce, server_key, cn_secret);
    if (rc == -1)
        return -1;

    rc = msg_->init_size (200);
    errno_assert (rc == 0);
    uint8_t *hello = static_cast <uint8_t *> (msg_->data ());

    memcpy (hello, "\x05HELLO", 6);
    //  CurveZMQ major and minor version numbers
    memcpy (hello + 6, "\1\0", 2);
    //  Anti-amplification padding
    memset (hello + 8, 0, 72);
    //  Client public connection key
    memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES);
    //  Short nonce, prefixed by "CurveZMQHELLO---"
    memcpy (hello + 112, hello_nonce + 16, 8);
    //  Signature, Box [64 * %x0](C'->S)
    memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80);

    cn_nonce++;

    return 0;
}
Beispiel #24
0
PyObject *pycrypto_box(PyObject *self, PyObject *args, PyObject *kw){
  char *m, *n, *pk, *sk;
  Py_ssize_t msize=0, nsize=0, pksize=0, sksize=0;
  static const char *kwlist[] = {"m", "n", "pk", "sk", 0};
  unsigned int i;
  PyObject *ret;
  size_t mlen;
  unsigned char *mpad;
  unsigned char *cpad;

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#s#:crypto_box", (char **) kwlist, &m, &msize, &n, &nsize, &pk, &pksize, &sk, &sksize)){
    return (PyObject *)0;}

  if (nsize != crypto_box_NONCEBYTES) return Py_BuildValue("i", 0);
  if (pksize != crypto_box_PUBLICKEYBYTES) return Py_BuildValue("i", 0);
  if (sksize != crypto_box_SECRETKEYBYTES) return Py_BuildValue("i", 0);

  mlen = msize + crypto_box_ZEROBYTES;
  mpad = PyMem_Malloc(mlen);

  if (!mpad)
    return PyErr_NoMemory();

  cpad = PyMem_Malloc(mlen);

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

  for (i = 0;i < crypto_box_ZEROBYTES;++i) mpad[i] = 0;
  for (i = crypto_box_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_box_ZEROBYTES];

  crypto_box(cpad, mpad, mlen,(const unsigned char *) n,(const unsigned char *) pk,(const unsigned char *) sk);

  ret = PyBytes_FromStringAndSize((char *)cpad + crypto_box_BOXZEROBYTES,mlen - crypto_box_BOXZEROBYTES);

  PyMem_Free(mpad);
  PyMem_Free(cpad);
  return ret;}
    static int produce_hello (void *data_,
                              const uint8_t *server_key_,
                              const uint64_t cn_nonce_,
                              const uint8_t *cn_public_,
                              const uint8_t *cn_secret_)
    {
        uint8_t hello_nonce[crypto_box_NONCEBYTES];
        uint8_t hello_plaintext[crypto_box_ZEROBYTES + 64];
        uint8_t hello_box[crypto_box_BOXZEROBYTES + 80];

        //  Prepare the full nonce
        memcpy (hello_nonce, "CurveZMQHELLO---", 16);
        put_uint64 (hello_nonce + 16, cn_nonce_);

        //  Create Box [64 * %x0](C'->S)
        memset (hello_plaintext, 0, sizeof hello_plaintext);

        int rc = crypto_box (hello_box, hello_plaintext, sizeof hello_plaintext,
                             hello_nonce, server_key_, cn_secret_);
        if (rc == -1)
            return -1;

        uint8_t *hello = static_cast<uint8_t *> (data_);

        memcpy (hello, "\x05HELLO", 6);
        //  CurveZMQ major and minor version numbers
        memcpy (hello + 6, "\1\0", 2);
        //  Anti-amplification padding
        memset (hello + 8, 0, 72);
        //  Client public connection key
        memcpy (hello + 80, cn_public_, crypto_box_PUBLICKEYBYTES);
        //  Short nonce, prefixed by "CurveZMQHELLO---"
        memcpy (hello + 112, hello_nonce + 16, 8);
        //  Signature, Box [64 * %x0](C'->S)
        memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80);

        return 0;
    }
Beispiel #26
0
int main(void)
{
  size_t mlen;
  size_t i;

  for (mlen = 0;mlen < 1000 && mlen + crypto_box_ZEROBYTES < sizeof m;++mlen) {
    crypto_box_keypair(alicepk,alicesk);
    crypto_box_keypair(bobpk,bobsk);
    randombytes(n,crypto_box_NONCEBYTES);
    randombytes(m + crypto_box_ZEROBYTES,mlen);
    crypto_box(c,m,mlen + crypto_box_ZEROBYTES,n,bobpk,alicesk);
    if (crypto_box_open(m2,c,mlen + crypto_box_ZEROBYTES,n,alicepk,bobsk) == 0) {
      for (i = 0;i < mlen + crypto_box_ZEROBYTES;++i)
        if (m2[i] != m[i]) {
          printf("bad decryption\n");
          break;
        }
    } else {
      printf("ciphertext fails verification\n");
    }
  }
  return 0;
}
    static int produce_initiate (void *data_,
                                 size_t size_,
                                 const uint64_t cn_nonce_,
                                 const uint8_t *server_key_,
                                 const uint8_t *public_key_,
                                 const uint8_t *secret_key_,
                                 const uint8_t *cn_public_,
                                 const uint8_t *cn_secret_,
                                 const uint8_t *cn_server_,
                                 const uint8_t *cn_cookie_,
                                 const uint8_t *metadata_plaintext_,
                                 const size_t metadata_length_)
    {
        uint8_t vouch_nonce[crypto_box_NONCEBYTES];
        uint8_t vouch_plaintext[crypto_box_ZEROBYTES + 64];
        uint8_t vouch_box[crypto_box_BOXZEROBYTES + 80];

        //  Create vouch = Box [C',S](C->S')
        memset (vouch_plaintext, 0, crypto_box_ZEROBYTES);
        memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public_, 32);
        memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key_, 32);

        memcpy (vouch_nonce, "VOUCH---", 8);
        randombytes (vouch_nonce + 8, 16);

        int rc = crypto_box (vouch_box, vouch_plaintext, sizeof vouch_plaintext,
                             vouch_nonce, cn_server_, secret_key_);
        if (rc == -1)
            return -1;

        uint8_t initiate_nonce[crypto_box_NONCEBYTES];
        uint8_t *initiate_box = static_cast<uint8_t *> (
          malloc (crypto_box_BOXZEROBYTES + 144 + metadata_length_));
        alloc_assert (initiate_box);
        uint8_t *initiate_plaintext = static_cast<uint8_t *> (
          malloc (crypto_box_ZEROBYTES + 128 + metadata_length_));
        alloc_assert (initiate_plaintext);

        //  Create Box [C + vouch + metadata](C'->S')
        memset (initiate_plaintext, 0, crypto_box_ZEROBYTES);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES, public_key_, 32);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32, vouch_nonce + 8,
                16);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48,
                vouch_box + crypto_box_BOXZEROBYTES, 80);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48 + 80,
                metadata_plaintext_, metadata_length_);

        memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
        put_uint64 (initiate_nonce + 16, cn_nonce_);

        rc = crypto_box (initiate_box, initiate_plaintext,
                         crypto_box_ZEROBYTES + 128 + metadata_length_,
                         initiate_nonce, cn_server_, cn_secret_);
        free (initiate_plaintext);

        if (rc == -1)
            return -1;

        uint8_t *initiate = static_cast<uint8_t *> (data_);

        zmq_assert (size_
                    == 113 + 128 + crypto_box_BOXZEROBYTES + metadata_length_);

        memcpy (initiate, "\x08INITIATE", 9);
        //  Cookie provided by the server in the WELCOME command
        memcpy (initiate + 9, cn_cookie_, 96);
        //  Short nonce, prefixed by "CurveZMQINITIATE"
        memcpy (initiate + 105, initiate_nonce + 16, 8);
        //  Box [C + vouch + metadata](C'->S')
        memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES,
                128 + metadata_length_ + crypto_box_BOXZEROBYTES);
        free (initiate_box);

        return 0;
    }
Beispiel #28
0
bool unit_test_crypto_box(){
  // 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];
  // Generation of the public/secret key couple
  uint8_t sk1[32], pk1[32];
  uint8_t sk2[32], pk2[32];
  tweet_crypto_box_keypair(pk1, sk1);
  tweet_crypto_box_keypair(pk2, sk2);
  // Random plaintext
  uint8_t *plaintext = malloc((HACL_UNIT_TESTS_SIZE + crypto_box_ZEROBYTES) * sizeof (uint8_t));
  READ_RANDOM_BYTES(len, plaintext + crypto_box_ZEROBYTES);
  for (int i = 0; i < crypto_box_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 < 3 * CHACHA_BLOCKSIZE; i++){
    tweet_crypto_box(expected_cipher, plaintext, crypto_box_ZEROBYTES + i, nonce, pk1, sk2);
    crypto_box(hacl_cipher, plaintext, crypto_box_ZEROBYTES + i, nonce, pk1, sk2);
    a = memcmp(hacl_cipher, expected_cipher, (crypto_box_ZEROBYTES + i) * sizeof (uint8_t));
    if (a != 0){
      pass = false;
      printf("BOX failed on input of size %d\n.", i);
      break;
    }
    a = crypto_box_open(hacl_cipher, expected_cipher, i + crypto_box_ZEROBYTES, nonce, pk2, sk1);
    if (a != 0) {
      pass = false;
      printf("BOX OPEN failed to verify on input of size %d\n", i);
      break;
    }
    a = memcmp(hacl_cipher, plaintext, (crypto_box_ZEROBYTES + i) * sizeof (uint8_t));
    if (a != 0) {
      pass = false;
      printf("BOX OPEN failed on input of size %d\n", i);
      break;
    }
  }
  if (!pass) return pass;

  // Test 2
  tweet_crypto_box(expected_cipher, plaintext, crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE, nonce, pk1, sk2);
  crypto_box(hacl_cipher, plaintext, crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE, nonce, pk1, sk2);
  a = memcmp(hacl_cipher, expected_cipher, (crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE) * sizeof (uint8_t));
  if (a != 0){
    pass = false;
    printf("BOX failed on input of size %d\n.", HACL_UNIT_TESTS_SIZE);
  }
  a = crypto_box_open(hacl_cipher, expected_cipher, HACL_UNIT_TESTS_SIZE + crypto_box_ZEROBYTES, nonce, pk2, sk1);
  if (a != 0) {
    pass = false;
    printf("BOX OPEN failed to verify on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }
  a = memcmp(hacl_cipher, plaintext, (crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE) * sizeof (uint8_t));
  if (a != 0) {
    pass = false;
    printf("BOX OPEN failed on input of size %d\n", HACL_UNIT_TESTS_SIZE);
  }

  free(plaintext);

  return pass;
}
Beispiel #29
0
int zmq::curve_client_t::produce_initiate (msg_t *msg_)
{
    uint8_t vouch_nonce [crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];

    //  Create vouch = Box [C',S](C->S')
    memset (vouch_plaintext, 0, crypto_box_ZEROBYTES);
    memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public, 32);
    memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key, 32);

    memcpy (vouch_nonce, "VOUCH---", 8);
    randombytes (vouch_nonce + 8, 16);

    int rc = crypto_box (vouch_box, vouch_plaintext,
                         sizeof vouch_plaintext,
                         vouch_nonce, cn_server, secret_key);
    zmq_assert (rc == 0);

    //  Assume here that metadata is limited to 256 bytes
    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];

    //  Create Box [C + vouch + metadata](C'->S')
    memset (initiate_plaintext, 0, crypto_box_ZEROBYTES);
    memcpy (initiate_plaintext + crypto_box_ZEROBYTES,
            public_key, 32);
    memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32,
            vouch_nonce + 8, 16);
    memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48,
            vouch_box + crypto_box_BOXZEROBYTES, 80);

    //  Metadata starts after vouch
    uint8_t *ptr = initiate_plaintext + crypto_box_ZEROBYTES + 128;

    //  Add socket type property
    const char *socket_type = socket_type_string (options.type);
    ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type));

    //  Add identity property
    if (options.type == ZMQ_REQ
    ||  options.type == ZMQ_DEALER
    ||  options.type == ZMQ_ROUTER)
        ptr += add_property (ptr, "Identity", options.identity, options.identity_size);

    const size_t mlen = ptr - initiate_plaintext;

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    put_uint64 (initiate_nonce + 16, cn_nonce);

    rc = crypto_box (initiate_box, initiate_plaintext,
                     mlen, initiate_nonce, cn_server, cn_secret);
    zmq_assert (rc == 0);

    rc = msg_->init_size (113 + mlen - crypto_box_BOXZEROBYTES);
    errno_assert (rc == 0);

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

    memcpy (initiate, "\x08INITIATE", 9);
    //  Cookie provided by the server in the WELCOME command
    memcpy (initiate + 9, cn_cookie, 96);
    //  Short nonce, prefixed by "CurveZMQINITIATE"
    memcpy (initiate + 105, initiate_nonce + 16, 8);
    //  Box [C + vouch + metadata](C'->S')
    memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES,
            mlen - crypto_box_BOXZEROBYTES);
    cn_nonce++;

    return 0;
}
Beispiel #30
0
int zmq::curve_server_t::produce_welcome (msg_t *msg_)
{
    uint8_t cookie_nonce[crypto_secretbox_NONCEBYTES];
    uint8_t cookie_plaintext[crypto_secretbox_ZEROBYTES + 64];
    uint8_t cookie_ciphertext[crypto_secretbox_BOXZEROBYTES + 80];

    //  Create full nonce for encryption
    //  8-byte prefix plus 16-byte random nonce
    memcpy (cookie_nonce, "COOKIE--", 8);
    randombytes (cookie_nonce + 8, 16);

    //  Generate cookie = Box [C' + s'](t)
    memset (cookie_plaintext, 0, crypto_secretbox_ZEROBYTES);
    memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES, _cn_client, 32);
    memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, _cn_secret, 32);

    //  Generate fresh cookie key
    randombytes (_cookie_key, crypto_secretbox_KEYBYTES);

    //  Encrypt using symmetric cookie key
    int rc =
      crypto_secretbox (cookie_ciphertext, cookie_plaintext,
                        sizeof cookie_plaintext, cookie_nonce, _cookie_key);
    zmq_assert (rc == 0);

    uint8_t welcome_nonce[crypto_box_NONCEBYTES];
    uint8_t welcome_plaintext[crypto_box_ZEROBYTES + 128];
    uint8_t welcome_ciphertext[crypto_box_BOXZEROBYTES + 144];

    //  Create full nonce for encryption
    //  8-byte prefix plus 16-byte random nonce
    memcpy (welcome_nonce, "WELCOME-", 8);
    randombytes (welcome_nonce + 8, crypto_box_NONCEBYTES - 8);

    //  Create 144-byte Box [S' + cookie](S->C')
    memset (welcome_plaintext, 0, crypto_box_ZEROBYTES);
    memcpy (welcome_plaintext + crypto_box_ZEROBYTES, _cn_public, 32);
    memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 32, cookie_nonce + 8,
            16);
    memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 48,
            cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80);

    rc = crypto_box (welcome_ciphertext, welcome_plaintext,
                     sizeof welcome_plaintext, welcome_nonce, _cn_client,
                     _secret_key);

    //  TODO I think we should change this back to zmq_assert (rc == 0);
    //  as it was before https://github.com/zeromq/libzmq/pull/1832
    //  The reason given there was that secret_key might be 0ed.
    //  But if it were, we would never get this far, since we could
    //  not have opened the client's hello box with a 0ed key.

    if (rc == -1)
        return -1;

    rc = msg_->init_size (168);
    errno_assert (rc == 0);

    uint8_t *const welcome = static_cast<uint8_t *> (msg_->data ());
    memcpy (welcome, "\x07WELCOME", 8);
    memcpy (welcome + 8, welcome_nonce + 8, 16);
    memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144);

    return 0;
}