Add kx_* functions from libsodium 1.0.12
This commit is contained in:
parent
a708d0b11e
commit
2da2ba138f
@ -1028,6 +1028,101 @@ ERL_NIF_TERM enif_randombytes(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[
|
|||||||
return enif_make_binary(env, &result);
|
return enif_make_binary(env, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Key exchange */
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_kx_SECRETKEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_kx_SECRETKEYBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_kx_PUBLICKEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_kx_PUBLICKEYBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_kx_SESSIONKEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_kx_SESSIONKEYBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_kx_keypair(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
|
||||||
|
{
|
||||||
|
ErlNifBinary pk, sk;
|
||||||
|
|
||||||
|
if (argc != 0) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enif_alloc_binary(crypto_kx_PUBLICKEYBYTES, &pk)) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enif_alloc_binary(crypto_kx_SECRETKEYBYTES, &sk)) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_kx_keypair(pk.data, sk.data);
|
||||||
|
|
||||||
|
return enif_make_tuple2(env, enif_make_binary(env, &pk), enif_make_binary(env, &sk));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_kx_server_session_keys(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
|
||||||
|
{
|
||||||
|
ErlNifBinary rx, tx, server_pk, server_sk, client_pk;
|
||||||
|
|
||||||
|
if ((argc != 3) ||
|
||||||
|
(!enif_inspect_binary(env, argv[0], &server_pk)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[1], &server_sk)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[2], &client_pk)) ||
|
||||||
|
(server_pk.size != crypto_kx_PUBLICKEYBYTES) ||
|
||||||
|
(server_sk.size != crypto_kx_SECRETKEYBYTES) ||
|
||||||
|
(client_pk.size != crypto_kx_PUBLICKEYBYTES)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &rx)) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &tx)) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_kx_server_session_keys(rx.data, tx.data, server_pk.data, server_sk.data, client_pk.data);
|
||||||
|
|
||||||
|
return enif_make_tuple2(env, enif_make_binary(env, &rx), enif_make_binary(env, &tx));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_kx_client_session_keys(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
|
||||||
|
{
|
||||||
|
ErlNifBinary rx, tx, client_pk, client_sk, server_pk;
|
||||||
|
|
||||||
|
if ((argc != 3) ||
|
||||||
|
(!enif_inspect_binary(env, argv[0], &client_pk)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[1], &client_sk)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[2], &server_pk)) ||
|
||||||
|
(client_pk.size != crypto_kx_PUBLICKEYBYTES) ||
|
||||||
|
(client_sk.size != crypto_kx_SECRETKEYBYTES) ||
|
||||||
|
(server_pk.size != crypto_kx_PUBLICKEYBYTES)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &rx)) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &tx)) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_kx_client_session_keys(rx.data, tx.data, client_pk.data, client_sk.data, server_pk.data);
|
||||||
|
|
||||||
|
return enif_make_tuple2(env, enif_make_binary(env, &rx), enif_make_binary(env, &tx));
|
||||||
|
}
|
||||||
|
|
||||||
/* Various other helper functions */
|
/* Various other helper functions */
|
||||||
static
|
static
|
||||||
void uint64_pack(unsigned char *y, ErlNifUInt64 x)
|
void uint64_pack(unsigned char *y, ErlNifUInt64 x)
|
||||||
@ -1195,6 +1290,13 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
|
|
||||||
{"randombytes", 1, enif_randombytes, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
{"randombytes", 1, enif_randombytes, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
|
||||||
|
{"crypto_kx_keypair", 0, enif_crypto_kx_keypair, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
{"crypto_kx_client_session_keys", 3, enif_crypto_kx_client_session_keys, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
{"crypto_kx_server_session_keys", 3, enif_crypto_kx_server_session_keys, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
{"crypto_kx_PUBLICKEYBYTES", 0, enif_crypto_kx_PUBLICKEYBYTES},
|
||||||
|
{"crypto_kx_SECRETKEYBYTES", 0, enif_crypto_kx_SECRETKEYBYTES},
|
||||||
|
{"crypto_kx_SESSIONKEYBYTES", 0, enif_crypto_kx_SESSIONKEYBYTES},
|
||||||
|
|
||||||
{"scramble_block_16", 2, enif_scramble_block_16}
|
{"scramble_block_16", 2, enif_scramble_block_16}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,6 +96,16 @@
|
|||||||
unsafe_memzero/1
|
unsafe_memzero/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
%% Key exchange functions
|
||||||
|
-export([
|
||||||
|
kx_keypair/0,
|
||||||
|
kx_client_session_keys/3,
|
||||||
|
kx_server_session_keys/3,
|
||||||
|
kx_public_key_size/0,
|
||||||
|
kx_secret_key_size/0,
|
||||||
|
kx_session_key_size/0
|
||||||
|
]).
|
||||||
|
|
||||||
%% Libsodium specific functions (which are also part of the "undocumented" interface to NaCl
|
%% Libsodium specific functions (which are also part of the "undocumented" interface to NaCl
|
||||||
-export([
|
-export([
|
||||||
randombytes/1
|
randombytes/1
|
||||||
@ -139,6 +149,9 @@
|
|||||||
-define(CRYPTO_STREAM_CHACHA20_NONCEBYTES, 8).
|
-define(CRYPTO_STREAM_CHACHA20_NONCEBYTES, 8).
|
||||||
-define(CRYPTO_STREAM_KEYBYTES, 32).
|
-define(CRYPTO_STREAM_KEYBYTES, 32).
|
||||||
-define(CRYPTO_STREAM_NONCEBYTES, 24).
|
-define(CRYPTO_STREAM_NONCEBYTES, 24).
|
||||||
|
-define(CRYPTO_KX_PUBLICKEYBYTES, 32).
|
||||||
|
-define(CRYPTO_KX_SECRETKEYBYTES, 32).
|
||||||
|
-define(CRYPTO_KX_SESSIONKEYBYTES, 32).
|
||||||
|
|
||||||
%% @doc Verify makes sure the constants defined in libsodium matches ours
|
%% @doc Verify makes sure the constants defined in libsodium matches ours
|
||||||
verify() ->
|
verify() ->
|
||||||
@ -156,7 +169,10 @@ verify() ->
|
|||||||
{crypto_box_ZEROBYTES, ?CRYPTO_BOX_ZEROBYTES},
|
{crypto_box_ZEROBYTES, ?CRYPTO_BOX_ZEROBYTES},
|
||||||
{crypto_box_BOXZEROBYTES, ?CRYPTO_BOX_BOXZEROBYTES},
|
{crypto_box_BOXZEROBYTES, ?CRYPTO_BOX_BOXZEROBYTES},
|
||||||
{crypto_secretbox_ZEROBYTES, ?CRYPTO_SECRETBOX_ZEROBYTES},
|
{crypto_secretbox_ZEROBYTES, ?CRYPTO_SECRETBOX_ZEROBYTES},
|
||||||
{crypto_secretbox_BOXZEROBYTES, ?CRYPTO_SECRETBOX_BOXZEROBYTES}
|
{crypto_secretbox_BOXZEROBYTES, ?CRYPTO_SECRETBOX_BOXZEROBYTES},
|
||||||
|
{crypto_kx_SESSIONKEYBYTES, ?CRYPTO_KX_SESSIONKEYBYTES},
|
||||||
|
{crypto_kx_PUBLICKEYBYTES, ?CRYPTO_KX_PUBLICKEYBYTES},
|
||||||
|
{crypto_kx_SECRETKEYBYTES, ?CRYPTO_KX_SECRETKEYBYTES}
|
||||||
],
|
],
|
||||||
run_verifiers(Verifiers).
|
run_verifiers(Verifiers).
|
||||||
|
|
||||||
@ -577,8 +593,6 @@ stream_chacha20_xor(Msg, Nonce, Key) ->
|
|||||||
enacl_nif:crypto_stream_chacha20_xor(Msg, Nonce, Key)
|
enacl_nif:crypto_stream_chacha20_xor(Msg, Nonce, Key)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc auth_key_size/0 returns the byte-size of the authentication key
|
|
||||||
%% @end
|
|
||||||
%% @doc stream_nonce_size/0 returns the byte size of the nonce for streams
|
%% @doc stream_nonce_size/0 returns the byte size of the nonce for streams
|
||||||
%% @end
|
%% @end
|
||||||
-spec stream_nonce_size() -> ?CRYPTO_STREAM_NONCEBYTES.
|
-spec stream_nonce_size() -> ?CRYPTO_STREAM_NONCEBYTES.
|
||||||
@ -812,6 +826,67 @@ crypto_sign_ed25519_public_size() ->
|
|||||||
crypto_sign_ed25519_secret_size() ->
|
crypto_sign_ed25519_secret_size() ->
|
||||||
enacl_nif:crypto_sign_ed25519_SECRETKEYBYTES().
|
enacl_nif:crypto_sign_ed25519_SECRETKEYBYTES().
|
||||||
|
|
||||||
|
%% Key exchange functions
|
||||||
|
%% ----------------------
|
||||||
|
%% @doc kx_keypair/0 creates a new Public/Secret keypair.
|
||||||
|
%%
|
||||||
|
%% Generates and returns a new key pair for the key exchange. The return value is a
|
||||||
|
%% map in order to avoid using the public key as a secret key and vice versa.
|
||||||
|
%% @end
|
||||||
|
-spec kx_keypair() -> #{ atom() => binary() }.
|
||||||
|
kx_keypair() ->
|
||||||
|
{PK, SK} = enacl_nif:crypto_kx_keypair(),
|
||||||
|
#{ public => PK, secret => SK}.
|
||||||
|
|
||||||
|
%% @doc kx_client_session_keys/3 computes and returns shared keys for client session.
|
||||||
|
%%
|
||||||
|
%% <p>Compute two shared keys using the server's public key `ServerPk' and the client's secret key `ClientPk'.</p>
|
||||||
|
%% <p>Returns map with two keys `client_rx' and `client_tx'.
|
||||||
|
%% `client_rx' will be used by the client to receive data from the server,
|
||||||
|
%% `client_tx' will by used by the client to send data to the server.</p>
|
||||||
|
%% @end
|
||||||
|
-spec kx_client_session_keys(ClientPk, ClientSk, ServerPk) -> #{ atom() => binary() }
|
||||||
|
when
|
||||||
|
ClientPk :: binary(),
|
||||||
|
ClientSk :: binary(),
|
||||||
|
ServerPk :: binary().
|
||||||
|
kx_client_session_keys(ClientPk, ClientSk, ServerPk) ->
|
||||||
|
{Rx, Tx} = enacl_nif:crypto_kx_client_session_keys(ClientPk, ClientSk, ServerPk),
|
||||||
|
#{ client_rx => Rx, client_tx => Tx}.
|
||||||
|
|
||||||
|
%% @doc kx_server_session_keys/3 computes and returns shared keys for server session.
|
||||||
|
%% <p>Compute two shared keys using the client's public key `ClientPk' and the server's secret key `ServerSk'.</p>
|
||||||
|
%% <p>Returns map with two keys `server_rx' and `server_tx'.
|
||||||
|
%% `server_rx' will be used by the server to receive data from the client,
|
||||||
|
%% `server_tx' will be used by the server to send data to the client.</p>
|
||||||
|
%% @end
|
||||||
|
-spec kx_server_session_keys(ServerPk, ServerSk, ClientPk) -> #{ atom() => binary() }
|
||||||
|
when
|
||||||
|
ServerPk :: binary(),
|
||||||
|
ServerSk :: binary(),
|
||||||
|
ClientPk :: binary().
|
||||||
|
kx_server_session_keys(ServerPk, ServerSk, ClientPk) ->
|
||||||
|
{Rx, Tx} = enacl_nif:crypto_kx_server_session_keys(ServerPk, ServerSk, ClientPk),
|
||||||
|
#{ server_rx => Rx, server_tx => Tx}.
|
||||||
|
|
||||||
|
%% @doc kx_session_key_size/0 returns the number of bytes of the generated during key exchange session key.
|
||||||
|
%% @end
|
||||||
|
-spec kx_session_key_size() -> pos_integer().
|
||||||
|
kx_session_key_size() ->
|
||||||
|
enacl_nif:crypto_kx_SESSIONKEYBYTES().
|
||||||
|
|
||||||
|
%% @doc kx_public_key_size/0 returns the number of bytes of the public key used in key exchange.
|
||||||
|
%% @end
|
||||||
|
-spec kx_public_key_size() -> pos_integer().
|
||||||
|
kx_public_key_size() ->
|
||||||
|
enacl_nif:crypto_kx_PUBLICKEYBYTES().
|
||||||
|
|
||||||
|
%% @doc kx_secret_key_size/0 returns the number of bytes of the secret key used in key exchange.
|
||||||
|
%% @end
|
||||||
|
-spec kx_secret_key_size() -> pos_integer().
|
||||||
|
kx_secret_key_size() ->
|
||||||
|
enacl_nif:crypto_kx_SECRETKEYBYTES().
|
||||||
|
|
||||||
%% Obtaining random bytes
|
%% Obtaining random bytes
|
||||||
|
|
||||||
%% @doc randombytes/1 produces a stream of random bytes of the given size
|
%% @doc randombytes/1 produces a stream of random bytes of the given size
|
||||||
|
@ -104,6 +104,16 @@
|
|||||||
crypto_sign_ed25519_SECRETKEYBYTES/0
|
crypto_sign_ed25519_SECRETKEYBYTES/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
%% Key exchange
|
||||||
|
-export([
|
||||||
|
crypto_kx_keypair/0,
|
||||||
|
crypto_kx_server_session_keys/3,
|
||||||
|
crypto_kx_client_session_keys/3,
|
||||||
|
crypto_kx_SESSIONKEYBYTES/0,
|
||||||
|
crypto_kx_PUBLICKEYBYTES/0,
|
||||||
|
crypto_kx_SECRETKEYBYTES/0
|
||||||
|
]).
|
||||||
|
|
||||||
%% Miscellaneous helper functions
|
%% Miscellaneous helper functions
|
||||||
-export([
|
-export([
|
||||||
crypto_hash/1,
|
crypto_hash/1,
|
||||||
@ -223,6 +233,13 @@ crypto_verify_16(_X, _Y) -> erlang:nif_error(nif_not_loaded).
|
|||||||
crypto_verify_32(_X, _Y) -> erlang:nif_error(nif_not_loaded).
|
crypto_verify_32(_X, _Y) -> erlang:nif_error(nif_not_loaded).
|
||||||
sodium_memzero(Input) when is_binary(Input) -> erlang:nif_error(nif_not_loaded).
|
sodium_memzero(Input) when is_binary(Input) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
|
crypto_kx_keypair() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_kx_server_session_keys(_ServerPk,_ServerSk,_ClientPk) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_kx_client_session_keys(_ClientPk,_ClientSk,_ServerPk) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_kx_SESSIONKEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_kx_PUBLICKEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_kx_SECRETKEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
randombytes(_RequestedSize) -> erlang:nif_error(nif_not_loaded).
|
randombytes(_RequestedSize) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
scramble_block_16(_Block, _Key) -> erlang:nif_error(nif_not_loaded).
|
scramble_block_16(_Block, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user