diff options
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/doc/src/crypto.xml | 146 | ||||
-rw-r--r-- | lib/crypto/doc/src/engine_keys.xml | 2 | ||||
-rw-r--r-- | lib/crypto/test/Makefile | 3 | ||||
-rw-r--r-- | lib/crypto/test/crypto.spec | 5 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 61 | ||||
-rw-r--r-- | lib/crypto/test/crypto_bench.spec | 3 | ||||
-rw-r--r-- | lib/crypto/test/crypto_bench_SUITE.erl | 400 |
7 files changed, 520 insertions, 100 deletions
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index b33db0d6e4..5c1909fc7f 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -23,7 +23,7 @@ <title>crypto</title> </header> - <module>crypto</module> + <module since="">crypto</module> <modulesummary>Crypto Functions</modulesummary> <description> <p>This module provides a set of cryptographic functions. @@ -524,7 +524,7 @@ <!--================ FUNCTIONS ================--> <funcs> <func> - <name name="block_encrypt" arity="3"/> + <name name="block_encrypt" arity="3" since="OTP 18.0"/> <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary> <desc> <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.</p> @@ -537,7 +537,7 @@ </func> <func> - <name name="block_decrypt" arity="3"/> + <name name="block_decrypt" arity="3" since="OTP 18.0"/> <fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary> <desc> <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.</p> @@ -550,9 +550,9 @@ </func> <func> - <name>block_encrypt(Type, Key, Ivec, PlainText) -> CipherText</name> - <name>block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag}</name> - <name>block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag}</name> + <name since="OTP R16B01">block_encrypt(Type, Key, Ivec, PlainText) -> CipherText</name> + <name since="OTP R16B01">block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag}</name> + <name since="OTP R16B01">block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag}</name> <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary> <type> <v>Type = <seealso marker="#type-block_cipher_with_iv">block_cipher_with_iv()</seealso></v> @@ -577,8 +577,8 @@ </func> <func> - <name>block_decrypt(Type, Key, Ivec, CipherText) -> PlainText</name> - <name>block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | error</name> + <name since="OTP R16B01">block_decrypt(Type, Key, Ivec, CipherText) -> PlainText</name> + <name since="OTP R16B01">block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | error</name> <fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary> <type> <v>Type = <seealso marker="#type-block_cipher_with_iv">block_cipher_with_iv()</seealso></v> @@ -603,7 +603,7 @@ </func> <func> - <name name="bytes_to_integer" arity="1"/> + <name name="bytes_to_integer" arity="1" since="OTP R16B01"/> <fsummary>Convert binary representation, of an integer, to an Erlang integer.</fsummary> <desc> <p>Convert binary representation, of an integer, to an Erlang integer. @@ -612,7 +612,7 @@ </func> <func> - <name name="compute_key" arity="4"/> + <name name="compute_key" arity="4" since="OTP R16B01"/> <fsummary>Computes the shared secret</fsummary> <desc> <p>Computes the shared secret from the private key and the other party's public key. @@ -622,7 +622,7 @@ </func> <func> - <name name="exor" arity="2"/> + <name name="exor" arity="2" since=""/> <fsummary>XOR data</fsummary> <desc> <p>Performs bit-wise XOR (exclusive or) on the data supplied.</p> @@ -631,8 +631,8 @@ <func> - <name name="generate_key" arity="2"/> - <name name="generate_key" arity="3"/> + <name name="generate_key" arity="2" since="OTP R16B01"/> + <name name="generate_key" arity="3" since="OTP R16B01"/> <fsummary>Generates a public key of type <c>Type</c></fsummary> <desc> <p>Generates a public key of type <c>Type</c>. @@ -653,7 +653,7 @@ </func> <func> - <name name="hash" arity="2"/> + <name name="hash" arity="2" since="OTP R15B02"/> <fsummary></fsummary> <desc> <p>Computes a message digest of type <c>Type</c> from <c>Data</c>.</p> @@ -663,7 +663,7 @@ </func> <func> - <name name="hash_init" arity="1"/> + <name name="hash_init" arity="1" since="OTP R15B02"/> <fsummary></fsummary> <desc> <p>Initializes the context for streaming hash operations. <c>Type</c> determines @@ -675,7 +675,7 @@ </func> <func> - <name name="hash_update" arity="2"/> + <name name="hash_update" arity="2" since="OTP R15B02"/> <fsummary></fsummary> <desc> <p>Updates the digest represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c> @@ -687,7 +687,7 @@ </func> <func> - <name name="hash_final" arity="1"/> + <name name="hash_final" arity="1" since="OTP R15B02"/> <fsummary></fsummary> <desc> <p>Finalizes the hash operation referenced by <c>Context</c> returned @@ -698,8 +698,8 @@ </func> <func> - <name name="hmac" arity="3"/> - <name name="hmac" arity="4"/> + <name name="hmac" arity="3" since="OTP R16B"/> + <name name="hmac" arity="4" since="OTP R16B"/> <fsummary></fsummary> <desc> <p>Computes a HMAC of type <c>Type</c> from <c>Data</c> using @@ -709,7 +709,7 @@ </func> <func> - <name name="hmac_init" arity="2"/> + <name name="hmac_init" arity="2" since="OTP R14B03"/> <fsummary></fsummary> <desc> <p>Initializes the context for streaming HMAC operations. <c>Type</c> determines @@ -719,7 +719,7 @@ </func> <func> - <name name="hmac_update" arity="2"/> + <name name="hmac_update" arity="2" since="OTP R14B03"/> <fsummary></fsummary> <desc> <p>Updates the HMAC represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c> @@ -738,7 +738,7 @@ </func> <func> - <name name="hmac_final" arity="1"/> + <name name="hmac_final" arity="1" since="OTP R14B03"/> <fsummary></fsummary> <desc> <p>Finalizes the HMAC operation referenced by <c>Context</c>. The size of the resultant MAC is @@ -747,7 +747,7 @@ </func> <func> - <name name="hmac_final_n" arity="2"/> + <name name="hmac_final_n" arity="2" since="OTP R14B03"/> <fsummary></fsummary> <desc> <p>Finalizes the HMAC operation referenced by <c>Context</c>. <c>HashLen</c> must be greater than @@ -756,8 +756,8 @@ </func> <func> - <name name="cmac" arity="3"/> - <name name="cmac" arity="4"/> + <name name="cmac" arity="3" since="OTP 20.0"/> + <name name="cmac" arity="4" since="OTP 20.0"/> <fsummary>Calculates the Cipher-based Message Authentication Code.</fsummary> <desc> <p>Computes a CMAC of type <c>Type</c> from <c>Data</c> using @@ -767,7 +767,7 @@ </func> <func> - <name name="info_fips" arity="0"/> + <name name="info_fips" arity="0" since="OTP 20.0"/> <fsummary>Provides information about the FIPS operating status.</fsummary> <desc> <p>Provides information about the FIPS operating status of @@ -790,7 +790,7 @@ </func> <func> - <name name="enable_fips_mode" arity="1"/> + <name name="enable_fips_mode" arity="1" since="OTP 21.1"/> <fsummary>Change FIPS mode.</fsummary> <desc> <p>Enables (<c>Enable = true</c>) or disables (<c>Enable = false</c>) FIPS mode. Returns <c>true</c> if @@ -805,7 +805,7 @@ </func> <func> - <name name="info_lib" arity="0"/> + <name name="info_lib" arity="0" since=""/> <fsummary>Provides information about the libraries used by crypto.</fsummary> <desc> <p>Provides the name and version of the libraries used by crypto.</p> @@ -826,7 +826,7 @@ </func> <func> - <name name="mod_pow" arity="3"/> + <name name="mod_pow" arity="3" since="OTP R16B01"/> <fsummary>Computes the function: N^P mod M</fsummary> <desc> <p>Computes the function <c>N^P mod M</c>.</p> @@ -834,8 +834,8 @@ </func> <func> - <name name="next_iv" arity="2"/> - <name name="next_iv" arity="3"/> + <name name="next_iv" arity="2" since="OTP R16B01"/> + <name name="next_iv" arity="3" since="OTP R16B01"/> <fsummary></fsummary> <desc> <p>Returns the initialization vector to be used in the next @@ -847,7 +847,7 @@ </func> <func> - <name name="poly1305" arity="2"/> + <name name="poly1305" arity="2" since="OTP 21.1"/> <fsummary></fsummary> <desc> <p>Computes a POLY1305 message authentication code (<c>Mac</c>) from <c>Data</c> using @@ -856,7 +856,7 @@ </func> <func> - <name name="private_decrypt" arity="4"/> + <name name="private_decrypt" arity="4" since="OTP R16B01"/> <fsummary>Decrypts CipherText using the private Key.</fsummary> <desc> <p>Decrypts the <c>CipherText</c>, encrypted with @@ -870,7 +870,7 @@ </func> <func> - <name name="private_encrypt" arity="4"/> + <name name="private_encrypt" arity="4" since="OTP R16B01"/> <fsummary>Encrypts PlainText using the private Key.</fsummary> <desc> <p>Encrypts the <c>PlainText</c> using the <c>PrivateKey</c> @@ -883,7 +883,7 @@ </func> <func> - <name name="public_decrypt" arity="4"/> + <name name="public_decrypt" arity="4" since="OTP R16B01"/> <fsummary>Decrypts CipherText using the public Key.</fsummary> <desc> <p>Decrypts the <c>CipherText</c>, encrypted with @@ -897,7 +897,7 @@ </func> <func> - <name name="public_encrypt" arity="4"/> + <name name="public_encrypt" arity="4" since="OTP R16B01"/> <fsummary>Encrypts PlainText using the public Key.</fsummary> <desc> <p>Encrypts the <c>PlainText</c> (message digest) using the <c>PublicKey</c> @@ -909,7 +909,7 @@ </func> <func> - <name name="rand_seed" arity="1"/> + <name name="rand_seed" arity="1" since="OTP 17.0"/> <fsummary>Set the seed for random bytes generation</fsummary> <desc> <p>Set the seed for PRNG to the given binary. This calls the @@ -922,7 +922,7 @@ </func> <func> - <name>rand_uniform(Lo, Hi) -> N</name> + <name since="">rand_uniform(Lo, Hi) -> N</name> <fsummary>Generate a random number</fsummary> <type> <v>Lo, Hi, N = integer()</v> @@ -935,7 +935,7 @@ </func> <func> - <name name="start" arity="0"/> + <name name="start" arity="0" since=""/> <fsummary> Equivalent to application:start(crypto). </fsummary> <desc> <p> Equivalent to application:start(crypto).</p> @@ -943,7 +943,7 @@ </func> <func> - <name name="stop" arity="0"/> + <name name="stop" arity="0" since=""/> <fsummary> Equivalent to application:stop(crypto).</fsummary> <desc> <p> Equivalent to application:stop(crypto).</p> @@ -951,7 +951,7 @@ </func> <func> - <name name="strong_rand_bytes" arity="1"/> + <name name="strong_rand_bytes" arity="1" since="OTP R14B03"/> <fsummary>Generate a binary of random bytes</fsummary> <desc> <p>Generates N bytes randomly uniform 0..255, and returns the @@ -964,7 +964,7 @@ </func> <func> - <name name="rand_seed" arity="0"/> + <name name="rand_seed" arity="0" since="OTP 20.0"/> <fsummary>Strong random number generation plugin state</fsummary> <desc> <p> @@ -992,7 +992,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="rand_seed_s" arity="0"/> + <name name="rand_seed_s" arity="0" since="OTP 20.0"/> <fsummary>Strong random number generation plugin state</fsummary> <desc> <p> @@ -1027,7 +1027,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name>rand_seed_alg(Alg) -> rand:state()</name> + <name since="OTP 21.0">rand_seed_alg(Alg) -> rand:state()</name> <fsummary>Strong random number generation plugin state</fsummary> <type> <v>Alg = crypto | crypto_cache</v> @@ -1063,7 +1063,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name>rand_seed_alg_s(Alg) -> rand:state()</name> + <name since="OTP 21.0">rand_seed_alg_s(Alg) -> rand:state()</name> <fsummary>Strong random number generation plugin state</fsummary> <type> <v>Alg = crypto | crypto_cache</v> @@ -1121,7 +1121,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="stream_init" arity="2"/> + <name name="stream_init" arity="2" since="OTP R16B01"/> <fsummary></fsummary> <desc> <p>Initializes the state for use in RC4 stream encryption @@ -1134,7 +1134,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="stream_init" arity="3"/> + <name name="stream_init" arity="3" since="OTP R16B01"/> <fsummary></fsummary> <desc> <p>Initializes the state for use in streaming AES encryption using Counter mode (CTR). @@ -1149,7 +1149,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="stream_encrypt" arity="2"/> + <name name="stream_encrypt" arity="2" since="OTP R16B01"/> <fsummary></fsummary> <desc> <p>Encrypts <c>PlainText</c> according to the stream cipher <c>Type</c> specified in stream_init/3. @@ -1160,7 +1160,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="stream_decrypt" arity="2"/> + <name name="stream_decrypt" arity="2" since="OTP R16B01"/> <fsummary></fsummary> <desc> <p>Decrypts <c>CipherText</c> according to the stream cipher <c>Type</c> specified in stream_init/3. @@ -1171,7 +1171,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="supports" arity="0"/> + <name name="supports" arity="0" since="OTP R16B01"/> <fsummary>Provide a list of available crypto algorithms.</fsummary> <desc> <p> Can be used to determine which crypto algorithms that are supported @@ -1183,7 +1183,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="ec_curves" arity="0"/> + <name name="ec_curves" arity="0" since="OTP 17.0"/> <fsummary>Provide a list of available named elliptic curves.</fsummary> <desc> <p>Can be used to determine which named elliptic curves are supported.</p> @@ -1191,7 +1191,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="ec_curve" arity="1"/> + <name name="ec_curve" arity="1" since="OTP 17.0"/> <fsummary>Get the defining parameters of a elliptic curve.</fsummary> <desc> <p>Return the defining parameters of a elliptic curve.</p> @@ -1199,8 +1199,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="sign" arity="4"/> - <name name="sign" arity="5"/> + <name name="sign" arity="4" since="OTP R16B01"/> + <name name="sign" arity="5" since="OTP 20.1"/> <fsummary> Create digital signature.</fsummary> <desc> <p>Creates a digital signature.</p> @@ -1214,8 +1214,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="verify" arity="5"/> - <name name="verify" arity="6"/> + <name name="verify" arity="5" since="OTP R16B01"/> + <name name="verify" arity="6" since="OTP 20.1"/> <fsummary>Verifies a digital signature.</fsummary> <desc> <p>Verifies a digital signature</p> @@ -1231,7 +1231,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> <!-- Engine functions --> <func> - <name name="privkey_to_pubkey" arity="2"/> + <name name="privkey_to_pubkey" arity="2" since="OTP 20.2"/> <fsummary>Fetches a public key from an Engine stored private key.</fsummary> <desc> <p>Fetches the corresponding public key from a private key stored in an Engine. @@ -1241,7 +1241,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_get_all_methods" arity="0"/> + <name name="engine_get_all_methods" arity="0" since="OTP 20.2"/> <fsummary>Return list of all possible engine methods</fsummary> <desc> <p> @@ -1259,7 +1259,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_load" arity="3"/> + <name name="engine_load" arity="3" since="OTP 20.2"/> <fsummary>Dynamical load an encryption engine</fsummary> <desc> <p> @@ -1281,7 +1281,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_load" arity="4"/> + <name name="engine_load" arity="4" since="OTP 20.2"/> <fsummary>Dynamical load an encryption engine</fsummary> <desc> <p> @@ -1301,7 +1301,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_unload" arity="1"/> + <name name="engine_unload" arity="1" since="OTP 20.2"/> <fsummary>Dynamical load an encryption engine</fsummary> <desc> <p> @@ -1321,7 +1321,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_by_id" arity="1"/> + <name name="engine_by_id" arity="1" since="OTP 21.0.6"/> <fsummary>Get a reference to an already loaded engine</fsummary> <desc> <p> @@ -1341,7 +1341,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_ctrl_cmd_string" arity="3"/> + <name name="engine_ctrl_cmd_string" arity="3" since="OTP 20.2"/> <fsummary>Sends ctrl commands to an OpenSSL engine</fsummary> <desc> <p> @@ -1358,7 +1358,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_ctrl_cmd_string" arity="4"/> + <name name="engine_ctrl_cmd_string" arity="4" since="OTP 20.2"/> <fsummary>Sends ctrl commands to an OpenSSL engine</fsummary> <desc> <p> @@ -1379,7 +1379,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_add" arity="1"/> + <name name="engine_add" arity="1" since="OTP 21.0.6"/> <fsummary>Add engine to OpenSSL internal list</fsummary> <desc> <p>Add the engine to OpenSSL's internal list.</p> @@ -1392,7 +1392,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_remove" arity="1"/> + <name name="engine_remove" arity="1" since="OTP 21.0.6"/> <fsummary>Remove engine to OpenSSL internal list</fsummary> <desc> <p>Remove the engine from OpenSSL's internal list.</p> @@ -1405,7 +1405,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_get_id" arity="1"/> + <name name="engine_get_id" arity="1" since="OTP 21.0.6"/> <fsummary>Fetch engine ID</fsummary> <desc> <p>Return the ID for the engine, or an empty binary if there is no id set.</p> @@ -1418,7 +1418,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_get_name" arity="1"/> + <name name="engine_get_name" arity="1" since="OTP 21.0.6"/> <fsummary>Fetch engine name</fsummary> <desc> <p>Return the name (eg a description) for the engine, or an empty binary if there is no name set.</p> @@ -1431,7 +1431,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="engine_list" arity="0"/> + <name name="engine_list" arity="0" since="OTP 20.2"/> <fsummary>List the known engine ids</fsummary> <desc> <p>List the id's of all engines in OpenSSL's internal list.</p> @@ -1451,7 +1451,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="ensure_engine_loaded" arity="2"/> + <name name="ensure_engine_loaded" arity="2" since="OTP 21.0.6"/> <fsummary>Ensure encryption engine just loaded once</fsummary> <desc> <p> @@ -1473,7 +1473,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="ensure_engine_loaded" arity="3"/> + <name name="ensure_engine_loaded" arity="3" since="OTP 21.0.6"/> <fsummary>Ensure encryption engine just loaded once</fsummary> <desc> <p> @@ -1496,7 +1496,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="ensure_engine_unloaded" arity="1"/> + <name name="ensure_engine_unloaded" arity="1" since="OTP 21.0.6"/> <fsummary>Unload an engine loaded with the ensure function</fsummary> <desc> <p> @@ -1519,7 +1519,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre> </func> <func> - <name name="ensure_engine_unloaded" arity="2"/> + <name name="ensure_engine_unloaded" arity="2" since="OTP 21.0.6"/> <fsummary>Unload an engine loaded with the ensure function</fsummary> <desc> <p> diff --git a/lib/crypto/doc/src/engine_keys.xml b/lib/crypto/doc/src/engine_keys.xml index feeb353d1e..5ac690eb90 100644 --- a/lib/crypto/doc/src/engine_keys.xml +++ b/lib/crypto/doc/src/engine_keys.xml @@ -51,7 +51,7 @@ <p> OTP/Crypto requires that the user provides two or three items of information about the key. The application used by the user is usually on a higher level, for example in - <seealso marker="ssl:ssl#key_option_def">SSL</seealso>. If using + <seealso marker="ssl:ssl#type-key">SSL</seealso>. If using the crypto application directly, it is required that: </p> <list> diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile index e046a25338..8b320e01a9 100644 --- a/lib/crypto/test/Makefile +++ b/lib/crypto/test/Makefile @@ -6,6 +6,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # ---------------------------------------------------- MODULES = \ + crypto_bench_SUITE \ blowfish_SUITE \ crypto_SUITE \ engine_SUITE @@ -77,7 +78,7 @@ release_spec: release_tests_spec: $(TEST_TARGET) $(INSTALL_DIR) "$(RELSYSDIR)" - $(INSTALL_DATA) crypto.spec crypto.cover $(RELTEST_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) crypto.spec crypto_bench.spec crypto.cover $(RELTEST_FILES) "$(RELSYSDIR)" @tar cfh - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) chmod -R u+w "$(RELSYSDIR)" diff --git a/lib/crypto/test/crypto.spec b/lib/crypto/test/crypto.spec index cc09970cb3..4a95275687 100644 --- a/lib/crypto/test/crypto.spec +++ b/lib/crypto/test/crypto.spec @@ -1 +1,6 @@ {suites,"../crypto_test",all}. + +{skip_suites, "../crypto_test", [crypto_bench_SUITE + ], + "Benchmarks run separately"}. + diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 6c6188f775..98de1d7700 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -156,7 +156,7 @@ groups() -> ]}, {dh, [], [generate_compute, compute_bug]}, - {ecdh, [], [generate_all_supported, compute, generate]}, + {ecdh, [], [use_all_elliptic_curves, compute, generate]}, {srp, [], [generate_compute]}, {des_cbc, [], [block]}, {des_cfb, [], [block]}, @@ -563,32 +563,43 @@ compute(Config) when is_list(Config) -> Gen = proplists:get_value(compute, Config), lists:foreach(fun do_compute/1, Gen). %%-------------------------------------------------------------------- -generate_all_supported() -> - [{doc, " Test that all curves from crypto:ec_curves/0 returns two binaries"}]. -generate_all_supported(_Config) -> +use_all_elliptic_curves() -> + [{doc, " Test that all curves from crypto:ec_curves/0"}]. +use_all_elliptic_curves(_Config) -> + Msg = <<"hello world!">>, + Sups = crypto:supports(), + Curves = proplists:get_value(curves, Sups), + Hashs = proplists:get_value(hashs, Sups), + ct:log("Lib: ~p~nFIPS: ~p~nCurves:~n~p~nHashs: ~p", [crypto:info_lib(), + crypto:info_fips(), + Curves, + Hashs]), Results = - [try - crypto:generate_key(ecdh, C) - of - {B1,B2} when is_binary(B1) and is_binary(B2) -> - %% That is, seems like it works as expected. - {ok,C}; - Err -> - ct:log("ERROR: Curve ~p generated ~p", [C,Err]), - {error,{C,Err}} - catch - Cls:Err:Stack -> - ct:log("ERROR: Curve ~p exception ~p:~p~n~p", [C,Cls,Err,Stack]), - {error,{C,{Cls,Err}}} - end - || C <- crypto:ec_curves(), - not lists:member(C, [ed25519, ed448]) + [{{Curve,Hash}, + try + {Pub,Priv} = crypto:generate_key(ecdh, Curve), + true = is_binary(Pub), + true = is_binary(Priv), + Sig = crypto:sign(ecdsa, Hash, Msg, [Priv, Curve]), + crypto:verify(ecdsa, Hash, Msg, Sig, [Pub, Curve]) + catch + C:E -> + {C,E} + end} + || Curve <- Curves -- [ed25519, ed448, x25519, x448, ipsec3, ipsec4], + Hash <- Hashs -- [md4, md5, ripemd160, sha3_224, sha3_256, sha3_384, sha3_512] ], - OK = [C || {ok,C} <- Results], - ct:log("Ok (len=~p): ~p", [length(OK), OK]), - false = lists:any(fun({error,_}) -> true; - (_) -> false - end, Results). + Fails = + lists:filter(fun({_,true}) -> false; + (_) -> true + end, Results), + case Fails of + [] -> + ok; + _ -> + ct:log("Fails:~n~p",[Fails]), + ct:fail("Bad curve(s)",[]) + end. %%-------------------------------------------------------------------- generate() -> diff --git a/lib/crypto/test/crypto_bench.spec b/lib/crypto/test/crypto_bench.spec new file mode 100644 index 0000000000..b9a26d94db --- /dev/null +++ b/lib/crypto/test/crypto_bench.spec @@ -0,0 +1,3 @@ +{suites, "../crypto_test", [ + crypto_bench_SUITE + ]}. diff --git a/lib/crypto/test/crypto_bench_SUITE.erl b/lib/crypto/test/crypto_bench_SUITE.erl new file mode 100644 index 0000000000..c66a27f0c8 --- /dev/null +++ b/lib/crypto/test/crypto_bench_SUITE.erl @@ -0,0 +1,400 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2009-2018. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(crypto_bench_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct_event.hrl"). +-include_lib("common_test/include/ct.hrl"). + +suite() -> [%%{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]}, + {timetrap,{minutes,2}} + ]. + +all() -> + [ + {group, textblock_256} + ]. + +groups() -> + [ + {textblock_256, [], [ + {group, ciphers_128}, + {group, ciphers_256} + ]}, + + {ciphers_128, [{repeat, 5}], [ + block, + stream + ]}, + + {ciphers_256, [{repeat, 5}], [ + block, + stream, + chacha + ]} + ]. + +%%%---------------------------------------------------------------- +%%% +init_per_suite(Config0) -> + try crypto:start() of + _ -> + [{_,_,Info}] = crypto:info_lib(), + ct:comment("~s",[Info]), + ct:pal("Crypto version: ~p~n~n~p",[Info,crypto:supports()]), + Config1 = measure_openssl_aes_cbc([128,256], Config0), + calibrate([{sec_goal,10} | Config1]) + + catch _:_ -> + {fail, "Crypto did not start"} + end. + +end_per_suite(_Config) -> + application:stop(crypto). + +%%%---------------------------------------------------------------- +%%% +init_per_group(Group, Config) -> + case atom_to_list(Group) of + "ciphers_"++KeySizeStr -> + KeySize = list_to_integer(KeySizeStr), + [{key_size,KeySize} | Config]; + + "textblock_"++BlockSizeStr -> + BlockSize = list_to_integer(BlockSizeStr), + [{block_size,BlockSize} | Config]; + + _ -> + Config + end. + +end_per_group(_Group, Config) -> + Config. + + +measure_openssl_aes_cbc(KeySizes, Config) -> + BLno_acc = [baseline(aes_cbc, KeySize, false) || KeySize <- KeySizes], + ct:pal("Non-accelerated baseline encryption time [µs/block]:~n~p", [BLno_acc]), + BLacc = [baseline(aes_cbc, KeySize, true) || KeySize <- KeySizes], + ct:pal("Possibly accelerated baseline encryption time [µs/block]:~n~p", [BLacc]), + [{acc,BLacc}, + {no_acc,BLno_acc} | Config]. + +calibrate(Config) -> + Secs = proplists:get_value(sec_goal, Config, 10), + {_,Empty} = data(empty, 0, 0), + {Ne,Te} = run1(Secs*3000, Empty), + report(["Overhead"], Te/Ne), + [{overhead,Te/Ne} | Config]. + +%%%================================================================ +%%% +%%% +block(Config) -> + run_cryptos([aes_cbc, aes_gcm, aes_ccm], + Config). + +stream(Config) -> + run_cryptos([aes_ctr], + Config). + +chacha(Config) -> + run_cryptos([chacha20, chacha20_poly1305], + Config). + + +%%%================================================================ +%%% +%%% + +run_cryptos(Cryptos, Config) -> + KeySize = proplists:get_value(key_size, Config), + BlockSize = proplists:get_value(block_size, Config), + MilliSecGoal = 1000*proplists:get_value(sec_goal,Config), + OverHead = proplists:get_value(overhead, Config, 0), + [try + TimePerOpBrutto = run(Crypto,KeySize,BlockSize,MilliSecGoal), + %% ct:pal("Brutto: ~p Overhead: ~p (~.2f %) Netto: ~p", + %% [TimePerOpBrutto, OverHead, 100*OverHead/TimePerOpBrutto,TimePerOpBrutto - OverHead]), + TimePerOpBrutto - OverHead + of + TimePerOp -> % µs + %% First, Report speed of encrypting blocks of 1000. [blocks/sec] + ReportUnit = 1000, + Label = [fmt(Crypto)," key:",KeySize," block:",BlockSize], + report(Label, + (BlockSize/ReportUnit)*1000000/TimePerOp + ), + + EffCrypto = case Crypto of + X -> X + end, + %% Percent of accelerated speed + case find_value([acc,{EffCrypto,KeySize},BlockSize], Config) of + undefined -> + ok; + TimePerOpBaseAcc -> + report(["Percent of acc OpenSSL "|Label], + 100*TimePerOpBaseAcc/TimePerOp % Percent of base *speed* + ) + end, + + %% Percent of non-accelerated speed + case find_value([no_acc,{EffCrypto,KeySize},BlockSize], Config) of + undefined -> + ok; + TimePerOpBaseNoAcc -> + report(["Percent of noacc OpenSSL "|Label], + 100*TimePerOpBaseNoAcc/TimePerOp % Percent of base *speed* + ) + end + catch + _:_ -> + ct:pal("~p unsupported",[{Crypto,KeySize,BlockSize}]) + end + || Crypto <- Cryptos, + supported(Crypto) + ]. + + +run(Crypto, KeySize, BlockSize, MilliSecGoal) -> + {_Type, Funs} = data(Crypto, KeySize, BlockSize), + {Nc,Tc} = run1(MilliSecGoal, Funs), + Tc/Nc. + +fmt(X) -> X. + + +find_value(KeyPath, PropList, Default) -> + try find_value(KeyPath, PropList) + of + undefined -> Default + catch + error:function_clause -> Default + end. + +find_value(KeyPath, PropList) -> + lists:foldl(fun(K, L) when is_list(L) -> proplists:get_value(K,L); + (_, _) -> undefined + end, PropList, KeyPath). + +%%%================================================================ +%%% +%%% +funs({block, {Type, Key, IV, Block}}) -> + {fun() -> ok end, + fun(_) -> crypto:block_encrypt(Type, Key, IV, Block) end, + fun(_) -> ok end}; + +funs({stream, {Type, Key, IV, Block}}) -> + {fun() -> {crypto:stream_init(Type, Key, IV),ok} end, + fun({Ctx,_}) -> crypto:stream_encrypt(Ctx, Block) end, + fun(_) -> ok end}. + + +data(aes_cbc, KeySize, BlockSize) -> + Type = case KeySize of + 128 -> aes_cbc128; + 256 -> aes_cbc256 + end, + Key = mk_bin(KeySize div 8), + IV = mk_bin(16), + Block = mk_bin(BlockSize), + {Type, funs({block, {Type, Key, IV, Block}})}; + +data(aes_gcm, KeySize, BlockSize) -> + Type = aes_gcm, + Key = mk_bin(KeySize div 8), + IV = mk_bin(12), + Block = mk_bin(BlockSize), + AAD = <<01,02,03,04>>, + {Type, funs({block, {Type, Key, IV, {AAD,Block,16}}})}; + +data(aes_ccm, KeySize, BlockSize) -> + Type = aes_ccm, + Key = mk_bin(KeySize div 8), + IV = mk_bin(12), + Block = mk_bin(BlockSize), + AAD = <<01,02,03,04>>, + {Type, funs({block, {Type, Key, IV, {AAD,Block,12}}})}; + +data(aes_ctr, KeySize, BlockSize) -> + Type = aes_ctr, + Key = mk_bin(KeySize div 8), + IV = mk_bin(16), + Block = mk_bin(BlockSize), + {Type, funs({stream, {Type, Key, IV, Block}})}; + +data(chacha20_poly1305, 256=KeySize, BlockSize) -> + Type = chacha20_poly1305, + Key = mk_bin(KeySize div 8), + IV = mk_bin(16), + AAD = <<01,02,03,04>>, + Block = mk_bin(BlockSize), + {Type, funs({block, {Type, Key, IV, {AAD,Block}}})}; + +data(chacha20, 256=KeySize, BlockSize) -> + Type = chacha20, + Key = mk_bin(KeySize div 8), + IV = mk_bin(16), + Block = mk_bin(BlockSize), + {Type, funs({stream, {Type, Key, IV, Block}})}; + +data(empty, 0, 0) -> + {undefined, + {fun() -> ok end, + fun(X) -> X end, + fun(_) -> ok end}}. + +%%%================================================================ +%%% +%%% +run1(MilliSecGoal, Funs) -> + Parent = self(), + Pid = spawn(fun() -> + {Fi,Fu,Ff} = Funs, + Ctx0 = Fi(), + erlang:garbage_collect(), + T0 = start_time(), + {N,Ctx} = loop(Fu, Ctx0, 0), + T = elapsed_time(T0), + Ff(Ctx), + Parent ! {result,N,microseconds(T)} + end), + Pid ! go, + receive + after MilliSecGoal -> + Pid ! stop + end, + receive + {result,N,MicroSecs} -> + {N,MicroSecs} + end. + + +loop(F, Ctx, N) -> + receive + stop -> + {N, Ctx} + after 0 -> + loop(F, F(Ctx), N+1) + end. + +%%%---------------------------------------------------------------- +report(LabelList, Value) -> + Label = report_chars(lists:concat(LabelList)), + ct:pal("ct_event:notify ~p: ~p", [Label, Value]), + ct_event:notify( + #event{name = benchmark_data, + data = [{name, Label}, + {value,Value}]}). + +report_chars(Cs) -> + [case C of + $- -> $_; + _ -> C + end || C <- Cs]. + +%%%---------------------------------------------------------------- +supported(Algorithm) -> + lists:member(Algorithm, + [A || {_,As} <- crypto:supports(), A <- As] + ). + +%%%---------------------------------------------------------------- +start_time() -> + erlang:system_time(). + +elapsed_time(StartTime) -> + erlang:system_time() - StartTime. + +microseconds(Time) -> + erlang:convert_time_unit(Time, native, microsecond). + +%%%---------------------------------------------------------------- + +%% Example output: +%% +DT:aes-128-cbc:3:16 +%% +R:135704772:aes-128-cbc:2.980000 +%% +DT:aes-128-cbc:3:64 +%% +R:36835089:aes-128-cbc:3.000000 +%% +DT:aes-128-cbc:3:256 +%% +R:9398616:aes-128-cbc:3.000000 +%% +DT:aes-128-cbc:3:1024 +%% +R:2355683:aes-128-cbc:2.990000 +%% +DT:aes-128-cbc:3:8192 +%% +R:294508:aes-128-cbc:2.990000 +%% +H:16:64:256:1024:8192 +%% +F:22:aes-128-cbc:728616225.50:785815232.00:802015232.00:806762338.46:806892821.40 + +baseline(Crypto, KeySize, EVP) -> + Spec= + case {Crypto,KeySize} of + {aes_cbc, 128} -> "aes-128-cbc"; + {aes_cbc, 256} -> "aes-256-cbc" + end, + {{Crypto,KeySize}, baseline(Spec, EVP)}. + +baseline(Spec, EVP) -> + Cmd = + case EVP of + true -> "openssl speed -mr -evp " ++ Spec; + false-> "openssl speed -mr " ++ Spec + end, + get_base_values(string:tokens(os:cmd(Cmd),"\n"), Spec, []). + + +get_base_values(["+DT:"++Sdt, + "+R:"++Sr + |T], Crypto, Acc) -> + [Crypto0,_GoalSecs0,BlockSize0] = string:tokens(Sdt, ":"), + [Nblocks0,Crypto0,RealSecs0] = string:tokens(Sr, ":"), + Crypto = fix_possible_space_bug(Crypto0), + RealSecs = list_to_float(RealSecs0), + BlockSize = list_to_integer(BlockSize0), + Nblocks = list_to_integer(Nblocks0), + get_base_values(T, Crypto, [{BlockSize, 1000000*RealSecs/Nblocks} | Acc]); + +get_base_values([_|T], Crypto, Acc) -> + get_base_values(T, Crypto, Acc); + +get_base_values([], _, Acc) -> + lists:sort(Acc). + +fix_possible_space_bug(S) -> lists:concat(lists:join("-",string:tokens(S,"- "))). + +%%%---------------------------------------------------------------- +mk_bin(Size) when Size =< 256 -> + list_to_binary(lists:seq(0,Size-1)); + +mk_bin(Size) when 1024 =< Size -> + B = mk_bin(Size div 4), + Brest = mk_bin(Size rem 4), + <<B/binary, B/binary, B/binary, B/binary, Brest/binary>>; + +mk_bin(Size) when 256 < Size -> + B = mk_bin(Size div 2), + Brest = mk_bin(Size rem 2), + <<B/binary, B/binary, Brest/binary>>. + |