diff --git a/ChangeLog b/ChangeLog
index 5ac0afe0..6f6a4734 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,16 @@
+* Version 1.0.4 (not released yet)
+ - ChaCha20 with an extended (96 bit) nonce and a 32-bit counter has
+been implemented as crypto_stream_chacha20_ietf(),
+crypto_stream_chacha20_ietf_xor() and crypto_stream_chacha20_ietf_xor_ic().
+An IETF-compatible version of ChaCha20Poly1305 is available as
+crypto_aead_chacha20poly1305_ietf_npubbytes(),
+crypto_aead_chacha20poly1305_ietf_encrypt() and
+crypto_aead_chacha20poly1305_ietf_decrypt().
+ - Sodium can now be used in Windows Store apps.
+ - The sodium_increment() helper function has been added, to increment
+an arbitrary long number (such as a nonce).
+
* Version 1.0.3
- In addition to sodium_bin2hex(), sodium_hex2bin() is now a
constant-time function.
diff --git a/builds/msvc/properties/ARM.props b/builds/msvc/properties/ARM.props
new file mode 100644
index 00000000..164b9b1f
--- /dev/null
+++ b/builds/msvc/properties/ARM.props
@@ -0,0 +1,20 @@
+
+
+
+
+ <_PropertySheetDisplayName>ARM Settings
+
+
+
+
+ WIN32;_WIN32;%(PreprocessorDefinitions)
+
+
+ MachineARM
+
+
+ /MACHINE:ARM %(AdditionalOptions)
+
+
+
+
diff --git a/dist-build/android-armv8-a.sh b/dist-build/android-armv8-a.sh
new file mode 100755
index 00000000..275b6ba6
--- /dev/null
+++ b/dist-build/android-armv8-a.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+export TARGET_ARCH=armv8-a
+export CFLAGS="-Os -march=${TARGET_ARCH}"
+ARCH=arm64 HOST_COMPILER=aarch64-linux-android "$(dirname "$0")/android-build.sh"
diff --git a/dist-build/emscripten.sh b/dist-build/emscripten.sh
index 9e43ae08..cc80947e 100755
--- a/dist-build/emscripten.sh
+++ b/dist-build/emscripten.sh
@@ -2,7 +2,7 @@
export MAKE_FLAGS='-j4'
export PREFIX="$(pwd)/libsodium-js"
-export EXPORTED_FUNCTIONS='["_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_keybytes","_crypto_auth_verify","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_noncebytes","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_generichash","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_pwhash_scryptsalsa208sha256","_crypto_pwhash_scryptsalsa208sha256_ll","_crypto_pwhash_scryptsalsa208sha256_memlimit_interactive","_crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_opslimit_interactive","_crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_saltbytes","_crypto_pwhash_scryptsalsa208sha256_str","_crypto_pwhash_scryptsalsa208sha256_str_verify","_crypto_pwhash_scryptsalsa208sha256_strbytes","_crypto_pwhash_scryptsalsa208sha256_strprefix","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_macbytes","_crypto_secretbox_noncebytes","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_keypair","_crypto_sign_open","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_verify_detached","_randombytes_buf","_randombytes_close","_randombytes_random","_randombytes_set_implementation","_randombytes_stir","_randombytes_uniform","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_version_major","_sodium_library_version_minor","_sodium_memcmp","_sodium_memzero","_sodium_version_string"]'
+export EXPORTED_FUNCTIONS='["_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_keybytes","_crypto_auth_verify","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_noncebytes","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_generichash","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_pwhash_scryptsalsa208sha256","_crypto_pwhash_scryptsalsa208sha256_ll","_crypto_pwhash_scryptsalsa208sha256_memlimit_interactive","_crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_opslimit_interactive","_crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_saltbytes","_crypto_pwhash_scryptsalsa208sha256_str","_crypto_pwhash_scryptsalsa208sha256_str_verify","_crypto_pwhash_scryptsalsa208sha256_strbytes","_crypto_pwhash_scryptsalsa208sha256_strprefix","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_macbytes","_crypto_secretbox_noncebytes","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_keypair","_crypto_sign_open","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_verify_detached","_randombytes_buf","_randombytes_close","_randombytes_random","_randombytes_set_implementation","_randombytes_stir","_randombytes_uniform","_sodium_bin2hex","_sodium_hex2bin","_sodium_increment","_sodium_init","_sodium_library_version_major","_sodium_library_version_minor","_sodium_memcmp","_sodium_memzero","_sodium_version_string"]'
export TOTAL_MEMORY=33554432
export JS_EXPORTS_FLAGS="-s EXPORTED_FUNCTIONS=${EXPORTED_FUNCTIONS}"
export LDFLAGS="-s TOTAL_MEMORY=${TOTAL_MEMORY} -s RESERVED_FUNCTION_POINTERS=8 -s NO_BROWSER=1"
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 00000000..9ffb5a89
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1,7 @@
+auth
+box
+box_detached
+generichash
+generichash_stream
+shorthash
+sign
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 00000000..5519a7c6
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,21 @@
+
+TARGETS = \
+ auth \
+ box \
+ box_detached \
+ generichash \
+ generichash_stream \
+ shorthash \
+ sign
+
+SODIUM_CFLAGS != pkg-config --cflags libsodium
+SODIUM_LIBS != pkg-config --libs libsodium
+CFLAGS += $(SODIUM_CFLAGS)
+LDFLAGS += $(SODIUM_LIBS)
+
+all: $(TARGETS)
+
+clean:
+ rm -f $(TARGETS)
+
+distclean: clean
diff --git a/examples/auth.c b/examples/auth.c
new file mode 100644
index 00000000..25e3eacf
--- /dev/null
+++ b/examples/auth.c
@@ -0,0 +1,68 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * This operation computes an authentication tag for a message and a
+ * secret key, and provides a way to verify that a given tag is valid
+ * for a given message and a key.
+ *
+ * The function computing the tag deterministic: the same (message,
+ * key) tuple will always produce the same output.
+ *
+ * However, even if the message is public, knowing the key is
+ * required in order to be able to compute a valid tag. Therefore,
+ * the key should remain confidential. The tag, however, can be
+ * public.
+ *
+ * A typical use case is:
+ *
+ * - A prepares a message, add an authentication tag, sends it to B
+ * - A doesn't store the message
+ * - Later on, B sends the message and the authentication tag to A
+ * - A uses the authentication tag to verify that it created this message.
+ *
+ * This operation does not encrypt the message. It only computes and
+ * verifies an authentication tag.
+ */
+static int
+auth(void)
+{
+ unsigned char key[crypto_auth_KEYBYTES];
+ unsigned char mac[crypto_auth_BYTES];
+ unsigned char message[MAX_INPUT_LEN];
+ size_t message_len;
+ int ret;
+
+ puts("Example: crypto_auth\n");
+
+ prompt_input("a key", (char*)key, sizeof key, 0);
+ message_len = prompt_input("a message", (char*)message, sizeof message, 1);
+
+ printf("Generating %s authentication...\n", crypto_auth_primitive());
+ crypto_auth(mac, message, message_len, key);
+
+ printf("Authentication tag: ");
+ print_hex(mac, sizeof mac);
+
+ puts("Verifying authentication tag...");
+ ret = crypto_auth_verify(mac, message, message_len, key);
+ print_verification(ret);
+
+ sodium_memzero(key, sizeof key); /* wipe sensitive data */
+
+ return ret;
+}
+
+int
+main(void)
+{
+ init();
+
+ return auth() != 0;
+}
diff --git a/examples/box.c b/examples/box.c
new file mode 100644
index 00000000..0f4ec7f5
--- /dev/null
+++ b/examples/box.c
@@ -0,0 +1,133 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * Using public-key authenticated encryption, Bob can encrypt a
+ * confidential message specifically for Alice, using Alice's public
+ * key.
+ *
+ * Using Bob's public key, Alice can verify that the encrypted
+ * message was actually created by Bob and was not tampered with,
+ * before eventually decrypting it.
+ *
+ * Alice only needs Bob's public key, the nonce and the ciphertext.
+ * Bob should never ever share his secret key, even with Alice.
+ *
+ * And in order to send messages to Alice, Bob only needs Alice's
+ * public key. Alice should never ever share her secret key either,
+ * even with Bob.
+ *
+ * Alice can reply to Bob using the same system, without having to
+ * generate a distinct key pair.
+ *
+ * The nonce doesn't have to be confidential, but it should be used
+ * with just one invokation of crypto_box_open_easy() for a
+ * particular pair of public and secret keys.
+ *
+ * One easy way to generate a nonce is to use randombytes_buf(),
+ * considering the size of nonces the risk of any random collisions
+ * is negligible. For some applications, if you wish to use nonces to
+ * detect missing messages or to ignore replayed messages, it is also
+ * ok to use a simple incrementing counter as a nonce.
+ *
+ * When doing so you must ensure that the same value can never be
+ * re-used (for example you may have multiple threads or even hosts
+ * generating messages using the same key pairs).
+ *
+ * This system provides mutual authentication. However, a typical use
+ * case is to secure communications between a server, whose public
+ * key is known in advance, and clients connecting anonymously.
+ */
+static int
+box(void)
+{
+ unsigned char bob_pk[crypto_box_PUBLICKEYBYTES]; /* Bob's public key */
+ unsigned char bob_sk[crypto_box_SECRETKEYBYTES]; /* Bob's secret key */
+
+ unsigned char alice_pk[crypto_box_PUBLICKEYBYTES]; /* Alice's public key */
+ unsigned char alice_sk[crypto_box_SECRETKEYBYTES]; /* Alice's secret key */
+
+ unsigned char nonce[crypto_box_NONCEBYTES];
+ unsigned char message[MAX_INPUT_LEN];
+ unsigned char ciphertext[crypto_box_MACBYTES + MAX_INPUT_LEN];
+ size_t message_len;
+ size_t ciphertext_len;
+ int ret;
+
+ puts("Example: crypto_box_easy\n");
+
+ puts("Generating keypairs...\n");
+ crypto_box_keypair(bob_pk, bob_sk); /* generate Bob's keys */
+ crypto_box_keypair(alice_pk, alice_sk); /* generate Alice's keys */
+
+ puts("Bob");
+ printf("Public key: ");
+ print_hex(bob_pk, sizeof bob_pk);
+ printf("Secret key: ");
+ print_hex(bob_sk, sizeof bob_sk);
+
+ puts("Alice");
+ printf("Public key: ");
+ print_hex(alice_pk, sizeof alice_pk);
+ printf("Secret key: ");
+ print_hex(alice_sk, sizeof alice_sk);
+
+ /* nonce must be unique per (key, message) - it can be public and deterministic */
+ puts("Generating nonce...");
+ randombytes_buf(nonce, sizeof nonce);
+ printf("Nonce: ");
+ print_hex(nonce, sizeof nonce);
+
+ /* read input */
+ message_len = prompt_input("a message", (char*)message, sizeof message, 1);
+
+ print_hex(message, message_len);
+
+ /* encrypt and authenticate the message */
+ printf("Encrypting and authenticating with %s\n\n", crypto_box_primitive());
+ crypto_box_easy(ciphertext, message, message_len, nonce, alice_pk, bob_sk);
+ ciphertext_len = crypto_box_MACBYTES + message_len;
+
+ /* send the nonce and the ciphertext */
+ puts("Bob sends the nonce and the ciphertext...\n");
+ printf("Ciphertext len: %zu bytes - Original message length: %zu bytes\n",
+ ciphertext_len, message_len);
+ puts("Notice the prepended 16 byte authentication token\n");
+ printf("Nonce: ");
+ print_hex(nonce, sizeof nonce);
+ printf("Ciphertext: ");
+ print_hex(ciphertext, ciphertext_len);
+
+ /* decrypt the message */
+ puts("Alice verifies and decrypts the ciphertext...");
+ ret = crypto_box_open_easy(message, ciphertext, ciphertext_len, nonce, bob_pk,
+ alice_sk);
+ print_hex(message, message_len);
+
+ print_verification(ret);
+ if (ret == 0) {
+ printf("Plaintext: ");
+ fwrite(message, 1U, message_len, stdout);
+ putchar('\n');
+ }
+ sodium_memzero(bob_sk, sizeof bob_sk); /* wipe sensitive data */
+ sodium_memzero(alice_sk, sizeof alice_sk);
+ sodium_memzero(message, sizeof message);
+ sodium_memzero(ciphertext, sizeof ciphertext);
+
+ return ret;
+}
+
+int
+main(void)
+{
+ init();
+
+ return box() != 0;
+}
diff --git a/examples/box_detached.c b/examples/box_detached.c
new file mode 100644
index 00000000..3ea5a739
--- /dev/null
+++ b/examples/box_detached.c
@@ -0,0 +1,132 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * Using public-key authenticated encryption, Bob can encrypt a
+ * confidential message specifically for Alice, using Alice's public
+ * key.
+ *
+ * Using Bob's public key, Alice can verify that the encrypted
+ * message was actually created by Bob and was not tampered with,
+ * before eventually decrypting it.
+ *
+ * Alice only needs Bob's public key, the nonce and the ciphertext.
+ * Bob should never ever share his secret key, even with Alice.
+ *
+ * And in order to send messages to Alice, Bob only needs Alice's
+ * public key. Alice should never ever share her secret key either,
+ * even with Bob.
+ *
+ * Alice can reply to Bob using the same system, without having to
+ * generate a distinct key pair.
+ *
+ * The nonce doesn't have to be confidential, but it should be used
+ * with just one invokation of crypto_box_open_easy() for a
+ * particular pair of public and secret keys.
+ *
+ * One easy way to generate a nonce is to use randombytes_buf(),
+ * considering the size of nonces the risk of any random collisions
+ * is negligible. For some applications, if you wish to use nonces to
+ * detect missing messages or to ignore replayed messages, it is also
+ * ok to use a simple incrementing counter as a nonce.
+ *
+ * When doing so you must ensure that the same value can never be
+ * re-used (for example you may have multiple threads or even hosts
+ * generating messages using the same key pairs).
+ *
+ * This system provides mutual authentication. However, a typical use
+ * case is to secure communications between a server, whose public
+ * key is known in advance, and clients connecting anonymously.
+ */
+static int
+box_detached(void)
+{
+ unsigned char bob_pk[crypto_box_PUBLICKEYBYTES]; /* Bob's public key */
+ unsigned char bob_sk[crypto_box_SECRETKEYBYTES]; /* Bob's secret key */
+
+ unsigned char alice_pk[crypto_box_PUBLICKEYBYTES]; /* Alice's public key */
+ unsigned char alice_sk[crypto_box_SECRETKEYBYTES]; /* Alice's secret key */
+
+ unsigned char nonce[crypto_box_NONCEBYTES];
+ unsigned char message[MAX_INPUT_LEN];
+ unsigned char mac[crypto_box_MACBYTES];
+ unsigned char ciphertext[MAX_INPUT_LEN];
+ size_t message_len;
+ int ret;
+
+ puts("Example: crypto_box_detached\n");
+
+ puts("Generating keypairs...\n");
+ crypto_box_keypair(bob_pk, bob_sk); /* generate Bob's keys */
+ crypto_box_keypair(alice_pk, alice_sk); /* generate Alice's keys */
+
+ puts("Bob");
+ printf("Public key: ");
+ print_hex(bob_pk, sizeof bob_pk);
+ printf("Secret key: ");
+ print_hex(bob_sk, sizeof bob_sk);
+
+ puts("Alice");
+ printf("Public key: ");
+ print_hex(alice_pk, sizeof alice_pk);
+ printf("Secret key: ");
+ print_hex(alice_sk, sizeof alice_sk);
+
+ /* nonce must be unique per (key, message) - it can be public and deterministic */
+ puts("Generating nonce...");
+ randombytes_buf(nonce, sizeof nonce);
+ printf("Nonce: ");
+ print_hex(nonce, sizeof nonce);
+
+ /* read input */
+ message_len = prompt_input("a message", (char*)message, sizeof message, 1);
+
+ print_hex(message, message_len);
+
+ /* encrypt and authenticate the message */
+ printf("Encrypting and authenticating with %s\n\n", crypto_box_primitive());
+ crypto_box_detached(ciphertext, mac, message, message_len, nonce,
+ alice_pk, bob_sk);
+
+ /* send the nonce, the MAC and the ciphertext */
+ puts("Bob sends the nonce, the MAC and the ciphertext...\n");
+ printf("Nonce: ");
+ print_hex(nonce, sizeof nonce);
+ printf("MAC: ");
+ print_hex(mac, sizeof mac);
+ printf("Ciphertext: ");
+ print_hex(ciphertext, message_len);
+
+ /* decrypt the message */
+ puts("Alice verifies the MAC and decrypts the ciphertext...");
+ ret = crypto_box_open_detached(message, ciphertext, mac, message_len, nonce,
+ bob_pk, alice_sk);
+ print_hex(message, message_len);
+
+ print_verification(ret);
+ if (ret == 0) {
+ printf("Plaintext: ");
+ fwrite(message, 1U, message_len, stdout);
+ putchar('\n');
+ }
+ sodium_memzero(bob_sk, sizeof bob_sk); /* wipe sensitive data */
+ sodium_memzero(alice_sk, sizeof alice_sk);
+ sodium_memzero(message, sizeof message);
+ sodium_memzero(ciphertext, sizeof ciphertext);
+
+ return ret;
+}
+
+int
+main(void)
+{
+ init();
+
+ return box_detached() != 0;
+}
diff --git a/examples/generichash.c b/examples/generichash.c
new file mode 100644
index 00000000..fbf00442
--- /dev/null
+++ b/examples/generichash.c
@@ -0,0 +1,80 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * This function computes a fixed-length fingerprint for an arbitrary long message.
+ *
+ * Sample use cases:
+ *
+ * File integrity checking
+ * Creating unique identifiers to index arbitrary long data
+ *
+ * The crypto_generichash() function puts a fingerprint of the
+ * message in whose length is inlen bytes into out. The output size
+ * can be chosen by the application.
+ *
+ * The minimum recommended output size is crypto_generichash_BYTES.
+ * This size makes it practically impossible for two messages to
+ * produce the same fingerprint.
+ *
+ * But for specific use cases, the size can be any value between
+ * crypto_generichash_BYTES_MIN (included) and
+ * crypto_generichash_BYTES_MAX (included).
+ *
+ * key can be NULL and keylen can be 0. In this case, a message will
+ * always have the same fingerprint, similar to the MD5 or SHA-1
+ * functions for which crypto_generichash() is a faster and more
+ * secure alternative.
+ *
+ * But a key can also be specified. A message will always have the
+ * same fingerprint for a given key, but different keys used to hash
+ * the same message are very likely to produce distinct fingerprints.
+ *
+ * In particular, the key can be used to make sure that different
+ * applications generate different fingerprints even if they process
+ * the same data.
+ *
+ * The recommended key size is crypto_generichash_KEYBYTES bytes.
+ *
+ * However, the key size can by any value between
+ * crypto_generichash_KEYBYTES_MIN (included) and
+ * crypto_generichash_KEYBYTES_MAX (included).
+ */
+void
+generichash(void)
+{
+ unsigned char key[crypto_generichash_KEYBYTES_MAX];
+ unsigned char hash[crypto_generichash_BYTES];
+ unsigned char message[MAX_INPUT_LEN];
+ size_t message_len;
+ size_t key_len;
+
+ puts("Example: crypto_generichash\n");
+
+ key_len = prompt_input("a key", (char*)key, sizeof key, 1);
+ message_len = prompt_input("a message", (char*)message, sizeof message, 1);
+
+ printf("Hashing message with %s\n", crypto_generichash_primitive());
+ if (crypto_generichash(hash, sizeof hash, message, message_len,
+ key, key_len) != 0) {
+ puts("Couldn't hash the message, probably due to the key length");
+ } else {
+ printf("Hash: ");
+ print_hex(hash, sizeof hash);
+ }
+}
+
+int
+main(void)
+{
+ init();
+ generichash();
+
+ return 0;
+}
diff --git a/examples/generichash_stream.c b/examples/generichash_stream.c
new file mode 100644
index 00000000..aab8b490
--- /dev/null
+++ b/examples/generichash_stream.c
@@ -0,0 +1,58 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * Streaming variant of generic hash. This has the ability to hash
+ * data in chunks at a time and compute the same result as hashing
+ * all of the data at once.
+ */
+void
+generichash_stream(void)
+{
+ unsigned char key[crypto_generichash_KEYBYTES_MAX];
+ unsigned char hash[crypto_generichash_BYTES];
+ unsigned char message_part[MAX_INPUT_LEN];
+ crypto_generichash_state state;
+ size_t message_part_len;
+
+ puts("Example: crypto_generichashstream\n");
+
+ prompt_input("a key", (char*)key, sizeof key, 1);
+
+ printf("Hashing message with %s\n", crypto_generichash_primitive());
+
+ /* initialize the stream */
+ if (crypto_generichash_init(&state, key, sizeof key, sizeof hash) != 0) {
+ puts("Couldn't hash the message, probably due to the key length");
+ exit(EXIT_FAILURE);
+ }
+
+ for(;;) {
+ message_part_len = prompt_input("the next part of the message",
+ (char*)message_part, sizeof message_part, 1);
+ if (message_part_len == 0)
+ break;
+
+ /* keep appending data */
+ crypto_generichash_update(&state, message_part, message_part_len);
+ }
+ crypto_generichash_final(&state, hash, sizeof hash);
+
+ printf("Hash: ");
+ print_hex(hash, sizeof hash);
+}
+
+int
+main(void)
+{
+ init();
+ generichash_stream();
+
+ return 0;
+}
diff --git a/examples/shorthash.c b/examples/shorthash.c
new file mode 100644
index 00000000..390150f6
--- /dev/null
+++ b/examples/shorthash.c
@@ -0,0 +1,58 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * Many applications and programming language implementations were
+ * recently found to be vulnerable to denial-of-service attacks when
+ * a hash function with weak security guarantees, such as Murmurhash
+ * 3, was used to construct a hash table.
+ *
+ * In order to address this, Sodium provides the crypto_shorthash()
+ * function, which outputs short but unpredictable (without knowing
+ * the secret key) values suitable for picking a list in a hash table
+ * for a given key.
+ *
+ * This function is optimized for short inputs.
+ *
+ * The output of this function is only 64 bits. Therefore, it should
+ * not be considered collision-resistant.
+ *
+ * Use cases:
+ *
+ * - Hash tables
+ * - Probabilistic data structures such as Bloom filters
+ * - Integrity checking in interactive protocols
+ */
+void
+shorthash(void)
+{
+ unsigned char key[crypto_shorthash_KEYBYTES];
+ unsigned char hash[crypto_shorthash_BYTES];
+ unsigned char message[MAX_INPUT_LEN];
+ size_t message_len;
+
+ puts("Example: crypto_shorthash\n");
+
+ prompt_input("a key", (char*)key, sizeof key, 0);
+ message_len = prompt_input("a message", (char*)message, sizeof message, 1);
+
+ printf("Hashing the message with %s\n", crypto_shorthash_primitive());
+ crypto_shorthash(hash, message, message_len, key);
+ printf("Hash: ");
+ print_hex(hash, sizeof hash);
+}
+
+int
+main(void)
+{
+ init();
+ shorthash();
+
+ return 0;
+}
diff --git a/examples/sign.c b/examples/sign.c
new file mode 100644
index 00000000..d17d3545
--- /dev/null
+++ b/examples/sign.c
@@ -0,0 +1,78 @@
+/*
+ * GraxRabble
+ * example programs for libsodium.
+ */
+
+#include /* library header */
+
+#include "utils.h" /* utility functions shared by examples */
+
+/*
+ * Signs a message with secret key which will authenticate a message.
+ * Everybody else can use the public key to ensure that the message is both
+ * valid and untampered.
+ *
+ * Note that the signed message will have 16 bytes of signature prepended.
+ * Ensure that the signed buffer is at least crypto_sign_BYTES longer then
+ * the actual message.
+ */
+static int
+sign(void)
+{
+ unsigned char pk[crypto_sign_PUBLICKEYBYTES]; /* Bob's public key */
+ unsigned char sk[crypto_sign_SECRETKEYBYTES]; /* Bob's secret key */
+ unsigned char message[MAX_INPUT_LEN];
+ unsigned char message_signed[crypto_sign_BYTES + MAX_INPUT_LEN];
+ unsigned long long message_len;
+ unsigned long long message_signed_len;
+ int ret;
+
+ puts("Example: crypto_sign\n");
+
+ puts("Generating keypair...");
+ crypto_sign_keypair(pk, sk); /* generate Bob's keys */
+
+ printf("Public key: ");
+ print_hex(pk, sizeof pk);
+ printf("Secret key: ");
+ print_hex(sk, sizeof sk);
+ puts("The secret key, as returned by crypto_sign_keypair(), actually includes "
+ "a copy of the public key, in order to avoid a scalar multiplication "
+ "when signing messages.");
+
+ message_len = prompt_input("a message", (char*)message, sizeof message, 1);
+
+ printf("Signing message with %s...\n", crypto_sign_primitive());
+ crypto_sign(message_signed, &message_signed_len, message, message_len, sk);
+
+ printf("Signed message:");
+ print_hex(message_signed, message_signed_len);
+ printf("A %u bytes signature was prepended to the message\n",
+ crypto_sign_BYTES);
+
+ printf("Signature: ");
+ print_hex(message_signed, crypto_sign_BYTES);
+ printf("Message: ");
+ fwrite(message_signed + crypto_sign_BYTES, 1U,
+ message_signed_len - crypto_sign_BYTES, stdout);
+ putchar('\n');
+
+ puts("Validating message...");
+ ret = crypto_sign_open(message, &message_len, message_signed,
+ message_signed_len, pk);
+ print_verification(ret);
+ if (ret == 0)
+ printf("Message: %s\n", message);
+
+ sodium_memzero(sk, sizeof sk); /* wipe sensitive data */
+
+ return ret;
+}
+
+int
+main(void)
+{
+ init();
+
+ return sign() != 0;
+}
diff --git a/examples/utils.h b/examples/utils.h
new file mode 100644
index 00000000..c9460474
--- /dev/null
+++ b/examples/utils.h
@@ -0,0 +1,106 @@
+/*
+ * Utility functions shared by all the demo programs.
+ */
+#ifndef UTILS_H
+#define UTILS_H
+
+#include
+#include
+#include
+#include
+
+#include
+
+#define MAX_INPUT_LEN 4096
+
+/*
+ * print_hex() is a wrapper around sodium_bin2hex() which allocates
+ * temporary memory then immediately prints the result followed by \n
+ */
+static void
+print_hex(const void *bin, const size_t bin_len)
+{
+ char *hex;
+ size_t hex_size;
+
+ if (bin_len >= SIZE_MAX / 2) {
+ abort();
+ }
+ hex_size = bin_len * 2 + 1;
+ if ((hex = malloc(hex_size)) == NULL) {
+ abort();
+ }
+ /* the library supplies a few utility functions like the one below */
+ if (sodium_bin2hex(hex, hex_size, bin, bin_len) == NULL) {
+ abort();
+ }
+ puts(hex);
+ free(hex);
+}
+
+/*
+ * Display a prompt for input by user. It will save the input into a buffer
+ * of a specific size with room for the null terminator while removing
+ * trailing newline characters.
+ */
+static size_t
+prompt_input(const char *prompt, char *input, const size_t max_input_len,
+ int variable_length)
+{
+ char input_tmp[MAX_INPUT_LEN + 1U];
+ size_t actual_input_len;
+
+ if (variable_length != 0) {
+ printf("\nEnter %s (%zu bytes max) > ", prompt, max_input_len);
+ } else {
+ printf("\nEnter %s (%zu bytes) > ", prompt, max_input_len);
+ }
+ fflush(stdout);
+ fgets(input_tmp, sizeof input_tmp, stdin);
+ actual_input_len = strlen(input_tmp);
+
+ /* trim \n */
+ if (actual_input_len > 0 && input_tmp[actual_input_len - 1] == '\n') {
+ input_tmp[actual_input_len - 1] = '\0';
+ --actual_input_len;
+ }
+
+ if (actual_input_len > max_input_len) {
+ printf("Warning: truncating input to %zu bytes\n\n", max_input_len);
+ actual_input_len = max_input_len;
+ } else if (actual_input_len < max_input_len && variable_length == 0) {
+ printf("Warning: %zu bytes expected, %zu bytes given: padding with zeros\n\n",
+ max_input_len, actual_input_len);
+ memset(input, 0, max_input_len);
+ } else {
+ printf("Length: %zu bytes\n\n", actual_input_len);
+ }
+
+ memcpy(input, input_tmp, actual_input_len);
+ if (variable_length == 0) {
+ return max_input_len;
+ } else {
+ return actual_input_len;
+ }
+}
+
+/*
+ * Display whether the function was sucessful or failed.
+ */
+static void
+print_verification(int ret)
+{
+ if (ret == 0)
+ puts("Success!\n");
+ else
+ puts("Failure.\n");
+}
+
+static void
+init(void)
+{
+ sodium_init();
+ printf("Using libsodium %s\n", sodium_version_string());
+}
+
+#endif /* UTILS_H */
diff --git a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c
index 2610477d..12e55c7b 100644
--- a/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c
+++ b/src/libsodium/crypto_generichash/blake2/ref/blake2b-ref.c
@@ -46,14 +46,14 @@ static const uint8_t blake2b_sigma[12][16] =
/* LCOV_EXCL_START */
static inline int blake2b_set_lastnode( blake2b_state *S )
{
- S->f[1] = ~0ULL;
+ S->f[1] = -1;
return 0;
}
/* LCOV_EXCL_STOP */
#if 0
static inline int blake2b_clear_lastnode( blake2b_state *S )
{
- S->f[1] = 0ULL;
+ S->f[1] = 0;
return 0;
}
#endif
@@ -62,7 +62,7 @@ static inline int blake2b_set_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_set_lastnode( S );
- S->f[0] = ~0ULL;
+ S->f[0] = -1;
return 0;
}
#if 0
@@ -70,7 +70,7 @@ static inline int blake2b_clear_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_clear_lastnode( S );
- S->f[0] = 0ULL;
+ S->f[0] = 0;
return 0;
}
#endif
diff --git a/src/libsodium/crypto_hash/sha256/cp/hash_sha256.c b/src/libsodium/crypto_hash/sha256/cp/hash_sha256.c
index 738794ac..c98f1bee 100644
--- a/src/libsodium/crypto_hash/sha256/cp/hash_sha256.c
+++ b/src/libsodium/crypto_hash/sha256/cp/hash_sha256.c
@@ -40,6 +40,7 @@
/* Avoid namespace collisions with BSD . */
#define be32dec _sha256_be32dec
#define be32enc _sha256_be32enc
+#define be64enc _sha256_be64enc
static inline uint32_t
be32dec(const void *pp)
@@ -53,7 +54,7 @@ be32dec(const void *pp)
static inline void
be32enc(void *pp, uint32_t x)
{
- uint8_t * p = (uint8_t *)pp;
+ uint8_t *p = (uint8_t *)pp;
p[3] = x & 0xff;
p[2] = (x >> 8) & 0xff;
@@ -61,6 +62,21 @@ be32enc(void *pp, uint32_t x)
p[0] = (x >> 24) & 0xff;
}
+static inline void
+be64enc(void * pp, uint64_t x)
+{
+ uint8_t * p = (uint8_t *)pp;
+
+ p[7] = x & 0xff;
+ p[6] = (x >> 8) & 0xff;
+ p[5] = (x >> 16) & 0xff;
+ p[4] = (x >> 24) & 0xff;
+ p[3] = (x >> 32) & 0xff;
+ p[2] = (x >> 40) & 0xff;
+ p[1] = (x >> 48) & 0xff;
+ p[0] = (x >> 56) & 0xff;
+}
+
static void
be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
{
@@ -206,9 +222,9 @@ SHA256_Pad(crypto_hash_sha256_state *state)
unsigned char len[8];
uint32_t r, plen;
- be32enc_vect(len, state->count, 8);
+ be64enc(len, state->count);
- r = (state->count[1] >> 3) & 0x3f;
+ r = (state->count >> 3) & 0x3f;
plen = (r < 56) ? (56 - r) : (120 - r);
crypto_hash_sha256_update(state, PAD, (unsigned long long) plen);
@@ -218,16 +234,13 @@ SHA256_Pad(crypto_hash_sha256_state *state)
int
crypto_hash_sha256_init(crypto_hash_sha256_state *state)
{
- state->count[0] = state->count[1] = 0;
+ static const uint32_t sha256_initstate[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ };
- state->state[0] = 0x6A09E667;
- state->state[1] = 0xBB67AE85;
- state->state[2] = 0x3C6EF372;
- state->state[3] = 0xA54FF53A;
- state->state[4] = 0x510E527F;
- state->state[5] = 0x9B05688C;
- state->state[6] = 0x1F83D9AB;
- state->state[7] = 0x5BE0CD19;
+ state->count = (uint64_t) 0U;
+ memcpy(state->state, sha256_initstate, sizeof sha256_initstate);
return 0;
}
@@ -237,20 +250,13 @@ crypto_hash_sha256_update(crypto_hash_sha256_state *state,
const unsigned char *in,
unsigned long long inlen)
{
- uint32_t bitlen[2];
uint32_t r;
- r = (state->count[1] >> 3) & 0x3f;
-
- bitlen[1] = ((uint32_t)inlen) << 3;
- bitlen[0] = (uint32_t)(inlen >> 29);
-
- /* LCOV_EXCL_START */
- if ((state->count[1] += bitlen[1]) < bitlen[1]) {
- state->count[0]++;
+ if (inlen <= 0U) {
+ return 0;
}
- /* LCOV_EXCL_STOP */
- state->count[0] += bitlen[0];
+ r = (state->count >> 3) & 0x3f;
+ state->count += (uint64_t)(inlen) << 3;
if (inlen < 64 - r) {
memcpy(&state->buf[r], in, inlen);
diff --git a/src/libsodium/crypto_hash/sha512/cp/hash_sha512.c b/src/libsodium/crypto_hash/sha512/cp/hash_sha512.c
index e85be74b..9eecff7c 100644
--- a/src/libsodium/crypto_hash/sha512/cp/hash_sha512.c
+++ b/src/libsodium/crypto_hash/sha512/cp/hash_sha512.c
@@ -244,16 +244,15 @@ SHA512_Pad(crypto_hash_sha512_state *state)
int
crypto_hash_sha512_init(crypto_hash_sha512_state *state)
{
- state->count[0] = state->count[1] = 0;
+ static const uint64_t sha512_initstate[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+ };
- state->state[0] = 0x6a09e667f3bcc908ULL;
- state->state[1] = 0xbb67ae8584caa73bULL;
- state->state[2] = 0x3c6ef372fe94f82bULL;
- state->state[3] = 0xa54ff53a5f1d36f1ULL;
- state->state[4] = 0x510e527fade682d1ULL;
- state->state[5] = 0x9b05688c2b3e6c1fULL;
- state->state[6] = 0x1f83d9abfb41bd6bULL;
- state->state[7] = 0x5be0cd19137e2179ULL;
+ state->count[0] = state->count[1] = (uint64_t) 0U;
+ memcpy(state->state, sha512_initstate, sizeof sha512_initstate);
return 0;
}
diff --git a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c
index 77be6ab9..8e9aceff 100644
--- a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c
+++ b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c
@@ -153,7 +153,8 @@ escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen,
if (need > buflen || need < saltlen) {
return NULL;
}
-#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
+#if defined(HAVE_EMMINTRIN_H) || \
+ (defined(_MSC_VER) && (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
escrypt_kdf =
sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
#else
@@ -234,7 +235,8 @@ crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
if (escrypt_init_local(&local)) {
return -1; /* LCOV_EXCL_LINE */
}
-#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
+#if defined(HAVE_EMMINTRIN_H) || \
+ (defined(_MSC_VER) && (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
escrypt_kdf =
sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
#else
diff --git a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
index a9eec746..4786e5bf 100644
--- a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
+++ b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
@@ -279,6 +279,10 @@ escrypt_kdf_nosse(escrypt_local_t * local,
errno = EFBIG;
return -1;
}
+ if (N > UINT32_MAX) {
+ errno = EFBIG;
+ return -1;
+ }
if (((N & (N - 1)) != 0) || (N < 2)) {
errno = EINVAL;
return -1;
diff --git a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c
index 9b585a27..85bb48bd 100644
--- a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c
+++ b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c
@@ -53,6 +53,9 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
int k;
size_t clen;
+ if (dkLen > 0x1fffffffe0UL) {
+ abort();
+ }
crypto_auth_hmacsha256_init(&PShctx, passwd, passwdlen);
crypto_auth_hmacsha256_update(&PShctx, salt, saltlen);
diff --git a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
index a5202ed6..faba9f17 100644
--- a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
+++ b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
@@ -28,7 +28,8 @@
* online backup system.
*/
-#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
+#if defined(HAVE_EMMINTRIN_H) || \
+ (defined(_MSC_VER) && (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
#if __GNUC__
# pragma GCC target("sse2")
#endif
diff --git a/src/libsodium/crypto_scalarmult/curve25519/ref10/fe_frombytes_curve25519_ref10.c b/src/libsodium/crypto_scalarmult/curve25519/ref10/fe_frombytes_curve25519_ref10.c
index f5d92efc..cad8f5a3 100644
--- a/src/libsodium/crypto_scalarmult/curve25519/ref10/fe_frombytes_curve25519_ref10.c
+++ b/src/libsodium/crypto_scalarmult/curve25519/ref10/fe_frombytes_curve25519_ref10.c
@@ -58,16 +58,16 @@ void fe_frombytes(fe h,const unsigned char *s)
carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
- h[0] = h0;
- h[1] = h1;
- h[2] = h2;
- h[3] = h3;
- h[4] = h4;
- h[5] = h5;
- h[6] = h6;
- h[7] = h7;
- h[8] = h8;
- h[9] = h9;
+ h[0] = (crypto_int32) h0;
+ h[1] = (crypto_int32) h1;
+ h[2] = (crypto_int32) h2;
+ h[3] = (crypto_int32) h3;
+ h[4] = (crypto_int32) h4;
+ h[5] = (crypto_int32) h5;
+ h[6] = (crypto_int32) h6;
+ h[7] = (crypto_int32) h7;
+ h[8] = (crypto_int32) h8;
+ h[9] = (crypto_int32) h9;
}
#endif
diff --git a/src/libsodium/include/sodium/crypto_hash_sha256.h b/src/libsodium/include/sodium/crypto_hash_sha256.h
index 2bc33efe..1bb816f4 100644
--- a/src/libsodium/include/sodium/crypto_hash_sha256.h
+++ b/src/libsodium/include/sodium/crypto_hash_sha256.h
@@ -23,7 +23,7 @@ extern "C" {
typedef struct crypto_hash_sha256_state {
uint32_t state[8];
- uint32_t count[2];
+ uint64_t count;
unsigned char buf[64];
} crypto_hash_sha256_state;
SODIUM_EXPORT
diff --git a/src/libsodium/include/sodium/randombytes_salsa20_random.h b/src/libsodium/include/sodium/randombytes_salsa20_random.h
index 46d38c54..e6d291c5 100644
--- a/src/libsodium/include/sodium/randombytes_salsa20_random.h
+++ b/src/libsodium/include/sodium/randombytes_salsa20_random.h
@@ -4,8 +4,9 @@
/*
* THREAD SAFETY: randombytes_salsa20_random*() functions are
- * fork()-safe but not thread-safe.
- * Always wrap them in a mutex if you need thread safety.
+ * not thread-safe.
+ * Always wrap them in a mutex if you need thread safety,
+ * and call randombytes_stir() after fork()ing.
*/
#include
diff --git a/src/libsodium/include/sodium/utils.h b/src/libsodium/include/sodium/utils.h
index 42f21bc2..4384262f 100644
--- a/src/libsodium/include/sodium/utils.h
+++ b/src/libsodium/include/sodium/utils.h
@@ -95,6 +95,9 @@ int sodium_mprotect_readonly(void *ptr);
SODIUM_EXPORT
int sodium_mprotect_readwrite(void *ptr);
+SODIUM_EXPORT
+void sodium_increment(unsigned char *n, const size_t nlen);
+
/* -------- */
int _sodium_alloc_init(void);
diff --git a/src/libsodium/randombytes/randombytes.c b/src/libsodium/randombytes/randombytes.c
index 8444cd4e..29becfc0 100644
--- a/src/libsodium/randombytes/randombytes.c
+++ b/src/libsodium/randombytes/randombytes.c
@@ -66,7 +66,8 @@ randombytes_stir(void)
EM_ASM({
if (Module.getRandomValue === undefined) {
try {
- var crypto_ = ("object" === typeof window ? window : self).crypto,
+ var window_ = "object" === typeof window ? window : self,
+ crypto_ = typeof window_.crypto !== "undefined" ? window_.crypto : window_.msCrypto,
randomValuesStandard = function() {
var buf = new Uint32Array(1);
crypto_.getRandomValues(buf);
diff --git a/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c b/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
index 43e2d0f2..377e4ba2 100644
--- a/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
+++ b/src/libsodium/randombytes/salsa20/randombytes_salsa20_random.c
@@ -65,27 +65,24 @@ static Salsa20Random stream = {
static uint64_t
sodium_hrtime(void)
{
- struct timeval tv;
- uint64_t ts = (uint64_t) 0U;
- int ret;
+ uint64_t ts;
#ifdef _WIN32
- struct _timeb tb;
-
+ {
+ struct _timeb tb;
# pragma warning(push)
# pragma warning(disable: 4996)
- _ftime(&tb);
+ _ftime(&tb);
# pragma warning(pop)
- tv.tv_sec = (long) tb.time;
- tv.tv_usec = ((int) tb.millitm) * 1000;
- ret = 0;
-#else
- ret = gettimeofday(&tv, NULL);
-#endif
- assert(ret == 0);
- if (ret == 0) {
- ts = (uint64_t) tv.tv_sec * 1000000U + (uint64_t) tv.tv_usec;
+ ts = ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U;
}
+#else
+ {
+ struct timeval tv;
+ assert(gettimeofday(&tv, NULL) == 0);
+ ts = ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec;
+ }
+#endif
return ts;
}
@@ -224,6 +221,17 @@ randombytes_salsa20_random_init(void)
}
#endif
+static void
+randombytes_salsa20_random_rekey(const unsigned char * const mix)
+{
+ unsigned char *key = stream.key;
+ size_t i;
+
+ for (i = (size_t) 0U; i < sizeof stream.key; i++) {
+ key[i] ^= mix[i];
+ }
+}
+
void
randombytes_salsa20_random_stir(void)
{
@@ -270,10 +278,11 @@ randombytes_salsa20_random_stir(void)
COMPILER_ASSERT(sizeof stream.key == crypto_auth_hmacsha512256_BYTES);
crypto_auth_hmacsha512256(stream.key, k0, sizeof_k0, s);
COMPILER_ASSERT(sizeof stream.key <= sizeof m0);
- for (i = (size_t) 0U; i < sizeof stream.key; i++) {
- stream.key[i] ^= m0[i];
- }
+ randombytes_salsa20_random_rekey(m0);
sodium_memzero(m0, sizeof m0);
+#ifndef _MSC_VER
+ stream.pid = getpid();
+#endif
}
static void
@@ -284,26 +293,14 @@ randombytes_salsa20_random_stir_if_needed(void)
randombytes_salsa20_random_stir();
}
#else
- const pid_t pid = getpid();
-
- if (stream.initialized == 0 || stream.pid != pid) {
- stream.pid = pid;
+ if (stream.initialized == 0) {
randombytes_salsa20_random_stir();
+ } else if (stream.pid != getpid()) {
+ abort();
}
#endif
}
-static void
-randombytes_salsa20_random_rekey(const unsigned char * const mix)
-{
- unsigned char *key = stream.key;
- size_t i;
-
- for (i = (size_t) 0U; i < sizeof stream.key; i++) {
- key[i] ^= mix[i];
- }
-}
-
static uint32_t
randombytes_salsa20_random_getword(void)
{
@@ -342,6 +339,7 @@ randombytes_salsa20_random_close(void)
close(stream.random_data_source_fd) == 0) {
stream.random_data_source_fd = -1;
stream.initialized = 0;
+ stream.pid = (pid_t) 0;
ret = 0;
}
# ifdef SYS_getrandom
diff --git a/src/libsodium/sodium/runtime.c b/src/libsodium/sodium/runtime.c
index 3e424a01..93b07932 100644
--- a/src/libsodium/sodium/runtime.c
+++ b/src/libsodium/sodium/runtime.c
@@ -43,7 +43,8 @@ _sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features)
static void
_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type)
{
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && \
+ (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86))
__cpuid((int *) cpu_info, cpu_info_type);
#elif defined(HAVE_CPUID)
cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
diff --git a/src/libsodium/sodium/utils.c b/src/libsodium/sodium/utils.c
index 1ba1d8e5..609820cf 100644
--- a/src/libsodium/sodium/utils.c
+++ b/src/libsodium/sodium/utils.c
@@ -23,6 +23,10 @@
# include
#endif
+#if defined(_WIN32) && (!defined(WINAPI_FAMILY) || WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
+# define WINAPI_DESKTOP
+#endif
+
#define CANARY_SIZE 16U
#define GARBAGE_VALUE 0xd0
@@ -32,13 +36,13 @@
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
# define MAP_ANON MAP_ANONYMOUS
#endif
-#if defined(_WIN32) || (defined(MAP_ANON) && defined(HAVE_MMAP)) || defined(HAVE_POSIX_MEMALIGN)
+#if defined(WINAPI_DESKTOP) || (defined(MAP_ANON) && defined(HAVE_MMAP)) || defined(HAVE_POSIX_MEMALIGN)
# define HAVE_ALIGNED_MALLOC
#endif
#if defined(HAVE_MPROTECT) && !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE))
# undef HAVE_MPROTECT
#endif
-#if defined(HAVE_ALIGNED_MALLOC) && (defined(_WIN32) || defined(HAVE_MPROTECT))
+#if defined(HAVE_ALIGNED_MALLOC) && (defined(WINAPI_DESKTOP) || defined(HAVE_MPROTECT))
# define HAVE_PAGE_PROTECTION
#endif
@@ -184,7 +188,7 @@ _sodium_alloc_init(void)
if (page_size_ > 0L) {
page_size = (size_t) page_size_;
}
-# elif defined(_WIN32)
+# elif defined(WINAPI_DESKTOP)
SYSTEM_INFO si;
GetSystemInfo(&si);
page_size = (size_t) si.dwPageSize;
@@ -206,7 +210,7 @@ sodium_mlock(void * const addr, const size_t len)
#endif
#ifdef HAVE_MLOCK
return mlock(addr, len);
-#elif defined(_WIN32)
+#elif defined(WINAPI_DESKTOP)
return -(VirtualLock(addr, len) == 0);
#else
errno = ENOSYS;
@@ -223,7 +227,7 @@ sodium_munlock(void * const addr, const size_t len)
#endif
#ifdef HAVE_MLOCK
return munlock(addr, len);
-#elif defined(_WIN32)
+#elif defined(WINAPI_DESKTOP)
return -(VirtualUnlock(addr, len) == 0);
#else
errno = ENOSYS;
@@ -236,7 +240,7 @@ _mprotect_noaccess(void *ptr, size_t size)
{
#ifdef HAVE_MPROTECT
return mprotect(ptr, size, PROT_NONE);
-#elif defined(_WIN32)
+#elif defined(WINAPI_DESKTOP)
DWORD old;
return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0);
#else
@@ -250,7 +254,7 @@ _mprotect_readonly(void *ptr, size_t size)
{
#ifdef HAVE_MPROTECT
return mprotect(ptr, size, PROT_READ);
-#elif defined(_WIN32)
+#elif defined(WINAPI_DESKTOP)
DWORD old;
return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0);
#else
@@ -264,7 +268,7 @@ _mprotect_readwrite(void *ptr, size_t size)
{
#ifdef HAVE_MPROTECT
return mprotect(ptr, size, PROT_READ | PROT_WRITE);
-#elif defined(_WIN32)
+#elif defined(WINAPI_DESKTOP)
DWORD old;
return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0);
#else
@@ -308,7 +312,7 @@ _alloc_aligned(const size_t size)
if (posix_memalign(&ptr, page_size, size) != 0) {
ptr = NULL; /* LCOV_EXCL_LINE */
} /* LCOV_EXCL_LINE */
-# elif defined(_WIN32)
+# elif defined(WINAPI_DESKTOP)
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
# else
# error Bug
@@ -323,7 +327,7 @@ _free_aligned(unsigned char * const ptr, const size_t size)
(void) munmap(ptr, size);
# elif defined(HAVE_POSIX_MEMALIGN)
free(ptr);
-# elif defined(_WIN32)
+# elif defined(WINAPI_DESKTOP)
VirtualFree(ptr, 0U, MEM_RELEASE);
# else
# error Bug
@@ -506,3 +510,16 @@ sodium_mprotect_readwrite(void *ptr)
{
return _sodium_mprotect(ptr, _mprotect_readwrite);
}
+
+void
+sodium_increment(unsigned char *n, const size_t nlen)
+{
+ size_t i;
+ unsigned int c = 1U << 8;
+
+ for (i = (size_t) 0U; i < nlen; i++) {
+ c >>= 8;
+ c += n[i];
+ n[i] = (unsigned char) c;
+ }
+}
diff --git a/test/default/sodium_utils.c b/test/default/sodium_utils.c
index 89274deb..137aab0b 100644
--- a/test/default/sodium_utils.c
+++ b/test/default/sodium_utils.c
@@ -8,6 +8,8 @@ int main(void)
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;
@@ -60,5 +62,26 @@ int main(void)
}
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));
return 0;
}
diff --git a/test/default/sodium_utils.exp b/test/default/sodium_utils.exp
index e087a911..661e6570 100644
--- a/test/default/sodium_utils.exp
+++ b/test/default/sodium_utils.exp
@@ -11,3 +11,8 @@ dt2: 2
dt3: 11
dt4: 11
dt5: 11
+010000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000
+010100000000000000000000000000000000000000000000
+020000000000000000000000000000000000000000000000
+0001ff000000000000000000000000000000000000000000