int
crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
                                              const char * const passwd,
                                              unsigned long long passwdlen)
{
    char            wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES];
    escrypt_local_t escrypt_local;
    int             ret = -1;

    if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) !=
        &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) {
        return -1;
    }
    if (escrypt_init_local(&escrypt_local) != 0) {
        return -1; /* LCOV_EXCL_LINE */
    }
    memset(wanted, 0, sizeof wanted);
    if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
                  (const uint8_t *) str, (uint8_t *) wanted,
                  sizeof wanted) == NULL) {
        escrypt_free_local(&escrypt_local);
        return -1;
    }
    escrypt_free_local(&escrypt_local);
    ret = sodium_memcmp(wanted, str, sizeof wanted);
    sodium_memzero(wanted, sizeof wanted);

    return ret;
}
int crypto_auth_hmacsha256_verify(const unsigned char *h,const unsigned char *in,unsigned long long inlen,const unsigned char *k)
{
  unsigned char correct[32];
  crypto_auth_hmacsha256(correct,in,inlen,k);
  return crypto_verify_32(h,correct) | (-(h == correct)) |
         sodium_memcmp(correct,h,32);
}
int crypto_auth_hmacsha512_verify(const unsigned char *h, const unsigned char *in,
                                  unsigned long long inlen, const unsigned char *k)
{
    unsigned char correct[64];
    crypto_auth_hmacsha512(correct,in,inlen,k);
    return crypto_verify_64(h,correct) | (-(h == correct)) |
           sodium_memcmp(correct,h,64);
}
Exemple #4
0
int dfcrypt_decrypt(
    const dfcrypt_state_t *state,
    const unsigned char *ctxt,
    size_t ctxt_len_bytes,
    const unsigned char *message_number,
    unsigned char *ptxt_out
)
{
    const unsigned char *salt = ctxt;
    const unsigned char *nonce = ctxt + DFCRYPT_INTERNAL_SALT_BYTES;
    const unsigned char *encrypted = nonce + crypto_stream_chacha20_NONCEBYTES;
    const unsigned char *ciphertext_mac = ctxt + ctxt_len_bytes - DFCRYPT_INTERNAL_MAC_BYTES;

    unsigned char keys[DFCRYPT_INTERNAL_AKEY_BYTES + DFCRYPT_INTERNAL_EKEY_BYTES];
    const unsigned char *akey = keys;
    const unsigned char *ekey = keys + DFCRYPT_INTERNAL_AKEY_BYTES;

    unsigned char computed_mac[DFCRYPT_INTERNAL_MAC_BYTES];

    /* Derive the authentication and encryption keys. */
    assert(sizeof(keys) == 64);
    crypto_generichash_blake2b_salt_personal(
        keys,                   /* output */
        sizeof(keys),           /* output length */
        state->appseed,         /* input */
        state->appseed_length,  /* input length */
        state->key,             /* key */
        DFCRYPT_KEY_BYTES,      /* key length */
        salt,                   /* salt */
        message_number          /* personalization (can be NULL) */
    );

    /* Re-compute the MAC. */
    crypto_generichash_blake2b(
        computed_mac,                                   /* output */
        DFCRYPT_INTERNAL_MAC_BYTES,                     /* output length */
        ctxt,                                           /* input */
        ctxt_len_bytes - DFCRYPT_INTERNAL_MAC_BYTES,    /* input length */
        akey,                                           /* key */
        DFCRYPT_INTERNAL_AKEY_BYTES                     /* key length */
    );

    /* Check the MAC. */
    if (sodium_memcmp(computed_mac, ciphertext_mac, DFCRYPT_INTERNAL_MAC_BYTES) != 0) {
        return -1;
    }

    /* Decrypt the plaintext. */
    crypto_stream_chacha20_xor(
        ptxt_out,                                   /* output */
        encrypted,                                  /* input */
        ctxt_len_bytes - DFCRYPT_CIPHERTEXT_GROWTH, /* input length */
        nonce,                                      /* nonce */
        ekey                                        /* key */
    );

    return 0;
}
int main(void)
{
  unsigned char buf1[1000];
  unsigned char buf2[1000];

  randombytes(buf1, sizeof buf1);
  memcpy(buf2, buf1, sizeof buf2);
  printf ("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  sodium_memzero(buf1, 0U);
  printf ("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  sodium_memzero(buf1, sizeof buf1 / 2);
  printf ("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  printf ("%d\n", sodium_memcmp(buf1, buf2, 0U));
  sodium_memzero(buf2, sizeof buf2 / 2);
  printf ("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));

  return 0;
}
int main(void) {
	sodium_init();

	//create random key
	unsigned char key[crypto_secretbox_KEYBYTES];
	randombytes_buf(key, crypto_secretbox_KEYBYTES);

	//print key
	printf("Key (%i Bytes):\n", crypto_secretbox_KEYBYTES);
	print_hex(key, crypto_secretbox_KEYBYTES, 30);
	putchar('\n');


	//encrypted message
	unsigned char ciphertext[500]; //TODO don't use fixed size buffer here

	size_t ciphertext_length = 0;
	int status;
	status = encrypt(ciphertext, &ciphertext_length, key);
	if (status != 0) {
		fprintf(stderr, "ERROR: Failed to encrypt message. (%i)\n", status);
		return status;
	}

	//print the ciphertext
	printf("Ciphertext (packet, %zu Bytes):\n", ciphertext_length);
	print_hex(ciphertext, ciphertext_length, 30);
	putchar('\n');

	puts("NOW DECRYPT -------------------------------------------------------------------\n");

	unsigned char header[ciphertext_length];

	size_t header_length = 0;

	status = extract_header_without_verifying(
			header,
			&header_length,
			ciphertext,
			ciphertext_length);
	if (status != 0) {
		fprintf(stderr, "ERROR: Failed to extract header from packet. (%i)\n", status);
		return status;
	}

	//print header
	printf("Received header (%zu Bytes):\n%s\n\n", header_length, header);

	//check header
	if (sodium_memcmp(header, HEADER, sizeof(HEADER)) != 0) {
		fprintf(stderr, "ERROR: Headers aren't the same!\n");
		return -1;
	}

	return EXIT_SUCCESS;
}
Exemple #7
0
int main(void)
{
  unsigned char buf1[1000];
  unsigned char buf2[1000];
  char          buf3[33];

  randombytes(buf1, sizeof buf1);
  memcpy(buf2, buf1, sizeof buf2);
  printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  sodium_memzero(buf1, 0U);
  printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  sodium_memzero(buf1, sizeof buf1 / 2);
  printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  printf("%d\n", sodium_memcmp(buf1, buf2, 0U));
  sodium_memzero(buf2, sizeof buf2 / 2);
  printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
  printf("%s\n", sodium_bin2hex(buf3, 33U,
                                (const unsigned char *)
                                "0123456789ABCDEF", 16U));
  return 0;
}
Exemple #8
0
/*
 * Helper function that checks if a buffer is <none>
 * (filled with zeroes), and does so without introducing
 * side channels, especially timing side channels.
 */
bool is_none(
		const unsigned char * const buffer,
		const size_t length) {
	//TODO: Find better implementation that
	//doesn't create an additional array. I don't
	//do that currently because I haven't enough
	//confidence that I'm not introducing any side
	//channels.

	//fill a buffer with zeroes
	unsigned char none[length];
	sodium_memzero(none, sizeof(none));

	return 0 == sodium_memcmp(none, buffer, sizeof(none));

}
Exemple #9
0
int
crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m,
                            unsigned long long mlen, const unsigned char *pk)
{
    crypto_hash_sha512_state hs;
    unsigned char h[64];
    unsigned char rcheck[32];
    unsigned int  i;
    unsigned char d = 0;
    ge_p3 A;
    ge_p2 R;

#ifdef ED25519_PREVENT_MALLEABILITY
    if (crypto_sign_check_S_lt_l(sig + 32) != 0) {
        return -1;
    }
#else
    if (sig[63] & 224) {
        return -1;
    }
#endif
    if (ge_frombytes_negate_vartime(&A, pk) != 0) {
        return -1;
    }
    for (i = 0; i < 32; ++i) {
        d |= pk[i];
    }
    if (d == 0) {
        return -1;
    }
    crypto_hash_sha512_init(&hs);
    crypto_hash_sha512_update(&hs, sig, 32);
    crypto_hash_sha512_update(&hs, pk, 32);
    crypto_hash_sha512_update(&hs, m, mlen);
    crypto_hash_sha512_final(&hs, h);
    sc_reduce(h);

    ge_double_scalarmult_vartime(&R, h, &A, sig + 32);
    ge_tobytes(rcheck, &R);

    return crypto_verify_32(rcheck, sig) | (-(rcheck - sig == 0)) |
           sodium_memcmp(sig, rcheck, 32);
}
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);
}
int main(void) {
	sodium_init();

	int status;

	//create Alice's keypair
	unsigned char alice_public_key[crypto_box_PUBLICKEYBYTES];
	unsigned char alice_private_key[crypto_box_SECRETKEYBYTES];
	status = generate_and_print_keypair(
			alice_public_key,
			alice_private_key,
			"Alice",
			"");
	if (status != 0) {
		sodium_memzero(alice_private_key, crypto_box_SECRETKEYBYTES);
		return status;
	}

	//create Bob's keypair
	unsigned char bob_public_key[crypto_box_PUBLICKEYBYTES];
	unsigned char bob_private_key[crypto_box_SECRETKEYBYTES];
	status = generate_and_print_keypair(
			bob_public_key,
			bob_private_key,
			"Bob",
			"");
	if (status != 0) {
		sodium_memzero(alice_private_key, crypto_box_SECRETKEYBYTES);
		sodium_memzero(bob_private_key, crypto_box_SECRETKEYBYTES);
		return status;
	}

	//Diffie Hellman on Alice's side
	unsigned char alice_shared_secret[crypto_generichash_BYTES];
	status = diffie_hellman(
			alice_shared_secret,
			alice_private_key,
			alice_public_key,
			bob_public_key,
			true);
	sodium_memzero(alice_private_key, crypto_box_SECRETKEYBYTES);
	if (status != 0) {
		fprintf(stderr, "ERROR: Diffie Hellman with Alice's private key failed. (%i)\n", status);
		sodium_memzero(bob_private_key, crypto_box_SECRETKEYBYTES);
		sodium_memzero(alice_shared_secret, crypto_generichash_BYTES);
		return status;
	}

	//print Alice's shared secret
	printf("Alice's shared secret ECDH(A_priv, B_pub) (%i Bytes):\n", crypto_generichash_BYTES);
	print_hex(alice_shared_secret, crypto_generichash_BYTES, 30);
	putchar('\n');

	//Diffie Hellman on Bob's side
	unsigned char bob_shared_secret[crypto_generichash_BYTES];
	status = diffie_hellman(
			bob_shared_secret,
			bob_private_key,
			bob_public_key,
			alice_public_key,
			false);
	sodium_memzero(bob_private_key, crypto_box_SECRETKEYBYTES);
	if (status != 0) {
		fprintf(stderr, "ERROR: Diffie Hellman with Bob's private key failed. (%i)\n", status);
		sodium_memzero(alice_shared_secret, crypto_generichash_BYTES);
		sodium_memzero(bob_shared_secret, crypto_generichash_BYTES);
		return status;
	}

	//print Bob's shared secret
	printf("Bob's shared secret ECDH(B_priv, A_pub) (%i Bytes):\n", crypto_generichash_BYTES);
	print_hex(bob_shared_secret, crypto_generichash_BYTES, 30);
	putchar('\n');

	//compare both shared secrets
	status = sodium_memcmp(alice_shared_secret, bob_shared_secret, crypto_generichash_BYTES);
	sodium_memzero(alice_shared_secret, crypto_generichash_BYTES);
	sodium_memzero(bob_shared_secret, crypto_generichash_BYTES);
	if (status != 0) {
		fprintf(stderr, "ERROR: Diffie Hellman didn't produce the same shared secret. (%i)\n", status);
		return status;
	}

	printf("Both shared secrets match!\n");
	return EXIT_SUCCESS;
}
Exemple #12
0
int
macaroon_memcmp(const void* data1, const void* data2, size_t data_sz)
{
    return sodium_memcmp(data1, data2, data_sz);
}
Exemple #13
0
int main(void)
{
    unsigned char  buf1[1000];
    unsigned char  buf2[1000];
    char           buf3[33];
    unsigned char  buf4[4];
    unsigned char  nonce[24];
    char           nonce_hex[49];
    const char    *hex;
    const char    *hex_end;
    size_t         bin_len;
    int            i;

    randombytes_buf(buf1, sizeof buf1);
    memcpy(buf2, buf1, sizeof buf2);
    printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
    sodium_memzero(buf1, 0U);
    printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
    sodium_memzero(buf1, sizeof buf1 / 2);
    printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
    printf("%d\n", sodium_memcmp(buf1, buf2, 0U));
    sodium_memzero(buf2, sizeof buf2 / 2);
    printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1));
    printf("%s\n",
           sodium_bin2hex(buf3, 33U, (const unsigned char *)"0123456789ABCDEF",
                          16U));
    hex = "Cafe : 6942";
    sodium_hex2bin(buf4, sizeof buf4, hex, strlen(hex), ": ", &bin_len, &hex_end);
    printf("%lu:%02x%02x%02x%02x\n", (unsigned long)bin_len, buf4[0], buf4[1],
           buf4[2], buf4[3]);
    printf("dt1: %ld\n", (long) (hex_end - hex));

    hex = "Cafe : 6942";
    sodium_hex2bin(buf4, sizeof buf4, hex, strlen(hex), ": ", &bin_len, NULL);
    printf("%lu:%02x%02x%02x%02x\n", (unsigned long)bin_len, buf4[2], buf4[3],
           buf4[2], buf4[3]);

    hex = "deadbeef";
    if (sodium_hex2bin(buf1, 1U, hex, 8U, NULL, &bin_len, &hex_end) != -1) {
        printf("sodium_hex2bin() overflow not detected\n");
    }
    printf("dt2: %ld\n", (long) (hex_end - hex));

    hex = "de:ad:be:eff";
    if (sodium_hex2bin(buf1, 4U, hex, 12U, ":", &bin_len, &hex_end) != -1) {
        printf("sodium_hex2bin() with an odd input length and a short output buffer\n");
    }
    printf("dt3: %ld\n", (long) (hex_end - hex));

    hex = "de:ad:be:eff";
    if (sodium_hex2bin(buf1, sizeof buf1, hex, 12U, ":", &bin_len, &hex_end) != 0) {
        printf("sodium_hex2bin() with an odd input length\n");
    }
    printf("dt4: %ld\n", (long) (hex_end - hex));

    hex = "de:ad:be:eff";
    if (sodium_hex2bin(buf1, sizeof buf1, hex, 13U, ":", &bin_len, &hex_end) != 0) {
        printf("sodium_hex2bin() with an odd input length\n");
    }
    printf("dt5: %ld\n", (long) (hex_end - hex));

    memset(nonce, 0, sizeof nonce);
    sodium_increment(nonce, sizeof nonce);
    printf("%s\n", sodium_bin2hex(nonce_hex, sizeof nonce_hex,
                                  nonce, sizeof nonce));
    memset(nonce, 255, sizeof nonce);
    sodium_increment(nonce, sizeof nonce);
    printf("%s\n", sodium_bin2hex(nonce_hex, sizeof nonce_hex,
                                  nonce, sizeof nonce));
    nonce[1] = 1U;
    sodium_increment(nonce, sizeof nonce);
    printf("%s\n", sodium_bin2hex(nonce_hex, sizeof nonce_hex,
                                  nonce, sizeof nonce));
    nonce[1] = 0U;
    sodium_increment(nonce, sizeof nonce);
    printf("%s\n", sodium_bin2hex(nonce_hex, sizeof nonce_hex,
                                  nonce, sizeof nonce));
    nonce[0] = 255U;
    nonce[2] = 255U;
    sodium_increment(nonce, sizeof nonce);
    printf("%s\n", sodium_bin2hex(nonce_hex, sizeof nonce_hex,
                                  nonce, sizeof nonce));
    for (i = 0; i < 1000; i++) {
        bin_len = (size_t) randombytes_uniform(sizeof buf1);
        randombytes_buf(buf1, bin_len);
        randombytes_buf(buf2, bin_len);
        if (memcmp(buf1, buf2, bin_len) *
            sodium_compare(buf1, buf2, bin_len) < 0) {
            printf("sodium_compare() failure with length=%u\n",
                   (unsigned int) bin_len);
        }
        memcpy(buf1, buf2, bin_len);
        if (sodium_compare(buf1, buf2, bin_len)) {
            printf("sodium_compare() equality failure with length=%u\n",
                   (unsigned int) bin_len);
        }
    }
    return 0;
}
Exemple #14
0
int main(void) {
	sodium_init();

	//create ephemeral key
	unsigned char our_public_ephemeral_key[crypto_box_PUBLICKEYBYTES];
	randombytes_buf(our_public_ephemeral_key, sizeof(our_public_ephemeral_key));
	printf("Our public ephemeral key (%zi Bytes):\n", sizeof(our_public_ephemeral_key));
	print_hex(our_public_ephemeral_key, sizeof(our_public_ephemeral_key), 30);

	//message numbers
	uint32_t message_number = 2;
	uint32_t previous_message_number = 10;
	printf("Message number: %u\n", message_number);
	printf("Previous message number: %u\n", previous_message_number);
	putchar('\n');

	//create the header
	unsigned char header[crypto_box_PUBLICKEYBYTES + 8];
	header_construct(
			header,
			our_public_ephemeral_key,
			message_number,
			previous_message_number);

	//print the header
	printf("Header (%zi Bytes):\n", sizeof(header));
	print_hex(header, sizeof(header), 30);
	putchar('\n');

	//get data back out of the header again
	unsigned char extracted_public_ephemeral_key[crypto_box_PUBLICKEYBYTES];
	uint32_t extracted_message_number;
	uint32_t extracted_previous_message_number;
	header_extract(
			header,
			extracted_public_ephemeral_key,
			&extracted_message_number,
			&extracted_previous_message_number);

	printf("Extracted public ephemeral key (%zi Bytes):\n", sizeof(extracted_public_ephemeral_key));
	print_hex(extracted_public_ephemeral_key, sizeof(extracted_public_ephemeral_key), 30);
	printf("Extracted message number: %u\n", extracted_message_number);
	printf("Extracted previous message number: %u\n", extracted_previous_message_number);
	putchar('\n');

	//compare them
	if (sodium_memcmp(our_public_ephemeral_key, extracted_public_ephemeral_key, sizeof(our_public_ephemeral_key)) != 0) {
		fprintf(stderr, "ERROR: Public ephemeral keys don't match.\n");
		return EXIT_FAILURE;
	}
	printf("Public ephemeral keys match.\n");

	if (message_number != extracted_message_number) {
		fprintf(stderr, "ERROR: Message numbers don't match.\n");
		return EXIT_FAILURE;
	}
	printf("Message numbers match.\n");

	if (previous_message_number != extracted_previous_message_number) {
		fprintf(stderr, "ERROR: Message numbers don't match.\n");
		return EXIT_FAILURE;
	}
	printf("Previous message numbers match.\n");

	return EXIT_SUCCESS;
}
int main(void) {
	sodium_init();

	int status;

	//create Alice's identity keypair
	unsigned char alice_public_identity[crypto_box_PUBLICKEYBYTES];
	unsigned char alice_private_identity[crypto_box_SECRETKEYBYTES];
	status = generate_and_print_keypair(
			alice_public_identity,
			alice_private_identity,
			"Alice",
			"identity");
	if (status != 0) {
		sodium_memzero(alice_private_identity, sizeof(alice_private_identity));
		return status;
	}

	//create Alice's ephemeral keypair
	unsigned char alice_public_ephemeral[crypto_box_PUBLICKEYBYTES];
	unsigned char alice_private_ephemeral[crypto_box_SECRETKEYBYTES];
	status = generate_and_print_keypair(
			alice_public_ephemeral,
			alice_private_ephemeral,
			"Alice",
			"ephemeral");
	if (status != 0) {
		sodium_memzero(alice_private_identity, sizeof(alice_private_identity));
		sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral));
		return status;
	}

	//create Bob's identity keypair
	unsigned char bob_public_identity[crypto_box_PUBLICKEYBYTES];
	unsigned char bob_private_identity[crypto_box_SECRETKEYBYTES];
	status = generate_and_print_keypair(
			bob_public_identity,
			bob_private_identity,
			"Bob",
			"identity");
	if (status != 0) {
		sodium_memzero(alice_private_identity, sizeof(alice_private_identity));
		sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral));
		sodium_memzero(bob_private_identity, sizeof(bob_private_identity));
		return status;
	}

	//create Bob's ephemeral keypair
	unsigned char bob_public_ephemeral[crypto_box_PUBLICKEYBYTES];
	unsigned char bob_private_ephemeral[crypto_box_SECRETKEYBYTES];
	status = generate_and_print_keypair(
			bob_public_ephemeral,
			bob_private_ephemeral,
			"Bob",
			"ephemeral");
	if (status != 0) {
		sodium_memzero(alice_private_identity, sizeof(alice_private_identity));
		sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral));
		sodium_memzero(bob_private_identity, sizeof(bob_private_identity));
		sodium_memzero(bob_private_ephemeral, sizeof(bob_private_ephemeral));
		return status;
	}

	//derive Alice's initial root and chain key
	unsigned char alice_root_key[crypto_secretbox_KEYBYTES];
	unsigned char alice_send_chain_key[crypto_secretbox_KEYBYTES];
	unsigned char alice_receive_chain_key[crypto_secretbox_KEYBYTES];
	unsigned char alice_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	unsigned char alice_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	unsigned char alice_next_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	unsigned char alice_next_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	status = derive_initial_root_chain_and_header_keys(
			alice_root_key,
			alice_send_chain_key,
			alice_receive_chain_key,
			alice_send_header_key,
			alice_receive_header_key,
			alice_next_send_header_key,
			alice_next_receive_header_key,
			alice_private_identity,
			alice_public_identity,
			bob_public_identity,
			alice_private_ephemeral,
			alice_public_ephemeral,
			bob_public_ephemeral,
			true);
	sodium_memzero(alice_private_identity, sizeof(alice_private_identity));
	sodium_memzero(alice_private_ephemeral, sizeof(alice_private_ephemeral));
	if (status != 0) {
		fprintf(stderr, "ERROR: Failed to derive Alice's initial root and chain key. (%i)\n", status);
		sodium_memzero(alice_root_key, sizeof(alice_root_key));
		sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key));
		sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key));
		sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));

		sodium_memzero(bob_private_identity, sizeof(bob_private_identity));
		sodium_memzero(bob_private_ephemeral, sizeof(bob_private_ephemeral));

		return status;
	}

	//print Alice's initial root and chain key
	printf("Alice's initial root key (%zi Bytes):\n", sizeof(alice_root_key));
	print_hex(alice_root_key, sizeof(alice_root_key), 30);
	putchar('\n');
	printf("Alice's initial send chain key (%zi Bytes):\n", sizeof(alice_send_chain_key));
	print_hex(alice_send_chain_key, sizeof(alice_send_chain_key), 30);
	putchar('\n');
	printf("Alice's initial receive chain key (%zi Bytes):\n", sizeof(alice_receive_chain_key));
	print_hex(alice_receive_chain_key, sizeof(alice_receive_chain_key), 30);
	putchar('\n');
	printf("Alice's initial send header key (%zi Bytes):\n", sizeof(alice_send_header_key));
	print_hex(alice_send_header_key, sizeof(alice_send_header_key), 30);
	putchar('\n');
	printf("Alice's initial receive header key (%zi Bytes):\n", sizeof(alice_receive_header_key));
	print_hex(alice_receive_header_key, sizeof(alice_receive_header_key), 30);
	printf("Alice's initial next send header key (%zi Bytes):\n", sizeof(alice_next_send_header_key));
	print_hex(alice_next_send_header_key, sizeof(alice_next_send_header_key), 30);
	putchar('\n');
	printf("Alice's initial next receive header key (%zi Bytes):\n", sizeof(alice_next_receive_header_key));
	print_hex(alice_next_receive_header_key, sizeof(alice_next_receive_header_key), 30);
	putchar('\n');

	//derive Bob's initial root and chain key
	unsigned char bob_root_key[crypto_secretbox_KEYBYTES];
	unsigned char bob_send_chain_key[crypto_secretbox_KEYBYTES];
	unsigned char bob_receive_chain_key[crypto_secretbox_KEYBYTES];
	unsigned char bob_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	unsigned char bob_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	unsigned char bob_next_send_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	unsigned char bob_next_receive_header_key[crypto_aead_chacha20poly1305_KEYBYTES];
	status = derive_initial_root_chain_and_header_keys(
			bob_root_key,
			bob_send_chain_key,
			bob_receive_chain_key,
			bob_send_header_key,
			bob_receive_header_key,
			bob_next_send_header_key,
			bob_next_receive_header_key,
			bob_private_identity,
			bob_public_identity,
			alice_public_identity,
			bob_private_ephemeral,
			bob_public_ephemeral,
			alice_public_ephemeral,
			false);
	sodium_memzero(bob_private_identity, sizeof(bob_private_identity));
	sodium_memzero(bob_private_ephemeral, sizeof(bob_private_ephemeral));
	if (status != 0) {
		fprintf(stderr, "ERROR: Failed to derive Bob's initial root and chain key. (%i)", status);
		sodium_memzero(alice_root_key, sizeof(alice_root_key));
		sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key));
		sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key));
		sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(bob_root_key, sizeof(bob_root_key));
		sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key));
		sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key));
		sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));
		sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return status;
	}

	//print Bob's initial root and chain key
	printf("Bob's initial root key (%zi Bytes):\n", sizeof(bob_root_key));
	print_hex(bob_root_key, sizeof(bob_root_key), 30);
	putchar('\n');
	printf("Bob's initial send chain key (%zi Bytes):\n", sizeof(bob_send_chain_key));
	print_hex(bob_send_chain_key, sizeof(bob_send_chain_key), 30);
	putchar('\n');
	printf("Bob's initial receive chain key (%zi Bytes):\n", sizeof(bob_receive_chain_key));
	print_hex(bob_receive_chain_key, sizeof(bob_receive_chain_key), 30);
	putchar('\n');
	printf("Bob's initial send header key (%zi Bytes):\n", sizeof(bob_send_header_key));
	print_hex(bob_send_header_key, sizeof(bob_send_header_key), 30);
	putchar('\n');
	printf("Bob's initial receive header key (%zi Bytes):\n", sizeof(bob_receive_header_key));
	print_hex(bob_receive_header_key, sizeof(bob_receive_header_key), 30);
	printf("Bob's initial next send header key (%zi Bytes):\n", sizeof(bob_next_send_header_key));
	print_hex(bob_next_send_header_key, sizeof(bob_next_send_header_key), 30);
	putchar('\n');
	printf("Bob's initial next receive header key (%zi Bytes):\n", sizeof(bob_next_receive_header_key));
	print_hex(bob_next_receive_header_key, sizeof(bob_next_receive_header_key), 30);
	putchar('\n');

	//compare Alice's and Bob's initial root key
	if (sodium_memcmp(alice_root_key, bob_root_key, sizeof(alice_root_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's and Bob's initial root keys don't match.\n");
		sodium_memzero(alice_root_key, sizeof(alice_root_key));
		sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key));
		sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key));
		sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(bob_root_key, sizeof(bob_root_key));
		sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key));
		sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key));
		sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));
		sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return -10;
	}
	printf("Alice's and Bob's initial root keys match.\n");

	sodium_memzero(alice_root_key, sizeof(alice_root_key));
	sodium_memzero(bob_root_key, sizeof(bob_root_key));

	//compare Alice's and Bob's initial chain keys
	if (sodium_memcmp(alice_send_chain_key, bob_receive_chain_key, sizeof(alice_send_chain_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's and Bob's initial chain keys don't match.\n");
		sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key));
		sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key));
		sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key));
		sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key));
		sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));
		sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return -10;
	}
	printf("Alice's and Bob's initial chain keys match.\n");

	sodium_memzero(alice_send_chain_key, sizeof(alice_send_chain_key));
	sodium_memzero(bob_receive_chain_key, sizeof(bob_receive_chain_key));

	if (sodium_memcmp(alice_receive_chain_key, bob_send_chain_key, sizeof(alice_receive_chain_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's and Bob's initial chain keys don't match.\n");
		sodium_memzero(alice_receive_chain_key, sizeof(alice_receive_chain_key));
		sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(bob_send_chain_key, sizeof(bob_send_chain_key));
		sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));
		sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return -10;
	}
	printf("Alice's and Bob's initial chain keys match.\n");

	//compare Alice's and Bob's initial header keys 1/2
	if (sodium_memcmp(alice_send_header_key, bob_receive_header_key, sizeof(alice_send_header_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's initial send and Bob's initial receive header keys don't match.\n");
		sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));
		sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return -10;
	}
	printf("Alice's initial send and Bob's initial receive header keys match.\n");

	sodium_memzero(alice_send_header_key, sizeof(alice_send_header_key));
	sodium_memzero(bob_receive_header_key, sizeof(bob_receive_header_key));

	//compare Alice's and Bob's initial header keys 2/2
	if (sodium_memcmp(alice_receive_header_key, bob_send_header_key, sizeof(alice_receive_header_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's initial receive and Bob's initial send header keys don't match.\n");
		sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return -10;
	}
	printf("Alice's initial receive and Bob's initial send header keys match.\n");

	sodium_memzero(alice_receive_header_key, sizeof(alice_receive_header_key));
	sodium_memzero(bob_send_header_key, sizeof(bob_send_header_key));

	//compare Alice's and Bob's initial next header keys 1/2
	if (sodium_memcmp(alice_next_send_header_key, bob_next_receive_header_key, sizeof(alice_next_send_header_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's initial next send and Bob's initial next receive header keys don't match.\n");
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));
		return -10;
	}
	printf("Alice's initial next send and Bob's initial next receive header keys match.\n");
	sodium_memzero(alice_next_send_header_key, sizeof(alice_next_send_header_key));
	sodium_memzero(bob_next_receive_header_key, sizeof(bob_next_receive_header_key));

	//compare Alice's and Bob's initial next header keys 2/2
	if (sodium_memcmp(alice_next_receive_header_key, bob_next_send_header_key, sizeof(alice_next_receive_header_key)) != 0) {
		fprintf(stderr, "ERROR: Alice's initial next receive and Bob's initial next send header keys don't match.\n");
		sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
		sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));
		return -10;
	}
	printf("Alice's initial next receive and Bob's initial next send header keys match.\n");

	sodium_memzero(alice_next_receive_header_key, sizeof(alice_next_receive_header_key));
	sodium_memzero(bob_next_send_header_key, sizeof(bob_next_send_header_key));

	return EXIT_SUCCESS;
}
Exemple #16
0
BOOL SodiumDecryptFile(LPTSTR password)
{
	ULONG numread;
	BOOL bErrorFlag;
	HLOCAL hFileBuffer = NULL;
	HLOCAL hCipherBuffer = NULL;
	YENCFILE encFileStrct;

	if (SetFilePointer(hFileIn, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
	{
		MessageBox(NULL, L"Cannot set file pointer", L"Decryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	if (!ReadFile(hFileIn, &encFileStrct, sizeof(YENCFILE), &numread, NULL))
	{
		MessageBox(NULL, L"Cannot read file into memory", L"Decryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	if (sodium_memcmp(encFileStrct.cbSignature, pszSignature, MAX_SIGNATURE))
	{
		MessageBox(NULL, L"This is not an encrypted file", L"Decryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	if (encFileStrct.algorithm != YC_SCRYPT_SALSA_POLY)
	{
		MessageBox(NULL, L"Encryption method not available", L"Decryption error", MB_ICONEXCLAMATION);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	hCipherBuffer = LocalAlloc(LPTR, (encFileStrct.rawSize + crypto_secretbox_MACBYTES) * sizeof(BYTE));
	if (!hCipherBuffer) {
		MessageBox(NULL, L"Cannot allocate memory", L"Decryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	if (!ReadFile(hFileIn, hCipherBuffer, encFileStrct.rawSize + crypto_secretbox_MACBYTES, &numread, NULL)) {
		MessageBox(NULL, L"Cannot read file into memory", L"Decryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	// For now read byes must equal filesize
	assert((encFileStrct.rawSize + crypto_secretbox_MACBYTES) == numread);

	// Wide password to multibyte password
	size_t nConvChars;
	char c_szPassword[100]; //TODO This might not be enough
	wcstombs_s(&nConvChars, c_szPassword, password, wcslen(password) + 1);

	// DERIVE KEY
	BYTE key[crypto_secretbox_KEYBYTES];

	if (crypto_pwhash_scryptsalsa208sha256(key, crypto_secretbox_KEYBYTES, c_szPassword, strlen(c_szPassword), encFileStrct.cbPasswordSalt,
		encFileStrct.dwOps,
		encFileStrct.dwMemory) != 0) {

		MessageBox(NULL, L"Operation takes too much system resources", L"Decryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	hFileBuffer = LocalAlloc(LPTR, encFileStrct.rawSize * sizeof(char));
	if (!hFileBuffer) {
		MessageBox(NULL, L"Cannot allocate memory", L"Encryption error", MB_ICONERROR);

		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	if (crypto_secretbox_open_easy((LPBYTE)hFileBuffer, (LPBYTE)hCipherBuffer, encFileStrct.rawSize + crypto_secretbox_MACBYTES, encFileStrct.cbNonce, key) != 0) {
		MessageBox(NULL, L"Decryption failed, please try again", L"Decryption error", MB_ICONERROR);
		
		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	LPCWSTR szOriginalFileName = fileNameStripExt(szFile);

	// WRITE
	HANDLE hFileOut = CreateFile(
		szOriginalFileName,		// Name of the write
		GENERIC_WRITE,			// Open for writing
		0,						// Do not share
		NULL,					// Default security
		CREATE_NEW,				// Create new file only
		FILE_ATTRIBUTE_NORMAL,	// Normal file
		NULL);					// No attr. template

	if (hFileOut == INVALID_HANDLE_VALUE) {
		MessageBox(NULL, L"Cannot open file", L"Decryption error", MB_ICONERROR);
		bErrorFlag = FALSE;
		goto dec_exit_on_failure;
	}

	bErrorFlag = WriteFile(
		hFileOut,				// Open file handle
		hFileBuffer,			// Start of data to write
		encFileStrct.rawSize,	// Number of bytes to write
		&numread,				// Number of bytes that were written
		NULL);					// No overlapped structure'

	CloseHandle(hFileOut);

dec_exit_on_failure:
	// Override sensitive in memory
	sodium_memzero(password, wcslen(password) * sizeof(TCHAR));
	sodium_memzero(c_szPassword, strlen(c_szPassword) * sizeof(BYTE));
	sodium_memzero(key, crypto_secretbox_KEYBYTES);

	LocalFree(hFileBuffer);
	LocalFree(hCipherBuffer);

	return bErrorFlag;
}
Exemple #17
0
int main(void)
{
    unsigned char *v16, *v16x;
    unsigned char *v32, *v32x;
    unsigned char *v64, *v64x;
    uint32_t       r;
    uint8_t        o;
    int            i;

    v16 = (unsigned char *) sodium_malloc(16);
    v16x = (unsigned char *) sodium_malloc(16);
    v32 = (unsigned char *) sodium_malloc(32);
    v32x = (unsigned char *) sodium_malloc(32);
    v64 = (unsigned char *) sodium_malloc(64);
    v64x = (unsigned char *) sodium_malloc(64);
    for (i = 0; i < 10000; i++) {
        randombytes_buf(v16, 16);
        randombytes_buf(v32, 32);
        randombytes_buf(v64, 64);

        memcpy(v16x, v16, 16);
        memcpy(v32x, v32, 32);
        memcpy(v64x, v64, 64);

        if (crypto_verify_16(v16, v16x) != 0 ||
            crypto_verify_32(v32, v32x) != 0 ||
            crypto_verify_64(v64, v64x) != 0 ||
            sodium_memcmp(v16, v16x, 16) != 0 ||
            sodium_memcmp(v32, v32x, 32) != 0 ||
            sodium_memcmp(v64, v64x, 64) != 0) {
            printf("Failed\n");
        }
    }
    printf("OK\n");

    for (i = 0; i < 100000; i++) {
        r = randombytes_random();
        o = (uint8_t) randombytes_random();
        if (o == 0) {
            continue;
        }
        v16x[r & 15U] ^= o;
        v32x[r & 31U] ^= o;
        v64x[r & 63U] ^= o;
        if (crypto_verify_16(v16, v16x) != -1 ||
            crypto_verify_32(v32, v32x) != -1 ||
            crypto_verify_64(v64, v64x) != -1 ||
            sodium_memcmp(v16, v16x, 16) != -1 ||
            sodium_memcmp(v32, v32x, 32) != -1 ||
            sodium_memcmp(v64, v64x, 64) != -1) {
            printf("Failed\n");
        }
        v16x[r & 15U] ^= o;
        v32x[r & 31U] ^= o;
        v64x[r & 63U] ^= o;
    }
    printf("OK\n");

    assert(crypto_verify_16_bytes() == 16U);
    assert(crypto_verify_32_bytes() == 32U);
    assert(crypto_verify_64_bytes() == 64U);

    sodium_free(v16);
    sodium_free(v16x);
    sodium_free(v32);
    sodium_free(v32x);
    sodium_free(v64);
    sodium_free(v64x);

    return 0;
}