From 7f3bc5cd0840b23d81f2b112d1f31603deaaf18d Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 25 Dec 2018 11:10:33 +0100 Subject: [PATCH] Add low-level kx_curve25519 functions --- src/libsodium/Makefile.am | 2 + src/libsodium/crypto_kx/crypto_kx.c | 96 ++---------- .../crypto_kx/curve25519/kx_curve25519.c | 143 ++++++++++++++++++ src/libsodium/include/sodium.h | 1 + src/libsodium/include/sodium/crypto_kx.h | 11 +- .../include/sodium/crypto_kx_curve25519.h | 66 ++++++++ 6 files changed, 230 insertions(+), 89 deletions(-) create mode 100644 src/libsodium/crypto_kx/curve25519/kx_curve25519.c create mode 100644 src/libsodium/include/sodium/crypto_kx_curve25519.h diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 2c3d210f..706d006e 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -1,3 +1,4 @@ + lib_LTLIBRARIES = \ libsodium.la @@ -34,6 +35,7 @@ libsodium_la_SOURCES = \ crypto_kdf/blake2b/kdf_blake2b.c \ crypto_kdf/crypto_kdf.c \ crypto_kx/crypto_kx.c \ + crypto_kx/curve25519/kx_curve25519.c \ crypto_onetimeauth/crypto_onetimeauth.c \ crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ crypto_onetimeauth/poly1305/onetimeauth_poly1305.h \ diff --git a/src/libsodium/crypto_kx/crypto_kx.c b/src/libsodium/crypto_kx/crypto_kx.c index 877ab7ff..729d464f 100644 --- a/src/libsodium/crypto_kx/crypto_kx.c +++ b/src/libsodium/crypto_kx/crypto_kx.c @@ -1,33 +1,21 @@ -#include - -#include "core.h" -#include "crypto_generichash.h" #include "crypto_kx.h" -#include "crypto_scalarmult.h" +#include "crypto_kx_curve25519.h" #include "private/common.h" -#include "randombytes.h" -#include "utils.h" int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], unsigned char sk[crypto_kx_SECRETKEYBYTES], const unsigned char seed[crypto_kx_SEEDBYTES]) { - crypto_generichash(sk, crypto_kx_SECRETKEYBYTES, - seed, crypto_kx_SEEDBYTES, NULL, 0); - return crypto_scalarmult_base(pk, sk); + return crypto_kx_curve25519_seed_keypair(pk, sk, seed); } int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], unsigned char sk[crypto_kx_SECRETKEYBYTES]) { - COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES); - COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES); - - randombytes_buf(sk, crypto_kx_SECRETKEYBYTES); - return crypto_scalarmult_base(pk, sk); + return crypto_kx_curve25519_keypair(pk, sk); } int @@ -37,38 +25,8 @@ crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) { - crypto_generichash_state h; - unsigned char q[crypto_scalarmult_BYTES]; - unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; - int i; - - if (rx == NULL) { - rx = tx; - } - if (tx == NULL) { - tx = rx; - } - if (rx == NULL) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - if (crypto_scalarmult(q, client_sk, server_pk) != 0) { - return -1; - } - COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); - crypto_generichash_init(&h, NULL, 0U, sizeof keys); - crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); - sodium_memzero(q, sizeof q); - crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); - crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); - crypto_generichash_final(&h, keys, sizeof keys); - sodium_memzero(&h, sizeof h); - for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { - rx[i] = keys[i]; - tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; - } - sodium_memzero(keys, sizeof keys); - - return 0; + return crypto_kx_curve25519_client_session_keys(rx, tx, client_pk, + client_sk, server_pk); } int @@ -78,66 +36,36 @@ crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) { - crypto_generichash_state h; - unsigned char q[crypto_scalarmult_BYTES]; - unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; - int i; - - if (rx == NULL) { - rx = tx; - } - if (tx == NULL) { - tx = rx; - } - if (rx == NULL) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - if (crypto_scalarmult(q, server_sk, client_pk) != 0) { - return -1; - } - COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); - crypto_generichash_init(&h, NULL, 0U, sizeof keys); - crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); - sodium_memzero(q, sizeof q); - crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); - crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); - crypto_generichash_final(&h, keys, sizeof keys); - sodium_memzero(&h, sizeof h); - for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { - tx[i] = keys[i]; - rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; - } - sodium_memzero(keys, sizeof keys); - - return 0; + return crypto_kx_curve25519_server_session_keys(rx, tx, server_pk, + server_sk, client_pk); } size_t crypto_kx_publickeybytes(void) { - return crypto_kx_PUBLICKEYBYTES; + return crypto_kx_curve25519_PUBLICKEYBYTES; } size_t crypto_kx_secretkeybytes(void) { - return crypto_kx_SECRETKEYBYTES; + return crypto_kx_curve25519_SECRETKEYBYTES; } size_t crypto_kx_seedbytes(void) { - return crypto_kx_SEEDBYTES; + return crypto_kx_curve25519_SEEDBYTES; } size_t crypto_kx_sessionkeybytes(void) { - return crypto_kx_SESSIONKEYBYTES; + return crypto_kx_curve25519_SESSIONKEYBYTES; } const char * crypto_kx_primitive(void) { - return crypto_kx_PRIMITIVE; + return crypto_kx_curve25519_PRIMITIVE; } diff --git a/src/libsodium/crypto_kx/curve25519/kx_curve25519.c b/src/libsodium/crypto_kx/curve25519/kx_curve25519.c new file mode 100644 index 00000000..4709a7de --- /dev/null +++ b/src/libsodium/crypto_kx/curve25519/kx_curve25519.c @@ -0,0 +1,143 @@ + +#include + +#include "core.h" +#include "crypto_generichash.h" +#include "crypto_kx_curve25519.h" +#include "crypto_scalarmult_curve25519.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_kx_curve25519_seed_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_curve25519_SEEDBYTES]) +{ + crypto_generichash(sk, crypto_kx_curve25519_SECRETKEYBYTES, + seed, crypto_kx_curve25519_SEEDBYTES, NULL, 0); + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_kx_curve25519_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES]) +{ + COMPILER_ASSERT(crypto_kx_curve25519_SECRETKEYBYTES == crypto_scalarmult_curve25519_SCALARBYTES); + COMPILER_ASSERT(crypto_kx_curve25519_PUBLICKEYBYTES == crypto_scalarmult_curve25519_BYTES); + + randombytes_buf(sk, crypto_kx_curve25519_SECRETKEYBYTES); + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_kx_curve25519_client_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_curve25519_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES]) +{ + crypto_generichash_state h; + unsigned char q[crypto_scalarmult_curve25519_BYTES]; + unsigned char keys[2 * crypto_kx_curve25519_SESSIONKEYBYTES]; + int i; + + if (rx == NULL) { + rx = tx; + } + if (tx == NULL) { + tx = rx; + } + if (rx == NULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (crypto_scalarmult_curve25519(q, client_sk, server_pk) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); + crypto_generichash_init(&h, NULL, 0U, sizeof keys); + crypto_generichash_update(&h, q, crypto_scalarmult_curve25519_BYTES); + sodium_memzero(q, sizeof q); + crypto_generichash_update(&h, client_pk, crypto_kx_curve25519_PUBLICKEYBYTES); + crypto_generichash_update(&h, server_pk, crypto_kx_curve25519_PUBLICKEYBYTES); + crypto_generichash_final(&h, keys, sizeof keys); + sodium_memzero(&h, sizeof h); + for (i = 0; i < crypto_kx_curve25519_SESSIONKEYBYTES; i++) { + rx[i] = keys[i]; + tx[i] = keys[i + crypto_kx_curve25519_SESSIONKEYBYTES]; + } + sodium_memzero(keys, sizeof keys); + + return 0; +} + +int +crypto_kx_curve25519_server_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_curve25519_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES]) +{ + crypto_generichash_state h; + unsigned char q[crypto_scalarmult_curve25519_BYTES]; + unsigned char keys[2 * crypto_kx_curve25519_SESSIONKEYBYTES]; + int i; + + if (rx == NULL) { + rx = tx; + } + if (tx == NULL) { + tx = rx; + } + if (rx == NULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (crypto_scalarmult_curve25519(q, server_sk, client_pk) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); + crypto_generichash_init(&h, NULL, 0U, sizeof keys); + crypto_generichash_update(&h, q, crypto_scalarmult_curve25519_BYTES); + sodium_memzero(q, sizeof q); + crypto_generichash_update(&h, client_pk, crypto_kx_curve25519_PUBLICKEYBYTES); + crypto_generichash_update(&h, server_pk, crypto_kx_curve25519_PUBLICKEYBYTES); + crypto_generichash_final(&h, keys, sizeof keys); + sodium_memzero(&h, sizeof h); + for (i = 0; i < crypto_kx_curve25519_SESSIONKEYBYTES; i++) { + tx[i] = keys[i]; + rx[i] = keys[i + crypto_kx_curve25519_SESSIONKEYBYTES]; + } + sodium_memzero(keys, sizeof keys); + + return 0; +} + +size_t +crypto_kx_curve25519_publickeybytes(void) +{ + return crypto_kx_curve25519_PUBLICKEYBYTES; +} + +size_t +crypto_kx_curve25519_secretkeybytes(void) +{ + return crypto_kx_curve25519_SECRETKEYBYTES; +} + +size_t +crypto_kx_curve25519_seedbytes(void) +{ + return crypto_kx_curve25519_SEEDBYTES; +} + +size_t +crypto_kx_curve25519_sessionkeybytes(void) +{ + return crypto_kx_curve25519_SESSIONKEYBYTES; +} + +const char * +crypto_kx_curve25519_primitive(void) +{ + return crypto_kx_curve25519_PRIMITIVE; +} diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index e7b1af46..f3049b2f 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -27,6 +27,7 @@ #include "sodium/crypto_kdf.h" #include "sodium/crypto_kdf_blake2b.h" #include "sodium/crypto_kx.h" +#include "sodium/crypto_kx_curve25519.h" #include "sodium/crypto_onetimeauth.h" #include "sodium/crypto_onetimeauth_poly1305.h" #include "sodium/crypto_pwhash.h" diff --git a/src/libsodium/include/sodium/crypto_kx.h b/src/libsodium/include/sodium/crypto_kx.h index 347132c3..6cd8b255 100644 --- a/src/libsodium/include/sodium/crypto_kx.h +++ b/src/libsodium/include/sodium/crypto_kx.h @@ -3,6 +3,7 @@ #include +#include "crypto_kx_curve25519.h" #include "export.h" #ifdef __cplusplus @@ -12,23 +13,23 @@ extern "C" { #endif -#define crypto_kx_PUBLICKEYBYTES 32 +#define crypto_kx_PUBLICKEYBYTES crypto_kx_curve25519_PUBLICKEYBYTES SODIUM_EXPORT size_t crypto_kx_publickeybytes(void); -#define crypto_kx_SECRETKEYBYTES 32 +#define crypto_kx_SECRETKEYBYTES crypto_kx_curve25519_SECRETKEYBYTES SODIUM_EXPORT size_t crypto_kx_secretkeybytes(void); -#define crypto_kx_SEEDBYTES 32 +#define crypto_kx_SEEDBYTES crypto_kx_curve25519_SEEDBYTES SODIUM_EXPORT size_t crypto_kx_seedbytes(void); -#define crypto_kx_SESSIONKEYBYTES 32 +#define crypto_kx_SESSIONKEYBYTES crypto_kx_curve25519_SESSIONKEYBYTES SODIUM_EXPORT size_t crypto_kx_sessionkeybytes(void); -#define crypto_kx_PRIMITIVE "x25519blake2b" +#define crypto_kx_PRIMITIVE crypto_kx_curve25519_PRIMITIVE SODIUM_EXPORT const char *crypto_kx_primitive(void); diff --git a/src/libsodium/include/sodium/crypto_kx_curve25519.h b/src/libsodium/include/sodium/crypto_kx_curve25519.h new file mode 100644 index 00000000..1b6beabe --- /dev/null +++ b/src/libsodium/include/sodium/crypto_kx_curve25519.h @@ -0,0 +1,66 @@ +#ifndef crypto_kx_curve25519_H +#define crypto_kx_curve25519_H + +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kx_curve25519_PUBLICKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_curve25519_publickeybytes(void); + +#define crypto_kx_curve25519_SECRETKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_curve25519_secretkeybytes(void); + +#define crypto_kx_curve25519_SEEDBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_curve25519_seedbytes(void); + +#define crypto_kx_curve25519_SESSIONKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_curve25519_sessionkeybytes(void); + +#define crypto_kx_curve25519_PRIMITIVE "x25519blake2b" +SODIUM_EXPORT +const char *crypto_kx_curve25519_primitive(void); + +SODIUM_EXPORT +int crypto_kx_curve25519_seed_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_curve25519_SEEDBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kx_curve25519_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kx_curve25519_client_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_curve25519_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5))); + +SODIUM_EXPORT +int crypto_kx_curve25519_server_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_curve25519_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5))); + +#ifdef __cplusplus +} +#endif + +#endif