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