aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/ops.tab11
-rw-r--r--lib/compiler/doc/src/compile.xml16
-rw-r--r--lib/crypto/doc/src/Makefile3
-rw-r--r--lib/crypto/doc/src/crypto.xml501
-rw-r--r--lib/crypto/doc/src/new_api.xml209
-rw-r--r--lib/crypto/doc/src/usersguide.xml1
-rw-r--r--lib/edoc/src/edoc_data.erl2
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl4
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl2
-rw-r--r--lib/ssl/test/ssl_test_lib.erl4
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl29
-rw-r--r--lib/stdlib/doc/src/calendar.xml2
-rw-r--r--lib/stdlib/src/erl_lint.erl46
-rw-r--r--lib/stdlib/src/otp_internal.erl147
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl27
15 files changed, 670 insertions, 334 deletions
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 7a125b0f67..10ca74cd60 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -1690,9 +1690,14 @@ i_plus S1=c S2=c Fail Dst => move S1 x | i_plus x S2 Fail Dst
i_plus xy xyc j? d
-i_minus x x j? d
-i_minus c x j? d
-i_minus s s j? d
+# A minus instruction with a constant right operand will be
+# converted to an i_increment instruction, except in guards or
+# when the negated value of the constant won't fit in a guard.
+# Therefore, it very rare.
+i_minus S1 S2=c Fail Dst => move S2 x | i_minus S1 x Fail Dst
+
+i_minus xy xy j? d
+i_minus c xy j? d
i_times j? s s d
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index 5219ba0f5d..549b1049d8 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -632,6 +632,22 @@ module.beam: module.erl \
to be deprecated.</p>
</item>
+ <tag><c>nowarn_removed</c></tag>
+ <item>
+ <p>Turns off warnings for calls to functions that have
+ been removed. Default is to emit warnings for every call
+ to a function known by the compiler to have been recently
+ removed from Erlang/OTP.</p>
+ </item>
+
+ <tag><c>{nowarn_removed, ModulesOrMFAs}</c></tag>
+ <item>
+ <p>Turns off warnings for calls to modules or functions
+ that have been removed. Default is to emit warnings for
+ every call to a function known by the compiler to have
+ been recently removed from Erlang/OTP.</p>
+ </item>
+
<tag><c>nowarn_obsolete_guard</c></tag>
<item>
<p>Turns off warnings for calls to old type testing BIFs,
diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile
index cbcafb7375..8da494dad6 100644
--- a/lib/crypto/doc/src/Makefile
+++ b/lib/crypto/doc/src/Makefile
@@ -39,7 +39,8 @@ XML_REF3_FILES = crypto.xml
XML_REF6_FILES = crypto_app.xml
XML_PART_FILES = usersguide.xml
-XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml algorithm_details.xml
+XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml \
+ algorithm_details.xml new_api.xml
BOOK_FILES = book.xml
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 8a4fad67de..14efc5c6f6 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -42,7 +42,7 @@
<item>
<url href="https://www.nist.gov/publications/sha-3-standard-permutation-based-hash-and-extendable-output-functions?pub_id=919061">
SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions [FIPS PUB 202]
- </url>
+ </url>
</item>
<tag>BLAKE2</tag>
<item>
@@ -190,70 +190,101 @@
</description>
<datatypes>
- <datatype_title>Ciphers</datatype_title>
+ <datatype_title>Ciphers, new API</datatype_title>
<datatype>
<name name="cipher"/>
- <name name="stream_cipher"/>
- <name name="block_cipher"/>
<desc>
- <p>Ciphers known byt the CRYPTO application. Note that this list might be reduced if the
- underlying libcrypto does not support all of them.</p>
</desc>
</datatype>
-
<datatype>
- <name name="stream_cipher_iv"/>
- <name name="stream_cipher_no_iv"/>
+ <name name="cipher_no_iv"/>
<desc>
- <p>Stream ciphers for
- <seealso marker="#stream_init-3">stream_init/3</seealso> and
- <seealso marker="#stream_init-2">stream_init/2</seealso> .
- </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="cipher_iv"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="cipher_aead"/>
+ <desc>
+ <p>Ciphers known by the CRYPTO application when using the
+ <seealso marker="crypto:new_api#the-new-api">new API</seealso>.</p>
+ <p>Note that this list might be reduced if the underlying libcrypto does not support all of them.</p>
</desc>
</datatype>
+ <datatype_title>Ciphers, old API</datatype_title>
+ <datatype>
+ <name name="block_cipher_with_iv"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="block_cipher_without_iv"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="stream_cipher"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="aead_cipher"/>
+ <desc>
+ </desc>
+ </datatype>
<datatype>
- <name name="block_cipher_iv"/>
<name name="cbc_cipher"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
<name name="cfb_cipher"/>
<desc>
- <p>Block ciphers with initialization vector for
- <seealso marker="#block_encrypt-4">block_encrypt/4</seealso> and
- <seealso marker="#block_decrypt-4">block_decrypt/4</seealso> .
- </p>
</desc>
</datatype>
-
<datatype>
- <name name="alias_cfb"/>
- <name name="alias_cbc"/>
+ <name name="ctr_cipher"/>
<desc>
- <p>Names that are replaced by more common names. They may deprecated in futer releases.</p>
- <p><c>des3_cbc</c> and <c>des_ede3</c> should be replaced by <c>des_ede3_cbc</c></p>
- <p><c>des_ede3_cbf</c>, <c>des3_cbf</c> and <c>des3_cfb</c> should be replaced by <c>des_ede3_cfb</c>.</p>
- <p><c>aes_cbc128</c> should be replaced by <c>aes_128_cbc</c>.</p>
- <p><c>aes_cbc256</c> should be replaced by <c>aes_256_cbc</c>.</p>
</desc>
</datatype>
-
<datatype>
- <name name="block_cipher_no_iv"/>
<name name="ecb_cipher"/>
<desc>
- <p>Block ciphers without initialization vector for
- <seealso marker="#block_encrypt-3">block_encrypt/3</seealso> and
- <seealso marker="#block_decrypt-3">block_decrypt/3</seealso> .
- </p>
+ <p>Ciphers known by the CRYPTO application when using the
+ <seealso marker="crypto:new_api#the-old-api">old API</seealso>.</p>
+ <p>Note that this list might be reduced if the underlying libcrypto does not support all of them.</p>
</desc>
</datatype>
<datatype>
- <name name="aead_cipher"/>
+ <name name="retired_cbc_cipher_aliases"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="retired_cfb_cipher_aliases"/>
<desc>
- <p>Ciphers with simultaneous MAC-calculation or MAC-checking.
- <seealso marker="#block_encrypt-4">block_encrypt/4</seealso> and
- <seealso marker="#block_decrypt-4">block_decrypt/4</seealso> .
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="retired_ctr_cipher_aliases"/>
+ <desc>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="retired_ecb_cipher_aliases"/>
+ <desc>
+ <p>Alternative, old names of ciphers known by the CRYPTO application when using the
+ <seealso marker="crypto:new_api#the-old-api">old API</seealso>.
+ See <seealso marker="crypto:new_api#retired-cipher-names">Retired cipher names</seealso> for names to
+ use instead to be prepared for an easy convertion to the
+ <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
</p>
+ <p>Note that this list might be reduced if the underlying libcrypto does not support all of them.</p>
</desc>
</datatype>
@@ -547,6 +578,7 @@
<name name="stream_state"/>
<name name="hmac_state"/>
<name name="hash_state"/>
+ <name name="crypto_state"/>
<desc>
<p>Contexts with an internal state that should not be manipulated but passed between function calls.
</p>
@@ -575,117 +607,171 @@
<p>This is a more developed variant of the older
<seealso marker="#type-run_time_error">run_time_error()</seealso>.
</p>
+ <p>The exception is:</p>
+ <pre>
+ {Tag, {C_FileName,LineNumber}, Description}
+
+ Tag = badarg | notsup | error
+ C_FileName = string()
+ LineNumber = integer()
+ Description = string()
+ </pre>
+
<p>It is like the older type an exception of the <c>error</c> class. In addition they contain
a descriptive text in English. That text is targeted to a developer. Examples are "Bad key size"
or "Cipher id is not an atom".
</p>
- <p>The exceptions are:</p>
+ <p>The exception tags are:</p>
<taglist>
- <tag><c>{badarg, Description::string()}</c></tag>
+ <tag><c>badarg</c></tag>
<item><p>Signifies that one or more arguments are of wrong data type or are otherwise badly formed.</p>
</item>
- <tag><c>{notsup, Description::string()}</c></tag>
+ <tag><c>notsup</c></tag>
<item><p>Signifies that the algorithm is known but is not supported by current underlying libcrypto
or explicitly disabled when building that one.</p>
</item>
- <tag><c>{error, Description::string()}</c></tag>
+ <tag><c>error</c></tag>
<item><p>An error condition that should not occur, for example a memory allocation failed or
the underlying cryptolib returned an error code, for example "Can't initialize context, step 1".
Thoose text usually needs searching the C-code to be understood.</p>
</item>
</taglist>
+ <p>To catch the exception, use for example:</p>
+ <code>
+ try crypto:crypto_init(Ciph, Key, IV, true)
+ catch
+ error:{Tag, {C_FileName,LineNumber}, Description} ->
+ do_something(......)
+ .....
+ end
+ </code>
</desc>
</datatype>
</datatypes>
<!--================ FUNCTIONS ================-->
+ <section>
+ <title>New API</title>
+ </section>
+
<funcs>
<func>
- <name name="block_encrypt" arity="3" since="OTP 18.0"/>
- <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
+ <name name="crypto_init" arity="3" since="OTP 22.0"/>
+ <fsummary>Initializes a series of encryptions or decryptions</fsummary>
<desc>
- <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.</p>
- <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying libcrypto implementation.</p>
- <p>For keylengths and blocksizes see the
- <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ <p>As <seealso marker="#crypto_init/4">crypto_init/4</seealso> but for ciphers without IVs.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="crypto_init" arity="4" since="OTP 22.0"/>
+ <fsummary>Initializes a series of encryptions or decryptions</fsummary>
+ <desc>
+ <p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
+ Initializes a series of encryptions or decryptions.
+ The actual encryption or decryption is done by
+ <seealso marker="crypto#crypto_update/2">crypto_update/2</seealso>.
+ </p>
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ </p>
+ <p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
</desc>
</func>
<func>
- <name name="block_decrypt" arity="3" since="OTP 18.0"/>
- <fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary>
+ <name name="crypto_init_dyn_iv" arity="3" since="OTP 22.0"/>
+ <fsummary>Initializes a series of encryptions or decryptions where the IV is provided later</fsummary>
<desc>
- <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.</p>
- <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying libcrypto implementation.</p>
- <p>For keylengths and blocksizes see the
- <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ <p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
+ Initializes a series of encryptions or decryptions where the IV is provided later.
+ The actual encryption or decryption is done by
+ <seealso marker="crypto#crypto_update_dyn_iv/3">crypto_update_dyn_iv/3</seealso>.
+ </p>
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ </p>
+ <p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
</desc>
</func>
<func>
- <name since="OTP R16B01">block_encrypt(Type, Key, Ivec, PlainText) -> CipherText | Error</name>
- <name since="OTP R16B01">block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag} | Error</name>
- <name since="OTP R16B01">block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} | Error </name>
- <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
- <type>
- <v>Type = <seealso marker="#type-block_cipher_iv">block_cipher_iv()</seealso></v>
- <v>AeadType = <seealso marker="#type-aead_cipher">aead_cipher()</seealso></v>
- <v>Key = <seealso marker="#type-key">key()</seealso> | <seealso marker="#type-des3_key">des3_key()</seealso></v>
- <v>PlainText = iodata()</v>
- <v>AAD = IVec = CipherText = CipherTag = binary()</v>
- <v>TagLength = 1..16</v>
- <v>Error = <seealso marker="#type-run_time_error">run_time_error()</seealso></v>
- </type>
+ <name name="crypto_update" arity="2" since="OTP 22.0"/>
+ <fsummary>Do an actual crypto operation on a part of the full text</fsummary>
<desc>
- <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.
- <c>IVec</c> is an arbitrary initializing vector.</p>
- <p>In AEAD (Authenticated Encryption with Associated Data) mode, encrypt
- <c>PlainText</c>according to <c>Type</c> block cipher and calculate
- <c>CipherTag</c> that also authenticates the <c>AAD</c> (Associated Authenticated Data).</p>
- <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying libcrypto implementation.</p>
- <p>For keylengths, iv-sizes and blocksizes see the
- <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ <p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
+ Do an actual crypto operation on a part of the full text.
+ The <c>State</c> should be created with
+ <seealso marker="crypto#crypto_init/3">crypto_init/3</seealso>
+ or
+ <seealso marker="crypto#crypto_init/4">crypto_init/4</seealso>.
+ </p>
+ <p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
</desc>
</func>
<func>
- <name since="OTP R16B01">block_decrypt(Type, Key, Ivec, CipherText) -> PlainText | Error</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_iv">block_cipher_iv()</seealso></v>
- <v>AeadType = <seealso marker="#type-aead_cipher">aead_cipher()</seealso></v>
- <v>Key = <seealso marker="#type-key">key()</seealso> | <seealso marker="#type-des3_key">des3_key()</seealso></v>
- <v>PlainText = iodata()</v>
- <v>AAD = IVec = CipherText = CipherTag = binary()</v>
- <v>Error = BadTag | <seealso marker="#type-run_time_error">run_time_error()</seealso></v>
- <v>BadTag = error</v>
- </type>
+ <name name="crypto_update_dyn_iv" arity="3" since="OTP 22.0"/>
+ <fsummary>Do an actual crypto operation on a part of the full text and the IV is supplied for each part</fsummary>
<desc>
- <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.
- <c>IVec</c> is an arbitrary initializing vector.</p>
- <p>In AEAD (Authenticated Encryption with Associated Data) mode, decrypt
- <c>CipherText</c>according to <c>Type</c> block cipher and check the authenticity
- the <c>PlainText</c> and <c>AAD</c> (Associated Authenticated Data) using the
- <c>CipherTag</c>. May return <c>error</c> if the decryption or validation fail's</p>
- <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying libcrypto implementation.</p>
- <p>For keylengths, iv-sizes and blocksizes see the
- <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ <p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
+ Do an actual crypto operation on a part of the full text and the IV is supplied for each part.
+ The <c>State</c> should be created with
+ <seealso marker="crypto#crypto_init_dyn_iv/3">crypto_init_dyn_iv/3</seealso>.
+ </p>
+ <p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
</desc>
</func>
- <func>
+ <func>
+ <name name="crypto_one_time" arity="4" since="OTP 22.0"/>
+ <fsummary>Do a complete encrypt or decrypt of the full text</fsummary>
+ <desc>
+ <p>As <seealso marker="#crypto_one_time/5">crypto_one_time/5</seealso> but for ciphers without IVs.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="crypto_one_time" arity="5" since="OTP 22.0"/>
+ <fsummary>Do a complete encrypt or decrypt of the full text</fsummary>
+ <desc>
+ <p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
+ Do a complete encrypt or decrypt of the full text.
+ </p>
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ </p>
+ <p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="crypto_aead" arity="6" since="OTP 22.0"/>
+ <name name="crypto_aead" arity="7" since="OTP 22.0"/>
+ <fsummary>Do a complete encrypt or decrypt with an AEAD cipher of the full text</fsummary>
+ <desc>
+ <p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
+ Do a complete encrypt or decrypt with an AEAD cipher of the full text.
+ </p>
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ </p>
+ <p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
+ </p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>API kept from previous versions</title>
+ </section>
+
+ <funcs>
+ <func>
<name name="bytes_to_integer" arity="1" since="OTP R16B01"/>
<fsummary>Convert binary representation, of an integer, to an Erlang integer.</fsummary>
<desc>
@@ -928,7 +1014,7 @@
cipher algorithm in question.
</p>
<note>
- <p>The ciphers <c>aes_cbc</c>, <c>aes_cfb8</c>, <c>aes_cfb128</c>, <c>aes_ctr</c>,
+ <p>The ciphers <c>aes_cbc</c>, <c>aes_cfb8</c>, <c>aes_cfb128</c>, <c>aes_ctr</c>,
<c>aes_ecb</c>, <c>aes_gcm</c> and <c>aes_ccm</c>
has no keylength in the <c>Type</c> as opposed to for example <c>aes_128_ctr</c>. They adapt to the length of
the key provided in the encrypt and decrypt function. Therefor it is impossible to return a valid keylength
@@ -1094,7 +1180,7 @@
<seealso marker="#rand_seed_s-0">rand_seed_s/0</seealso>.
</p>
<p>
- When using the state object from this function the
+ When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
@@ -1120,7 +1206,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<seealso marker="stdlib:rand#seed_s-1">rand:seed_s/1</seealso>.
</p>
<p>
- When using the state object from this function the
+ When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
@@ -1129,7 +1215,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<p>
The state returned from this function cannot be used
to get a reproducable random sequence as from
- the other
+ the other
<seealso marker="stdlib:rand">rand</seealso>
functions,
since reproducability does not match cryptographically safe.
@@ -1160,7 +1246,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<seealso marker="#rand_seed_alg_s-1">rand_seed_alg_s/1</seealso>.
</p>
<p>
- When using the state object from this function the
+ When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
@@ -1227,7 +1313,7 @@ FloatValue = rand:uniform(). % again
of 56 bits that makes calculations fast on 64 bit machines.
</p>
<p>
- When using the state object from this function the
+ When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
@@ -1248,7 +1334,7 @@ FloatValue = rand:uniform(). % again
<p>
The state returned from this function cannot be used
to get a reproducable random sequence as from
- the other
+ the other
<seealso marker="stdlib:rand">rand</seealso>
functions,
since reproducability does not match cryptographically safe.
@@ -1331,56 +1417,6 @@ FloatValue = rand:uniform(). % again
</desc>
</func>
- <func>
- <name name="stream_init" arity="2" since="OTP R16B01"/>
- <fsummary></fsummary>
- <desc>
- <p>Initializes the state for use in RC4 stream encryption
- <seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and
- <seealso marker="#stream_decrypt-2">stream_decrypt</seealso></p>
- <p>For keylengths see the
- <seealso marker="crypto:algorithm_details#stream-ciphers">User's Guide</seealso>.
- </p>
- </desc>
- </func>
-
- <func>
- <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).
- <c>Key</c> is the AES key and must be either 128, 192, or 256 bits long. <c>IVec</c> is
- an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with
- <seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and
- <seealso marker="#stream_decrypt-2">stream_decrypt</seealso>.</p>
- <p>For keylengths and iv-sizes see the
- <seealso marker="crypto:algorithm_details#stream-ciphers">User's Guide</seealso>.
- </p>
- </desc>
- </func>
-
- <func>
- <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.
- <c>Text</c> can be any number of bytes. The initial <c>State</c> is created using
- <seealso marker="#stream_init-2">stream_init</seealso>.
- <c>NewState</c> must be passed into the next call to <c>stream_encrypt</c>.</p>
- </desc>
- </func>
-
- <func>
- <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.
- <c>PlainText</c> can be any number of bytes. The initial <c>State</c> is created using
- <seealso marker="#stream_init-2">stream_init</seealso>.
- <c>NewState</c> must be passed into the next call to <c>stream_decrypt</c>.</p>
- </desc>
- </func>
-
<func>
<name name="supports" arity="0" since="OTP R16B01"/>
<fsummary>Provide a list of available crypto algorithms.</fsummary>
@@ -1440,6 +1476,12 @@ FloatValue = rand:uniform(). % again
</desc>
</func>
+ </funcs>
+ <section>
+ <title>Engine API</title>
+ </section>
+
+ <funcs>
<!-- Engine functions -->
<func>
<name name="privkey_to_pubkey" arity="2" since="OTP 20.2"/>
@@ -1752,5 +1794,152 @@ FloatValue = rand:uniform(). % again
</funcs>
+<section>
+ <title>Old API</title>
+</section>
+
+ <funcs>
+ <func>
+ <name name="block_encrypt" arity="3" since="OTP 18.0"/>
+ <fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the-new-api</seealso>.</p></dont>
+ <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.</p>
+ <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
+ is not supported by the underlying libcrypto implementation.</p>
+ <p>For keylengths and blocksizes see the
+ <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="block_decrypt" arity="3" since="OTP 18.0"/>
+ <fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.</p>
+ <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
+ is not supported by the underlying libcrypto implementation.</p>
+ <p>For keylengths and blocksizes see the
+ <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name since="OTP R16B01">block_encrypt(Type, Key, Ivec, PlainText) -> CipherText | Error</name>
+ <name since="OTP R16B01">block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag} | Error</name>
+ <name since="OTP R16B01">block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} | Error </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>
+ <v>AeadType = <seealso marker="#type-aead_cipher">aead_cipher()</seealso></v>
+ <v>Key = <seealso marker="#type-key">key()</seealso> | <seealso marker="#type-des3_key">des3_key()</seealso></v>
+ <v>PlainText = iodata()</v>
+ <v>AAD = IVec = CipherText = CipherTag = binary()</v>
+ <v>TagLength = 1..16</v>
+ <v>Error = <seealso marker="#type-run_time_error">run_time_error()</seealso></v>
+ </type>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.
+ <c>IVec</c> is an arbitrary initializing vector.</p>
+ <p>In AEAD (Authenticated Encryption with Associated Data) mode, encrypt
+ <c>PlainText</c>according to <c>Type</c> block cipher and calculate
+ <c>CipherTag</c> that also authenticates the <c>AAD</c> (Associated Authenticated Data).</p>
+ <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
+ is not supported by the underlying libcrypto implementation.</p>
+ <p>For keylengths, iv-sizes and blocksizes see the
+ <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name since="OTP R16B01">block_decrypt(Type, Key, Ivec, CipherText) -> PlainText | Error</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>
+ <v>AeadType = <seealso marker="#type-aead_cipher">aead_cipher()</seealso></v>
+ <v>Key = <seealso marker="#type-key">key()</seealso> | <seealso marker="#type-des3_key">des3_key()</seealso></v>
+ <v>PlainText = iodata()</v>
+ <v>AAD = IVec = CipherText = CipherTag = binary()</v>
+ <v>Error = BadTag | <seealso marker="#type-run_time_error">run_time_error()</seealso></v>
+ <v>BadTag = error</v>
+ </type>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.
+ <c>IVec</c> is an arbitrary initializing vector.</p>
+ <p>In AEAD (Authenticated Encryption with Associated Data) mode, decrypt
+ <c>CipherText</c>according to <c>Type</c> block cipher and check the authenticity
+ the <c>PlainText</c> and <c>AAD</c> (Associated Authenticated Data) using the
+ <c>CipherTag</c>. May return <c>error</c> if the decryption or validation fail's</p>
+ <p>May raise exception <c>error:notsup</c> in case the chosen <c>Type</c>
+ is not supported by the underlying libcrypto implementation.</p>
+ <p>For keylengths, iv-sizes and blocksizes see the
+ <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="stream_init" arity="2" since="OTP R16B01"/>
+ <fsummary></fsummary>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Initializes the state for use in RC4 stream encryption
+ <seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and
+ <seealso marker="#stream_decrypt-2">stream_decrypt</seealso></p>
+ <p>For keylengths see the
+ <seealso marker="crypto:algorithm_details#stream-ciphers">User's Guide</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="stream_init" arity="3" since="OTP R16B01"/>
+ <fsummary></fsummary>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Initializes the state for use in streaming AES encryption using Counter mode (CTR).
+ <c>Key</c> is the AES key and must be either 128, 192, or 256 bits long. <c>IVec</c> is
+ an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with
+ <seealso marker="#stream_encrypt-2">stream_encrypt</seealso> and
+ <seealso marker="#stream_decrypt-2">stream_decrypt</seealso>.</p>
+ <p>For keylengths and iv-sizes see the
+ <seealso marker="crypto:algorithm_details#stream-ciphers">User's Guide</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="stream_encrypt" arity="2" since="OTP R16B01"/>
+ <fsummary></fsummary>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Encrypts <c>PlainText</c> according to the stream cipher <c>Type</c> specified in stream_init/3.
+ <c>Text</c> can be any number of bytes. The initial <c>State</c> is created using
+ <seealso marker="#stream_init-2">stream_init</seealso>.
+ <c>NewState</c> must be passed into the next call to <c>stream_encrypt</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="stream_decrypt" arity="2" since="OTP R16B01"/>
+ <fsummary></fsummary>
+ <desc>
+ <dont><p>Don't use this function for new programs! Use <seealso marker="crypto:new_api">the new api</seealso>.</p></dont>
+ <p>Decrypts <c>CipherText</c> according to the stream cipher <c>Type</c> specified in stream_init/3.
+ <c>PlainText</c> can be any number of bytes. The initial <c>State</c> is created using
+ <seealso marker="#stream_init-2">stream_init</seealso>.
+ <c>NewState</c> must be passed into the next call to <c>stream_decrypt</c>.</p>
+ </desc>
+ </func>
+
+ </funcs>
+
</erlref>
diff --git a/lib/crypto/doc/src/new_api.xml b/lib/crypto/doc/src/new_api.xml
new file mode 100644
index 0000000000..66eeefb692
--- /dev/null
+++ b/lib/crypto/doc/src/new_api.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2014</year><year>2019</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ 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.
+
+ </legalnotice>
+
+ <title>New and Old API</title>
+ <prepared>Hans Nilsson</prepared>
+ <docno></docno>
+ <date>2019-08-22</date>
+ <rev>A</rev>
+ <file>new_api.xml</file>
+ </header>
+ <p>
+ This chapter describes the new api to encryption and decryption.
+ </p>
+
+ <section>
+ <title>Background</title>
+ <p>The CRYPTO app has evolved during its lifetime. Since also the OpenSSL cryptolib has changed the
+ API several times, there are parts of the CRYPTO app that uses a very old one internally and
+ other parts that uses the latest one. The internal definitions of e.g cipher names was a bit hard
+ to maintain.
+ </p>
+ <p>It turned out that using the old api in the new way (more about that later), and still keep it
+ backwards compatible was not possible. Specially as more precision in the error messages was wanted
+ it could not be combined with the old standard.
+ </p>
+ <p>Therefore the old api (see next section) is kept for now but internally implemented with new primitives.
+ </p>
+ </section>
+
+ <section>
+ <title>The old API</title>
+ <p>The old functions - not recommended for new programs - are:</p>
+ <list>
+ <item><seealso marker="crypto#block_encrypt-3">block_encrypt/3</seealso></item>
+ <item><seealso marker="crypto#block_encrypt-4">block_encrypt/4</seealso></item>
+ <item><seealso marker="crypto#block_decrypt-3">block_decrypt/3</seealso></item>
+ <item><seealso marker="crypto#block_decrypt-4">block_decrypt/4</seealso></item>
+ <item><seealso marker="crypto#stream_init-2">stream_init/2</seealso></item>
+ <item><seealso marker="crypto#stream_init-2">stream_init/3</seealso></item>
+ <item><seealso marker="crypto#stream_encrypt-2">stream_encrypt/2</seealso></item>
+ <item><seealso marker="crypto#stream_decrypt-2">stream_decrypt/2</seealso></item>
+ </list>
+ <p>They are not deprecated for now, but may be in a future.
+ </p>
+ </section>
+
+ <section>
+ <title>The new API</title>
+ <p>The new functions for encrypting or decrypting one single text in one binary are:
+ </p>
+ <list>
+ <item><seealso marker="crypto#crypto_one_time/4">crypto_one_time/4</seealso></item>
+ <item><seealso marker="crypto#crypto_one_time/5">crypto_one_time/5</seealso></item>
+ <item><seealso marker="crypto#crypto_aead/6">crypto_aead/6</seealso></item>
+ <item><seealso marker="crypto#crypto_aead/7">crypto_aead/7</seealso></item>
+ </list>
+ <p>The <c>crypto_aead</c> functions are for the ciphers of mode <c>ccm</c> or
+ <c>gcm</c>, and for the cipher <c>chacha20-poly1305</c>.
+ </p>
+ <p>For repeated encryption or decryption of a text divided in parts, where the parts are handled
+ one by one but in sequence, the functions are:
+ </p>
+ <list>
+ <item><seealso marker="crypto#crypto_init/4">crypto_init/4</seealso></item>
+ <item><seealso marker="crypto#crypto_init/3">crypto_init/3</seealso></item>
+ <item><seealso marker="crypto#crypto_update/2">crypto_update/2</seealso></item>
+ </list>
+ <p>The <c>crypto_init</c> initialies a cipher operation and one or more calls of
+ <c>crypto_update</c> does the acual encryption or decryption. Note that AEAD ciphers
+ can't be handled this way due to their nature.
+ </p>
+ <p>Finally, for repeated encryption or decryption of a text divided in parts where the
+ same cipher and same key is used, but a new initialization vector (nounce) should be applied
+ for each part, the functions are:
+ </p>
+ <list>
+ <item><seealso marker="crypto#crypto_init_dyn_iv/3">crypto_init_dyn_iv/3</seealso></item>
+ <item><seealso marker="crypto#crypto_update_dyn_iv/3">crypto_update_dyn_iv/3</seealso></item>
+ </list>
+ <p>An example of where those functions are needed, is when handling the TLS protocol.</p>
+
+ <section>
+ <title>Examples of crypto_init/4 and crypto_update/2</title>
+ <p>Encrypting two blocks:</p>
+ <code type="erl">
+ 1> crypto:start().
+ ok
+ 2> Key = &lt;&lt;1:128>>,
+ 2> IV = &lt;&lt;0:128>>,
+ 2> StateEnc = crypto:crypto_init(aes_128_ctr, Key, IV, true). % encrypt -> true
+ #Ref&lt;0.3768901617.1128660993.124047>
+ 3> crypto:crypto_update(StateEnc, &lt;&lt;"First bytes">>).
+ &lt;&lt;67,44,216,166,25,130,203,5,66,6,162>>
+ 4> crypto:crypto_update(StateEnc, &lt;&lt;"Second bytes">>).
+ &lt;&lt;16,79,94,115,234,197,94,253,16,144,151,41>>
+ 5>
+ 5> StateDec = crypto:crypto_init(aes_128_ctr, Key, IV, false). % decrypt -> false
+ #Ref&lt;0.3768901617.1128660994.124255>
+ 6> crypto:crypto_update(StateDec, &lt;&lt;67,44,216,166,25,130,203>>).
+ &lt;&lt;"First b">>
+ 7> crypto:crypto_update(StateDec, &lt;&lt;5,66,6,162,16,79,94,115,234,197,
+ 94,253,16,144,151>>).
+ &lt;&lt;"ytesSecond byte">>
+ 8> crypto:crypto_update(StateDec, &lt;&lt;41>>).
+ &lt;&lt;"s">>
+ 9>
+ </code>
+ <p>Note that the data that the <c>StateEnc</c> and <c>StateDec</c> references are destructivly
+ updated by the calls to <seealso marker="crypto#crypto_update/2">crypto_update/2</seealso>.
+ This is to gain time in the calls of the nifs interfacing the cryptolib. In a loop where the
+ state is saved in the loop's state, it also saves one update of the loop state per crypto operation.
+ </p>
+ <p>For example, a simple server receiving text parts to encrypt and send the result back to the
+ one who sent them (the <c>Requester</c>):
+ </p>
+ <code type="erl">
+ encode(Crypto, Key, IV) ->
+ crypto_loop(crypto:crypto_init(Crypto, Key, IV, true)).
+
+ crypto_loop(State) ->
+ receive
+ {Text, Requester} ->
+ Requester ! crypto:crypto_update(State, Text),
+ loop(State)
+ end.
+ </code>
+ <p>Note that the <c>State</c> is not updated. Such updates could be costly if the loop state
+ is a tuple or record with many elements.
+ </p>
+ </section>
+
+ <section>
+ <title>Example of crypto_one_time/5</title>
+ <p>The same eample as in the
+ <seealso marker="#examples-of-crypto_init-4-and-crypto_update-2">previous section</seealso>,
+ but now with one call to <c>crypto_one_time/5</c>:
+ </p>
+ <code>
+ 2> Key = &lt;&lt;1:128>>,
+ 2> IV = &lt;&lt;0:128>>,
+ 2> Txt = [&lt;&lt;"First bytes">>,&lt;&lt;"Second bytes">>],
+ 2> crypto:crypto_one_time(aes_128_ctr, Key, IV, Txt, true).
+ &lt;&lt;67,44,216,166,25,130,203,5,66,6,162,16,79,94,115,234,
+ 197,94,253,16,144,151,41>>
+ 3>
+ </code>
+ <p>The <c>[&lt;&lt;"First bytes">>,&lt;&lt;"Second bytes">>]</c> could of course have been one
+ single binary: <c>&lt;&lt;"First bytesSecond bytes">></c>.
+ </p>
+ </section>
+ </section>
+
+ <section>
+ <title>Retired cipher names</title>
+ <p>This table lists the retired cipher names in the first column and suggests names to replace them with
+ in the second column.
+ </p>
+ <p>The new names follows the OpenSSL libcrypto names. The format is ALGORITM_KEYSIZE_MODE.
+ </p>
+ <p>Examples of algorithms are aes, chacha20 and des. The keysize is the number of bits
+ and examples of the mode are cbc, ctr and gcm. The mode may be followed by a number depending
+ on the mode. An example is the ccm mode which has a variant called ccm8 where the so called tag
+ has a length of eight bits.
+ </p>
+ <p>The old names had by time lost any common naming which the new names now introduces. The new names include
+ the key length which improves the error checking in the lower levels of the crypto application.
+ </p>
+
+ <table>
+ <row><cell><strong>Instead of:</strong></cell> <cell><strong>Use:</strong> </cell></row>
+
+ <row><cell><c>aes_cbc128</c> </cell> <cell> <c>aes_128_cbc</c> </cell></row>
+ <row><cell><c>aes_cbc256</c> </cell> <cell> <c>aes_256_cbc</c> </cell></row>
+ <row><cell><c>aes_cbc</c> </cell> <cell> <c>aes_128_cbc, aes_192_cbc, aes_256_cbc</c></cell></row>
+ <row><cell><c>aes_ccm</c> </cell> <cell> <c>aes_128_ccm, aes_192_ccm, aes_256_ccm</c></cell></row>
+ <row><cell><c>aes_cfb128</c> </cell> <cell> <c>aes_128_cfb128, aes_192_cfb128, aes_256_cfb128</c></cell></row>
+ <row><cell><c>aes_cfb8</c> </cell> <cell> <c>aes_128_cfb8, aes_192_cfb8, aes_256_cfb8</c></cell></row>
+ <row><cell><c>aes_ctr</c> </cell> <cell> <c>aes_128_ctr, aes_192_ctr, aes_256_ctr</c></cell></row>
+ <row><cell><c>aes_gcm</c> </cell> <cell> <c>aes_128_gcm, aes_192_gcm, aes_256_gcm</c></cell></row>
+ <row><cell><c>des3_cbc</c> </cell> <cell> <c>des_ede3_cbc</c></cell></row>
+ <row><cell><c>des3_cbf</c> </cell> <cell> <c>des_ede3_cfb</c></cell></row>
+ <row><cell><c>des3_cfb</c> </cell> <cell> <c>des_ede3_cfb</c></cell></row>
+ <row><cell><c>des_ede3</c> </cell> <cell> <c>des_ede3_cbc</c></cell></row>
+ <row><cell><c>des_ede3_cbf</c> </cell> <cell> <c>des_ede3_cfb</c></cell></row>
+ <tcaption></tcaption>
+ </table>
+ </section>
+
+</chapter>
diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml
index 2dfc966609..134f900d4c 100644
--- a/lib/crypto/doc/src/usersguide.xml
+++ b/lib/crypto/doc/src/usersguide.xml
@@ -51,4 +51,5 @@
<xi:include href="engine_load.xml"/>
<xi:include href="engine_keys.xml"/>
<xi:include href="algorithm_details.xml"/>
+ <xi:include href="new_api.xml"/>
</part>
diff --git a/lib/edoc/src/edoc_data.erl b/lib/edoc/src/edoc_data.erl
index 7c077d3acd..a8373d6536 100644
--- a/lib/edoc/src/edoc_data.erl
+++ b/lib/edoc/src/edoc_data.erl
@@ -345,6 +345,8 @@ deprecated(Repl, Env) ->
deprecated(Desc) ->
[{deprecated, description(Desc)}].
+-dialyzer({no_match, replacement_function/2}).
+
replacement_function(M0, {M,F,A}) when is_list(A) ->
%% refer to the largest listed arity - the most general version
replacement_function(M0, {M,F,lists:last(lists:sort(A))});
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 03ee97de5d..7b98209b31 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -2775,8 +2775,8 @@ make_sure_expired(Host, Port, Id) ->
server_does_not_want_to_reuse_session() ->
[{doc,"Test reuse of sessions (short handshake)"}].
server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
- ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server =
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index 7f33fe3204..b71b15b028 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -186,7 +186,7 @@ session_cleanup() ->
session_cleanup(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Server =
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 94c2cb8d9b..b8672f46ba 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1756,10 +1756,10 @@ is_sane_ecc(crypto) ->
is_sane_ecc(_) ->
sufficient_crypto_support(cipher_ec).
-is_sane_oppenssl_sni() ->
+is_sane_oppenssl_client() ->
[{_,_, Bin}] = crypto:info_lib(),
case binary_to_list(Bin) of
- "OpenSSL 0.9" ++ _ -> % Does not support ECC
+ "OpenSSL 0.9" ++ _ ->
false;
_ ->
true
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index 1a9a5b712d..07abddbcf7 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -181,16 +181,6 @@ end_per_suite(_Config) ->
ssl:stop(),
application:stop(crypto).
-init_per_group(basic, Config0) ->
- case ssl_test_lib:supports_ssl_tls_version('tlsv1.2')
- orelse ssl_test_lib:supports_ssl_tls_version('tlsv1.1')
- orelse ssl_test_lib:supports_ssl_tls_version('tlsv1')
- of
- true ->
- ssl_test_lib:clean_tls_version(Config0);
- false ->
- {skip, "only sslv3 supported by OpenSSL"}
- end;
init_per_group(GroupName, Config) ->
case ssl_test_lib:is_tls_version(GroupName) of
@@ -233,7 +223,7 @@ init_per_testcase(TestCase, Config) when
TestCase == erlang_server_openssl_client_dsa_cert;
TestCase == erlang_client_openssl_server_dsa_cert;
TestCase == erlang_server_openssl_client_dsa_cert ->
- case ssl_test_lib:openssl_dsa_support() of
+ case ssl_test_lib:openssl_dsa_support() andalso ssl_test_lib:is_sane_oppenssl_client() of
true ->
special_init(TestCase, Config);
false ->
@@ -334,7 +324,16 @@ special_init(TestCase, Config0)
]}
]}]} | Config0],
check_openssl_sni_support(Config);
-
+special_init(TestCase, Config)
+ when TestCase == erlang_server_openssl_client;
+ TestCase == erlang_server_openssl_client_client_cert;
+ TestCase == erlang_server_openssl_client_reuse_session ->
+ case ssl_test_lib:is_sane_oppenssl_client() of
+ true ->
+ Config;
+ false ->
+ {skip, "Broken OpenSSL client"}
+ end;
special_init(_, Config) ->
Config.
@@ -1073,7 +1072,7 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) ->
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
- {mfa, {ssl_test_lib, no_result_msg, []}},
+ {mfa, {ssl_test_lib, no_result, []}},
{options,
[{versions, [Version]} | ClientOpts]}]),
@@ -1912,7 +1911,7 @@ send_wait_send(Socket, [ErlData, OpenSslData]) ->
check_openssl_sni_support(Config) ->
HelpText = os:cmd("openssl s_client --help"),
- case ssl_test_lib:is_sane_oppenssl_sni() of
+ case ssl_test_lib:is_sane_oppenssl_client() of
true ->
case string:str(HelpText, "-servername") of
0 ->
@@ -2011,7 +2010,7 @@ openssl_has_common_ciphers(Ciphers) ->
OCiphers = ssl_test_lib:common_ciphers(openssl),
has_common_ciphers(Ciphers, OCiphers).
-has_common_ciphers([], OCiphers) ->
+has_common_ciphers([], _) ->
false;
has_common_ciphers([Cipher | Rest], OCiphers) ->
case lists:member(Cipher, OCiphers) of
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index 518a085c89..6308420c52 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -513,7 +513,7 @@
<title>Date and Time Source</title>
<p>Local time is obtained from the Erlang BIF <c>localtime/0</c>.
Universal time is computed from the BIF <c>universaltime/0</c>.</p>
- <p>The following fapply:</p>
+ <p>The following apply:</p>
<list type="bulleted">
<item>There are 86400 seconds in a day.</item>
<item>There are 365 days in an ordinary year.</item>
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 3ec78a2667..00fd731e1d 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -79,6 +79,8 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
-type fa() :: {atom(), arity()}. % function+arity
-type ta() :: {atom(), arity()}. % type+arity
+-type module_or_mfa() :: module() | mfa().
+
-record(typeinfo, {attr, line}).
%% Usage of records, functions, and imports. The variable table, which
@@ -115,6 +117,8 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
:: erl_anno:anno(),
clashes=[], %Exported functions named as BIFs
not_deprecated=[], %Not considered deprecated
+ not_removed=gb_sets:empty() %Not considered removed
+ :: gb_sets:set(module_or_mfa()),
func=[], %Current function
warn_format=0, %Warn format calls
enabled_warnings=[], %All enabled warnings (ordset).
@@ -573,7 +577,10 @@ start(File, Opts) ->
false, Opts)},
{missing_spec_all,
bool_option(warn_missing_spec_all, nowarn_missing_spec_all,
- false, Opts)}
+ false, Opts)},
+ {removed,
+ bool_option(warn_removed, nowarn_removed,
+ true, Opts)}
],
Enabled1 = [Category || {Category,true} <- Enabled0],
Enabled = ordsets:from_list(Enabled1),
@@ -670,8 +677,9 @@ forms(Forms0, St0) ->
no_auto = AutoImportSuppressed}),
St2 = bif_clashes(Forms, St1),
St3 = not_deprecated(Forms, St2),
- St4 = foldl(fun form/2, pre_scan(Forms, St3), Forms),
- post_traversal_check(Forms, St4).
+ St4 = not_removed(Forms, St3),
+ St5 = foldl(fun form/2, pre_scan(Forms, St4), Forms),
+ post_traversal_check(Forms, St5).
pre_scan([{attribute,L,compile,C} | Fs], St) ->
case is_warn_enabled(export_all, St) andalso
@@ -846,6 +854,24 @@ not_deprecated(Forms, #lint{compile=Opts}=St0) ->
end, St0, ML),
St1#lint{not_deprecated = ordsets:from_list(Nowarn)}.
+%% not_removed(Forms, State0) -> State
+
+not_removed(Forms, #lint{compile=Opts}=St0) ->
+ %% There are no line numbers in St0#lint.compile.
+ MFAsL = [{MFA,L} ||
+ {attribute, L, compile, Args} <- Forms,
+ {nowarn_removed, MFAs0} <- lists:flatten([Args]),
+ MFA <- lists:flatten([MFAs0])],
+ Nowarn = [MFA ||
+ {nowarn_removed, MFAs0} <- Opts,
+ MFA <- lists:flatten([MFAs0])],
+ St1 = foldl(fun ({{M, _F, _A}, L}, St2) ->
+ check_module_name(M, L, St2);
+ ({M,L}, St2) ->
+ check_module_name(M, L, St2)
+ end, St0, MFAsL),
+ St1#lint{not_removed = gb_sets:from_list(Nowarn)}.
+
%% The nowarn_bif_clash directive is not only deprecated, it's actually an error from R14A
disallowed_compile_flags(Forms, St0) ->
%% There are (still) no line numbers in St0#lint.compile.
@@ -3769,13 +3795,23 @@ deprecated_function(Line, M, F, As, St) ->
add_warning(Line, {deprecated, MFA, Replacement, Rel}, St)
end;
{removed, String} when is_list(String) ->
- add_warning(Line, {removed, MFA, String}, St);
+ add_removed_warning(Line, MFA, {removed, MFA, String}, St);
{removed, Replacement, Rel} ->
- add_warning(Line, {removed, MFA, Replacement, Rel}, St);
+ add_removed_warning(Line, MFA, {removed, MFA, Replacement, Rel}, St);
no ->
St
end.
+add_removed_warning(Line, {M, _, _}=MFA, Warning, #lint{not_removed=NotRemoved}=St) ->
+ case is_warn_enabled(removed, St) andalso
+ not gb_sets:is_element(M, NotRemoved) andalso
+ not gb_sets:is_element(MFA, NotRemoved) of
+ true ->
+ add_warning(Line, Warning, St);
+ false ->
+ St
+ end.
+
-dialyzer({no_match, deprecated_type/5}).
deprecated_type(L, M, N, As, St) ->
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index b95cb8f525..fa34f19637 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -323,90 +323,6 @@ obsolete_1(snmp, N, A) ->
obsolete_1(snmpa, old_info_format, 1) ->
{deprecated, "Deprecated; (will be removed in OTP 18); use \"new\" format instead"};
-obsolete_1(snmpm, agent_info, 3) ->
- {removed, {snmpm, agent_info, 2}, "R16B"};
-obsolete_1(snmpm, update_agent_info, 5) ->
- {removed, {snmpm, update_agent_info, 4}, "R16B"};
-obsolete_1(snmpm, g, 3) ->
- {removed, {snmpm, sync_get, 3}, "R16B"};
-obsolete_1(snmpm, g, 4) ->
- {removed, {snmpm, sync_get, [3,4]}, "R16B"};
-obsolete_1(snmpm, g, 5) ->
- {removed, {snmpm, sync_get, [4,5]}, "R16B"};
-obsolete_1(snmpm, g, 6) ->
- {removed, {snmpm, sync_get, [5,6]}, "R16B"};
-obsolete_1(snmpm, g, 7) ->
- {removed, {snmpm, sync_get, 6}, "R16B"};
-obsolete_1(snmpm, ag, 3) ->
- {removed, {snmpm, async_get, 3}, "R16B"};
-obsolete_1(snmpm, ag, 4) ->
- {removed, {snmpm, async_get, [3,4]}, "R16B"};
-obsolete_1(snmpm, ag, 5) ->
- {removed, {snmpm, async_get, [4,5]}, "R16B"};
-obsolete_1(snmpm, ag, 6) ->
- {removed, {snmpm, async_get, [5,6]}, "R16B"};
-obsolete_1(snmpm, ag, 7) ->
- {removed, {snmpm, async_get, 6}, "R16B"};
-obsolete_1(snmpm, gn, 3) ->
- {removed, {snmpm, sync_get_next, 3}, "R16B"};
-obsolete_1(snmpm, gn, 4) ->
- {removed, {snmpm, sync_get_next, [3,4]}, "R16B"};
-obsolete_1(snmpm, gn, 5) ->
- {removed, {snmpm, sync_get_next, [4,5]}, "R16B"};
-obsolete_1(snmpm, gn, 6) ->
- {removed, {snmpm, sync_get_next, [5,6]}, "R16B"};
-obsolete_1(snmpm, gn, 7) ->
- {removed, {snmpm, sync_get_next, 6}, "R16B"};
-obsolete_1(snmpm, agn, 3) ->
- {removed, {snmpm, async_get_next, 3}, "R16B"};
-obsolete_1(snmpm, agn, 4) ->
- {removed, {snmpm, async_get_next, [3,4]}, "R16B"};
-obsolete_1(snmpm, agn, 5) ->
- {removed, {snmpm, async_get_next, [4,5]}, "R16B"};
-obsolete_1(snmpm, agn, 6) ->
- {removed, {snmpm, async_get_next, [5,6]}, "R16B"};
-obsolete_1(snmpm, agn, 7) ->
- {removed, {snmpm, async_get_next, 6}, "R16B"};
-obsolete_1(snmpm, s, 3) ->
- {removed, {snmpm, sync_set, 3}, "R16B"};
-obsolete_1(snmpm, s, 4) ->
- {removed, {snmpm, sync_set, [3,4]}, "R16B"};
-obsolete_1(snmpm, s, 5) ->
- {removed, {snmpm, sync_set, [4,5]}, "R16B"};
-obsolete_1(snmpm, s, 6) ->
- {removed, {snmpm, sync_set, [5,6]}, "R16B"};
-obsolete_1(snmpm, s, 7) ->
- {removed, {snmpm, sync_set, 6}, "R16B"};
-obsolete_1(snmpm, as, 3) ->
- {removed, {snmpm, async_set, 3}, "R16B"};
-obsolete_1(snmpm, as, 4) ->
- {removed, {snmpm, async_set, [3,4]}, "R16B"};
-obsolete_1(snmpm, as, 5) ->
- {removed, {snmpm, async_set, [4,5]}, "R16B"};
-obsolete_1(snmpm, as, 6) ->
- {removed, {snmpm, async_set, [5,6]}, "R16B"};
-obsolete_1(snmpm, as, 7) ->
- {removed, {snmpm, async_set, 6}, "R16B"};
-obsolete_1(snmpm, gb, 5) ->
- {removed, {snmpm, sync_get_bulk, 5}, "R16B"};
-obsolete_1(snmpm, gb, 6) ->
- {removed, {snmpm, sync_get_bulk, [5,6]}, "R16B"};
-obsolete_1(snmpm, gb, 7) ->
- {removed, {snmpm, sync_get_bulk, [6,7]}, "R16B"};
-obsolete_1(snmpm, gb, 8) ->
- {removed, {snmpm, sync_get_bulk, [7,8]}, "R16B"};
-obsolete_1(snmpm, gb, 9) ->
- {removed, {snmpm, sync_get_bulk, 8}, "R16B"};
-obsolete_1(snmpm, agb, 5) ->
- {removed, {snmpm, async_get_bulk, 5}, "R16B"};
-obsolete_1(snmpm, agb, 6) ->
- {removed, {snmpm, async_get_bulk, [5,6]}, "R16B"};
-obsolete_1(snmpm, agb, 7) ->
- {removed, {snmpm, async_get_bulk, [6,7]}, "R16B"};
-obsolete_1(snmpm, agb, 8) ->
- {removed, {snmpm, async_get_bulk, [7,8]}, "R16B"};
-obsolete_1(snmpm, agb, 9) ->
- {removed, {snmpm, async_get_bulk, 8}, "R16B"};
%% *** MEGACO ***
@@ -417,6 +333,7 @@ obsolete_1(megaco, format_versions, 1) ->
%% *** OS-MON-MIB ***
+%% FIXME: Remove this warning in OTP 24.
obsolete_1(os_mon_mib, _, _) ->
{removed, "was removed in 22.0"};
@@ -431,64 +348,6 @@ obsolete_1(auth, node_cookie, 1) ->
obsolete_1(auth, node_cookie, 2) ->
{deprecated, "Deprecated; use erlang:set_cookie/2 and net_adm:ping/1 instead"};
-obsolete_1(http, request, 1) -> {removed,{httpc,request,1},"R15B"};
-obsolete_1(http, request, 2) -> {removed,{httpc,request,2},"R15B"};
-obsolete_1(http, request, 4) -> {removed,{httpc,request,4},"R15B"};
-obsolete_1(http, request, 5) -> {removed,{httpc,request,5},"R15B"};
-obsolete_1(http, cancel_request, 1) -> {removed,{httpc,cancel_request,1},"R15B"};
-obsolete_1(http, cancel_request, 2) -> {removed,{httpc,cancel_request,2},"R15B"};
-obsolete_1(http, set_option, 2) -> {removed,{httpc,set_option,2},"R15B"};
-obsolete_1(http, set_option, 3) -> {removed,{httpc,set_option,3},"R15B"};
-obsolete_1(http, set_options, 1) -> {removed,{httpc,set_options,1},"R15B"};
-obsolete_1(http, set_options, 2) -> {removed,{httpc,set_options,2},"R15B"};
-obsolete_1(http, verify_cookies, 2) -> {removed,{httpc,store_cookies,2},"R15B"};
-obsolete_1(http, verify_cookies, 3) -> {removed,{httpc,store_cookies,3},"R15B"};
-obsolete_1(http, cookie_header, 1) -> {removed,{httpc,cookie_header,1},"R15B"};
-obsolete_1(http, cookie_header, 2) -> {removed,{httpc,cookie_header,2},"R15B"};
-obsolete_1(http, stream_next, 1) -> {removed,{httpc,stream_next,1},"R15B"};
-obsolete_1(http, default_profile, 0) -> {removed,{httpc,default_profile,0},"R15B"};
-
-%% Added in R13A.
-obsolete_1(regexp, _, _) ->
- {removed, "removed in R15; use the re module instead"};
-
-%% Added in R13B04.
-obsolete_1(erlang, concat_binary, 1) ->
- {removed,{erlang,list_to_binary,1},"R15B"};
-
-%% Added in R14A.
-obsolete_1(ssl, peercert, 2) ->
- {removed ,"removed in R15A; use ssl:peercert/1 and public_key:pkix_decode_cert/2 instead"};
-
-%% Added in R14B.
-obsolete_1(public_key, pem_to_der, 1) ->
- {removed,"removed in R15A; use file:read_file/1 and public_key:pem_decode/1"};
-obsolete_1(public_key, decode_private_key, A) when A =:= 1; A =:= 2 ->
- {removed, "removed in R15A; use public_key:pem_entry_decode/1"};
-
-%% Added in R14B03.
-obsolete_1(docb_gen, _, _) ->
- {removed,"the DocBuilder application was removed in R15B"};
-obsolete_1(docb_transform, _, _) ->
- {removed,"the DocBuilder application was removed in R15B"};
-obsolete_1(docb_xml_check, _, _) ->
- {removed,"the DocBuilder application was removed in R15B"};
-
-%% Added in R15B
-obsolete_1(asn1rt, F, _) when F == load_driver; F == unload_driver ->
- {removed,"removed (will be removed in OTP 18); has no effect as drivers are no longer used"};
-obsolete_1(ssl, pid, 1) ->
- {removed,"was removed in R16; is no longer needed"};
-obsolete_1(inviso, _, _) ->
- {removed,"the inviso application was removed in R16"};
-
-%% Added in R15B01.
-obsolete_1(ssh, sign_data, 2) ->
- {removed,"removed in R16A; use public_key:pem_decode/1, public_key:pem_entry_decode/1 "
- "and public_key:sign/3 instead"};
-obsolete_1(ssh, verify_data, 3) ->
- {removed,"removed in R16A; use public_key:ssh_decode/1, and public_key:verify/4 instead"};
-
%% Added in R16
obsolete_1(wxCalendarCtrl, enableYearChange, _) -> %% wx bug documented?
{deprecated,"deprecated function not available in wxWidgets-2.9 and later"};
@@ -609,10 +468,8 @@ obsolete_1(queue, lait, 1) ->
%% Removed in OTP 19.
-obsolete_1(overload, _, _) ->
- {removed, "removed in OTP 19"};
obsolete_1(rpc, safe_multi_server_call, A) when A =:= 2; A =:= 3 ->
- {removed, {rpc, multi_server_call, A}, "removed in OTP 19"};
+ {removed, {rpc, multi_server_call, A}, "19.0"};
%% Added in OTP 20.
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index e791da48cf..939cc1024c 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -2109,11 +2109,32 @@ otp_5362(Config) when is_list(Config) ->
{calendar,local_time_to_universal_time_dst,1}, "a future release"}}]}},
{call_removed_function,
- <<"t(X) -> regexp:match(X).">>,
+ <<"t(X) -> erlang:hash(X, 10000).">>,
[],
{warnings,
- [{1,erl_lint,{removed,{regexp,match,1},
- "removed in R15; use the re module instead"}}]}}
+ [{1,erl_lint,{removed,{erlang,hash,2},{erlang,phash2,2},"20.0"}}]}},
+
+ {nowarn_call_removed_function_1,
+ <<"t(X) -> erlang:hash(X, 10000).">>,
+ [{nowarn_removed,{erlang,hash,2}}],
+ []},
+
+ {nowarn_call_removed_function_2,
+ <<"t(X) -> os_mon_mib:any_function_really(erlang:hash(X, 10000)).">>,
+ [nowarn_removed],
+ []},
+
+ {call_removed_module,
+ <<"t(X) -> os_mon_mib:any_function_really(X).">>,
+ [],
+ {warnings,[{1,erl_lint,
+ {removed,{os_mon_mib,any_function_really,1},
+ "was removed in 22.0"}}]}},
+
+ {nowarn_call_removed_module,
+ <<"t(X) -> os_mon_mib:any_function_really(X).">>,
+ [{nowarn_removed,os_mon_mib}],
+ []}
],