aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/crypto/c_src/crypto.c8
-rwxr-xr-xlib/crypto/doc/src/crypto.xml138
-rw-r--r--lib/crypto/src/crypto.erl178
-rw-r--r--lib/crypto/test/crypto_SUITE.erl112
4 files changed, 267 insertions, 169 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 47a577085c..fac77308f6 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2012. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2013. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -210,7 +210,7 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM srp_value_B_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM srp_client_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM srp_server_secret(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM srp_server_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM bf_cfb64_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM bf_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM bf_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -329,7 +329,7 @@ static ErlNifFunc nif_funcs[] = {
{"dh_compute_key_nif", 3, dh_compute_key_nif},
{"srp_value_B_nif", 5, srp_value_B_nif},
{"srp_client_secret_nif", 7, srp_client_secret_nif},
- {"srp_server_secret", 5, srp_server_secret},
+ {"srp_server_secret_nif", 5, srp_server_secret_nif},
{"bf_cfb64_crypt", 4, bf_cfb64_crypt},
{"bf_cbc_crypt", 4, bf_cbc_crypt},
{"bf_ecb_crypt", 3, bf_ecb_crypt},
@@ -2537,7 +2537,7 @@ static ERL_NIF_TERM srp_client_secret_nif(ErlNifEnv* env, int argc, const ERL_NI
return ret;
}
-static ERL_NIF_TERM srp_server_secret(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+static ERL_NIF_TERM srp_server_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Verifier, b, u, A, Prime) */
/*
<premaster secret> = (A * v^u) ^ b % N
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index e27cc486ec..f30a058ca4 100755
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -63,6 +63,11 @@
<item>
<p>dss: Digital Signature Standard (FIPS 186-2)</p>
</item>
+ <item>
+ <p>srp: Secure Remote Password Protocol (RFC 2945)</p>
+ </item>
+
+
</list>
<p>The above publications can be found at <url href="http://csrc.nist.gov/publications">NIST publications</url>, at <url href="http://www.ietf.org">IETF</url>.
</p>
@@ -1275,82 +1280,83 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
</func>
<func>
- <name>srp_value_B(Multiplier, Verifier, Generator, Exponent, Prime) -> ValueB</name>
- <fsummary>Computes the SRP function: B = k*v + g^b % N</fsummary>
- <type>
- <v>Verifier (v), Generator (g), Exponent (b), Prime (N), ValueB (B) = binary()</v>
- <v>Multiplier (k) = integer() | binary()</v>
- </type>
- <desc>
- <p>Computes the SRP value B according to RFC-2945, Sect. 3 and RFC-5054, Sect. 2.5.3</p>
- <p>B = k*v + g^b % N</p>
- </desc>
- </func>
-
- <func>
- <name>srp_client_secret(A, U, B, Multiplier, Generator, Exponent, Prime) -> Secret</name>
- <fsummary>Computes the SRP client secret</fsummary>
- <type>
- <v>A (a), U (u), B, Multiplier (k), Generator (g), Exponent (x), Prime (N), Secret = binary()</v>
- <v>Multiplier (k) = integer() | binary()</v>
- </type>
- <desc>
- <p>Computes the SRP client secret according to RFC-2945, Sect. 3 and RFC-5054, Sect. 2.6</p>
- <p>Secret = (B - (k * g^x)) ^ (a + (u * x)) % N</p>
- </desc>
- </func>
-
- <func>
- <name>srp_server_secret(Verifier, B, U, A, Prime) -> Secret</name>
- <fsummary>Computes the SRP host secret</fsummary>
- <type>
- <v>Verifier (v), B (b), U (u), A, Prime (N), Secret = binary()</v>
- </type>
- <desc>
- <p>Computes the SRP host secret according to RFC-2945, Sect. 3 and RFC-5054, Sect. 2.6</p>
- <p>Secret = (A * v^u) ^ b % N</p>
- </desc>
- </func>
-
- <func>
- <name>srp3_value_u(B) -> Result</name>
- <fsummary>Computes the SRP3-SHA value u</fsummary>
- <type>
- <v>B = binary()</v>
- <v>Result = integer()</v>
- </type>
- <desc>
- <p>Computes the SRP-3 value u according to RFC-2945, Sect. 3
- </p>
- </desc>
- </func>
-
- <func>
- <name>srp6_value_u(A, B, Prime) -> Result</name>
- <fsummary>Computes the SRP6a value u as u = SHA1(PAD(A) | PAD(B))</fsummary>
+ <name>srp_generate_key(Generator, Prime, Version) -> {PublicKey, PrivateKey} </name>
+ <name>srp_generate_key(Generator, Prime, Version, Private) -> {PublicKey, PrivateKey} </name>
+ <name>srp_generate_key(Verifier, Generator, Prime, Version) -> {PublicKey, PrivateKey} </name>
+ <name>srp_generate_key(Verifier, Generator, Prime, Version, Private) -> {PublicKey, PrivateKey} </name>
+ <fsummary>Generates SRP public keys</fsummary>
<type>
- <v>A, B, Prime = binary()</v>
- <v>Result = integer()</v>
+ <v>Verifier = binary()</v>
+ <d>Parameter v from <seealso marker="http://srp.stanford.edu/design.html">SRP design</seealso>
+ </d>
+ <v>Generator = binary() </v>
+ <d>Parameter g from <seealso marker="http://srp.stanford.edu/design.html">SRP design</seealso>
+ </d>
+ <v>Prime = binary() </v>
+ <d>Parameter N from <seealso marker="http://srp.stanford.edu/design.html">SRP design</seealso>
+ </d>
+ <v>Version = '3' | '6' | '6a' </v>
+ <d>SRP version, TLS SRP cipher suites uses '6a'.</d>
+ <v>PublicKey = binary()</v>
+ <d> Parameter A or B from <seealso marker="http://srp.stanford.edu/design.html">SRP design</seealso></d>
+ <v>PrivateKey = binary() - generated if not supplied</v>
+ <d>Parameter a or b from <seealso marker="http://srp.stanford.edu/design.html">SRP design</seealso></d>
</type>
<desc>
- <p>Computes the SRP-6 value u according to RFC-5054, Sect. 2.6
- </p>
+ <p>Generates SRP public keys</p>
</desc>
</func>
<func>
- <name>srp6a_multiplier(Generator, Prime) -> Result</name>
- <fsummary>Computes the SRP-SHA function: k = SHA1(N | PAD(g))</fsummary>
- <type>
- <v>Generator, Prime = binary()</v>
- <v>Result = integer()</v>
- </type>
- <desc>
- <p>Computes the SRP-6a function SHA1(N | PAD(g)) as the multiplier
+ <name>srp_compute_key(DerivedKey, Prime, Generator,
+ ClientPublic, ClientPrivate, ServerPublic, Version) -> SessionKey</name>
+ <name>srp_compute_key(DerivedKey, Prime, Generator,
+ ClientPublic, ClientPrivate, ServerPublic, Version, Scrambler) -> SessionKey</name>
+ <name>srp_compute_key(Verifier, Prime,
+ ClientPublic, ServerPublic, ServerPrivate, Version, Scrambler)-> SessionKey</name>
+ <name>srp_compute_key(Verifier, Prime,
+ ClientPublic, ServerPublic, ServerPrivate, Version) -> SessionKey</name>
+
+ <fsummary>Computes SRP session key</fsummary>
+ <type>
+ <v>DerivedKey = binary()</v>
+ <d>Parameter x from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>Verifier = binary()</v>
+ <d>Parameter v from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>Prime = binary() </v>
+ <d>Parameter N from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>Generator = binary() </v>
+ <d>Parameter g from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>ClientPublic = binary() </v>
+ <d>Parameter A from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>ClientPrivate = binary() </v>
+ <d>Parameter a from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>ServerPublic = binary() </v>
+ <d>Parameter B from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>ServerPrivate = binary() </v>
+ <d>Parameter b from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ <v>Version = '3' | '6' | '6a' </v>
+ <d>SRP version, TLS SRP cipher suites uses '6a'.</d>
+ <v>SessionKey = binary()</v>
+ <d>Result K from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ </d>
+ </type>
+ <desc>
+ <p>
+ Computes the SRP session key (shared secret). Also used
+ as premaster secret by TLS-SRP ciher suites.
</p>
</desc>
</func>
-
+
<func>
<name>exor(Data1, Data2) -> Result</name>
<fsummary>XOR data</fsummary>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index e8867236ac..1d0a9943c3 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -58,9 +58,8 @@
-export([rand_bytes/1, rand_bytes/3, rand_uniform/2]).
-export([strong_rand_bytes/1, strong_rand_mpint/3]).
-export([mod_exp/3, mod_exp_prime/3, mpint/1, erlint/1]).
--export([srp_value_B/5]).
--export([srp3_value_u/1, srp6_value_u/3, srp6a_multiplier/2]).
--export([srp_client_secret/7, srp_server_secret/5]).
+-export([srp_generate_key/4, srp_generate_key/3,
+ srp_generate_key/5, srp_compute_key/6, srp_compute_key/7, srp_compute_key/8]).
%% -export([idea_cbc_encrypt/3, idea_cbc_decrypt/3]).
-export([aes_cbc_128_encrypt/3, aes_cbc_128_decrypt/3]).
@@ -113,9 +112,7 @@
hash, hash_init, hash_update, hash_final,
hmac, hmac_init, hmac_update, hmac_final, hmac_final_n, info,
rc2_cbc_encrypt, rc2_cbc_decrypt,
- srp_value_B,
- srp3_value_u, srp6_value_u, srp6a_multiplier,
- srp_client_secret, srp_server_secret,
+ srp_generate_key, srp_compute_key,
info_lib, algorithms]).
-type rsa_digest_type() :: 'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'.
@@ -801,7 +798,7 @@ mod_exp(Base, Exponent, Modulo)
mod_exp(Base, Exponent, Modulo) ->
mod_exp_nif(mpint_to_bin(Base),mpint_to_bin(Exponent),mpint_to_bin(Modulo), 4).
--spec mod_exp_prime(binary(), binary(), binary()) -> binary().
+-spec mod_exp_prime(binary(), binary(), binary()) -> binary() | error.
mod_exp_prime(Base, Exponent, Prime) ->
case mod_exp_nif(Base, Exponent, Prime, 0) of
<<0>> -> error;
@@ -1077,49 +1074,130 @@ dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) ->
dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
--spec srp_value_B(binary(), integer(), binary(), binary(), binary()) -> binary().
-srp_value_B(Multiplier, Verifier, Generator, Exponent, Prime) ->
- srp_value_B_nif(srp_multiplier(Multiplier), Verifier, Generator, Exponent, Prime).
+%%% SRP
+-spec srp_generate_key(binary(), binary(), atom() | binary(), atom() | binary() ) -> {Public::binary(), Private::binary()}.
+srp_generate_key(Verifier, Generator, Prime, Version) when is_binary(Verifier),
+ is_binary(Generator),
+ is_binary(Prime),
+ is_atom(Version) ->
+ Private = random_bytes(32),
+ server_srp_gen_key(Private, Verifier, Generator, Prime, Version);
+
+srp_generate_key(Generator, Prime, Version, Private) when is_binary(Generator),
+ is_binary(Prime),
+ is_atom(Version),
+ is_binary(Private) ->
+ client_srp_gen_key(Private, Generator, Prime).
+
+-spec srp_generate_key(binary(), binary(), binary(), atom(), binary()) -> {Public::binary(), Private::binary()}.
+srp_generate_key(Verifier, Generator, Prime, Version, Private) when is_binary(Verifier),
+ is_binary(Generator),
+ is_binary(Prime),
+ is_atom(Version),
+ is_binary(Private)
+ ->
+ server_srp_gen_key(Private, Verifier, Generator, Prime, Version).
+
+-spec srp_generate_key(binary(), binary(), atom()) -> {Public::binary(), Private::binary()}.
+srp_generate_key(Generator, Prime, Version) when is_binary(Generator),
+ is_binary(Prime),
+ is_atom(Version) ->
+ Private = random_bytes(32),
+ client_srp_gen_key(Private, Generator, Prime).
+
+-spec srp_compute_key(binary(), binary(), binary(), binary(), binary(), atom()| binary(), atom() | binary() ) -> binary().
+srp_compute_key(DerivedKey, Prime, Generator, ClientPublic, ClientPrivate, ServerPublic, Version) when
+ is_binary(Prime),
+ is_binary(Generator),
+ is_binary(ClientPublic),
+ is_binary(ClientPrivate),
+ is_binary(ServerPublic),
+ is_atom(Version) ->
+ Multiplier = srp_multiplier(Version, Generator, Prime),
+ Scrambler = srp_scrambler(Version, ClientPublic, ServerPublic, Prime),
+ srp_client_secret_nif(ClientPrivate, Scrambler, ServerPublic, Multiplier,
+ Generator, DerivedKey, Prime);
+
+srp_compute_key(Verifier, Prime, ClientPublic, ServerPublic, ServerPrivate, Version, Scrambler) when
+ is_binary(Verifier),
+ is_binary(Prime),
+ is_binary(ClientPublic),
+ is_binary(ServerPublic),
+ is_binary(ServerPrivate),
+ is_atom(Version),
+ is_binary(Scrambler) ->
+ srp_server_secret_nif(Verifier, ServerPrivate, Scrambler, ClientPublic, Prime).
+
+-spec srp_compute_key(binary(), binary(), binary(), binary(), binary(), binary(), atom(), binary()) -> binary().
+srp_compute_key(DerivedKey, Prime, Generator, ClientPublic, ClientPrivate,
+ ServerPublic, Version, Scrambler) when is_binary(DerivedKey),
+ is_binary(Prime),
+ is_binary(Generator),
+ is_binary(ClientPublic),
+ is_binary(ClientPrivate),
+ is_binary(ServerPublic),
+ is_atom(Version),
+ is_binary(Scrambler) ->
+ Multiplier = srp_multiplier(Version, Generator, Prime),
+ srp_client_secret_nif(ClientPrivate, Scrambler, ServerPublic, Multiplier,
+ Generator, DerivedKey, Prime).
+
+-spec srp_compute_key(binary(), binary(), binary(), binary(), binary(), atom()) -> binary().
+srp_compute_key(Verifier, Prime, ClientPublic, ServerPublic, ServerPrivate, Version) when
+ is_binary(Verifier),
+ is_binary(Prime),
+ is_binary(ClientPublic),
+ is_binary(ServerPublic),
+ is_binary(ServerPrivate),
+ is_atom(Version) ->
+ Scrambler = srp_scrambler(Version, ClientPublic, ServerPublic, Prime),
+ srp_server_secret_nif(Verifier, ServerPrivate, Scrambler, ClientPublic, Prime).
-srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub.
-
--spec srp_client_secret(binary(), binary(), binary(), integer()|binary(), binary(), binary(), binary()) -> binary().
-srp_client_secret(A, U, B, Multiplier, Generator, Exponent, Prime) ->
- srp_client_secret_nif(A, U, B, srp_multiplier(Multiplier), Generator, Exponent, Prime).
+%%
+%% LOCAL FUNCTIONS
+%%
-srp_client_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?nif_stub.
+client_srp_gen_key(Private, Generator, Prime) ->
+ case mod_exp_prime(Generator, Private, Prime) of
+ error ->
+ error;
+ Public ->
+ {Public, Private}
+ end.
--spec srp_server_secret(binary(), binary(), binary(), binary(), binary()) -> binary().
-srp_server_secret(_Verifier, _B, _U, _A, _Prime) -> ?nif_stub.
+server_srp_gen_key(Private, Verifier, Generator, Prime, Version) ->
+ Multiplier = srp_multiplier(Version, Generator, Prime),
+ case srp_value_B_nif(Multiplier, Verifier, Generator, Private, Prime) of
+ error ->
+ error;
+ Public ->
+ {Public, Private}
+ end.
--spec srp6a_multiplier(binary(), binary()) -> binary().
-srp6a_multiplier(Generator, Prime) ->
- %% k = SHA1(N | PAD(g))
+srp_multiplier('6a', Generator, Prime) ->
+ %% k = SHA1(N | PAD(g)) from http://srp.stanford.edu/design.html
C0 = sha_init(),
C1 = sha_update(C0, Prime),
C2 = sha_update(C1, srp_pad_to(erlang:byte_size(Prime), Generator)),
- sha_final(C2).
-
--spec srp3_value_u(binary()) -> binary().
-srp3_value_u(B) ->
+ sha_final(C2);
+srp_multiplier('6', _, _) ->
+ <<3/integer>>;
+srp_multiplier('3', _, _) ->
+ <<1/integer>>.
+
+srp_scrambler(Version, ClientPublic, ServerPublic, Prime) when Version == '6'; Version == '6a'->
+ %% SHA1(PAD(A) | PAD(B)) from http://srp.stanford.edu/design.html
+ PadLength = erlang:byte_size(Prime),
+ C0 = sha_init(),
+ C1 = sha_update(C0, srp_pad_to(PadLength, ClientPublic)),
+ C2 = sha_update(C1, srp_pad_to(PadLength, ServerPublic)),
+ sha_final(C2);
+srp_scrambler('3', _, ServerPublic, _Prime) ->
%% The parameter u is a 32-bit unsigned integer which takes its value
%% from the first 32 bits of the SHA1 hash of B, MSB first.
- <<U:32/bits, _/binary>> = sha(B),
+ <<U:32/bits, _/binary>> = sha(ServerPublic),
U.
--spec srp6_value_u(binary(), binary(), binary()) -> binary().
-srp6_value_u(A, B, Prime) ->
- %% SHA1(PAD(A) | PAD(B))
- PadLength = erlang:byte_size(Prime),
- C0 = sha_init(),
- C1 = sha_update(C0, srp_pad_to(PadLength, A)),
- C2 = sha_update(C1, srp_pad_to(PadLength, B)),
- sha_final(C2).
-
-%%
-%% LOCAL FUNCTIONS
-%%
-
srp_pad_length(Width, Length) ->
(Width - Length rem Width) rem Width.
@@ -1129,10 +1207,11 @@ srp_pad_to(Width, Binary) ->
N -> << 0:(N*8), Binary/binary>>
end.
-srp_multiplier(Multiplier) when is_binary(Multiplier) ->
- Multiplier;
-srp_multiplier(Multiplier) when is_integer(Multiplier) ->
- int_to_bin_pos(Multiplier).
+srp_server_secret_nif(_Verifier, _B, _U, _A, _Prime) -> ?nif_stub.
+
+srp_client_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?nif_stub.
+
+srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub.
%% large integer in a binary with 32bit length
%% MP representaion (SSH2)
@@ -1160,8 +1239,8 @@ mpint_pos(X) ->
int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []);
int_to_bin(X) -> int_to_bin_pos(X, []).
-int_to_bin_pos(X) when X >= 0 ->
- int_to_bin_pos(X, []).
+%%int_to_bin_pos(X) when X >= 0 ->
+%% int_to_bin_pos(X, []).
int_to_bin_pos(0,Ds=[_|_]) ->
list_to_binary(Ds);
@@ -1187,3 +1266,12 @@ erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) ->
mpint_to_bin(<<Len:32, Bin:Len/binary>>) ->
Bin.
+
+random_bytes(N) ->
+ try strong_rand_bytes(N) of
+ RandBytes ->
+ RandBytes
+ catch
+ error:low_entropy ->
+ rand_bytes(N)
+ end.
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 92d16a438d..08ecad3233 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -1860,42 +1860,45 @@ srp3(Config) when is_list(Config) ->
"7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
"FD5138FE8376435B9FC61D2FC0EB06E3"),
Generator = <<2>>,
- Multiplier = 1,
+ Version = '3',
+ Scrambler = hexstr2bin("02E2476A"),
+
%% X = hexstr2bin("96E54AB0CD4C5123EDCFA4A1502918AAD3C9E2A8"),
Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
"C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
"49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
"D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
"519E8FDD9AA4F410C28A58AF42974D2D"),
- ClntPriv = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
+ ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
"49C75C7B"),
- SrvrPriv = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
+ ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
"9AADCF8B"),
- ClntPub = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
+ ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
"55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
"640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
"CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
"948A090E0C25938E5F84067D1883DC63"),
- SrvrPub = hexstr2bin("93A8C4D8B7F7395ADCFD4ABA37B015124513D3F37B3E85EB23064BE5"
+ ServerPublic = hexstr2bin("93A8C4D8B7F7395ADCFD4ABA37B015124513D3F37B3E85EB23064BE5"
"F53C0AE32FFB9D8C0AA0DCFFA74D632DD67DEBB5C35AAE9812286CC8"
"C43CC176ECBC6D3F447594D9554E995B2509127BF88FADDDA4982D03"
"8EC3001320712D3B1269308CE70F319B2295FA57674F03A2D993CFB1"
"F84C35B7D0C012FA73CD4C8F7D5A71C7"),
- U = hexstr2bin("02E2476A"),
- PremasterSecret = hexstr2bin("C29A986C4D521BBC66428ED11D994CD7431574A6184B83CDCC345092"
- "791E75748A1D38CAC4BD14760F0D2694B711236419240FF2F172454C"
- "46ABF4FF39498DAFDD2C82924F7D7BD76CDFCE688C77D93F18A65409"
- "9176A9192615DC0277AE7C12F1F6A7F6563FCA11675D809AF578BDE5"
- "2B51E05D440B63099A017A0B45044801"),
+ SessionKey = hexstr2bin("C29A986C4D521BBC66428ED11D994CD7431574A6184B83CDCC345092"
+ "791E75748A1D38CAC4BD14760F0D2694B711236419240FF2F172454C"
+ "46ABF4FF39498DAFDD2C82924F7D7BD76CDFCE688C77D93F18A65409"
+ "9176A9192615DC0277AE7C12F1F6A7F6563FCA11675D809AF578BDE5"
+ "2B51E05D440B63099A017A0B45044801"),
UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- m(crypto:mod_exp_prime(Generator, UserPassHash, Prime), Verifier),
- m(crypto:mod_exp_prime(Generator, ClntPriv, Prime), ClntPub),
- m(crypto:srp3_value_u(SrvrPub), U),
- m(crypto:srp_value_B(Multiplier, Verifier, Generator, SrvrPriv, Prime), SrvrPub),
- m(crypto:srp_client_secret(ClntPriv, U, SrvrPub, Multiplier, Generator, UserPassHash, Prime), PremasterSecret),
- m(crypto:srp_server_secret(Verifier, SrvrPriv, U, ClntPub, Prime), PremasterSecret),
- ok.
+ Verifier = crypto:mod_exp_prime(Generator, UserPassHash, Prime),
+ ClientPublic = crypto:mod_exp_prime(Generator, ClientPrivate, Prime),
+
+ {ClientPublic, ClientPrivate} = crypto:srp_generate_key(Generator, Prime, Version, ClientPrivate),
+ {ServerPublic, ServerPrivate} = crypto:srp_generate_key(Verifier, Generator, Prime, Version, ServerPrivate),
+ SessionKey = crypto:srp_compute_key(UserPassHash, Prime, Generator, ClientPublic,
+ ClientPrivate, ServerPublic, Version, Scrambler),
+ SessionKey = crypto:srp_compute_key(Verifier, Prime, ClientPublic,
+ ServerPublic, ServerPrivate, Version, Scrambler).
srp6(doc) ->
["SRP-6 test vectors generated by http://srp.stanford.edu/demo/demo.html"];
@@ -1910,42 +1913,43 @@ srp6(Config) when is_list(Config) ->
"7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
"FD5138FE8376435B9FC61D2FC0EB06E3"),
Generator = <<2>>,
- Multiplier = 3,
- %% X = hexstr2bin("96E54AB0CD4C5123EDCFA4A1502918AAD3C9E2A8"),
+ Version = '6',
+ Scrambler = hexstr2bin("0A2534C0BF52A0DA9001EEC62CF2A546AB0908A7"),
Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
"C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
"49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
"D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
"519E8FDD9AA4F410C28A58AF42974D2D"),
- ClntPriv = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
+ ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
"49C75C7B"),
- SrvrPriv = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
+ ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
"9AADCF8B"),
- ClntPub = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
+ ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
"55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
"640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
"CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
"948A090E0C25938E5F84067D1883DC63"),
- SrvrPub = hexstr2bin("D2D07845CE7ECDB9845DD36B10ACD3598CC29049DE9F467F84CE16B6"
+ ServerPublic = hexstr2bin("D2D07845CE7ECDB9845DD36B10ACD3598CC29049DE9F467F84CE16B6"
"D97A6DC567AF8B0F9FEDF74962400AD5C357951E64E67B641246F264"
"C8DE6D9A72E554D6C8D3194548780A0C438A0FCC509CA88A14AA1DEB"
"C0F09E4B37A965D1545DB4AD361346F3189B0EA569C06D326C4E4797"
"9E381C748293B7C0591BE0BE419E053E"),
- U = hexstr2bin("0A2534C0BF52A0DA9001EEC62CF2A546AB0908A7"),
- PremasterSecret = hexstr2bin("19D22C19612874EBF1F2581F8EFCFDC44C6FDA3B87B0A73823D7E962"
+ SessionKey = hexstr2bin("19D22C19612874EBF1F2581F8EFCFDC44C6FDA3B87B0A73823D7E962"
"554295D4E48D3A336523ADBDDD0EC8FB0F02687109E97E01C17C93CC"
"7216F9CD8A4AC39F0429857D8D1023066614BDFCBCB89F59A0FEB81C"
"72E992AAD89095A84B6A5FADA152369AB1E350A03693BEF044DF3EDF"
"0C34741F4696C30E9F675D09F58ACBEB"),
UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- m(crypto:mod_exp_prime(Generator, UserPassHash, Prime), Verifier),
- m(crypto:mod_exp_prime(Generator, ClntPriv, Prime), ClntPub),
- m(crypto:srp6_value_u(ClntPub, SrvrPub, Prime), U),
- m(crypto:srp_value_B(Multiplier, Verifier, Generator, SrvrPriv, Prime), SrvrPub),
- m(crypto:srp_client_secret(ClntPriv, U, SrvrPub, Multiplier, Generator, UserPassHash, Prime), PremasterSecret),
- m(crypto:srp_server_secret(Verifier, SrvrPriv, U, ClntPub, Prime), PremasterSecret),
- ok.
+ Verifier = crypto:mod_exp_prime(Generator, UserPassHash, Prime),
+ ClientPublic = crypto:mod_exp_prime(Generator, ClientPrivate, Prime),
+
+ {ClientPublic, ClientPrivate} = crypto:srp_generate_key(Generator, Prime, Version, ClientPrivate),
+ {ServerPublic, ServerPrivate} = crypto:srp_generate_key(Verifier, Generator, Prime, Version, ServerPrivate),
+ SessionKey = crypto:srp_compute_key(UserPassHash, Prime, Generator, ClientPublic,
+ ClientPrivate, ServerPublic, Version, Scrambler),
+ SessionKey = crypto:srp_compute_key(Verifier, Prime, ClientPublic,
+ ServerPublic, ServerPrivate, Version, Scrambler).
srp6a(doc) ->
["SRP-6a test vectors from RFC5054."];
@@ -1960,44 +1964,44 @@ srp6a(Config) when is_list(Config) ->
"7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
"FD5138FE8376435B9FC61D2FC0EB06E3"),
Generator = <<2>>,
- Multiplier = hexstr2bin("7556AA045AEF2CDD07ABAF0F665C3E818913186F"),
- %% X = hexstr2bin("94B7555AABE9127CC58CCF4993DB6CF84D16C124"),
+ Version = '6a',
+ Scrambler = hexstr2bin("CE38B9593487DA98554ED47D70A7AE5F462EF019"),
Verifier = hexstr2bin("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812"
"9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5"
"C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5"
"EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78"
"E955A5E29E7AB245DB2BE315E2099AFB"),
- ClntPriv = hexstr2bin("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD"
+ ClientPrivate = hexstr2bin("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD"
"DA2D4393"),
- SrvrPriv = hexstr2bin("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1"
+ ServerPrivate = hexstr2bin("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1"
"05284D20"),
- ClntPub = hexstr2bin("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
+ ClientPublic = hexstr2bin("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
"4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC"
"8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44"
"BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA"
"B349EF5D76988A3672FAC47B0769447B"),
- SrvrPub = hexstr2bin("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
+ ServerPublic = hexstr2bin("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
"BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99"
"6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA"
"37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE"
"EB4012B7D7665238A8E3FB004B117B58"),
- U = hexstr2bin("CE38B9593487DA98554ED47D70A7AE5F462EF019"),
-
- PremasterSecret = hexstr2bin("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
- "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
- "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
- "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
- "C346D7E474B29EDE8A469FFECA686E5A"),
+
+ SessionKey = hexstr2bin("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
+ "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
+ "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
+ "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
+ "C346D7E474B29EDE8A469FFECA686E5A"),
UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- m(crypto:mod_exp_prime(Generator, UserPassHash, Prime), Verifier),
- m(crypto:mod_exp_prime(Generator, ClntPriv, Prime), ClntPub),
- m(crypto:srp6a_multiplier(Generator, Prime), Multiplier),
- m(crypto:srp6_value_u(ClntPub, SrvrPub, Prime), U),
- m(crypto:srp_value_B(Multiplier, Verifier, Generator, SrvrPriv, Prime), SrvrPub),
- m(crypto:srp_client_secret(ClntPriv, U, SrvrPub, Multiplier, Generator, UserPassHash, Prime), PremasterSecret),
- m(crypto:srp_server_secret(Verifier, SrvrPriv, U, ClntPub, Prime), PremasterSecret),
- ok.
+ Verifier = crypto:mod_exp_prime(Generator, UserPassHash, Prime),
+ {ClientPublic, ClientPrivate} = crypto:srp_generate_key(Generator, Prime, Version, ClientPrivate),
+ {ServerPublic, ServerPrivate} = crypto:srp_generate_key(Verifier, Generator, Prime, Version, ServerPrivate),
+
+ SessionKey = crypto:srp_compute_key(UserPassHash, Prime, Generator, ClientPublic,
+ ClientPrivate, ServerPublic, Version, Scrambler),
+ SessionKey = crypto:srp_compute_key(Verifier, Prime, ClientPublic,
+ ServerPublic, ServerPrivate, Version, Scrambler).
+
%%
%%
exor_test(doc) ->