Пример #1
0
int main(void)
{
    unsigned char k[crypto_box_BEFORENMBYTES];
    int i;
    int ret;

    if (crypto_box_open(m, c, 163, nonce, alicepk, bobsk) == 0) {
        for (i = 32; i < 163; ++i) {
            printf(",0x%02x", (unsigned int)m[i]);
            if (i % 8 == 7)
                printf("\n");
        }
        printf("\n");
    }
    ret = crypto_box_open(m, c, 163, nonce, small_order_p, bobsk);
    assert(ret == -1);

    memset(m, 0, sizeof m);
    ret = crypto_box_beforenm(k, alicepk, bobsk);
    assert(ret == 0);
    if (crypto_box_open_afternm(m, c, 163, nonce, k) == 0) {
        for (i = 32; i < 163; ++i) {
            printf(",0x%02x", (unsigned int)m[i]);
            if (i % 8 == 7)
                printf("\n");
        }
        printf("\n");
    }
    return 0;
}
Пример #2
0
int zmq::curve_server_t::process_hello (msg_t *msg_)
{
	puts("zmq::curve_server_t::process_hello start");

	if (msg_->size() != 200) {
        //  Temporary support for security debugging
        puts ("CURVE I: client HELLO is not correct size");
        errno = EPROTO;
        return -1;
    }

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

    const uint8_t major = hello [6];
    const uint8_t minor = hello [7];

    if (major != 1 || minor != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: client HELLO has unknown version number");
        errno = EPROTO;
        return -1;
    }

    //  Save client's short-term public key (C')
    memcpy (cn_client, hello + 80, 32);

    uint8_t hello_nonce [crypto_box_NONCEBYTES];
    uint8_t hello_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t hello_box [crypto_box_BOXZEROBYTES + 80];

    memcpy (hello_nonce, "CurveZMQHELLO---", 16);
    memcpy (hello_nonce + 16, hello + 112, 8);
    cn_peer_nonce = get_uint64(hello + 112);

    memset (hello_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (hello_box + crypto_box_BOXZEROBYTES, hello + 120, 80);

    //  Open Box [64 * %x0](C'->S)
    int rc = crypto_box_open (hello_plaintext, hello_box,
                              sizeof hello_box,
                              hello_nonce, cn_client, secret_key);
    if (rc != 0) {
        //  Temporary support for security debugging
        puts ("CURVE I: cannot open client HELLO -- wrong server key?");
        errno = EPROTO;
        return -1;
    }

    state = send_welcome;

	puts("zmq::curve_server_t::process_hello end");

	return rc;
}
Пример #3
0
/* decrypts encrypted of length length to plain of length length - 16 using the
   public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
   return -1 if there was a problem(decryption failed)
   return length of plain data if everything was fine. */
int decrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, 
                                       uint8_t * encrypted, uint32_t length, uint8_t * plain)
{
    if(length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
    {
        return -1;
    }
    uint8_t temp_plain[MAX_DATA_SIZE - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES];
    uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0};
    uint8_t zeroes[crypto_box_ZEROBYTES] = {0};
    
    memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */
    
    if(crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, 
                                            nonce, public_key, secret_key) == -1)
    {
        return -1;
    }
    /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero */
    if(memcmp(temp_plain, zeroes, crypto_box_ZEROBYTES) != 0)
    {
        return -1;
    }
    /* unpad the plain message */
    memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES);
    return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES;
}
Пример #4
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);
}
Пример #5
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;
}
Пример #6
0
Файл: main.c Проект: A-Paul/RIOT
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);
}
Пример #7
0
/* decrypts encrypted of length length to plain of length length - 16 using the
   public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce
   return -1 if there was a problem(decryption failed)
   return length of plain data if everything was fine. */
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
                 uint8_t *encrypted, uint32_t length, uint8_t *plain)
{
    if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
        return -1;

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

    memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */

    if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
                        nonce, public_key, secret_key) == -1)
        return -1;

    /* if decryption is successful the first crypto_box_ZEROBYTES 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_ZEROBYTES; ++i) {
            check |= temp_plain[i] ^ 0;
    }
    if(check != 0)
        return -1;

    /* unpad the plain message */
    memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES);
    return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES;
}
Пример #8
0
Файл: t5.c Проект: tca/up
void main(int argc, char **argv) {
  char *pubkey_filename, *seckey_filename, *message_plain_filename, *message_enc_filename;
  
  unsigned char pk[crypto_box_PUBLICKEYBYTES];
  unsigned char sk[crypto_box_SECRETKEYBYTES];
  
  unsigned char *pubkey_data;
  size_t pubkey_data_size;

  unsigned char *seckey_data;
  size_t seckey_data_size;
  
  if(argc != 1 + 4) return;
  seckey_filename = argv[1];
  pubkey_filename = argv[2];
  message_enc_filename = argv[3];
  message_plain_filename = argv[4];
  printf("seckey:%s pubkey:%s ciphertext:%s -> decrypted:%s\n", seckey_filename, pubkey_filename, message_enc_filename, message_plain_filename);

  // read public key from a file
  if(read_from_file(seckey_filename, &seckey_data, &seckey_data_size)) return;  
  if(read_from_file(pubkey_filename, &pubkey_data, &pubkey_data_size)) return;

  // check that it is the right size
  if(pubkey_data_size != crypto_box_PUBLICKEYBYTES) {
    puts("Public key is wrong size!");
    return;
  }
  
  // check that it is the right size                                                           
  if(seckey_data_size != crypto_box_SECRETKEYBYTES) {
    puts("Public key is wrong size!");
    return;
  }

  unsigned char n[crypto_box_NONCEBYTES] = { 0 };

  unsigned char *ciphertext;
  size_t ciphertext_size;
  
  unsigned char *ciphertext_padded;

  if(read_from_file(message_enc_filename, &ciphertext, &ciphertext_size)) return;

  unsigned char *m;
  m = calloc(ciphertext_size, sizeof(char));

  // decrypt
  if(crypto_box_open(m, ciphertext, ciphertext_size, n, pubkey_data, seckey_data))
    puts("NO1");
  
  // write to message.enc
  
  if(write_to_file(message_plain_filename, m + crypto_box_BOXZEROBYTES, ciphertext_size))
    puts("NO2");
}
Пример #9
0
// Decrypt with the same key but from the message bytes (from bytes)
Message CryptoEngine::DecryptWithPublicKeyAndVerify(const std::vector<unsigned char> message_bytes, 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;
    }

    // Convert bytes to encrypted message
    EncryptedMessage encrypted_msg = EncryptedMessage::FromBytes(message_bytes);

    // decrypt
    std::string clear_text_signed_message = crypto_box_open(encrypted_msg.message(), encrypted_msg.nonce(),
                                                            ver_engine.public_key(), private_key_);

    // take the signature out
    std::string signature = clear_text_signed_message.substr(0,128);

    // verify the signature - if it fails it throws an exception
    std::string signed_message = crypto_sign_open(signature,ver_engine.signing_public_key());

    // remove the signing part and the hash
    std::string message_with_data = clear_text_signed_message.substr(128,clear_text_signed_message.size());

    // Convert to message
    Message message = Message::FromBytesString(message_with_data);

    return message;

}
Пример #10
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;
}
Пример #11
0
int main(int argc, char** argv) {
	if (argc != 2) {fprintf(stderr, "%s our_sk", argv[0]); return 1;}
    unsigned char sk[crypto_box_SECRETKEYBYTES];
    {
        FILE* f = fopen(argv[1], "r");
        if (f == NULL) {fprintf(stderr, "Cannot open our secret key file"); return 1;}
        int len = fread(sk, 1, crypto_box_SECRETKEYBYTES, f);
        fclose(f);
        if (len != crypto_box_SECRETKEYBYTES) {fprintf(stderr, "Bad secret key file"); return 1;}
    }

    uint8_t buf[1<<16];
    int len = fread(buf, 1, 1<<16, stdin);
    pb_istream_t stream = pb_istream_from_buffer(buf, len);
    Box box;
    if (!pb_decode(&stream, Box_fields, &box)) return 1;
    if (box.enc_algo != 1) return 1;

    uint8_t n[crypto_box_NONCEBYTES];
    for (int i=0; i<crypto_box_NONCEBYTES; ++i) n[i] = box.data.bytes[i];
    for (int i=0; i<crypto_box_BOXZEROBYTES; ++i) box.data.bytes[i] = 0;

    stream = pb_istream_from_buffer(box.sender.bytes, box.sender.size);
    PublicKey pk;
    if (!pb_decode(&stream, PublicKey_fields, &pk)) return 1;
    PublicKeyData pkd;
    stream = pb_istream_from_buffer(pk.publickey_msg.bytes,
            pk.publickey_msg.size);
    if (!pb_decode(&stream, PublicKeyData_fields, &pkd)) return 1;
    int decrypted = 0;
    for (int i=0; i<min(pkd.enc_keys_count,pkd.enc_algos_count); i++) {
        if (pkd.enc_keys[i].size == crypto_box_PUBLICKEYBYTES
                && pkd.sig_algos[i] == 1) {
            uint8_t* encpk = &pkd.enc_keys[i].bytes[0];
            if (crypto_box_open(buf,box.data.bytes+8,box.data.size-8,n,encpk,sk)
                 == 0) {
                decrypted = 1;
                break;
            }
        }
    }
    for (int i=0; i<crypto_box_SECRETKEYBYTES; i++) sk[i] = 0;


    if (decrypted) {
        int got = fwrite(buf+crypto_box_ZEROBYTES, 1, box.data.size-8-crypto_box_ZEROBYTES, stdout);
        assert(got == box.data.size-8-crypto_box_ZEROBYTES);
        got = fwrite(box.sender.bytes, 1, box.sender.size, stderr);
        assert(got == box.sender.size);
    }

    return !decrypted;
}
Пример #12
0
// decrypted_bytes = crypto_box_open(enc_bytes, nonce, pk_other, sk_self);
static int tweetnacl_crypto_box_open( lua_State* L )
{
  unsigned int emsg_len;
  const char* emsg = luaL_checklstring(L,1,&emsg_len);
  if(emsg_len < crypto_box_BOXZEROBYTES)
    return luaL_error( L, "len(emessage)=%d, too short", emsg_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 pmsg_len = emsg_len + crypto_box_BOXZEROBYTES;
  char *pmsg = (char *)c_malloc(pmsg_len);
  if(!pmsg)
    return luaL_error( L, "malloc failed, %d bytes", pmsg_len);

  int i;
  for(i=0;i<crypto_box_BOXZEROBYTES;i++) pmsg[i] = 0;
  for(;i<pmsg_len;i++) pmsg[i] = emsg[i-crypto_box_BOXZEROBYTES];

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

  int r;
  r = crypto_box_open(cmsg, pmsg, pmsg_len, nonce, pk_other, sk_self);
  if(r!=0)
  {
    c_free(cmsg);
    c_free(pmsg);
    return luaL_error( L, "decryption failed");
  } 
  lua_pushlstring(L, cmsg+crypto_box_ZEROBYTES, cmsg_len-crypto_box_ZEROBYTES);
  c_free(cmsg);
  c_free(pmsg);
  return 1;
}
Пример #13
0
String NaCl::public_decrypt(String enc_msg)
{
    try
    {
        std::string encrypted_message = from_ruby<std::string>(enc_msg);
        std::string message = crypto_box_open(encrypted_message, my_nonce, remote_pk, my_sk);
        return to_ruby<std::string>(message);
    }
    catch (int e)
    {
        return to_ruby<std::string>("");
    }
}
Пример #14
0
/**
 *  Deciphered data without making it a packet.
 *  @src: source of the data
 *  @len: length of the entire src array
 *  @pk: public key to decrypt the data from
 *  @sk: secret key to decrypt the data with
 *  @dest: destination for plaintext, must be as big as len - PREFIX
 */
int crypto_decipher_data (const void *src, int len, const unsigned char *pek,
                          const unsigned char *sek, void *dest)
{
        int report = 0;
        unsigned char buf[len - crypto_box_NONCEBYTES];
        memset(buf, 0, len - crypto_box_NONCEBYTES);

        report =  crypto_box_open(buf, (const unsigned char *)src +
                                  crypto_box_NONCEBYTES, len -
                                  crypto_box_NONCEBYTES, src, pek, sek);

        memcpy(dest, buf + crypto_box_ZEROBYTES, len - PREFIX);

        return report;
}
Пример #15
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;
}
Пример #16
0
error tunnel_openPacket(struct tunnel *t, uint8_t *packet, uint8_t *message, size_t packetSize, size_t *messageSize) {
  if (packetSize < sizeof t->tid) {
    return "Invalid packet";
  }

  uint64_t tidWithFlags       = readUint64LE(packet),
           tid                = tidWithFlags & ~TID_FLAGS;
  bool     hasPublickey       = tidWithFlags & PUBLICKEY_FLAG,
           hasPuzzle          = tidWithFlags & PUZZLE_FLAG,
           expectingPublickey = t->state == TUNNEL_STATE_SERVER_PRE_HANDSHAKE;
  size_t   headerSize         = sizeof tid +
                                sizeof t->nonce +
                                (hasPublickey ? sizeof t->remotePublickey : 0),
           contentSize        = packetSize - headerSize;

  if (headerSize > packetSize) {
    return "Invalid packet (1)";
  }

  if (hasPuzzle) {
    return "Puzzles not supported";
  }

  if (hasPublickey && !expectingPublickey) {
    return "Unexpected public key";
  } else if (!hasPublickey && expectingPublickey) {
    return "Expected public key";
  } else if (hasPublickey && expectingPublickey) {
    t->state = TUNNEL_STATE_NORMAL;
    memcpy(t->remotePublickey, &packet[sizeof tid + sizeof t->nonce], sizeof t->remotePublickey);
  }

  uint8_t crypted[crypto_box_BOXZEROBYTES + contentSize];

  memset(crypted, 0, crypto_box_BOXZEROBYTES);
  memcpy(&crypted[crypto_box_BOXZEROBYTES], &packet[headerSize], contentSize);

  if (crypto_box_open(crypted, crypted, sizeof crypted, &packet[sizeof tid], t->remotePublickey, t->localSecretkey) == -1) {
    return "Invalid packet (2)";
  }

  *messageSize = sizeof crypted - crypto_box_ZEROBYTES;

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

  return NULL;
}
Пример #17
0
PyObject *pycrypto_box_open(PyObject *self, PyObject *args, PyObject *kw){
  char *c, *n, *pk, *sk;
  Py_ssize_t csize=0, nsize=0, pksize=0, sksize=0;
  static const char *kwlist[] = {"c", "n", "pk", "sk", 0};
  unsigned int i;
  PyObject *ret;
  size_t clen;
  unsigned char *mpad;
  unsigned char *cpad;

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#s#:crypto_box_open", (char **) kwlist, &c, &csize, &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);

  clen = csize + crypto_box_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_box_BOXZEROBYTES;++i) cpad[i] = 0;
  for (i = crypto_box_BOXZEROBYTES;i < clen;++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES];

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

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

  ret = PyBytes_FromStringAndSize((char *)mpad + crypto_box_ZEROBYTES, clen - crypto_box_ZEROBYTES);
  PyMem_Free(mpad);
  PyMem_Free(cpad);
  return ret;}
