Exemplo n.º 1
0
int crypto_stream(
        unsigned char *c,unsigned long long clen,
  const unsigned char *n,
  const unsigned char *k
)
{
  return crypto_stream_xor(c,0,clen,n,k);
}
Exemplo n.º 2
0
int crypto_stream(
                                  unsigned char *out,
                                  unsigned long long outlen,
                                  const unsigned char *n,
                                  const unsigned char *k
                                  )
{
    memset(out,0,outlen);
    return crypto_stream_xor(out,out,outlen,n,k);
}
Exemplo n.º 3
0
int crypto_stream(
          unsigned char *c,crypto_uint16 clen,
    const unsigned char *n,
    const unsigned char *k
    )
{
  crypto_uint16 i;
  for(i=0;i<clen;i++)
    c[i] = 0;
  return crypto_stream_xor(c,c,clen,n,k);
}
Exemplo n.º 4
0
int crypto_stream(
          unsigned char *c, unsigned long long l,
    const unsigned char *n,
    const unsigned char *k
) {

    long long i;

    for (i = 0; i < l; ++i) c[i] = 0;
    return crypto_stream_xor(c, c, l, n, k);
}
Exemplo n.º 5
0
QString ClientConfiguration::toBackup(QString const& password) const {
	QByteArray encryptionKey(BACKUP_ENCRYPTION_KEY_BYTES, 0x00);

	// Generate a Salt
	QByteArray salt(BACKUP_SALT_BYTES, 0x00);
	randombytes_buf(salt.data(), BACKUP_SALT_BYTES);

	// Convert the password into bytes
	QByteArray password8Bit = password.toUtf8();

	// Generate the encryption key for the Backup from the Salt and the Password
	PKCS5_PBKDF2_HMAC(reinterpret_cast<unsigned char*>(password8Bit.data()), password8Bit.size(), reinterpret_cast<unsigned char*>(salt.data()), BACKUP_SALT_BYTES, BACKUP_KEY_PBKDF_ITERATIONS, BACKUP_ENCRYPTION_KEY_BYTES, reinterpret_cast<unsigned char*>(encryptionKey.data()));

	QByteArray nonceBytes(crypto_stream_NONCEBYTES, 0x00);

	// The backup content
	QByteArray clientId(IdentityHelper::uint64ToIdentityString(getClientIdentity().getContactId()).toLatin1());
	if (clientId.size() != BACKUP_IDENTITY_BYTES) {
		throw InternalErrorException() << QString("Could not build backup - invalid client identity length (%1 vs. %2 Bytes).").arg(clientId.size()).arg(BACKUP_IDENTITY_BYTES).toStdString();
	}
	QByteArray clientSecKey(getClientLongTermKeyPair().getPrivateKey());
	if (clientSecKey.size() != PROTO_KEY_LENGTH_BYTES) {
		throw InternalErrorException() << QString("Could not build backup - invalid client secret key length (%1 vs. %2 Bytes).").arg(clientSecKey.size()).arg(PROTO_KEY_LENGTH_BYTES).toStdString();
	}

	QByteArray backup(salt);
	backup.append(clientId);
	backup.append(clientSecKey);

	// Compute Hash
	QByteArray controlHash(crypto_hash_sha256_BYTES, 0x00);
	crypto_hash_sha256(reinterpret_cast<unsigned char*>(controlHash.data()), reinterpret_cast<unsigned char*>(backup.data() + BACKUP_SALT_BYTES), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES);
	backup.append(controlHash.left(BACKUP_HASH_BYTES));

	if (backup.size() != (BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES)) {
		throw InternalErrorException() << QString("Could not build backup - invalid packet length (%1 vs. %2 Bytes).").arg(clientSecKey.size()).arg(BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES).toStdString();
	}

	// The Backup is build from SALT + IDENTITY + KEY + HASH
	crypto_stream_xor(reinterpret_cast<unsigned char*>(backup.data() + BACKUP_SALT_BYTES), reinterpret_cast<unsigned char*>(backup.data() + BACKUP_SALT_BYTES), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES, reinterpret_cast<unsigned char*>(nonceBytes.data()), reinterpret_cast<unsigned char*>(encryptionKey.data()));

	// Encode in Base32
	return Base32::encodeBase32Sequence(backup);
}
Exemplo n.º 6
0
i64 packet_encrypt(u8 *output, u8* key, u8 *data, i64 size) {
   u8 nonce[NONCE_BYTES];

   if (!output || !key || !data || size < IPV4_AND_UDP_HEADER_SIZE) {
      return -1;
   }

   randombytes(nonce, NONCE_BYTES);

   crypto_stream_xor(output + NONCE_BYTES + IPV4_AND_UDP_HEADER_SIZE,
                     data + IPV4_AND_UDP_HEADER_SIZE, size - IPV4_AND_UDP_HEADER_SIZE,
                     nonce, key);
   
   
   memcpy(output, data, IPV4_AND_UDP_HEADER_SIZE);
   memcpy(output + IPV4_AND_UDP_HEADER_SIZE, nonce, NONCE_BYTES);
   
   return size + NONCE_BYTES;
}
Exemplo n.º 7
0
i64 packet_decrypt(u8 *output, u8* key, u8 *data, i64 size) {
   u8 nonce[NONCE_BYTES];

   if (!output || !key || !data || size < (IPV4_AND_UDP_HEADER_SIZE + NONCE_BYTES)) {
      return -1;
   }

   memcpy(nonce, data + IPV4_AND_UDP_HEADER_SIZE, NONCE_BYTES);

   crypto_stream_xor(output + IPV4_AND_UDP_HEADER_SIZE, 
                     data + NONCE_BYTES + IPV4_AND_UDP_HEADER_SIZE,
                     size - IPV4_AND_UDP_HEADER_SIZE - NONCE_BYTES,
                     nonce, key);
   
   
   memcpy(output, data, IPV4_AND_UDP_HEADER_SIZE);

   return size - NONCE_BYTES;
}
Exemplo n.º 8
0
ClientConfiguration::BackupData ClientConfiguration::fromBackup(QString const& backup, QString const& password) {
	QByteArray decodedBase32 = Base32::decodeBase32Sequence(backup);
	if (decodedBase32.size() != BACKUP_DECODED_BYTES) {
		throw IllegalArgumentException() << "Invalid Backup: Size of decoded Backup String is incorrect (" << decodedBase32.size() << " Bytes instead of " << BACKUP_DECODED_BYTES << " Bytes).";
	}

	unsigned char encryptionKey[BACKUP_ENCRYPTION_KEY_BYTES];
	sodium_memzero(encryptionKey, BACKUP_ENCRYPTION_KEY_BYTES);

	// The pointer to the base32-decoded Backup
	unsigned char* decodedBase32Ptr = reinterpret_cast<unsigned char*>(decodedBase32.data());

	// The Salt used in the PBKDF2 Key Derivation process is embedded in the first 8 bytes of the Backup.
	QByteArray password8Bit = password.toUtf8();
	PKCS5_PBKDF2_HMAC(reinterpret_cast<unsigned char*>(password8Bit.data()), password8Bit.size(), decodedBase32Ptr, BACKUP_SALT_BYTES, BACKUP_KEY_PBKDF_ITERATIONS, BACKUP_ENCRYPTION_KEY_BYTES, encryptionKey);

	unsigned char nonceBytes[crypto_stream_NONCEBYTES];
	sodium_memzero(nonceBytes, crypto_stream_NONCEBYTES);

	crypto_stream_xor(&decodedBase32Ptr[BACKUP_SALT_BYTES], &decodedBase32Ptr[BACKUP_SALT_BYTES], BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES, nonceBytes, encryptionKey);

	// The last two bytes of the Backup contain the truncated SHA-256 Hash over the identity and its Private Key.
	unsigned char controlHash[crypto_hash_sha256_BYTES];
	sodium_memzero(controlHash, crypto_hash_sha256_BYTES);
	crypto_hash_sha256(controlHash, &(decodedBase32Ptr[BACKUP_SALT_BYTES]), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES);

	if (sodium_memcmp(&(decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES]), controlHash, BACKUP_HASH_BYTES) != 0) {
		throw IllegalArgumentException() << "Decryption of Backup failed: Invalid Control Hash (" << controlHash[0] << controlHash[1] << " vs. " << decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES] << decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + 1] << ").";
	}

	unsigned char derivedPublicKey[PROTO_KEY_LENGTH_BYTES];
	crypto_scalarmult_base(derivedPublicKey, &decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES]);
	KeyPair kp = KeyPair::fromArrays(derivedPublicKey, &decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES]);

	QString identityString(QByteArray(reinterpret_cast<char*>(&decodedBase32Ptr[BACKUP_SALT_BYTES]), BACKUP_IDENTITY_BYTES));
	if (!isValidIdentity(identityString)) {
		throw IllegalArgumentException() << "Invalid ClientConfiguration: Decryption of Backup failed: Not a valid Identity.";
	}

	return BackupData(ContactId(identityString.toUtf8()), kp);
}
Exemplo n.º 9
0
static nif_term_t
salt_stream_xor(nif_heap_t *hp, int argc, const nif_term_t argv[])
{
	/* salt_stream_xor(In_text, Nonce, Secret_key) -> Out_text. */
	nif_bin_t 		it;
	nif_bin_t 		nc;
	nif_bin_t 		sk;
	nif_bin_t 		ot;

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

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

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

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

	/* Check constraints on size. */
	if (it.size < 1 || it.size > SALT_MAX_MESSAGE_SIZE)
		return (BADARG);

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

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

	/* Allocate space for output byte stream. NB: Passing ENOMEM as BADARG. */
	if (! enif_alloc_binary(it.size, &ot))
		return (BADARG);

	(void)crypto_stream_xor(ot.data, it.data, it.size, nc.data, sk.data);
	return (enif_make_binary(hp, &ot));
}
Exemplo n.º 10
0
bool unit_test_crypto_stream(){
  // Global length
  uint64_t len = HACL_UNIT_TESTS_SIZE * sizeof(uint8_t);
  // Scratch buffers
  uint8_t hacl_cipher[HACL_UNIT_TESTS_SIZE], expected_cipher[HACL_UNIT_TESTS_SIZE];
  // Shared key
  uint8_t key[32], nonce[24];
  // Random plaintext
  uint8_t *plaintext = malloc(HACL_UNIT_TESTS_SIZE * sizeof (uint8_t));
  READ_RANDOM_BYTES(len, plaintext);
  // Test 1
  int a;
  bool pass = true;
  for (int i = 0; i < 1024; i++){
    tweet_crypto_stream(expected_cipher, i, nonce, key);
    crypto_stream(hacl_cipher, i, nonce, key);
    a = memcmp(hacl_cipher, expected_cipher, i * sizeof(uint8_t));
    if (a != 0){
      pass = false;
      printf("SECRETBOX failed on input of size %d\n.", i);
      break;
    }
  }
  if (!pass) return pass;
  // Test 2
  tweet_crypto_stream_xor(expected_cipher, plaintext, HACL_UNIT_TESTS_SIZE, nonce, key);
  crypto_stream_xor(hacl_cipher, plaintext, HACL_UNIT_TESTS_SIZE, nonce, key);
  a = memcmp(hacl_cipher, expected_cipher, HACL_UNIT_TESTS_SIZE * sizeof(uint8_t));
  if (a != 0){
    pass = false;
    printf("SECRETBOX failed on input of size %d\n.", HACL_UNIT_TESTS_SIZE);
  }

  free(plaintext);

  return pass;
}
Exemplo n.º 11
0
const char *checksum_compute(void)
{
  long long i;
  long long j;

  for (i = 0;i < CHECKSUM_BYTES;++i) {
    long long mlen = i;
    long long clen = i;
    long long slen = i;
    long long klen = crypto_stream_KEYBYTES;
    long long nlen = crypto_stream_NONCEBYTES;
    for (j = -16;j < 0;++j) m[j] = rand();
    for (j = -16;j < 0;++j) c[j] = rand();
    for (j = -16;j < 0;++j) s[j] = rand();
    for (j = -16;j < 0;++j) n[j] = rand();
    for (j = -16;j < 0;++j) k[j] = rand();
    for (j = mlen;j < mlen + 16;++j) m[j] = rand();
    for (j = clen;j < clen + 16;++j) c[j] = rand();
    for (j = slen;j < slen + 16;++j) s[j] = rand();
    for (j = nlen;j < nlen + 16;++j) n[j] = rand();
    for (j = klen;j < klen + 16;++j) k[j] = rand();
    for (j = -16;j < mlen + 16;++j) m2[j] = m[j];
    for (j = -16;j < clen + 16;++j) c2[j] = c[j];
    for (j = -16;j < slen + 16;++j) s2[j] = s[j];
    for (j = -16;j < nlen + 16;++j) n2[j] = n[j];
    for (j = -16;j < klen + 16;++j) k2[j] = k[j];

    crypto_stream_xor(c,m,mlen,n,k);

    for (j = -16;j < mlen + 16;++j) if (m[j] != m2[j]) return "crypto_stream_xor overwrites m";
    for (j = -16;j < slen + 16;++j) if (s[j] != s2[j]) return "crypto_stream_xor overwrites s";
    for (j = -16;j < nlen + 16;++j) if (n[j] != n2[j]) return "crypto_stream_xor overwrites n";
    for (j = -16;j < klen + 16;++j) if (k[j] != k2[j]) return "crypto_stream_xor overwrites k";
    for (j = -16;j < 0;++j) if (c[j] != c2[j]) return "crypto_stream_xor writes before output";
    for (j = clen;j < clen + 16;++j) if (c[j] != c2[j]) return "crypto_stream_xor writes after output";

    for (j = -16;j < clen + 16;++j) c2[j] = c[j];

    crypto_stream(s,slen,n,k);

    for (j = -16;j < mlen + 16;++j) if (m[j] != m2[j]) return "crypto_stream overwrites m";
    for (j = -16;j < clen + 16;++j) if (c[j] != c2[j]) return "crypto_stream overwrites c";
    for (j = -16;j < nlen + 16;++j) if (n[j] != n2[j]) return "crypto_stream overwrites n";
    for (j = -16;j < klen + 16;++j) if (k[j] != k2[j]) return "crypto_stream overwrites k";
    for (j = -16;j < 0;++j) if (s[j] != s2[j]) return "crypto_stream writes before output";
    for (j = slen;j < slen + 16;++j) if (s[j] != s2[j]) return "crypto_stream writes after output";

    for (j = 0;j < mlen;++j)
      if ((s[j] ^ m[j]) != c[j]) return "crypto_stream_xor does not match crypto_stream";

    for (j = 0;j < clen;++j) k[j % klen] ^= c[j];
    crypto_stream_xor(m,c,clen,n,k);
    crypto_stream(s,slen,n,k);
    for (j = 0;j < mlen;++j)
      if ((s[j] ^ m[j]) != c[j]) return "crypto_stream_xor does not match crypto_stream";
    for (j = 0;j < mlen;++j) n[j % nlen] ^= m[j];
    m[mlen] = 0;
  }

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

  return 0;
}
Exemplo n.º 12
0
void doit(void)
{
  crypto_stream_xor(c,m,TUNE_BYTES,n,k);
}
Exemplo n.º 13
0
int crypto_stream(unsigned char *out, unsigned long long outlen,
		  const unsigned char *n,const unsigned char *k)
{
	return crypto_stream_xor(out, NULL, outlen, n, k);
}
Exemplo n.º 14
0
int _tmain(int argc, _TCHAR* argv[])
{
	if (sodium_init() == -1)
	{
		_tprintf(_T("Could not initialize cryptography subsystem!\n"));
		return 1;
	}

	if (argc < 3)
	{
		_tprintf(_T("usage: cryptfile [-d] [-o <outfile>] <password> <file>\n"));
		_tprintf(_T("where\n"));
		_tprintf(_T("\t-o <outfile> filename for non inplace encryption\n"));
		_tprintf(_T("\t-d decrypt file\n"));
		return 1;
	}

	bool bDecrypt = false;
	bool bUseTempFile = true;
	TCHAR szSourceFile[MAX_PATH];
	TCHAR szTargetFile[MAX_PATH];

	for (int i = 1; i < argc - 2; i++)
	{
		if (_tcscmp(_T("-d"), argv[i]) == 0)
			bDecrypt = true;
		if (_tcscmp(_T("-o"), argv[i]) == 0)
		{
			_tcscpy_s(szTargetFile, MAX_PATH, argv[i + 1]);
			bUseTempFile = false;
		}
	}

	if (bUseTempFile)
	{
		_tcscpy_s(szTargetFile, MAX_PATH, argv[argc - 1]);
		_tcscpy_s(szSourceFile, MAX_PATH, argv[argc - 1]);
		_tcscat_s(szSourceFile, MAX_PATH, _T(".tmp"));
		if (!::MoveFile(szTargetFile, szSourceFile))
		{
			_tprintf(_T("File access denied: %s\n"), szTargetFile);
			return 1;
		}
	}
	else
	{
		_tcscpy_s(szSourceFile, MAX_PATH, argv[argc - 1]);
	}

	unsigned char pKey[crypto_stream_KEYBYTES];
	unsigned char pNonce[crypto_stream_NONCEBYTES];
	unsigned char pSalt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];

	// generate simple password salt (unique for this application)
	for (size_t i = 2; i < crypto_pwhash_scryptsalsa208sha256_SALTBYTES; i++)
		pSalt[i] = (i * 2) & 0xFF;
	pSalt[0] = 'C';
	pSalt[1] = 'S';

	// generate key (derived from password)
	crypto_pwhash_scryptsalsa208sha256(
		pKey, sizeof(pKey),
		reinterpret_cast<const char*>(argv[argc - 2]), _tcslen(argv[argc - 2]) * sizeof(TCHAR),
		pSalt,
		crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
		crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);

	HANDLE hSourceFile = ::CreateFile(szSourceFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hSourceFile == INVALID_HANDLE_VALUE)
	{
		_tprintf(_T("File access denied: %s\n"), szSourceFile);
		return 1;
	}

	HANDLE hTargetFile = ::CreateFile(szTargetFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hTargetFile == INVALID_HANDLE_VALUE)
	{
		::CloseHandle(hSourceFile);
		_tprintf(_T("File access denied: %s\n"), szTargetFile);
		return 1;
	}

	BYTE *pData = new BYTE[CHUNK_SIZE];
	DWORD dwBytesRead = 0;
	DWORD dwBytesWritten = 0;

	if (bDecrypt)
	{
		// load file unique number for decryption
		::ReadFile(hSourceFile, pNonce, sizeof(pNonce), &dwBytesRead, NULL);
	}
	else
	{
		// generate number to used once (unique for each file)
		randombytes_buf(pNonce, sizeof(pNonce));
		::WriteFile(hTargetFile, pNonce, sizeof(pNonce), &dwBytesWritten, NULL);
	}
	
	while (::ReadFile(hSourceFile, pData, CHUNK_SIZE, &dwBytesRead, NULL) && dwBytesRead > 0)
	{
		crypto_stream_xor(pData, pData, dwBytesRead, pNonce, pKey); // inplace
		::WriteFile(hTargetFile, pData, dwBytesRead, &dwBytesWritten, NULL);
	}

	delete[] pData;

	::CloseHandle(hTargetFile);
	::CloseHandle(hSourceFile);

	if (bUseTempFile)
		::DeleteFile(szSourceFile);

#ifdef _DEBUG
	_tsystem(_T("pause"));
#endif 
	return 0;
}