From 52a70455853d625f8e92c1c5e7f22b6f75adff63 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Thu, 20 Sep 2012 14:42:40 +0200 Subject: SSL: add TLS-SRP (RFC 5054) cipher suites --- lib/ssl/src/Makefile | 3 +- lib/ssl/src/ssl.app.src | 1 + lib/ssl/src/ssl.erl | 13 +- lib/ssl/src/ssl_cipher.erl | 114 +++++++++- lib/ssl/src/ssl_cipher.hrl | 29 +++ lib/ssl/src/ssl_connection.erl | 167 +++++++++++++- lib/ssl/src/ssl_handshake.erl | 100 +++++++- lib/ssl/src/ssl_handshake.hrl | 23 ++ lib/ssl/src/ssl_internal.hrl | 1 + lib/ssl/src/ssl_srp.hrl | 31 +++ lib/ssl/src/ssl_srp_primes.erl | 506 +++++++++++++++++++++++++++++++++++++++++ lib/ssl/src/ssl_srp_primes.hrl | 1 + 12 files changed, 964 insertions(+), 25 deletions(-) create mode 100644 lib/ssl/src/ssl_srp.hrl create mode 100644 lib/ssl/src/ssl_srp_primes.erl create mode 100644 lib/ssl/src/ssl_srp_primes.hrl diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile index e61f415c84..d3ba76d34e 100644 --- a/lib/ssl/src/Makefile +++ b/lib/ssl/src/Makefile @@ -50,6 +50,7 @@ MODULES= \ ssl_certificate\ ssl_certificate_db\ ssl_cipher \ + ssl_srp_primes \ ssl_connection \ ssl_connection_sup \ ssl_handshake \ @@ -65,7 +66,7 @@ MODULES= \ INTERNAL_HRL_FILES = \ ssl_alert.hrl ssl_cipher.hrl ssl_handshake.hrl ssl_internal.hrl \ - ssl_record.hrl + ssl_record.hrl ssl_srp.hrl ssl_srp_primes.hrl ERL_FILES= \ $(MODULES:%=%.erl) \ diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src index 897a097f73..5c34de905e 100644 --- a/lib/ssl/src/ssl.app.src +++ b/lib/ssl/src/ssl.app.src @@ -20,6 +20,7 @@ ssl_connection_sup, ssl_connection, ssl_cipher, + ssl_srp_primes, ssl_certificate_db, ssl_certificate, ssl_alert diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 0381f81edd..d5f5fa6b04 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -37,6 +37,7 @@ -include("ssl_record.hrl"). -include("ssl_cipher.hrl"). -include("ssl_handshake.hrl"). +-include("ssl_srp_primes.hrl"). -include_lib("public_key/include/public_key.hrl"). @@ -67,6 +68,7 @@ {cacertfile, path()} | {dh, Der::binary()} | {dhfile, path()} | {user_lookup_fun, {fun(), InitialUserState::term()}} | {psk_identity, string()} | + {srp_identity, {string(), string()}} | {ciphers, ciphers()} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()} | {hibernate_after, integer()|undefined} | {next_protocols_advertised, list(binary())} | @@ -639,6 +641,7 @@ handle_options(Opts0, _Role) -> dhfile = handle_option(dhfile, Opts, undefined), user_lookup_fun = handle_option(user_lookup_fun, Opts, undefined), psk_identity = handle_option(psk_identity, Opts, undefined), + srp_identity = handle_option(srp_identity, Opts, undefined), ciphers = handle_option(ciphers, Opts, []), %% Server side option reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun), @@ -659,7 +662,7 @@ handle_options(Opts0, _Role) -> fail_if_no_peer_cert, verify_client_once, depth, cert, certfile, key, keyfile, password, cacerts, cacertfile, dh, dhfile, - user_lookup_fun, psk_identity, ciphers, + user_lookup_fun, psk_identity, srp_identity, ciphers, reuse_session, reuse_sessions, ssl_imp, cb_info, renegotiate_at, secure_renegotiate, hibernate_after, erl_dist, next_protocols_advertised, @@ -770,6 +773,11 @@ validate_option(user_lookup_fun, undefined) -> undefined; validate_option(user_lookup_fun, {Fun, _} = Value) when is_function(Fun, 3) -> Value; +validate_option(srp_identity, undefined) -> + undefined; +validate_option(srp_identity, {Username, Password}) + when is_list(Username), is_list(Password), Username =/= "", length(Username) =< 255 -> + {list_to_binary(Username), list_to_binary(Password)}; validate_option(ciphers, Value) when is_list(Value) -> Version = ssl_record:highest_protocol_version([]), try cipher_suites(Version, Value) @@ -942,7 +950,8 @@ cipher_suites(Version, [{_,_,_}| _] = Ciphers0) -> cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) -> Supported = ssl_cipher:suites(Version) ++ ssl_cipher:anonymous_suites() - ++ ssl_cipher:psk_suites(Version), + ++ ssl_cipher:psk_suites(Version) + ++ ssl_cipher:srp_suites(), case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported)] of [] -> Supported; diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 0bdcfd236d..be629dcdd1 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -34,7 +34,7 @@ -export([security_parameters/3, suite_definition/1, decipher/5, cipher/5, - suite/1, suites/1, anonymous_suites/0, psk_suites/1, + suite/1, suites/1, anonymous_suites/0, psk_suites/1, srp_suites/0, openssl_suite/1, openssl_suite_name/1, filter/2, hash_algorithm/1, sign_algorithm/1]). @@ -247,6 +247,23 @@ psk_suites(_) -> ?TLS_RSA_PSK_WITH_RC4_128_SHA, ?TLS_PSK_WITH_RC4_128_SHA]. +%%-------------------------------------------------------------------- +-spec srp_suites() -> [cipher_suite()]. +%% +%% Description: Returns a list of the SRP cipher suites, only supported +%% if explicitly set by user. +%%-------------------------------------------------------------------- +srp_suites() -> + [?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + ?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + ?TLS_SRP_SHA_WITH_AES_128_CBC_SHA, + ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + ?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + ?TLS_SRP_SHA_WITH_AES_256_CBC_SHA, + ?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA]. + %%-------------------------------------------------------------------- -spec suite_definition(cipher_suite()) -> int_cipher_suite(). %% @@ -385,7 +402,29 @@ suite_definition(?TLS_DHE_PSK_WITH_NULL_SHA384) -> suite_definition(?TLS_RSA_PSK_WITH_NULL_SHA256) -> {rsa_psk, null, sha256, default_prf}; suite_definition(?TLS_RSA_PSK_WITH_NULL_SHA384) -> - {rsa_psk, null, sha384, default_prf}. + {rsa_psk, null, sha384, default_prf}; + +%%% SRP Cipher Suites RFC 5054 + +suite_definition(?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) -> + {srp_anon, '3des_ede_cbc', sha, default_prf}; +suite_definition(?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) -> + {srp_rsa, '3des_ede_cbc', sha, default_prf}; +suite_definition(?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) -> + {srp_dss, '3des_ede_cbc', sha, default_prf}; +suite_definition(?TLS_SRP_SHA_WITH_AES_128_CBC_SHA) -> + {srp_anon, aes_128_cbc, sha, default_prf}; +suite_definition(?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) -> + {srp_rsa, aes_128_cbc, sha, default_prf}; +suite_definition(?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA) -> + {srp_dss, aes_128_cbc, sha, default_prf}; +suite_definition(?TLS_SRP_SHA_WITH_AES_256_CBC_SHA) -> + {srp_anon, aes_256_cbc, sha, default_prf}; +suite_definition(?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) -> + {srp_rsa, aes_256_cbc, sha, default_prf}; +suite_definition(?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA) -> + {srp_dss, aes_256_cbc, sha, default_prf}. + %%-------------------------------------------------------------------- -spec suite(erl_cipher_suite()) -> cipher_suite(). @@ -513,7 +552,28 @@ suite({dhe_psk, null, sha384}) -> suite({rsa_psk, null, sha256}) -> ?TLS_RSA_PSK_WITH_NULL_SHA256; suite({rsa_psk, null, sha384}) -> - ?TLS_RSA_PSK_WITH_NULL_SHA384. + ?TLS_RSA_PSK_WITH_NULL_SHA384; + +%%% SRP Cipher Suites RFC 5054 + +suite({srp_anon, '3des_ede_cbc', sha}) -> + ?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA; +suite({srp_rsa, '3des_ede_cbc', sha}) -> + ?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA; +suite({srp_dss, '3des_ede_cbc', sha}) -> + ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA; +suite({srp_anon, aes_128_cbc, sha}) -> + ?TLS_SRP_SHA_WITH_AES_128_CBC_SHA; +suite({srp_rsa, aes_128_cbc, sha}) -> + ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA; +suite({srp_dss, aes_128_cbc, sha}) -> + ?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA; +suite({srp_anon, aes_256_cbc, sha}) -> + ?TLS_SRP_SHA_WITH_AES_256_CBC_SHA; +suite({srp_rsa, aes_256_cbc, sha}) -> + ?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA; +suite({srp_dss, aes_256_cbc, sha}) -> + ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA. %%-------------------------------------------------------------------- -spec openssl_suite(openssl_cipher_suite()) -> cipher_suite(). @@ -558,7 +618,24 @@ openssl_suite("RC4-MD5") -> openssl_suite("EDH-RSA-DES-CBC-SHA") -> ?TLS_DHE_RSA_WITH_DES_CBC_SHA; openssl_suite("DES-CBC-SHA") -> - ?TLS_RSA_WITH_DES_CBC_SHA. + ?TLS_RSA_WITH_DES_CBC_SHA; + +%%% SRP Cipher Suites RFC 5054 + +openssl_suite("SRP-DSS-AES-256-CBC-SHA") -> + ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA; +openssl_suite("SRP-RSA-AES-256-CBC-SHA") -> + ?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA; +openssl_suite("SRP-DSS-3DES-EDE-CBC-SHA") -> + ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA; +openssl_suite("SRP-RSA-3DES-EDE-CBC-SHA") -> + ?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA; +openssl_suite("SRP-DSS-AES-128-CBC-SHA") -> + ?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA; +openssl_suite("SRP-RSA-AES-128-CBC-SHA") -> + ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA. + + %%-------------------------------------------------------------------- -spec openssl_suite_name(cipher_suite()) -> openssl_cipher_suite(). %% @@ -624,6 +701,21 @@ openssl_suite_name(?TLS_PSK_WITH_AES_128_CBC_SHA) -> openssl_suite_name(?TLS_PSK_WITH_RC4_128_SHA) -> "PSK-RC4-SHA"; +%%% SRP Cipher Suites RFC 5054 + +openssl_suite_name(?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) -> + "SRP-RSA-3DES-EDE-CBC-SHA"; +openssl_suite_name(?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) -> + "SRP-DSS-3DES-EDE-CBC-SHA"; +openssl_suite_name(?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) -> + "SRP-RSA-AES-128-CBC-SHA"; +openssl_suite_name(?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA) -> + "SRP-DSS-AES-128-CBC-SHA"; +openssl_suite_name(?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) -> + "SRP-RSA-AES-256-CBC-SHA"; +openssl_suite_name(?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA) -> + "SRP-DSS-AES-256-CBC-SHA"; + %% No oppenssl name openssl_suite_name(Cipher) -> suite_definition(Cipher). @@ -858,7 +950,7 @@ next_iv(Bin, IV) -> rsa_signed_suites() -> dhe_rsa_suites() ++ rsa_suites() ++ - psk_rsa_suites(). + psk_rsa_suites() ++ srp_rsa_suites(). dhe_rsa_suites() -> [?TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, @@ -876,6 +968,11 @@ psk_rsa_suites() -> ?TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, ?TLS_RSA_PSK_WITH_RC4_128_SHA]. +srp_rsa_suites() -> + [?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + ?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA]. + rsa_suites() -> [?TLS_RSA_WITH_AES_256_CBC_SHA256, ?TLS_RSA_WITH_AES_256_CBC_SHA, @@ -887,7 +984,7 @@ rsa_suites() -> ?TLS_RSA_WITH_DES_CBC_SHA]. dsa_signed_suites() -> - dhe_dss_suites(). + dhe_dss_suites() ++ srp_dss_suites(). dhe_dss_suites() -> [?TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, @@ -897,6 +994,11 @@ dhe_dss_suites() -> ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA, ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA]. +srp_dss_suites() -> + [?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + ?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA]. + filter_rsa(OtpCert, RsaCiphers) -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, TBSExtensions = TBSCert#'OTPTBSCertificate'.extensions, diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl index db6e36741d..90d3704efd 100644 --- a/lib/ssl/src/ssl_cipher.hrl +++ b/lib/ssl/src/ssl_cipher.hrl @@ -326,4 +326,33 @@ %% TLS_RSA_PSK_WITH_NULL_SHA384 = {0x00,0xB9}; -define(TLS_RSA_PSK_WITH_NULL_SHA384, <>). +%%% SRP Cipher Suites RFC 5054 + +%% TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = { 0xC0,0x1A }; +-define(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, <>). + +%% TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = { 0xC0,0x1B }; +-define(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, <>). + +%% TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = { 0xC0,0x1C }; +-define(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, <>). + +%% TLS_SRP_SHA_WITH_AES_128_CBC_SHA = { 0xC0,0x1D }; +-define(TLS_SRP_SHA_WITH_AES_128_CBC_SHA, <>). + +%% TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = { 0xC0,0x1E }; +-define(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, <>). + +%% TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = { 0xC0,0x1F }; +-define(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, <>). + +%% TLS_SRP_SHA_WITH_AES_256_CBC_SHA = { 0xC0,0x20 }; +-define(TLS_SRP_SHA_WITH_AES_256_CBC_SHA, <>). + +%% TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = { 0xC0,0x21 }; +-define(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, <>). + +%% TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = { 0xC0,0x22 }; +-define(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, <>). + -endif. % -ifdef(ssl_cipher). diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index e3ddce85e1..e752b70d18 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -34,6 +34,8 @@ -include("ssl_record.hrl"). -include("ssl_cipher.hrl"). -include("ssl_internal.hrl"). +-include("ssl_srp.hrl"). +-include("ssl_srp_primes.hrl"). -include_lib("public_key/include/public_key.hrl"). %% Internal application API @@ -81,6 +83,8 @@ diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side diffie_hellman_keys, % {PublicKey, PrivateKey} psk_identity, % binary() - server psk identity hint + srp_params, % #srp_user{} + srp_keys, % {PublicKey, PrivateKey} premaster_secret, % file_ref_db, % ets() cert_db_ref, % ref() @@ -530,7 +534,8 @@ certify(#server_key_exchange{} = KeyExchangeMsg, #state{role = client, negotiated_version = Version, key_algorithm = Alg} = State0) when Alg == dhe_dss; Alg == dhe_rsa; Alg == dh_anon; - Alg == psk; Alg == dhe_psk; Alg == rsa_psk -> + Alg == psk; Alg == dhe_psk; Alg == rsa_psk; + Alg == srp_dss; Alg == srp_rsa; Alg == srp_anon -> case handle_server_key(KeyExchangeMsg, State0) of #state{} = State1 -> {Record, State} = next_record(State1), @@ -712,6 +717,20 @@ certify_client_key_exchange(#client_rsa_psk_identity{ next_state(certify, cipher, Record, State); #alert{} = Alert -> handle_own_alert(Alert, Version, certify, State0) + end; + +certify_client_key_exchange(#client_srp_public{srp_a = ClientPublicKey}, + #state{negotiated_version = Version, + srp_params = + #srp_user{prime = Prime, + verifier = Verifier} + } = State0) -> + case server_srp_master_secret(Verifier, Prime, ClientPublicKey, State0) of + #state{} = State1 -> + {Record, State} = next_record(State1), + next_state(certify, cipher, Record, State); + #alert{} = Alert -> + handle_own_alert(Alert, Version, certify, State0) end. %%-------------------------------------------------------------------- @@ -1667,6 +1686,44 @@ key_exchange(#state{role = server, key_algorithm = rsa_psk, State#state{connection_states = ConnectionStates, tls_handshake_history = Handshake}; +key_exchange(#state{role = server, key_algorithm = Algo, + ssl_options = #ssl_options{user_lookup_fun = LookupFun}, + hashsign_algorithm = HashSignAlgo, + session = #session{srp_username = Username}, + private_key = PrivateKey, + connection_states = ConnectionStates0, + negotiated_version = Version, + tls_handshake_history = Handshake0, + socket = Socket, + transport_cb = Transport + } = State) + when Algo == srp_dss; + Algo == srp_rsa; + Algo == srp_anon -> + SrpParams = handle_srp_identity(Username, LookupFun), + Keys = case generate_srp_server_keys(SrpParams, 0) of + Alert = #alert{} -> + throw(Alert); + Keys0 = {_,_} -> + Keys0 + end, + ConnectionState = + ssl_record:pending_connection_state(ConnectionStates0, read), + SecParams = ConnectionState#connection_state.security_parameters, + #security_parameters{client_random = ClientRandom, + server_random = ServerRandom} = SecParams, + Msg = ssl_handshake:key_exchange(server, Version, {srp, Keys, SrpParams, + HashSignAlgo, ClientRandom, + ServerRandom, + PrivateKey}), + {BinMsg, ConnectionStates, Handshake} = + encode_handshake(Msg, Version, ConnectionStates0, Handshake0), + Transport:send(Socket, BinMsg), + State#state{connection_states = ConnectionStates, + srp_params = SrpParams, + srp_keys = Keys, + tls_handshake_history = Handshake}; + key_exchange(#state{role = client, connection_states = ConnectionStates0, key_algorithm = rsa, @@ -1740,6 +1797,23 @@ key_exchange(#state{role = client, {BinMsg, ConnectionStates, Handshake} = encode_handshake(Msg, Version, ConnectionStates0, Handshake0), Transport:send(Socket, BinMsg), + State#state{connection_states = ConnectionStates, + tls_handshake_history = Handshake}; + +key_exchange(#state{role = client, + connection_states = ConnectionStates0, + key_algorithm = Algorithm, + negotiated_version = Version, + srp_keys = {ClntPubKey, _}, + socket = Socket, transport_cb = Transport, + tls_handshake_history = Handshake0} = State) + when Algorithm == srp_dss; + Algorithm == srp_rsa; + Algorithm == srp_anon -> + Msg = ssl_handshake:key_exchange(client, Version, {srp, ClntPubKey}), + {BinMsg, ConnectionStates, Handshake} = + encode_handshake(Msg, Version, ConnectionStates0, Handshake0), + Transport:send(Socket, BinMsg), State#state{connection_states = ConnectionStates, tls_handshake_history = Handshake}. @@ -1905,7 +1979,11 @@ server_master_secret(#server_dhe_psk_params{ hint = IdentityHint, dh_params = #server_dh_params{dh_p = P, dh_g = G, dh_y = ServerPublicDhKey}}, State) -> - dhe_psk_master_secret(IdentityHint, P, G, ServerPublicDhKey, undefined, State). + dhe_psk_master_secret(IdentityHint, P, G, ServerPublicDhKey, undefined, State); + +server_master_secret(#server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}, + State) -> + client_srp_master_secret(G, N, S, B, undefined, State). master_from_premaster_secret(PremasterSecret, #state{session = Session, @@ -1992,6 +2070,79 @@ server_rsa_psk_master_secret(PskIdentity, PremasterSecret, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER) end. +generate_srp_server_keys(_SrpParams, 10) -> + ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER); +generate_srp_server_keys(SrpParams = + #srp_user{generator = Generator, prime = Prime, + verifier = Verifier}, N) -> + Private = ssl:random_bytes(32), + Multiplier = crypto:srp6a_multiplier(Generator, Prime), + case crypto:srp_value_B(Multiplier, Verifier, Generator, Private, Prime) of + error -> + generate_srp_server_keys(SrpParams, N+1); + Public -> {Public, Private} + end. + +generate_srp_client_keys(_Generator, _Prime, 10) -> + ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER); +generate_srp_client_keys(Generator, Prime, N) -> + Private = ssl:random_bytes(32), + case crypto:srp_mod_exp(Generator, Private, Prime) of + error -> + generate_srp_client_keys(Generator, Prime, N+1); + Public -> {Public, Private} + end. + +handle_srp_identity(Username, {Fun, UserState}) -> + case Fun(srp, Username, UserState) of + {ok, {SRPParams, Salt, UserPassHash}} + when is_atom(SRPParams), is_binary(Salt), is_binary(UserPassHash) -> + {Generator, Prime} = ssl_srp_primes:get_srp_params(SRPParams), + Verifier = crypto:srp_mod_exp(Generator, UserPassHash, Prime), + #srp_user{generator = Generator, prime = Prime, + salt = Salt, verifier = Verifier}; + #alert{} = Alert -> + throw(Alert); + _ -> + throw(?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)) + end. + +server_srp_master_secret(Verifier, Prime, ClntPub, State = #state{srp_keys = {SrvrPub, SrvrPriv}}) -> + U = crypto:srp6_value_u(ClntPub, SrvrPub, Prime), + case crypto:srp_server_secret(Verifier, SrvrPriv, U, ClntPub, Prime) of + error -> + ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER); + PremasterSecret -> + master_from_premaster_secret(PremasterSecret, State) + end. + +client_srp_master_secret(_Generator, _Prime, _Salt, _SrvrPub, #alert{} = Alert, _State) -> + Alert; +client_srp_master_secret(Generator, Prime, Salt, SrvrPub, undefined, State) -> + Keys = generate_srp_client_keys(Generator, Prime, 0), + client_srp_master_secret(Generator, Prime, Salt, SrvrPub, Keys, State#state{srp_keys = Keys}); + +client_srp_master_secret(Generator, Prime, Salt, SrvrPub, {ClntPub, ClntPriv}, + #state{ssl_options = SslOpts} = State) -> + case ssl_srp_primes:check_srp_params(Generator, Prime) of + ok -> + {Username, Password} = SslOpts#ssl_options.srp_identity, + UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]), + + Multiplier = crypto:srp6a_multiplier(Generator, Prime), + U = crypto:srp6_value_u(ClntPub, SrvrPub, Prime), + case crypto:srp_client_secret(ClntPriv, U, SrvrPub, Multiplier, + Generator, UserPassHash, Prime) of + error -> + ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER); + PremasterSecret -> + + master_from_premaster_secret(PremasterSecret, State) + end; + _ -> + ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER) + end. + cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) -> ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0), next_state_connection(cipher, ack_connection(State#state{session = Session, @@ -2791,22 +2942,26 @@ default_hashsign(_Version = {Major, Minor}, KeyExchange) when Major == 3 andalso Minor >= 3 andalso (KeyExchange == rsa orelse KeyExchange == dhe_rsa orelse - KeyExchange == dh_rsa) -> + KeyExchange == dh_rsa orelse + KeyExchange == srp_rsa) -> {sha, rsa}; default_hashsign(_Version, KeyExchange) when KeyExchange == rsa; KeyExchange == dhe_rsa; - KeyExchange == dh_rsa -> + KeyExchange == dh_rsa; + KeyExchange == srp_rsa -> {md5sha, rsa}; default_hashsign(_Version, KeyExchange) when KeyExchange == dhe_dss; - KeyExchange == dh_dss -> + KeyExchange == dh_dss; + KeyExchange == srp_dss -> {sha, dsa}; default_hashsign(_Version, KeyExchange) when KeyExchange == dh_anon; KeyExchange == psk; KeyExchange == dhe_psk; - KeyExchange == rsa_psk -> + KeyExchange == rsa_psk; + KeyExchange == srp_anon -> {null, anon}. start_or_recv_cancel_timer(infinity, _RecvFrom) -> diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index d0bf710e03..83c0092de2 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -28,6 +28,7 @@ -include("ssl_cipher.hrl"). -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). +-include("ssl_srp.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([master_secret/4, client_hello/8, server_hello/5, hello/4, @@ -65,6 +66,7 @@ client_hello(Host, Port, ConnectionStates, Pending = ssl_record:pending_connection_state(ConnectionStates, read), SecParams = Pending#connection_state.security_parameters, Ciphers = available_suites(UserSuites, Version), + SRP = srp_user(SslOpts), Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), @@ -76,6 +78,7 @@ client_hello(Host, Port, ConnectionStates, renegotiation_info = renegotiation_info(client, ConnectionStates, Renegotiation), + srp = SRP, hash_signs = default_hash_signs(), next_protocol_negotiation = encode_client_protocol_negotiation(SslOpts#ssl_options.next_protocol_selector, Renegotiation) @@ -162,7 +165,8 @@ hello(#server_hello{cipher_suite = CipherSuite, server_version = Version, hello(#client_hello{client_version = ClientVersion, random = Random, cipher_suites = CipherSuites, - renegotiation_info = Info} = Hello, + renegotiation_info = Info, + srp = SRP} = Hello, #ssl_options{versions = Versions, secure_renegotiate = SecureRenegotation} = SslOpts, {Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) -> @@ -171,13 +175,14 @@ hello(#client_hello{client_version = ClientVersion, random = Random, case ssl_record:is_acceptable_version(Version, Versions) of true -> {Type, #session{cipher_suite = CipherSuite, - compression_method = Compression} = Session} + compression_method = Compression} = Session1} = select_session(Hello, Port, Session0, Version, SslOpts, Cache, CacheCb, Cert), case CipherSuite of no_suite -> ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY); _ -> + Session = handle_srp_info(SRP, Session1), case handle_renegotiation_info(server, Info, ConnectionStates0, Renegotiation, SecureRenegotation, CipherSuites) of @@ -372,8 +377,10 @@ certificate_request(ConnectionStates, CertDbHandle, CertDbRef) -> {premaster_secret, binary(), public_key_info()} | {dh, binary()} | {dh, {binary(), binary()}, #'DHParameter'{}, {HashAlgo::atom(), SignAlgo::atom()}, + binary(), binary(), private_key()} | {psk, binary()} | - {dhe_psk, binary(), binary()}, + {dhe_psk, binary(), binary()} | + {srp, {binary(), binary()}, #srp_user{}, {HashAlgo::atom(), SignAlgo::atom()}, binary(), binary(), private_key()}) -> #client_key_exchange{} | #server_key_exchange{}. %% @@ -411,6 +418,12 @@ key_exchange(client, _Version, {psk_premaster_secret, PskIdentity, Secret, {_, P identity = PskIdentity, exchange_keys = EncPremasterSecret}}; +key_exchange(client, _Version, {srp, PublicKey}) -> + #client_key_exchange{ + exchange_keys = #client_srp_public{ + srp_a = PublicKey} + }; + key_exchange(server, Version, {dh, {<>, _}, #'DHParameter'{prime = P, base = G}, HashSign, ClientRandom, ServerRandom, PrivateKey}) -> @@ -437,7 +450,16 @@ key_exchange(server, Version, {dhe_psk, PskIdentityHint, {< + ServerSRPParams = #server_srp_params{srp_n = Prime, srp_g = Generator, + srp_s = Salt, srp_b = PublicKey}, + enc_server_key_exchange(Version, ServerSRPParams, HashSign, ClientRandom, ServerRandom, PrivateKey). enc_server_key_exchange(Version, Params, {HashAlgo, SignAlgo}, @@ -571,7 +593,8 @@ get_tls_handshake(Version, Data, Buffer) -> | #client_diffie_hellman_public{} | #client_psk_identity{} | #client_dhe_psk_identity{} - | #client_rsa_psk_identity{}. + | #client_rsa_psk_identity{} + | #client_srp_public{}. %% %% Description: Decode client_key data and return appropriate type %%-------------------------------------------------------------------- @@ -723,6 +746,11 @@ cipher_suites(Suites, false) -> cipher_suites(Suites, true) -> Suites. +srp_user(#ssl_options{srp_identity = {UserName, _}}) -> + #srp{username = UserName}; +srp_user(_) -> + undefined. + renegotiation_info(client, _, false) -> #renegotiation_info{renegotiated_connection = undefined}; renegotiation_info(server, ConnectionStates, false) -> @@ -805,6 +833,11 @@ select_next_protocol(Protocols, NextProtocolSelector) -> Protocol end. +handle_srp_info(undefined, Session) -> + Session; +handle_srp_info(#srp{username = Username}, Session) -> + Session#session{srp_username = Username}. + handle_renegotiation_info(_, #renegotiation_info{renegotiated_connection = ?byte(0)}, ConnectionStates, false, _, _) -> {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)}; @@ -987,6 +1020,7 @@ dec_hs(_Version, ?CLIENT_HELLO, <>, #client_rsa_psk_identity{identity = Id, exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; dec_client_key(<>, ?KEY_EXCHANGE_RSA_PSK, _) -> - #client_rsa_psk_identity{identity = Id, exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}. + #client_rsa_psk_identity{identity = Id, exchange_keys = #encrypted_premaster_secret{premaster_secret = PKEPMS}}; +dec_client_key(<>, + ?KEY_EXCHANGE_SRP, _) -> + #client_srp_public{srp_a = A}. dec_ske_params(Len, Keys, Version) -> <> = Keys, @@ -1147,6 +1185,17 @@ dec_server_key(<> = KeyStruct, + ?KEY_EXCHANGE_SRP, Version) -> + Params = #server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}, + {BinMsg, HashSign, Signature} = dec_ske_params(NLen + GLen + SLen + BLen + 7, KeyStruct, Version), + #server_key_params{params = Params, + params_bin = BinMsg, + hashsign = HashSign, + signature = Signature}; dec_server_key(_, _, _) -> throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)). @@ -1174,6 +1223,11 @@ dec_hello_extensions(<>, Acc) + when Len == SRPLen + 2 -> + dec_hello_extensions(Rest, [{srp, + #srp{username = SRP}} | Acc]); + dec_hello_extensions(<>, Acc) -> SignAlgoListLen = Len - 2, @@ -1231,6 +1285,7 @@ enc_hs(#client_hello{client_version = {Major, Minor}, cipher_suites = CipherSuites, compression_methods = CompMethods, renegotiation_info = RenegotiationInfo, + srp = SRP, hash_signs = HashSigns, next_protocol_negotiation = NextProtocolNegotiation}, _Version) -> SIDLength = byte_size(SessionID), @@ -1238,7 +1293,7 @@ enc_hs(#client_hello{client_version = {Major, Minor}, CmLength = byte_size(BinCompMethods), BinCipherSuites = list_to_binary(CipherSuites), CsLength = byte_size(BinCipherSuites), - Extensions0 = hello_extensions(RenegotiationInfo, NextProtocolNegotiation), + Extensions0 = hello_extensions(RenegotiationInfo, SRP, NextProtocolNegotiation), Extensions1 = if Major == 3, Minor >=3 -> Extensions0 ++ hello_extensions(HashSigns); true -> Extensions0 @@ -1333,7 +1388,10 @@ enc_cke(Identity = #client_rsa_psk_identity{identity = undefined}, Version) -> enc_cke(#client_rsa_psk_identity{identity = Id, exchange_keys = ExchangeKeys}, Version) -> EncPMS = enc_cke(ExchangeKeys, Version), Len = byte_size(Id), - <>. + <>; +enc_cke(#client_srp_public{srp_a = A}, _) -> + Len = byte_size(A), + <>. enc_server_key(#server_dh_params{dh_p = P, dh_g = G, dh_y = Y}) -> PLen = byte_size(P), @@ -1353,7 +1411,14 @@ enc_server_key(#server_dhe_psk_params{ GLen = byte_size(G), YLen = byte_size(Y), <>. + ?UINT16(PLen), P/binary, ?UINT16(GLen), G/binary, ?UINT16(YLen), Y/binary>>; +enc_server_key(#server_srp_params{srp_n = N, srp_g = G, srp_s = S, srp_b = B}) -> + NLen = byte_size(N), + GLen = byte_size(G), + SLen = byte_size(S), + BLen = byte_size(B), + <>. enc_sign({_, anon}, _Sign, _Version) -> <<>>; @@ -1369,13 +1434,20 @@ enc_sign(_HashSign, Sign, _Version) -> hello_extensions(RenegotiationInfo, NextProtocolNegotiation) -> hello_extensions(RenegotiationInfo) ++ next_protocol_extension(NextProtocolNegotiation). +hello_extensions(RenegotiationInfo, SRP, NextProtocolNegotiation) -> + hello_extensions(RenegotiationInfo) ++ hello_extensions(SRP) ++ next_protocol_extension(NextProtocolNegotiation). + %% Renegotiation info hello_extensions(#renegotiation_info{renegotiated_connection = undefined}) -> []; hello_extensions(#renegotiation_info{} = Info) -> [Info]; +hello_extensions(#srp{} = Info) -> + [Info]; hello_extensions(#hash_sign_algos{} = Info) -> - [Info]. + [Info]; +hello_extensions(undefined) -> + []. next_protocol_extension(undefined) -> []; @@ -1402,6 +1474,11 @@ enc_hello_extensions([#renegotiation_info{renegotiated_connection = Info} | Rest Len = InfoLen +1, enc_hello_extensions(Rest, <>); +enc_hello_extensions([#srp{username = UserName} | Rest], Acc) -> + SRPLen = byte_size(UserName), + Len = SRPLen + 2, + enc_hello_extensions(Rest, <>); + enc_hello_extensions([#hash_sign_algos{hash_sign_algos = HashSignAlgos} | Rest], Acc) -> SignAlgoList = << <<(ssl_cipher:hash_algorithm(Hash)):8, (ssl_cipher:sign_algorithm(Sign)):8>> || {Hash, Sign} <- HashSignAlgos >>, @@ -1517,6 +1594,9 @@ key_exchange_alg(dhe_psk) -> ?KEY_EXCHANGE_DHE_PSK; key_exchange_alg(rsa_psk) -> ?KEY_EXCHANGE_RSA_PSK; +key_exchange_alg(Alg) + when Alg == srp_rsa; Alg == srp_dss; Alg == srp_anon -> + ?KEY_EXCHANGE_SRP; key_exchange_alg(_) -> ?NULL. diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index e35f68409e..1fbb88f5f6 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -48,6 +48,7 @@ compression_method, cipher_suite, master_secret, + srp_username, is_resumable, time_stamp }). @@ -99,6 +100,7 @@ cipher_suites, % cipher_suites<2..2^16-1> compression_methods, % compression_methods<1..2^8-1>, renegotiation_info, + srp, % srp username to send hash_signs, % supported combinations of hashes/signature algos next_protocol_negotiation = undefined % [binary()] }). @@ -131,6 +133,7 @@ -define(KEY_EXCHANGE_PSK, 2). -define(KEY_EXCHANGE_DHE_PSK, 3). -define(KEY_EXCHANGE_RSA_PSK, 4). +-define(KEY_EXCHANGE_SRP, 5). -record(server_rsa_params, { rsa_modulus, %% opaque RSA_modulus<1..2^16-1> @@ -152,6 +155,13 @@ dh_params }). +-record(server_srp_params, { + srp_n, %% opaque srp_N<1..2^16-1> + srp_g, %% opaque srp_g<1..2^16-1> + srp_s, %% opaque srp_s<1..2^8-1> + srp_b %% opaque srp_B<1..2^16-1> + }). + -record(server_key_exchange, { exchange_keys }). @@ -235,6 +245,10 @@ exchange_keys }). +-record(client_srp_public, { + srp_a + }). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Certificate verify - RFC 4346 section 7.4.8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -260,6 +274,15 @@ renegotiated_connection }). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% SRP RFC 5054 section 2.8.1. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-define(SRP_EXT, 12). + +-record(srp, { + username + }). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Signature Algorithms RFC 5746 section 7.4.1.4.1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index fc441a3f01..96a1c8e1ce 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -92,6 +92,7 @@ dhfile, % file() user_lookup_fun, % server option, fun to lookup the user psk_identity, % binary + srp_identity, % client option {User, Password} ciphers, % %% Local policy for the server if it want's to reuse the session %% or not. Defaluts to allways returning true. diff --git a/lib/ssl/src/ssl_srp.hrl b/lib/ssl/src/ssl_srp.hrl new file mode 100644 index 0000000000..ab2be33ab2 --- /dev/null +++ b/lib/ssl/src/ssl_srp.hrl @@ -0,0 +1,31 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2007-2012. 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 +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%---------------------------------------------------------------------- +%% Purpose: Record definition for the TLS SRP protocol +%% see RFC 5054 +%%---------------------------------------------------------------------- + +-record(srp_user, { + generator :: binary(), + prime :: binary(), + salt :: binary(), + verifier :: binary() + }). diff --git a/lib/ssl/src/ssl_srp_primes.erl b/lib/ssl/src/ssl_srp_primes.erl new file mode 100644 index 0000000000..ca20a8d673 --- /dev/null +++ b/lib/ssl/src/ssl_srp_primes.erl @@ -0,0 +1,506 @@ +-module(ssl_srp_primes). + +-export([get_srp_params/1, check_srp_params/2]). + +-define(PRIME_1024, <<16#EE, 16#AF, 16#0A, 16#B9, 16#AD, 16#B3, 16#8D, + 16#D6, 16#9C, 16#33, 16#F8, 16#0A, 16#FA, 16#8F, + 16#C5, 16#E8, 16#60, 16#72, 16#61, 16#87, 16#75, + 16#FF, 16#3C, 16#0B, 16#9E, 16#A2, 16#31, 16#4C, + 16#9C, 16#25, 16#65, 16#76, 16#D6, 16#74, 16#DF, + 16#74, 16#96, 16#EA, 16#81, 16#D3, 16#38, 16#3B, + 16#48, 16#13, 16#D6, 16#92, 16#C6, 16#E0, 16#E0, + 16#D5, 16#D8, 16#E2, 16#50, 16#B9, 16#8B, 16#E4, + 16#8E, 16#49, 16#5C, 16#1D, 16#60, 16#89, 16#DA, + 16#D1, 16#5D, 16#C7, 16#D7, 16#B4, 16#61, 16#54, + 16#D6, 16#B6, 16#CE, 16#8E, 16#F4, 16#AD, 16#69, + 16#B1, 16#5D, 16#49, 16#82, 16#55, 16#9B, 16#29, + 16#7B, 16#CF, 16#18, 16#85, 16#C5, 16#29, 16#F5, + 16#66, 16#66, 16#0E, 16#57, 16#EC, 16#68, 16#ED, + 16#BC, 16#3C, 16#05, 16#72, 16#6C, 16#C0, 16#2F, + 16#D4, 16#CB, 16#F4, 16#97, 16#6E, 16#AA, 16#9A, + 16#FD, 16#51, 16#38, 16#FE, 16#83, 16#76, 16#43, + 16#5B, 16#9F, 16#C6, 16#1D, 16#2F, 16#C0, 16#EB, + 16#06, 16#E3>>). +-define(GENERATOR_1024, <<2>>). + + +-define(PRIME_1536, <<16#9D, 16#EF, 16#3C, 16#AF, 16#B9, 16#39, 16#27, + 16#7A, 16#B1, 16#F1, 16#2A, 16#86, 16#17, 16#A4, + 16#7B, 16#BB, 16#DB, 16#A5, 16#1D, 16#F4, 16#99, + 16#AC, 16#4C, 16#80, 16#BE, 16#EE, 16#A9, 16#61, + 16#4B, 16#19, 16#CC, 16#4D, 16#5F, 16#4F, 16#5F, + 16#55, 16#6E, 16#27, 16#CB, 16#DE, 16#51, 16#C6, + 16#A9, 16#4B, 16#E4, 16#60, 16#7A, 16#29, 16#15, + 16#58, 16#90, 16#3B, 16#A0, 16#D0, 16#F8, 16#43, + 16#80, 16#B6, 16#55, 16#BB, 16#9A, 16#22, 16#E8, + 16#DC, 16#DF, 16#02, 16#8A, 16#7C, 16#EC, 16#67, + 16#F0, 16#D0, 16#81, 16#34, 16#B1, 16#C8, 16#B9, + 16#79, 16#89, 16#14, 16#9B, 16#60, 16#9E, 16#0B, + 16#E3, 16#BA, 16#B6, 16#3D, 16#47, 16#54, 16#83, + 16#81, 16#DB, 16#C5, 16#B1, 16#FC, 16#76, 16#4E, + 16#3F, 16#4B, 16#53, 16#DD, 16#9D, 16#A1, 16#15, + 16#8B, 16#FD, 16#3E, 16#2B, 16#9C, 16#8C, 16#F5, + 16#6E, 16#DF, 16#01, 16#95, 16#39, 16#34, 16#96, + 16#27, 16#DB, 16#2F, 16#D5, 16#3D, 16#24, 16#B7, + 16#C4, 16#86, 16#65, 16#77, 16#2E, 16#43, 16#7D, + 16#6C, 16#7F, 16#8C, 16#E4, 16#42, 16#73, 16#4A, + 16#F7, 16#CC, 16#B7, 16#AE, 16#83, 16#7C, 16#26, + 16#4A, 16#E3, 16#A9, 16#BE, 16#B8, 16#7F, 16#8A, + 16#2F, 16#E9, 16#B8, 16#B5, 16#29, 16#2E, 16#5A, + 16#02, 16#1F, 16#FF, 16#5E, 16#91, 16#47, 16#9E, + 16#8C, 16#E7, 16#A2, 16#8C, 16#24, 16#42, 16#C6, + 16#F3, 16#15, 16#18, 16#0F, 16#93, 16#49, 16#9A, + 16#23, 16#4D, 16#CF, 16#76, 16#E3, 16#FE, 16#D1, + 16#35, 16#F9, 16#BB>>). +-define(GENERATOR_1536, <<2>>). + +-define(PRIME_2048, <<16#AC, 16#6B, 16#DB, 16#41, 16#32, 16#4A, 16#9A, + 16#9B, 16#F1, 16#66, 16#DE, 16#5E, 16#13, 16#89, + 16#58, 16#2F, 16#AF, 16#72, 16#B6, 16#65, 16#19, + 16#87, 16#EE, 16#07, 16#FC, 16#31, 16#92, 16#94, + 16#3D, 16#B5, 16#60, 16#50, 16#A3, 16#73, 16#29, + 16#CB, 16#B4, 16#A0, 16#99, 16#ED, 16#81, 16#93, + 16#E0, 16#75, 16#77, 16#67, 16#A1, 16#3D, 16#D5, + 16#23, 16#12, 16#AB, 16#4B, 16#03, 16#31, 16#0D, + 16#CD, 16#7F, 16#48, 16#A9, 16#DA, 16#04, 16#FD, + 16#50, 16#E8, 16#08, 16#39, 16#69, 16#ED, 16#B7, + 16#67, 16#B0, 16#CF, 16#60, 16#95, 16#17, 16#9A, + 16#16, 16#3A, 16#B3, 16#66, 16#1A, 16#05, 16#FB, + 16#D5, 16#FA, 16#AA, 16#E8, 16#29, 16#18, 16#A9, + 16#96, 16#2F, 16#0B, 16#93, 16#B8, 16#55, 16#F9, + 16#79, 16#93, 16#EC, 16#97, 16#5E, 16#EA, 16#A8, + 16#0D, 16#74, 16#0A, 16#DB, 16#F4, 16#FF, 16#74, + 16#73, 16#59, 16#D0, 16#41, 16#D5, 16#C3, 16#3E, + 16#A7, 16#1D, 16#28, 16#1E, 16#44, 16#6B, 16#14, + 16#77, 16#3B, 16#CA, 16#97, 16#B4, 16#3A, 16#23, + 16#FB, 16#80, 16#16, 16#76, 16#BD, 16#20, 16#7A, + 16#43, 16#6C, 16#64, 16#81, 16#F1, 16#D2, 16#B9, + 16#07, 16#87, 16#17, 16#46, 16#1A, 16#5B, 16#9D, + 16#32, 16#E6, 16#88, 16#F8, 16#77, 16#48, 16#54, + 16#45, 16#23, 16#B5, 16#24, 16#B0, 16#D5, 16#7D, + 16#5E, 16#A7, 16#7A, 16#27, 16#75, 16#D2, 16#EC, + 16#FA, 16#03, 16#2C, 16#FB, 16#DB, 16#F5, 16#2F, + 16#B3, 16#78, 16#61, 16#60, 16#27, 16#90, 16#04, + 16#E5, 16#7A, 16#E6, 16#AF, 16#87, 16#4E, 16#73, + 16#03, 16#CE, 16#53, 16#29, 16#9C, 16#CC, 16#04, + 16#1C, 16#7B, 16#C3, 16#08, 16#D8, 16#2A, 16#56, + 16#98, 16#F3, 16#A8, 16#D0, 16#C3, 16#82, 16#71, + 16#AE, 16#35, 16#F8, 16#E9, 16#DB, 16#FB, 16#B6, + 16#94, 16#B5, 16#C8, 16#03, 16#D8, 16#9F, 16#7A, + 16#E4, 16#35, 16#DE, 16#23, 16#6D, 16#52, 16#5F, + 16#54, 16#75, 16#9B, 16#65, 16#E3, 16#72, 16#FC, + 16#D6, 16#8E, 16#F2, 16#0F, 16#A7, 16#11, 16#1F, + 16#9E, 16#4A, 16#FF, 16#73>>). +-define(GENERATOR_2048, <<2>>). + +-define(PRIME_3072, <<16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, + 16#FF, 16#C9, 16#0F, 16#DA, 16#A2, 16#21, 16#68, + 16#C2, 16#34, 16#C4, 16#C6, 16#62, 16#8B, 16#80, + 16#DC, 16#1C, 16#D1, 16#29, 16#02, 16#4E, 16#08, + 16#8A, 16#67, 16#CC, 16#74, 16#02, 16#0B, 16#BE, + 16#A6, 16#3B, 16#13, 16#9B, 16#22, 16#51, 16#4A, + 16#08, 16#79, 16#8E, 16#34, 16#04, 16#DD, 16#EF, + 16#95, 16#19, 16#B3, 16#CD, 16#3A, 16#43, 16#1B, + 16#30, 16#2B, 16#0A, 16#6D, 16#F2, 16#5F, 16#14, + 16#37, 16#4F, 16#E1, 16#35, 16#6D, 16#6D, 16#51, + 16#C2, 16#45, 16#E4, 16#85, 16#B5, 16#76, 16#62, + 16#5E, 16#7E, 16#C6, 16#F4, 16#4C, 16#42, 16#E9, + 16#A6, 16#37, 16#ED, 16#6B, 16#0B, 16#FF, 16#5C, + 16#B6, 16#F4, 16#06, 16#B7, 16#ED, 16#EE, 16#38, + 16#6B, 16#FB, 16#5A, 16#89, 16#9F, 16#A5, 16#AE, + 16#9F, 16#24, 16#11, 16#7C, 16#4B, 16#1F, 16#E6, + 16#49, 16#28, 16#66, 16#51, 16#EC, 16#E4, 16#5B, + 16#3D, 16#C2, 16#00, 16#7C, 16#B8, 16#A1, 16#63, + 16#BF, 16#05, 16#98, 16#DA, 16#48, 16#36, 16#1C, + 16#55, 16#D3, 16#9A, 16#69, 16#16, 16#3F, 16#A8, + 16#FD, 16#24, 16#CF, 16#5F, 16#83, 16#65, 16#5D, + 16#23, 16#DC, 16#A3, 16#AD, 16#96, 16#1C, 16#62, + 16#F3, 16#56, 16#20, 16#85, 16#52, 16#BB, 16#9E, + 16#D5, 16#29, 16#07, 16#70, 16#96, 16#96, 16#6D, + 16#67, 16#0C, 16#35, 16#4E, 16#4A, 16#BC, 16#98, + 16#04, 16#F1, 16#74, 16#6C, 16#08, 16#CA, 16#18, + 16#21, 16#7C, 16#32, 16#90, 16#5E, 16#46, 16#2E, + 16#36, 16#CE, 16#3B, 16#E3, 16#9E, 16#77, 16#2C, + 16#18, 16#0E, 16#86, 16#03, 16#9B, 16#27, 16#83, + 16#A2, 16#EC, 16#07, 16#A2, 16#8F, 16#B5, 16#C5, + 16#5D, 16#F0, 16#6F, 16#4C, 16#52, 16#C9, 16#DE, + 16#2B, 16#CB, 16#F6, 16#95, 16#58, 16#17, 16#18, + 16#39, 16#95, 16#49, 16#7C, 16#EA, 16#95, 16#6A, + 16#E5, 16#15, 16#D2, 16#26, 16#18, 16#98, 16#FA, + 16#05, 16#10, 16#15, 16#72, 16#8E, 16#5A, 16#8A, + 16#AA, 16#C4, 16#2D, 16#AD, 16#33, 16#17, 16#0D, + 16#04, 16#50, 16#7A, 16#33, 16#A8, 16#55, 16#21, + 16#AB, 16#DF, 16#1C, 16#BA, 16#64, 16#EC, 16#FB, + 16#85, 16#04, 16#58, 16#DB, 16#EF, 16#0A, 16#8A, + 16#EA, 16#71, 16#57, 16#5D, 16#06, 16#0C, 16#7D, + 16#B3, 16#97, 16#0F, 16#85, 16#A6, 16#E1, 16#E4, + 16#C7, 16#AB, 16#F5, 16#AE, 16#8C, 16#DB, 16#09, + 16#33, 16#D7, 16#1E, 16#8C, 16#94, 16#E0, 16#4A, + 16#25, 16#61, 16#9D, 16#CE, 16#E3, 16#D2, 16#26, + 16#1A, 16#D2, 16#EE, 16#6B, 16#F1, 16#2F, 16#FA, + 16#06, 16#D9, 16#8A, 16#08, 16#64, 16#D8, 16#76, + 16#02, 16#73, 16#3E, 16#C8, 16#6A, 16#64, 16#52, + 16#1F, 16#2B, 16#18, 16#17, 16#7B, 16#20, 16#0C, + 16#BB, 16#E1, 16#17, 16#57, 16#7A, 16#61, 16#5D, + 16#6C, 16#77, 16#09, 16#88, 16#C0, 16#BA, 16#D9, + 16#46, 16#E2, 16#08, 16#E2, 16#4F, 16#A0, 16#74, + 16#E5, 16#AB, 16#31, 16#43, 16#DB, 16#5B, 16#FC, + 16#E0, 16#FD, 16#10, 16#8E, 16#4B, 16#82, 16#D1, + 16#20, 16#A9, 16#3A, 16#D2, 16#CA, 16#FF, 16#FF, + 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF>>). +-define(GENERATOR_3072, <<5>>). + +-define(PRIME_4096, <<16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, + 16#FF, 16#C9, 16#0F, 16#DA, 16#A2, 16#21, 16#68, + 16#C2, 16#34, 16#C4, 16#C6, 16#62, 16#8B, 16#80, + 16#DC, 16#1C, 16#D1, 16#29, 16#02, 16#4E, 16#08, + 16#8A, 16#67, 16#CC, 16#74, 16#02, 16#0B, 16#BE, + 16#A6, 16#3B, 16#13, 16#9B, 16#22, 16#51, 16#4A, + 16#08, 16#79, 16#8E, 16#34, 16#04, 16#DD, 16#EF, + 16#95, 16#19, 16#B3, 16#CD, 16#3A, 16#43, 16#1B, + 16#30, 16#2B, 16#0A, 16#6D, 16#F2, 16#5F, 16#14, + 16#37, 16#4F, 16#E1, 16#35, 16#6D, 16#6D, 16#51, + 16#C2, 16#45, 16#E4, 16#85, 16#B5, 16#76, 16#62, + 16#5E, 16#7E, 16#C6, 16#F4, 16#4C, 16#42, 16#E9, + 16#A6, 16#37, 16#ED, 16#6B, 16#0B, 16#FF, 16#5C, + 16#B6, 16#F4, 16#06, 16#B7, 16#ED, 16#EE, 16#38, + 16#6B, 16#FB, 16#5A, 16#89, 16#9F, 16#A5, 16#AE, + 16#9F, 16#24, 16#11, 16#7C, 16#4B, 16#1F, 16#E6, + 16#49, 16#28, 16#66, 16#51, 16#EC, 16#E4, 16#5B, + 16#3D, 16#C2, 16#00, 16#7C, 16#B8, 16#A1, 16#63, + 16#BF, 16#05, 16#98, 16#DA, 16#48, 16#36, 16#1C, + 16#55, 16#D3, 16#9A, 16#69, 16#16, 16#3F, 16#A8, + 16#FD, 16#24, 16#CF, 16#5F, 16#83, 16#65, 16#5D, + 16#23, 16#DC, 16#A3, 16#AD, 16#96, 16#1C, 16#62, + 16#F3, 16#56, 16#20, 16#85, 16#52, 16#BB, 16#9E, + 16#D5, 16#29, 16#07, 16#70, 16#96, 16#96, 16#6D, + 16#67, 16#0C, 16#35, 16#4E, 16#4A, 16#BC, 16#98, + 16#04, 16#F1, 16#74, 16#6C, 16#08, 16#CA, 16#18, + 16#21, 16#7C, 16#32, 16#90, 16#5E, 16#46, 16#2E, + 16#36, 16#CE, 16#3B, 16#E3, 16#9E, 16#77, 16#2C, + 16#18, 16#0E, 16#86, 16#03, 16#9B, 16#27, 16#83, + 16#A2, 16#EC, 16#07, 16#A2, 16#8F, 16#B5, 16#C5, + 16#5D, 16#F0, 16#6F, 16#4C, 16#52, 16#C9, 16#DE, + 16#2B, 16#CB, 16#F6, 16#95, 16#58, 16#17, 16#18, + 16#39, 16#95, 16#49, 16#7C, 16#EA, 16#95, 16#6A, + 16#E5, 16#15, 16#D2, 16#26, 16#18, 16#98, 16#FA, + 16#05, 16#10, 16#15, 16#72, 16#8E, 16#5A, 16#8A, + 16#AA, 16#C4, 16#2D, 16#AD, 16#33, 16#17, 16#0D, + 16#04, 16#50, 16#7A, 16#33, 16#A8, 16#55, 16#21, + 16#AB, 16#DF, 16#1C, 16#BA, 16#64, 16#EC, 16#FB, + 16#85, 16#04, 16#58, 16#DB, 16#EF, 16#0A, 16#8A, + 16#EA, 16#71, 16#57, 16#5D, 16#06, 16#0C, 16#7D, + 16#B3, 16#97, 16#0F, 16#85, 16#A6, 16#E1, 16#E4, + 16#C7, 16#AB, 16#F5, 16#AE, 16#8C, 16#DB, 16#09, + 16#33, 16#D7, 16#1E, 16#8C, 16#94, 16#E0, 16#4A, + 16#25, 16#61, 16#9D, 16#CE, 16#E3, 16#D2, 16#26, + 16#1A, 16#D2, 16#EE, 16#6B, 16#F1, 16#2F, 16#FA, + 16#06, 16#D9, 16#8A, 16#08, 16#64, 16#D8, 16#76, + 16#02, 16#73, 16#3E, 16#C8, 16#6A, 16#64, 16#52, + 16#1F, 16#2B, 16#18, 16#17, 16#7B, 16#20, 16#0C, + 16#BB, 16#E1, 16#17, 16#57, 16#7A, 16#61, 16#5D, + 16#6C, 16#77, 16#09, 16#88, 16#C0, 16#BA, 16#D9, + 16#46, 16#E2, 16#08, 16#E2, 16#4F, 16#A0, 16#74, + 16#E5, 16#AB, 16#31, 16#43, 16#DB, 16#5B, 16#FC, + 16#E0, 16#FD, 16#10, 16#8E, 16#4B, 16#82, 16#D1, + 16#20, 16#A9, 16#21, 16#08, 16#01, 16#1A, 16#72, + 16#3C, 16#12, 16#A7, 16#87, 16#E6, 16#D7, 16#88, + 16#71, 16#9A, 16#10, 16#BD, 16#BA, 16#5B, 16#26, + 16#99, 16#C3, 16#27, 16#18, 16#6A, 16#F4, 16#E2, + 16#3C, 16#1A, 16#94, 16#68, 16#34, 16#B6, 16#15, + 16#0B, 16#DA, 16#25, 16#83, 16#E9, 16#CA, 16#2A, + 16#D4, 16#4C, 16#E8, 16#DB, 16#BB, 16#C2, 16#DB, + 16#04, 16#DE, 16#8E, 16#F9, 16#2E, 16#8E, 16#FC, + 16#14, 16#1F, 16#BE, 16#CA, 16#A6, 16#28, 16#7C, + 16#59, 16#47, 16#4E, 16#6B, 16#C0, 16#5D, 16#99, + 16#B2, 16#96, 16#4F, 16#A0, 16#90, 16#C3, 16#A2, + 16#23, 16#3B, 16#A1, 16#86, 16#51, 16#5B, 16#E7, + 16#ED, 16#1F, 16#61, 16#29, 16#70, 16#CE, 16#E2, + 16#D7, 16#AF, 16#B8, 16#1B, 16#DD, 16#76, 16#21, + 16#70, 16#48, 16#1C, 16#D0, 16#06, 16#91, 16#27, + 16#D5, 16#B0, 16#5A, 16#A9, 16#93, 16#B4, 16#EA, + 16#98, 16#8D, 16#8F, 16#DD, 16#C1, 16#86, 16#FF, + 16#B7, 16#DC, 16#90, 16#A6, 16#C0, 16#8F, 16#4D, + 16#F4, 16#35, 16#C9, 16#34, 16#06, 16#31, 16#99, + 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, + 16#FF>>). +-define(GENERATOR_4096, <<5>>). + +-define(PRIME_6144, <<16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, + 16#FF, 16#C9, 16#0F, 16#DA, 16#A2, 16#21, 16#68, + 16#C2, 16#34, 16#C4, 16#C6, 16#62, 16#8B, 16#80, + 16#DC, 16#1C, 16#D1, 16#29, 16#02, 16#4E, 16#08, + 16#8A, 16#67, 16#CC, 16#74, 16#02, 16#0B, 16#BE, + 16#A6, 16#3B, 16#13, 16#9B, 16#22, 16#51, 16#4A, + 16#08, 16#79, 16#8E, 16#34, 16#04, 16#DD, 16#EF, + 16#95, 16#19, 16#B3, 16#CD, 16#3A, 16#43, 16#1B, + 16#30, 16#2B, 16#0A, 16#6D, 16#F2, 16#5F, 16#14, + 16#37, 16#4F, 16#E1, 16#35, 16#6D, 16#6D, 16#51, + 16#C2, 16#45, 16#E4, 16#85, 16#B5, 16#76, 16#62, + 16#5E, 16#7E, 16#C6, 16#F4, 16#4C, 16#42, 16#E9, + 16#A6, 16#37, 16#ED, 16#6B, 16#0B, 16#FF, 16#5C, + 16#B6, 16#F4, 16#06, 16#B7, 16#ED, 16#EE, 16#38, + 16#6B, 16#FB, 16#5A, 16#89, 16#9F, 16#A5, 16#AE, + 16#9F, 16#24, 16#11, 16#7C, 16#4B, 16#1F, 16#E6, + 16#49, 16#28, 16#66, 16#51, 16#EC, 16#E4, 16#5B, + 16#3D, 16#C2, 16#00, 16#7C, 16#B8, 16#A1, 16#63, + 16#BF, 16#05, 16#98, 16#DA, 16#48, 16#36, 16#1C, + 16#55, 16#D3, 16#9A, 16#69, 16#16, 16#3F, 16#A8, + 16#FD, 16#24, 16#CF, 16#5F, 16#83, 16#65, 16#5D, + 16#23, 16#DC, 16#A3, 16#AD, 16#96, 16#1C, 16#62, + 16#F3, 16#56, 16#20, 16#85, 16#52, 16#BB, 16#9E, + 16#D5, 16#29, 16#07, 16#70, 16#96, 16#96, 16#6D, + 16#67, 16#0C, 16#35, 16#4E, 16#4A, 16#BC, 16#98, + 16#04, 16#F1, 16#74, 16#6C, 16#08, 16#CA, 16#18, + 16#21, 16#7C, 16#32, 16#90, 16#5E, 16#46, 16#2E, + 16#36, 16#CE, 16#3B, 16#E3, 16#9E, 16#77, 16#2C, + 16#18, 16#0E, 16#86, 16#03, 16#9B, 16#27, 16#83, + 16#A2, 16#EC, 16#07, 16#A2, 16#8F, 16#B5, 16#C5, + 16#5D, 16#F0, 16#6F, 16#4C, 16#52, 16#C9, 16#DE, + 16#2B, 16#CB, 16#F6, 16#95, 16#58, 16#17, 16#18, + 16#39, 16#95, 16#49, 16#7C, 16#EA, 16#95, 16#6A, + 16#E5, 16#15, 16#D2, 16#26, 16#18, 16#98, 16#FA, + 16#05, 16#10, 16#15, 16#72, 16#8E, 16#5A, 16#8A, + 16#AA, 16#C4, 16#2D, 16#AD, 16#33, 16#17, 16#0D, + 16#04, 16#50, 16#7A, 16#33, 16#A8, 16#55, 16#21, + 16#AB, 16#DF, 16#1C, 16#BA, 16#64, 16#EC, 16#FB, + 16#85, 16#04, 16#58, 16#DB, 16#EF, 16#0A, 16#8A, + 16#EA, 16#71, 16#57, 16#5D, 16#06, 16#0C, 16#7D, + 16#B3, 16#97, 16#0F, 16#85, 16#A6, 16#E1, 16#E4, + 16#C7, 16#AB, 16#F5, 16#AE, 16#8C, 16#DB, 16#09, + 16#33, 16#D7, 16#1E, 16#8C, 16#94, 16#E0, 16#4A, + 16#25, 16#61, 16#9D, 16#CE, 16#E3, 16#D2, 16#26, + 16#1A, 16#D2, 16#EE, 16#6B, 16#F1, 16#2F, 16#FA, + 16#06, 16#D9, 16#8A, 16#08, 16#64, 16#D8, 16#76, + 16#02, 16#73, 16#3E, 16#C8, 16#6A, 16#64, 16#52, + 16#1F, 16#2B, 16#18, 16#17, 16#7B, 16#20, 16#0C, + 16#BB, 16#E1, 16#17, 16#57, 16#7A, 16#61, 16#5D, + 16#6C, 16#77, 16#09, 16#88, 16#C0, 16#BA, 16#D9, + 16#46, 16#E2, 16#08, 16#E2, 16#4F, 16#A0, 16#74, + 16#E5, 16#AB, 16#31, 16#43, 16#DB, 16#5B, 16#FC, + 16#E0, 16#FD, 16#10, 16#8E, 16#4B, 16#82, 16#D1, + 16#20, 16#A9, 16#21, 16#08, 16#01, 16#1A, 16#72, + 16#3C, 16#12, 16#A7, 16#87, 16#E6, 16#D7, 16#88, + 16#71, 16#9A, 16#10, 16#BD, 16#BA, 16#5B, 16#26, + 16#99, 16#C3, 16#27, 16#18, 16#6A, 16#F4, 16#E2, + 16#3C, 16#1A, 16#94, 16#68, 16#34, 16#B6, 16#15, + 16#0B, 16#DA, 16#25, 16#83, 16#E9, 16#CA, 16#2A, + 16#D4, 16#4C, 16#E8, 16#DB, 16#BB, 16#C2, 16#DB, + 16#04, 16#DE, 16#8E, 16#F9, 16#2E, 16#8E, 16#FC, + 16#14, 16#1F, 16#BE, 16#CA, 16#A6, 16#28, 16#7C, + 16#59, 16#47, 16#4E, 16#6B, 16#C0, 16#5D, 16#99, + 16#B2, 16#96, 16#4F, 16#A0, 16#90, 16#C3, 16#A2, + 16#23, 16#3B, 16#A1, 16#86, 16#51, 16#5B, 16#E7, + 16#ED, 16#1F, 16#61, 16#29, 16#70, 16#CE, 16#E2, + 16#D7, 16#AF, 16#B8, 16#1B, 16#DD, 16#76, 16#21, + 16#70, 16#48, 16#1C, 16#D0, 16#06, 16#91, 16#27, + 16#D5, 16#B0, 16#5A, 16#A9, 16#93, 16#B4, 16#EA, + 16#98, 16#8D, 16#8F, 16#DD, 16#C1, 16#86, 16#FF, + 16#B7, 16#DC, 16#90, 16#A6, 16#C0, 16#8F, 16#4D, + 16#F4, 16#35, 16#C9, 16#34, 16#02, 16#84, 16#92, + 16#36, 16#C3, 16#FA, 16#B4, 16#D2, 16#7C, 16#70, + 16#26, 16#C1, 16#D4, 16#DC, 16#B2, 16#60, 16#26, + 16#46, 16#DE, 16#C9, 16#75, 16#1E, 16#76, 16#3D, + 16#BA, 16#37, 16#BD, 16#F8, 16#FF, 16#94, 16#06, + 16#AD, 16#9E, 16#53, 16#0E, 16#E5, 16#DB, 16#38, + 16#2F, 16#41, 16#30, 16#01, 16#AE, 16#B0, 16#6A, + 16#53, 16#ED, 16#90, 16#27, 16#D8, 16#31, 16#17, + 16#97, 16#27, 16#B0, 16#86, 16#5A, 16#89, 16#18, + 16#DA, 16#3E, 16#DB, 16#EB, 16#CF, 16#9B, 16#14, + 16#ED, 16#44, 16#CE, 16#6C, 16#BA, 16#CE, 16#D4, + 16#BB, 16#1B, 16#DB, 16#7F, 16#14, 16#47, 16#E6, + 16#CC, 16#25, 16#4B, 16#33, 16#20, 16#51, 16#51, + 16#2B, 16#D7, 16#AF, 16#42, 16#6F, 16#B8, 16#F4, + 16#01, 16#37, 16#8C, 16#D2, 16#BF, 16#59, 16#83, + 16#CA, 16#01, 16#C6, 16#4B, 16#92, 16#EC, 16#F0, + 16#32, 16#EA, 16#15, 16#D1, 16#72, 16#1D, 16#03, + 16#F4, 16#82, 16#D7, 16#CE, 16#6E, 16#74, 16#FE, + 16#F6, 16#D5, 16#5E, 16#70, 16#2F, 16#46, 16#98, + 16#0C, 16#82, 16#B5, 16#A8, 16#40, 16#31, 16#90, + 16#0B, 16#1C, 16#9E, 16#59, 16#E7, 16#C9, 16#7F, + 16#BE, 16#C7, 16#E8, 16#F3, 16#23, 16#A9, 16#7A, + 16#7E, 16#36, 16#CC, 16#88, 16#BE, 16#0F, 16#1D, + 16#45, 16#B7, 16#FF, 16#58, 16#5A, 16#C5, 16#4B, + 16#D4, 16#07, 16#B2, 16#2B, 16#41, 16#54, 16#AA, + 16#CC, 16#8F, 16#6D, 16#7E, 16#BF, 16#48, 16#E1, + 16#D8, 16#14, 16#CC, 16#5E, 16#D2, 16#0F, 16#80, + 16#37, 16#E0, 16#A7, 16#97, 16#15, 16#EE, 16#F2, + 16#9B, 16#E3, 16#28, 16#06, 16#A1, 16#D5, 16#8B, + 16#B7, 16#C5, 16#DA, 16#76, 16#F5, 16#50, 16#AA, + 16#3D, 16#8A, 16#1F, 16#BF, 16#F0, 16#EB, 16#19, + 16#CC, 16#B1, 16#A3, 16#13, 16#D5, 16#5C, 16#DA, + 16#56, 16#C9, 16#EC, 16#2E, 16#F2, 16#96, 16#32, + 16#38, 16#7F, 16#E8, 16#D7, 16#6E, 16#3C, 16#04, + 16#68, 16#04, 16#3E, 16#8F, 16#66, 16#3F, 16#48, + 16#60, 16#EE, 16#12, 16#BF, 16#2D, 16#5B, 16#0B, + 16#74, 16#74, 16#D6, 16#E6, 16#94, 16#F9, 16#1E, + 16#6D, 16#CC, 16#40, 16#24, 16#FF, 16#FF, 16#FF, + 16#FF, 16#FF, 16#FF, 16#FF, 16#FF>>). +-define(GENERATOR_6144, <<5>>). + +-define(PRIME_8192, <<16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, + 16#FF, 16#C9, 16#0F, 16#DA, 16#A2, 16#21, 16#68, + 16#C2, 16#34, 16#C4, 16#C6, 16#62, 16#8B, 16#80, + 16#DC, 16#1C, 16#D1, 16#29, 16#02, 16#4E, 16#08, + 16#8A, 16#67, 16#CC, 16#74, 16#02, 16#0B, 16#BE, + 16#A6, 16#3B, 16#13, 16#9B, 16#22, 16#51, 16#4A, + 16#08, 16#79, 16#8E, 16#34, 16#04, 16#DD, 16#EF, + 16#95, 16#19, 16#B3, 16#CD, 16#3A, 16#43, 16#1B, + 16#30, 16#2B, 16#0A, 16#6D, 16#F2, 16#5F, 16#14, + 16#37, 16#4F, 16#E1, 16#35, 16#6D, 16#6D, 16#51, + 16#C2, 16#45, 16#E4, 16#85, 16#B5, 16#76, 16#62, + 16#5E, 16#7E, 16#C6, 16#F4, 16#4C, 16#42, 16#E9, + 16#A6, 16#37, 16#ED, 16#6B, 16#0B, 16#FF, 16#5C, + 16#B6, 16#F4, 16#06, 16#B7, 16#ED, 16#EE, 16#38, + 16#6B, 16#FB, 16#5A, 16#89, 16#9F, 16#A5, 16#AE, + 16#9F, 16#24, 16#11, 16#7C, 16#4B, 16#1F, 16#E6, + 16#49, 16#28, 16#66, 16#51, 16#EC, 16#E4, 16#5B, + 16#3D, 16#C2, 16#00, 16#7C, 16#B8, 16#A1, 16#63, + 16#BF, 16#05, 16#98, 16#DA, 16#48, 16#36, 16#1C, + 16#55, 16#D3, 16#9A, 16#69, 16#16, 16#3F, 16#A8, + 16#FD, 16#24, 16#CF, 16#5F, 16#83, 16#65, 16#5D, + 16#23, 16#DC, 16#A3, 16#AD, 16#96, 16#1C, 16#62, + 16#F3, 16#56, 16#20, 16#85, 16#52, 16#BB, 16#9E, + 16#D5, 16#29, 16#07, 16#70, 16#96, 16#96, 16#6D, + 16#67, 16#0C, 16#35, 16#4E, 16#4A, 16#BC, 16#98, + 16#04, 16#F1, 16#74, 16#6C, 16#08, 16#CA, 16#18, + 16#21, 16#7C, 16#32, 16#90, 16#5E, 16#46, 16#2E, + 16#36, 16#CE, 16#3B, 16#E3, 16#9E, 16#77, 16#2C, + 16#18, 16#0E, 16#86, 16#03, 16#9B, 16#27, 16#83, + 16#A2, 16#EC, 16#07, 16#A2, 16#8F, 16#B5, 16#C5, + 16#5D, 16#F0, 16#6F, 16#4C, 16#52, 16#C9, 16#DE, + 16#2B, 16#CB, 16#F6, 16#95, 16#58, 16#17, 16#18, + 16#39, 16#95, 16#49, 16#7C, 16#EA, 16#95, 16#6A, + 16#E5, 16#15, 16#D2, 16#26, 16#18, 16#98, 16#FA, + 16#05, 16#10, 16#15, 16#72, 16#8E, 16#5A, 16#8A, + 16#AA, 16#C4, 16#2D, 16#AD, 16#33, 16#17, 16#0D, + 16#04, 16#50, 16#7A, 16#33, 16#A8, 16#55, 16#21, + 16#AB, 16#DF, 16#1C, 16#BA, 16#64, 16#EC, 16#FB, + 16#85, 16#04, 16#58, 16#DB, 16#EF, 16#0A, 16#8A, + 16#EA, 16#71, 16#57, 16#5D, 16#06, 16#0C, 16#7D, + 16#B3, 16#97, 16#0F, 16#85, 16#A6, 16#E1, 16#E4, + 16#C7, 16#AB, 16#F5, 16#AE, 16#8C, 16#DB, 16#09, + 16#33, 16#D7, 16#1E, 16#8C, 16#94, 16#E0, 16#4A, + 16#25, 16#61, 16#9D, 16#CE, 16#E3, 16#D2, 16#26, + 16#1A, 16#D2, 16#EE, 16#6B, 16#F1, 16#2F, 16#FA, + 16#06, 16#D9, 16#8A, 16#08, 16#64, 16#D8, 16#76, + 16#02, 16#73, 16#3E, 16#C8, 16#6A, 16#64, 16#52, + 16#1F, 16#2B, 16#18, 16#17, 16#7B, 16#20, 16#0C, + 16#BB, 16#E1, 16#17, 16#57, 16#7A, 16#61, 16#5D, + 16#6C, 16#77, 16#09, 16#88, 16#C0, 16#BA, 16#D9, + 16#46, 16#E2, 16#08, 16#E2, 16#4F, 16#A0, 16#74, + 16#E5, 16#AB, 16#31, 16#43, 16#DB, 16#5B, 16#FC, + 16#E0, 16#FD, 16#10, 16#8E, 16#4B, 16#82, 16#D1, + 16#20, 16#A9, 16#21, 16#08, 16#01, 16#1A, 16#72, + 16#3C, 16#12, 16#A7, 16#87, 16#E6, 16#D7, 16#88, + 16#71, 16#9A, 16#10, 16#BD, 16#BA, 16#5B, 16#26, + 16#99, 16#C3, 16#27, 16#18, 16#6A, 16#F4, 16#E2, + 16#3C, 16#1A, 16#94, 16#68, 16#34, 16#B6, 16#15, + 16#0B, 16#DA, 16#25, 16#83, 16#E9, 16#CA, 16#2A, + 16#D4, 16#4C, 16#E8, 16#DB, 16#BB, 16#C2, 16#DB, + 16#04, 16#DE, 16#8E, 16#F9, 16#2E, 16#8E, 16#FC, + 16#14, 16#1F, 16#BE, 16#CA, 16#A6, 16#28, 16#7C, + 16#59, 16#47, 16#4E, 16#6B, 16#C0, 16#5D, 16#99, + 16#B2, 16#96, 16#4F, 16#A0, 16#90, 16#C3, 16#A2, + 16#23, 16#3B, 16#A1, 16#86, 16#51, 16#5B, 16#E7, + 16#ED, 16#1F, 16#61, 16#29, 16#70, 16#CE, 16#E2, + 16#D7, 16#AF, 16#B8, 16#1B, 16#DD, 16#76, 16#21, + 16#70, 16#48, 16#1C, 16#D0, 16#06, 16#91, 16#27, + 16#D5, 16#B0, 16#5A, 16#A9, 16#93, 16#B4, 16#EA, + 16#98, 16#8D, 16#8F, 16#DD, 16#C1, 16#86, 16#FF, + 16#B7, 16#DC, 16#90, 16#A6, 16#C0, 16#8F, 16#4D, + 16#F4, 16#35, 16#C9, 16#34, 16#02, 16#84, 16#92, + 16#36, 16#C3, 16#FA, 16#B4, 16#D2, 16#7C, 16#70, + 16#26, 16#C1, 16#D4, 16#DC, 16#B2, 16#60, 16#26, + 16#46, 16#DE, 16#C9, 16#75, 16#1E, 16#76, 16#3D, + 16#BA, 16#37, 16#BD, 16#F8, 16#FF, 16#94, 16#06, + 16#AD, 16#9E, 16#53, 16#0E, 16#E5, 16#DB, 16#38, + 16#2F, 16#41, 16#30, 16#01, 16#AE, 16#B0, 16#6A, + 16#53, 16#ED, 16#90, 16#27, 16#D8, 16#31, 16#17, + 16#97, 16#27, 16#B0, 16#86, 16#5A, 16#89, 16#18, + 16#DA, 16#3E, 16#DB, 16#EB, 16#CF, 16#9B, 16#14, + 16#ED, 16#44, 16#CE, 16#6C, 16#BA, 16#CE, 16#D4, + 16#BB, 16#1B, 16#DB, 16#7F, 16#14, 16#47, 16#E6, + 16#CC, 16#25, 16#4B, 16#33, 16#20, 16#51, 16#51, + 16#2B, 16#D7, 16#AF, 16#42, 16#6F, 16#B8, 16#F4, + 16#01, 16#37, 16#8C, 16#D2, 16#BF, 16#59, 16#83, + 16#CA, 16#01, 16#C6, 16#4B, 16#92, 16#EC, 16#F0, + 16#32, 16#EA, 16#15, 16#D1, 16#72, 16#1D, 16#03, + 16#F4, 16#82, 16#D7, 16#CE, 16#6E, 16#74, 16#FE, + 16#F6, 16#D5, 16#5E, 16#70, 16#2F, 16#46, 16#98, + 16#0C, 16#82, 16#B5, 16#A8, 16#40, 16#31, 16#90, + 16#0B, 16#1C, 16#9E, 16#59, 16#E7, 16#C9, 16#7F, + 16#BE, 16#C7, 16#E8, 16#F3, 16#23, 16#A9, 16#7A, + 16#7E, 16#36, 16#CC, 16#88, 16#BE, 16#0F, 16#1D, + 16#45, 16#B7, 16#FF, 16#58, 16#5A, 16#C5, 16#4B, + 16#D4, 16#07, 16#B2, 16#2B, 16#41, 16#54, 16#AA, + 16#CC, 16#8F, 16#6D, 16#7E, 16#BF, 16#48, 16#E1, + 16#D8, 16#14, 16#CC, 16#5E, 16#D2, 16#0F, 16#80, + 16#37, 16#E0, 16#A7, 16#97, 16#15, 16#EE, 16#F2, + 16#9B, 16#E3, 16#28, 16#06, 16#A1, 16#D5, 16#8B, + 16#B7, 16#C5, 16#DA, 16#76, 16#F5, 16#50, 16#AA, + 16#3D, 16#8A, 16#1F, 16#BF, 16#F0, 16#EB, 16#19, + 16#CC, 16#B1, 16#A3, 16#13, 16#D5, 16#5C, 16#DA, + 16#56, 16#C9, 16#EC, 16#2E, 16#F2, 16#96, 16#32, + 16#38, 16#7F, 16#E8, 16#D7, 16#6E, 16#3C, 16#04, + 16#68, 16#04, 16#3E, 16#8F, 16#66, 16#3F, 16#48, + 16#60, 16#EE, 16#12, 16#BF, 16#2D, 16#5B, 16#0B, + 16#74, 16#74, 16#D6, 16#E6, 16#94, 16#F9, 16#1E, + 16#6D, 16#BE, 16#11, 16#59, 16#74, 16#A3, 16#92, + 16#6F, 16#12, 16#FE, 16#E5, 16#E4, 16#38, 16#77, + 16#7C, 16#B6, 16#A9, 16#32, 16#DF, 16#8C, 16#D8, + 16#BE, 16#C4, 16#D0, 16#73, 16#B9, 16#31, 16#BA, + 16#3B, 16#C8, 16#32, 16#B6, 16#8D, 16#9D, 16#D3, + 16#00, 16#74, 16#1F, 16#A7, 16#BF, 16#8A, 16#FC, + 16#47, 16#ED, 16#25, 16#76, 16#F6, 16#93, 16#6B, + 16#A4, 16#24, 16#66, 16#3A, 16#AB, 16#63, 16#9C, + 16#5A, 16#E4, 16#F5, 16#68, 16#34, 16#23, 16#B4, + 16#74, 16#2B, 16#F1, 16#C9, 16#78, 16#23, 16#8F, + 16#16, 16#CB, 16#E3, 16#9D, 16#65, 16#2D, 16#E3, + 16#FD, 16#B8, 16#BE, 16#FC, 16#84, 16#8A, 16#D9, + 16#22, 16#22, 16#2E, 16#04, 16#A4, 16#03, 16#7C, + 16#07, 16#13, 16#EB, 16#57, 16#A8, 16#1A, 16#23, + 16#F0, 16#C7, 16#34, 16#73, 16#FC, 16#64, 16#6C, + 16#EA, 16#30, 16#6B, 16#4B, 16#CB, 16#C8, 16#86, + 16#2F, 16#83, 16#85, 16#DD, 16#FA, 16#9D, 16#4B, + 16#7F, 16#A2, 16#C0, 16#87, 16#E8, 16#79, 16#68, + 16#33, 16#03, 16#ED, 16#5B, 16#DD, 16#3A, 16#06, + 16#2B, 16#3C, 16#F5, 16#B3, 16#A2, 16#78, 16#A6, + 16#6D, 16#2A, 16#13, 16#F8, 16#3F, 16#44, 16#F8, + 16#2D, 16#DF, 16#31, 16#0E, 16#E0, 16#74, 16#AB, + 16#6A, 16#36, 16#45, 16#97, 16#E8, 16#99, 16#A0, + 16#25, 16#5D, 16#C1, 16#64, 16#F3, 16#1C, 16#C5, + 16#08, 16#46, 16#85, 16#1D, 16#F9, 16#AB, 16#48, + 16#19, 16#5D, 16#ED, 16#7E, 16#A1, 16#B1, 16#D5, + 16#10, 16#BD, 16#7E, 16#E7, 16#4D, 16#73, 16#FA, + 16#F3, 16#6B, 16#C3, 16#1E, 16#CF, 16#A2, 16#68, + 16#35, 16#90, 16#46, 16#F4, 16#EB, 16#87, 16#9F, + 16#92, 16#40, 16#09, 16#43, 16#8B, 16#48, 16#1C, + 16#6C, 16#D7, 16#88, 16#9A, 16#00, 16#2E, 16#D5, + 16#EE, 16#38, 16#2B, 16#C9, 16#19, 16#0D, 16#A6, + 16#FC, 16#02, 16#6E, 16#47, 16#95, 16#58, 16#E4, + 16#47, 16#56, 16#77, 16#E9, 16#AA, 16#9E, 16#30, + 16#50, 16#E2, 16#76, 16#56, 16#94, 16#DF, 16#C8, + 16#1F, 16#56, 16#E8, 16#80, 16#B9, 16#6E, 16#71, + 16#60, 16#C9, 16#80, 16#DD, 16#98, 16#ED, 16#D3, + 16#DF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, 16#FF, + 16#FF, 16#FF>>). +-define(GENERATOR_8192, <<19>>). + +get_srp_params(srp_1024) -> {?GENERATOR_1024, ?PRIME_1024}; +get_srp_params(srp_1536) -> {?GENERATOR_1536, ?PRIME_1536}; +get_srp_params(srp_2048) -> {?GENERATOR_2048, ?PRIME_2048}; +get_srp_params(srp_3072) -> {?GENERATOR_3072, ?PRIME_3072}; +get_srp_params(srp_4096) -> {?GENERATOR_4096, ?PRIME_4096}; +get_srp_params(srp_6144) -> {?GENERATOR_6144, ?PRIME_6144}; +get_srp_params(srp_8192) -> {?GENERATOR_8192, ?PRIME_8192}. + +check_srp_params(?GENERATOR_1024, ?PRIME_1024) -> ok; +check_srp_params(?GENERATOR_1536, ?PRIME_1536) -> ok; +check_srp_params(?GENERATOR_2048, ?PRIME_2048) -> ok; +check_srp_params(?GENERATOR_3072, ?PRIME_3072) -> ok; +check_srp_params(?GENERATOR_4096, ?PRIME_4096) -> ok; +check_srp_params(?GENERATOR_6144, ?PRIME_6144) -> ok; +check_srp_params(?GENERATOR_8192, ?PRIME_8192) -> ok; +check_srp_params(_Generator, _Prime) -> + not_accepted. diff --git a/lib/ssl/src/ssl_srp_primes.hrl b/lib/ssl/src/ssl_srp_primes.hrl new file mode 100644 index 0000000000..4bd534efbf --- /dev/null +++ b/lib/ssl/src/ssl_srp_primes.hrl @@ -0,0 +1 @@ +-type srp_parameters() :: srp_1024 | srp_1536 | srp_2048 | srp_3072 | srp_4096 | srp_6144 | srp_8192. -- cgit v1.2.3