Пример #18
0
int zmq::curve_server_t::process_hello (msg_t *msg_)
{
    if (msg_->size () != 200) {
        errno = EPROTO;
        return -1;
    }

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

    const uint8_t major = hello [6];
    const uint8_t minor = hello [7];

    if (major != 1 || minor != 0) {
        errno = EPROTO;
        return -1;
    }

    //  Save client's short-term public key (C')
    memcpy (cn_client, hello + 80, 32);

    uint8_t hello_nonce [crypto_box_NONCEBYTES];
    uint8_t hello_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t hello_box [crypto_box_BOXZEROBYTES + 80];

    memcpy (hello_nonce, "CurveZMQHELLO---", 16);
    memcpy (hello_nonce + 16, hello + 112, 8);

    memset (hello_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (hello_box + crypto_box_BOXZEROBYTES, hello + 120, 80);

    //  Open Box [64 * %x0](C'->S)
    int rc = crypto_box_open (hello_plaintext, hello_box,
                              sizeof hello_box,
                              hello_nonce, cn_client, secret_key);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    return rc;
}
Пример #19
0
int decrypt(UCHAR plain[], const UCHAR pk[], const UCHAR sk[], const UCHAR nonce[], const UCHAR encrypted[], int length)
{
	UCHAR temp_encrypted[BLEN + crypto_box_BOXZEROBYTES];
	UCHAR temp_plain[BLEN + crypto_box_BOXZEROBYTES];
	int rc;

	if (length + crypto_box_BOXZEROBYTES >= BLEN) {
		puts("fail greater max");
		return -2;
	}

	/*
	 * http://mob5.host.cs.st-andrews.ac.uk/html/d7/d46/a00002.html#gad0201c5b5acc5e1ad6bf23fb6cb82a1d
	 *
	 * Precondition:
	 *    first crypto_box_BOXZEROBYTES of ctxt be all 0.
	 *    the nonce must have size crypto_box_NONCEBYTES.
	 */

	memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES);
	memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length);

	rc = crypto_box_open(temp_plain, temp_encrypted, crypto_box_BOXZEROBYTES + length, nonce, pk, sk);

	if( rc != 0 ) {
		puts("crypto_box_open fails");
		return -1;
	}

	/*
	 * Postcondition:
	 *   first clen bytes of msg will contain the plaintext.
	 *   first crypto_box_ZEROBYTES of msg will be all 0.
	 */

	if( is_zero(temp_plain, crypto_box_ZEROBYTES) != 0 ) {
		puts("is_zero fails");
		return -3;
	}

	memcpy(plain, temp_plain + crypto_box_ZEROBYTES, crypto_box_BOXZEROBYTES + length);

	return crypto_box_BOXZEROBYTES + length - crypto_box_ZEROBYTES;
}
Пример #20
0
    static int process_welcome (const uint8_t *msg_data_,
                                size_t msg_size_,
                                const uint8_t *server_key_,
                                const uint8_t *cn_secret_,
                                uint8_t *cn_server_,
                                uint8_t *cn_cookie_,
                                uint8_t *cn_precom_)
    {
        if (msg_size_ != 168) {
            errno = EPROTO;
            return -1;
        }

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

        //  Open Box [S' + cookie](C'->S)
        memset (welcome_box, 0, crypto_box_BOXZEROBYTES);
        memcpy (welcome_box + crypto_box_BOXZEROBYTES, msg_data_ + 24, 144);

        memcpy (welcome_nonce, "WELCOME-", 8);
        memcpy (welcome_nonce + 8, msg_data_ + 8, 16);

        int rc =
          crypto_box_open (welcome_plaintext, welcome_box, sizeof welcome_box,
                           welcome_nonce, server_key_, cn_secret_);
        if (rc != 0) {
            errno = EPROTO;
            return -1;
        }

        memcpy (cn_server_, welcome_plaintext + crypto_box_ZEROBYTES, 32);
        memcpy (cn_cookie_, welcome_plaintext + crypto_box_ZEROBYTES + 32,
                16 + 80);

        //  Message independent precomputation
        rc = crypto_box_beforenm (cn_precom_, cn_server_, cn_secret_);
        zmq_assert (rc == 0);

        return 0;
    }
