diff --git a/.gitignore b/.gitignore index 50d47f3d..9adea7ab 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,7 @@ test/default/box7 test/default/box8 test/default/box_easy test/default/box_easy2 +test/default/box_seal test/default/box_seed test/default/chacha20 test/default/core1 diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj index 04c8950e..42f8e490 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj @@ -163,6 +163,7 @@ + diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters index 438508a9..cd65154e 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters @@ -460,6 +460,9 @@ src\crypto_box + + src\crypto_box + src\crypto_secretbox diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj index d6edfc43..a7fb1b9a 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj @@ -163,6 +163,7 @@ + diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters index 438508a9..cd65154e 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters @@ -460,6 +460,9 @@ src\crypto_box + + src\crypto_box + src\crypto_secretbox diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj index bd30e82a..06cdd004 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj @@ -163,6 +163,7 @@ + diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters index 438508a9..cd65154e 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters @@ -460,6 +460,9 @@ src\crypto_box + + src\crypto_box + src\crypto_secretbox diff --git a/dist-build/emscripten.sh b/dist-build/emscripten.sh index 29e120fe..728375c3 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_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_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_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 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/libsodium.vcxproj b/libsodium.vcxproj index 4100a188..80714856 100644 --- a/libsodium.vcxproj +++ b/libsodium.vcxproj @@ -383,6 +383,7 @@ + diff --git a/libsodium.vcxproj.filters b/libsodium.vcxproj.filters index 18f0b461..4cee5b22 100644 --- a/libsodium.vcxproj.filters +++ b/libsodium.vcxproj.filters @@ -569,6 +569,9 @@ Source Files + + Source Files + Source Files diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index c45119dc..d6813454 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -18,6 +18,7 @@ libsodium_la_SOURCES = \ crypto_auth/hmacsha512256/cp/verify_hmacsha512256.c \ crypto_box/crypto_box.c \ crypto_box/crypto_box_easy.c \ + crypto_box/crypto_box_seal.c \ crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305_api.c \ crypto_box/curve25519xsalsa20poly1305/ref/api.h \ crypto_box/curve25519xsalsa20poly1305/ref/after_curve25519xsalsa20poly1305.c \ diff --git a/src/libsodium/crypto_box/crypto_box_seal.c b/src/libsodium/crypto_box/crypto_box_seal.c new file mode 100644 index 00000000..0feab7ea --- /dev/null +++ b/src/libsodium/crypto_box/crypto_box_seal.c @@ -0,0 +1,65 @@ + +#include + +#include "crypto_box.h" +#include "crypto_generichash.h" +#include "utils.h" + +static int +_crypto_box_seal_nonce(unsigned char *nonce, + const unsigned char *pk1, const unsigned char *pk2) +{ + crypto_generichash_state st; + + crypto_generichash_init(&st, NULL, 0U, crypto_box_NONCEBYTES); + crypto_generichash_update(&st, pk1, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&st, pk2, crypto_box_PUBLICKEYBYTES); + crypto_generichash_final(&st, nonce, crypto_box_NONCEBYTES); + + return 0; +} + +int +crypto_box_seal(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *pk) +{ + unsigned char nonce[crypto_box_NONCEBYTES]; + unsigned char epk[crypto_box_PUBLICKEYBYTES]; + unsigned char esk[crypto_box_SECRETKEYBYTES]; + int ret; + + if (crypto_box_keypair(epk, esk) != 0) { + return -1; + } + memcpy(out, epk, crypto_box_PUBLICKEYBYTES); + _crypto_box_seal_nonce(nonce, epk, pk); + ret = crypto_box_easy(out + crypto_box_PUBLICKEYBYTES, in, inlen, + nonce, pk, esk); + sodium_memzero(esk, sizeof esk); + + return ret; +} + +int +crypto_box_seal_open(unsigned char *out, const unsigned char *in, + unsigned long long inlen, + const unsigned char *pk, const unsigned char *sk) +{ + unsigned char nonce[crypto_box_NONCEBYTES]; + + if (inlen < crypto_box_SEALBYTES) { + return -1; + } + _crypto_box_seal_nonce(nonce, in, pk); + + (void) sizeof(int[crypto_box_PUBLICKEYBYTES < crypto_box_SEALBYTES ? 1 : -1]); + return crypto_box_open_easy(out, in + crypto_box_PUBLICKEYBYTES, + inlen - crypto_box_PUBLICKEYBYTES, + nonce, in, sk); +} + +size_t +crypto_box_sealbytes(void) +{ + return crypto_box_SEALBYTES; +} diff --git a/src/libsodium/include/sodium/crypto_box.h b/src/libsodium/include/sodium/crypto_box.h index 8fff2d27..b780055a 100644 --- a/src/libsodium/include/sodium/crypto_box.h +++ b/src/libsodium/include/sodium/crypto_box.h @@ -106,6 +106,21 @@ int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, unsigned long long clen, const unsigned char *n, const unsigned char *k); +/* -- Ephemeral SK interface -- */ + +#define crypto_box_SEALBYTES (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_sealbytes(void); + +SODIUM_EXPORT +int crypto_box_seal(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *pk); + +SODIUM_EXPORT +int crypto_box_seal_open(unsigned char *out, const unsigned char *in, + unsigned long long inlen, + const unsigned char *pk, const unsigned char *sk); + /* -- NaCl compatibility interface ; Requires padding -- */ #define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES diff --git a/test/default/Makefile.am b/test/default/Makefile.am index d665ba02..a4bf6e7d 100644 --- a/test/default/Makefile.am +++ b/test/default/Makefile.am @@ -16,6 +16,7 @@ EXTRA_DIST = \ box8.exp \ box_easy.exp \ box_easy2.exp \ + box_seal.exp \ box_seed.exp \ chacha20.exp \ core1.exp \ @@ -75,6 +76,7 @@ DISTCLEANFILES = \ box8.res \ box_easy.res \ box_easy2.res \ + box_seal.res \ box_seed.res \ chacha20.res \ core1.res \ @@ -144,6 +146,7 @@ TESTS_TARGETS = \ box8 \ box_easy \ box_easy2 \ + box_seal \ box_seed \ chacha20 \ core1 \ @@ -238,6 +241,9 @@ box_easy_LDADD = $(TESTS_LDADD) box_easy2_SOURCE = cmptest.h box_easy2.c box_easy2_LDADD = $(TESTS_LDADD) +box_seal_SOURCE = cmptest.h box_seal.c +box_seal_LDADD = $(TESTS_LDADD) + box_seed_SOURCE = cmptest.h box_seed.c box_seed_LDADD = $(TESTS_LDADD) diff --git a/test/default/box_seal.c b/test/default/box_seal.c new file mode 100644 index 00000000..1d73e30c --- /dev/null +++ b/test/default/box_seal.c @@ -0,0 +1,43 @@ + +#define TEST_NAME "box_seal" +#include "cmptest.h" + +int main(void) +{ + unsigned char pk[crypto_box_PUBLICKEYBYTES]; + unsigned char sk[crypto_box_SECRETKEYBYTES]; + unsigned char *c; + unsigned char *m; + unsigned char *m2; + size_t m_len; + size_t c_len; + + crypto_box_keypair(pk, sk); + m_len = (size_t) randombytes_uniform(1000); + c_len = crypto_box_SEALBYTES + m_len; + m = (unsigned char *) sodium_malloc(m_len); + m2 = (unsigned char *) sodium_malloc(m_len); + c = (unsigned char *) sodium_malloc(c_len); + randombytes_buf(m, m_len); + if (crypto_box_seal(c, m, m_len, pk) != 0) { + printf("crypto_box_seal() failure\n"); + return 1; + } + if (crypto_box_seal_open(m2, c, c_len, pk, sk) != 0) { + printf("crypto_box_seal_open() failure\n"); + return 1; + } + printf("%d\n", memcmp(m, m2, m_len)); + + printf("%d\n", crypto_box_seal_open(m, c, 0U, pk, sk)); + printf("%d\n", crypto_box_seal_open(m, c, c_len - 1U, pk, sk)); + printf("%d\n", crypto_box_seal_open(m, c, c_len, sk, pk)); + + sodium_free(c); + sodium_free(m); + sodium_free(m2); + + assert(crypto_box_sealbytes() == crypto_box_SEALBYTES); + + return 0; +} diff --git a/test/default/box_seal.exp b/test/default/box_seal.exp new file mode 100644 index 00000000..78ea705a --- /dev/null +++ b/test/default/box_seal.exp @@ -0,0 +1,4 @@ +0 +-1 +-1 +-1