Пример #21
0
// Decrypt from the message bytes
Message CryptoEngine::DecryptWithPublicKey(const std::vector<unsigned char> message_bytes, 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;
    }

    // from bytes to encrypted message
    EncryptedMessage encrypted_msg = EncryptedMessage::FromBytes(message_bytes);

    // get the clear text, with the additional data prepended
    std::string clear_text_with_data(crypto_box_open(encrypted_msg.message(), encrypted_msg.nonce(), ver_engine.public_key(), private_key_));

    // extract the additional data and build the message
    Message message = Message::FromBytesString(clear_text_with_data);

    return message;

}
Пример #22
0
int zmq::curve_client_t::process_welcome (msg_t *msg_)
{
    if (msg_->size () != 168) {
        errno = EPROTO;
        return -1;
    }

    const uint8_t * welcome = static_cast <uint8_t *> (msg_->data ());
    if (memcmp (welcome, "\x07WELCOME", 8)) {
        errno = EPROTO;
        return -1;
    }

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

    //  Open Box [S' + cookie](C'->S)
    memset (welcome_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (welcome_box + crypto_box_BOXZEROBYTES, welcome + 24, 144);

    memcpy (welcome_nonce, "WELCOME-", 8);
    memcpy (welcome_nonce + 8, welcome + 8, 16);

    int rc = crypto_box_open (welcome_plaintext, welcome_box,
                              sizeof welcome_box,
                              welcome_nonce, server_key, cn_secret);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    memcpy (cn_server, welcome_plaintext + crypto_box_ZEROBYTES, 32);
    memcpy (cn_cookie, welcome_plaintext + crypto_box_ZEROBYTES + 32, 16 + 80);

    //  Message independent precomputation
    rc = crypto_box_beforenm (cn_precom, cn_server, cn_secret);
    zmq_assert (rc == 0);

    return 0;
}
Пример #23
0
int zmq::curve_client_t::process_welcome (
        const uint8_t *msg_data, size_t msg_size)
{
    if (msg_size != 168) {
        errno = EPROTO;
        return -1;
    }

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

    //  Open Box [S' + cookie](C'->S)
    memset (welcome_box, 0, crypto_box_BOXZEROBYTES);
    memcpy (welcome_box + crypto_box_BOXZEROBYTES, msg_data + 24, 144);

    memcpy (welcome_nonce, "WELCOME-", 8);
    memcpy (welcome_nonce + 8, msg_data + 8, 16);

    int rc = crypto_box_open (welcome_plaintext, welcome_box,
                              sizeof welcome_box,
                              welcome_nonce, server_key, cn_secret);
    if (rc != 0) {
        errno = EPROTO;
        return -1;
    }

    memcpy (cn_server, welcome_plaintext + crypto_box_ZEROBYTES, 32);
    memcpy (cn_cookie, welcome_plaintext + crypto_box_ZEROBYTES + 32, 16 + 80);

    //  Message independent precomputation
    rc = crypto_box_beforenm (cn_precom, cn_server, cn_secret);
    zmq_assert (rc == 0);

    state = send_initiate;

    return 0;
}
Пример #24
0
static ERL_NIF_TERM nacl_box_open_padded(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
{
  ErlNifBinary padded_ciphertext;
  ErlNifBinary nonce;
  ErlNifBinary pk;
  ErlNifBinary sk;
  ErlNifBinary result;

  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], &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_ciphertext.size < crypto_box_BOXZEROBYTES) return enif_make_badarg(env);

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

  if (crypto_box_open(result.data, padded_ciphertext.data, padded_ciphertext.size,
		      nonce.data, pk.data, sk.data)) {
    return nacl_error_tuple(env, "crypto_failed");
  }

  return enif_make_sub_binary(env,
			      enif_make_binary(env, &result),
			      crypto_box_ZEROBYTES,
			      padded_ciphertext.size - crypto_box_ZEROBYTES);
}
Пример #25
0
int validate_crypto_cookie_packet(unsigned char *buffer,
    UNUSED(uint64_t length))
{
  unsigned char *block;
  unsigned char *ciphertextpadded;
  unsigned char nonce[crypto_box_NONCEBYTES];
  uint64_t ciphertextlen;
  uint64_t blocklen;

  memcpy(nonce, "splonePK", 8);
  memcpy(nonce + 8, buffer + 8, 16);

  ciphertextlen = 160;
  blocklen = 144;

  block = MALLOC_ARRAY(ciphertextlen, unsigned char);
  ciphertextpadded = CALLOC(ciphertextlen, unsigned char);

  if (block == NULL || ciphertextpadded == NULL)
    return (-1);

  memcpy(ciphertextpadded + 16, buffer + 24, blocklen);

  if (crypto_box_open(block, ciphertextpadded, ciphertextlen, nonce,
      serverlongtermpk, clientshorttermsk)) {
    FREE(block);
    FREE(ciphertextpadded);
    return (-1);
  }

  memcpy(servershorttermpk, block + 32, 32);
  memcpy(cookie, block + 64, 96);

  FREE(block);
  FREE(ciphertextpadded);

  return (0);
}
Пример #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;
}
Пример #27
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);
}
Пример #28
0
static nif_term_t
salt_box_open(nif_heap_t *hp, int argc, const nif_term_t argv[])
{
	/* salt_box_open(Cipher_text, Nonce, Public_key, Secret_key) -> {ok, Plain_text} | forged_or_garbled. */
	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;
	nif_term_t 		tag;

	if (argc != 4)
		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], &pk))
		return (BADARG);

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

	/* Check constraints on size and zero prefixing. */
	if (ct.size < crypto_box_BOXZEROBYTES || ct.size > SALT_MAX_MESSAGE_SIZE)
		return (BADARG);
	if (memcmp((const void *)ct.data, &salt_box_boxzerobytes[0], crypto_box_BOXZEROBYTES) != 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 plain text. NB: Passing ENOMEM as BADARG. */
	if (! enif_alloc_binary(ct.size, &pt))
		return (BADARG);

	/* Perform the crypto, strip leading zeros and return rest if authentic. */
	if (crypto_box_open(pt.data, ct.data, ct.size, nc.data, pk.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_box_ZEROBYTES, pt.size - crypto_box_ZEROBYTES);
	tag = enif_make_atom(hp, "ok");

	return (enif_make_tuple2(hp, tag, sub));
}
Пример #29
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;
}
Пример #30
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);
}