aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2018-09-13 12:15:40 +0200
committerHans Nilsson <[email protected]>2018-09-13 12:15:40 +0200
commit9df71f46b41e34b0be5cd561533e2b3d3948dc57 (patch)
treedb88bf06418a5b7cccd467fc86697144d3397094 /lib/crypto
parent6d665a8296999822e4d516343d0e21ed62e70b37 (diff)
parentdf39504bc6f9b106a20959b969b258db327261a5 (diff)
downloadotp-9df71f46b41e34b0be5cd561533e2b3d3948dc57.tar.gz
otp-9df71f46b41e34b0be5cd561533e2b3d3948dc57.tar.bz2
otp-9df71f46b41e34b0be5cd561533e2b3d3948dc57.zip
Merge branch 'hans/crypto/doc/OTP-15134' into maint
* hans/crypto/doc/OTP-15134: ssh: Use exported crypto types public_key: Generate refman from types and specs public_key: Rework -type and -spec Check existing specs with code and documentation and adjust. Prepare for doc generation public_key: Setup for doc generation public_key: Remove special type signature for one test crypto: Add missing documentation for enable_fips_mode/1 crypto: Generate refman from types and specs and fix links in engine chapter for generated crypto module refman crypto: Rework -type and -spec Check code and documentation and write -type/-spec or adjust existing. Prepare for doc generation crypto: Setup for doc generation crypto: A user's guide chapter on algorithm details Such as keylengths, blocksizes and IV lengths are hard to find otherwise
Diffstat (limited to 'lib/crypto')
-rw-r--r--lib/crypto/doc/specs/.gitignore1
-rw-r--r--lib/crypto/doc/src/Makefile9
-rw-r--r--lib/crypto/doc/src/algorithm_details.xml290
-rw-r--r--lib/crypto/doc/src/crypto.xml1125
-rw-r--r--lib/crypto/doc/src/engine_keys.xml2
-rw-r--r--lib/crypto/doc/src/specs.xml4
-rw-r--r--lib/crypto/doc/src/usersguide.xml1
-rw-r--r--lib/crypto/src/crypto.erl980
8 files changed, 1546 insertions, 866 deletions
diff --git a/lib/crypto/doc/specs/.gitignore b/lib/crypto/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/lib/crypto/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile
index 2148062e78..cbcafb7375 100644
--- a/lib/crypto/doc/src/Makefile
+++ b/lib/crypto/doc/src/Makefile
@@ -39,7 +39,7 @@ 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
+XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml algorithm_details.xml
BOOK_FILES = book.xml
@@ -62,11 +62,17 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml)
+
+TOP_SPECS_FILE = specs.xml
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
XML_FLAGS +=
+#in ssh it looks like this: SPECS_FLAGS = -I../../../public_key/include -I../../../public_key/src -I../../..
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -93,6 +99,7 @@ clean clean_docs clean_tex:
rm -f $(MAN3DIR)/*
rm -f $(MAN6DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECS_FILES)
rm -f errs core *~
# ----------------------------------------------------
diff --git a/lib/crypto/doc/src/algorithm_details.xml b/lib/crypto/doc/src/algorithm_details.xml
new file mode 100644
index 0000000000..088f5e8e97
--- /dev/null
+++ b/lib/crypto/doc/src/algorithm_details.xml
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2014</year><year>2017</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>Algorithm Details</title>
+ <prepared>Hans Nilsson</prepared>
+ <docno></docno>
+ <date>2018-08-22</date>
+ <rev>A</rev>
+ <file>algorithm_details.xml</file>
+ </header>
+ <p>
+ This chapter describes details of algorithms in the crypto application.
+ </p>
+ <p>The tables only documents the supported cryptos and key lengths. The user should not draw any conclusion
+ on security from the supplied tables.
+ </p>
+
+ <section>
+ <title>Ciphers</title>
+ <section>
+ <title>Block Ciphers</title>
+ <p>To be used in
+ <seealso marker="crypto#block_encrypt-3">block_encrypt/3</seealso>,
+ <seealso marker="crypto#block_encrypt-4">block_encrypt/4</seealso>,
+ <seealso marker="crypto#block_decrypt-3">block_decrypt/3</seealso> and
+ <seealso marker="crypto#block_decrypt-4">block_decrypt/4</seealso>.
+ </p>
+ <p>Available in all OpenSSL compatible with Erlang CRYPTO if not disabled by configuration.
+ </p>
+ <p>To dynamically check availability, check that the name in the <i>Cipher and Mode</i> column is present in the
+ list with the <c>cipher</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ <table>
+ <row><cell><strong>Cipher and Mode</strong></cell><cell><strong>Key length</strong><br/><strong>[bytes]</strong></cell><cell><strong>IV length</strong><br/><strong>[bytes]</strong></cell><cell><strong>Block size</strong><br/><strong>[bytes]</strong></cell></row>
+ <row><cell><c>aes_cbc</c></cell> <cell>16, 24, 32</cell><cell>16</cell><cell>16</cell></row>
+ <row><cell><c>aes_cbc128</c></cell><cell>16</cell><cell>16</cell><cell>16</cell></row>
+ <row><cell><c>aes_cbc256</c></cell><cell>32</cell><cell>16</cell><cell>16</cell></row>
+
+ <row><cell><c>aes_cfb8</c></cell> <cell>16, 24, 32</cell><cell>16</cell><cell>any</cell></row>
+
+ <row><cell><c>aes_ecb</c></cell><cell>16, 24, 32</cell><cell> </cell><cell>16</cell></row>
+
+ <row><cell><c>aes_ige256</c></cell><cell>16</cell><cell>32</cell><cell>16</cell></row>
+ <row><cell><c>blowfish_cbc</c></cell> <cell>4-56</cell> <cell>8</cell> <cell>8</cell></row>
+ <row><cell><c>blowfish_cfb64</c></cell> <cell>1-</cell> <cell>8</cell> <cell>any</cell></row>
+ <row><cell><c>blowfish_ecb</c></cell><cell>1-</cell><cell> </cell><cell>8</cell></row>
+ <row><cell><c>blowfish_ofb64</c></cell><cell>1-</cell><cell>8</cell><cell>any</cell></row>
+
+ <row><cell><c>des3_cbc</c><br/><i>(=DES EDE3 CBC)</i></cell><cell>[8,8,8]</cell><cell>8</cell><cell>8</cell></row>
+ <row><cell><c>des3_cfb</c><br/><i>(=DES EDE3 CFB)</i></cell><cell>[8,8,8]</cell><cell>8</cell><cell>any</cell></row>
+
+ <row><cell><c>des_cbc</c></cell><cell>8</cell><cell>8</cell> <cell>8</cell></row>
+ <row><cell><c>des_cfb</c></cell><cell>8</cell><cell>8</cell><cell>any</cell></row>
+ <row><cell><c>des_ecb</c></cell><cell>8</cell><cell> </cell><cell>8</cell></row>
+ <row><cell><c>des_ede3</c><br/><i>(=DES EDE3 CBC)</i></cell><cell>[8,8,8]</cell><cell>8</cell><cell>8</cell></row>
+ <row><cell><c>rc2_cbc</c></cell><cell>1-</cell><cell>8</cell><cell>8</cell></row>
+ <tcaption>Block cipher key lengths</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>AEAD Ciphers</title>
+ <p>To be used in <seealso marker="crypto#block_encrypt-4">block_encrypt/4</seealso> and
+ <seealso marker="crypto#block_decrypt-4">block_decrypt/4</seealso>.
+ </p>
+ <p>To dynamically check availability, check that the name in the <i>Cipher and Mode</i> column is present in the
+ list with the <c>cipher</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ <table>
+ <row><cell><strong>Cipher and Mode</strong></cell><cell><strong>Key length</strong><br/><strong>[bytes]</strong></cell><cell><strong>IV length</strong><br/><strong>[bytes]</strong></cell><cell><strong>AAD length</strong><br/><strong>[bytes]</strong></cell><cell><strong>Block size</strong><br/><strong>[bytes]</strong></cell><cell><strong>Supported with</strong><br/><strong>OpenSSL versions</strong></cell></row>
+ <row><cell><c>aes_gcm</c></cell> <cell>16</cell> <cell>16</cell> <cell>0-16</cell> <cell>any</cell><cell>1.0.1 -</cell></row>
+ <row><cell><c>chacha20_poly1305</c></cell><cell>32</cell> <cell>1-16</cell> <cell>any</cell> <cell>any</cell><cell>1.1.0 -</cell></row>
+ <tcaption>AEAD cipher key lengths</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>Stream Ciphers</title>
+ <p>To be used in <seealso marker="crypto#stream_init-2">stream_init/2</seealso> and
+ <seealso marker="crypto#stream_init/3">stream_init/3</seealso>.
+ </p>
+ <p>To dynamically check availability, check that the name in the <i>Cipher and Mode</i> column is present in the
+ list with the <c>cipher</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ <table>
+ <row><cell><strong>Cipher and Mode</strong></cell><cell><strong>Key length</strong><br/><strong>[bytes]</strong></cell><cell><strong>IV length</strong><br/><strong>[bytes]</strong></cell><cell><strong>Supported with</strong><br/><strong>OpenSSL versions</strong></cell></row>
+ <row><cell><c>aes_ctr</c></cell><cell>16, 24, 32</cell><cell>16</cell><cell>1.0.1 -</cell></row>
+ <row><cell><c>rc4</c></cell><cell>1-</cell><cell> </cell> <cell>all</cell></row>
+ <tcaption>Stream cipher key lengths</tcaption>
+ </table>
+ </section>
+ </section>
+
+ <section>
+ <title>Message Authentication Codes (MACs)</title>
+
+ <section>
+ <title>CMAC</title>
+ <p>To be used in <seealso marker="crypto#cmac-3">cmac/3</seealso> and
+ <seealso marker="crypto#cmac-3">cmac/4</seealso>.
+ </p>
+ <p>CMAC with the following ciphers are available with OpenSSL 1.0.1 or later if not disabled by configuration.
+ </p>
+
+ <p>To dynamically check availability, check that the name <c>cmac</c> is present in the
+ list with the <c>macs</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ Also check that the name in the <i>Cipher and Mode</i> column is present in the
+ list with the <c>cipher</c> tag in the return value.
+ </p>
+ <table>
+ <row><cell><strong>Cipher and Mode</strong></cell><cell><strong>Key length</strong><br/><strong>[bytes]</strong></cell><cell><strong>Max Mac Length</strong><br/><strong>[bytes]</strong></cell></row>
+ <row><cell><c>aes_cbc</c></cell> <cell>16, 24, 32</cell><cell>16</cell></row>
+ <row><cell><c>aes_cbc128</c></cell><cell>16</cell><cell>16</cell></row>
+ <row><cell><c>aes_cbc256</c></cell><cell>32</cell><cell>16</cell></row>
+
+ <row><cell><c>aes_cfb8</c></cell> <cell>16</cell><cell>1</cell></row>
+
+ <row><cell><c>blowfish_cbc</c></cell> <cell>4-56</cell> <cell>8</cell></row>
+ <row><cell><c>blowfish_cfb64</c></cell> <cell>1-</cell> <cell>1</cell></row>
+ <row><cell><c>blowfish_ecb</c></cell><cell>1-</cell> <cell>8</cell></row>
+ <row><cell><c>blowfish_ofb64</c></cell><cell>1-</cell> <cell>1</cell></row>
+
+ <row><cell><c>des3_cbc</c><br/><i>(=DES EDE3 CBC)</i></cell><cell>[8,8,8]</cell><cell>8</cell></row>
+ <row><cell><c>des3_cfb</c><br/><i>(=DES EDE3 CFB)</i></cell><cell>[8,8,8]</cell><cell>1</cell></row>
+
+ <row><cell><c>des_cbc</c></cell><cell>8</cell><cell>8</cell></row>
+
+ <row><cell><c>des_cfb</c></cell><cell>8</cell><cell>1</cell></row>
+ <row><cell><c>des_ecb</c></cell><cell>8</cell><cell>1</cell></row>
+ <row><cell><c>rc2_cbc</c></cell><cell>1-</cell><cell>8</cell></row>
+ <tcaption>CMAC cipher key lengths</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>HMAC</title>
+ <p>Available in all OpenSSL compatible with Erlang CRYPTO if not disabled by configuration.
+ </p>
+ <p>To dynamically check availability, check that the name <c>hmac</c> is present in the
+ list with the <c>macs</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>POLY1305</title>
+ <p>POLY1305 is available with OpenSSL 1.1.1 or later if not disabled by configuration.
+ </p>
+ <p>To dynamically check availability, check that the name <c>poly1305</c> is present in the
+ list with the <c>macs</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ </section>
+
+ </section>
+
+ <section>
+ <title>Hash</title>
+
+ <p>To dynamically check availability, check that the wanted name in the <i>Names</i> column is present in the
+ list with the <c>hashs</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+
+
+ <table>
+ <row><cell><strong>Type</strong></cell>
+ <cell><strong>Names</strong></cell>
+ <cell><strong>Supported with</strong><br/><strong>OpenSSL versions</strong></cell>
+ </row>
+ <row><cell>SHA1</cell><cell>sha</cell><cell>all</cell></row>
+ <row><cell>SHA2</cell><cell>sha224, sha256, sha384, sha512</cell><cell>all</cell></row>
+ <row><cell>SHA3</cell><cell>sha3_224, sha3_256, sha3_384, sha3_512</cell><cell>1.1.1 -</cell></row>
+ <row><cell>MD4</cell><cell>md4</cell><cell>all</cell></row>
+ <row><cell>MD5</cell><cell>md5</cell><cell>all</cell></row>
+ <row><cell>RIPEMD</cell><cell>ripemd160</cell><cell>all</cell></row>
+ <tcaption></tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>Public Key Cryptography</title>
+
+ <section>
+ <title>RSA</title>
+ <p>RSA is available with all OpenSSL versions compatible with Erlang CRYPTO if not disabled by configuration.
+ To dynamically check availability, check that the atom <c>rsa</c> is present in the
+ list with the <c>public_keys</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+
+ <table>
+ <row><cell><strong>Option</strong></cell> <cell><strong>sign/verify</strong></cell> <cell><strong>encrypt/decrypt</strong></cell> <cell><strong>Supported with</strong><br/><strong>OpenSSL versions</strong></cell> </row>
+ <row><cell>{rsa_mgf1_md,atom()}</cell> <cell>x</cell> <cell>x</cell> <cell>1.0.1</cell></row>
+ <row><cell>{rsa_oaep_label, binary()}</cell> <cell> </cell> <cell>x</cell> <cell></cell></row>
+ <row><cell>{rsa_oaep_md, atom()}</cell> <cell> </cell> <cell>x</cell> <cell></cell></row>
+ <row><cell>{rsa_padding,rsa_pkcs1_pss_padding}</cell> <cell>x</cell> <cell> </cell> <cell>1.0.0</cell></row>
+ <row><cell>{rsa_pss_saltlen, -2..}</cell> <cell>x</cell> <cell> </cell> <cell>1.0.0</cell></row>
+ <row><cell>{rsa_padding,rsa_no_padding}</cell> <cell>x</cell> <cell>x</cell> <cell></cell></row>
+ <row><cell>{rsa_padding,rsa_pkcs1_padding}</cell> <cell>x</cell> <cell>x</cell> <cell></cell></row>
+ <row><cell>{rsa_padding,rsa_sslv23_padding}</cell> <cell> </cell> <cell>x</cell> <cell></cell></row>
+ <row><cell>{rsa_padding,rsa_x931_padding}</cell> <cell>x</cell> <cell> </cell> <cell></cell></row>
+ <tcaption></tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>DSS</title>
+ <p>DSS is available with OpenSSL versions compatible with Erlang CRYPTO if not disabled by configuration.
+ To dynamically check availability, check that the atom <c>dss</c> is present in the
+ list with the <c>public_keys</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>ECDSA</title>
+ <p>ECDSA is available with OpenSSL 0.9.8o or later if not disabled by configuration.
+ To dynamically check availability, check that the atom <c>ecdsa</c> is present in the
+ list with the <c>public_keys</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ If the atom <c>ec_gf2m</c> characteristic two field curves are available.
+ </p>
+ <p>The actual supported named curves could be checked by examining the list with the
+ <c>curves</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>Diffie-Hellman</title>
+ <p>Diffie-Hellman computations are available with OpenSSL versions compatible with Erlang CRYPTO
+ if not disabled by configuration.
+ To dynamically check availability, check that the atom <c>dh</c> is present in the
+ list with the <c>public_keys</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>Elliptic Curve Diffie-Hellman</title>
+ <p>Elliptic Curve Diffie-Hellman is available with OpenSSL 0.9.8o or later if not disabled by configuration.
+ To dynamically check availability, check that the atom <c>ecdh</c> is present in the
+ list with the <c>public_keys</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+
+ <p>The Edward curves <c>x25519</c> and <c>x448</c> are supported with OpenSSL 1.1.1 or later
+ if not disabled by configuration.
+ </p>
+
+ <p>The actual supported named curves could be checked by examining the list with the
+ <c>curves</c> tag in the return value of
+ <seealso marker="crypto#supports-0">crypto:supports()</seealso>.
+ </p>
+ </section>
+
+ </section>
+
+
+</chapter>
+
+
+
+
+
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 4289bd4a64..d5f5009297 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -47,6 +47,12 @@
Block Cipher Modes - <url href="http://csrc.nist.gov/groups/ST/toolkit/BCM/index.html"> ECB, CBC, CFB, OFB, CTR and GCM </url></p>
</item>
<item>
+ <p>GCM: <url href="https://csrc.nist.gov/publications/detail/sp/800-38d/final">Dworkin, M.,
+ "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC",
+ National Institute of Standards and Technology SP 800-38D, November 2007</url>.
+ </p>
+ </item>
+ <item>
<p><url href="http://www.ietf.org/rfc/rfc1321.txt"> RSA encryption RFC 1321 </url> </p>
</item>
<item>
@@ -56,192 +62,358 @@
<item>
<p><url href="http://www.ietf.org/rfc/rfc2945.txt"> Secure Remote Password Protocol (SRP - RFC 2945) </url></p>
</item>
- <item>
- <p>gcm: Dworkin, M., "Recommendation for Block Cipher Modes of
- Operation: Galois/Counter Mode (GCM) and GMAC",
- National Institute of Standards and Technology SP 800-
- 38D, November 2007.</p>
- </item>
</list>
- </description>
-
- <section>
- <title>DATA TYPES </title>
- <code>key_value() = integer() | binary() </code>
- <p>Always <c>binary()</c> when used as return value</p>
+ <note>
+ <p>The actual supported algorithms and features depends on their availability in the actual libcrypto used.
+ See the <seealso marker="crypto:crypto_app">crypto (App)</seealso> about dependencies.
+ </p>
+ <p>Enabling FIPS mode will also disable algorithms and features.
+ </p>
+ </note>
- <code>rsa_public() = [key_value()] = [E, N] </code>
- <p> Where E is the public exponent and N is public modulus. </p>
+ <p>The <seealso marker="users_guide">CRYPTO User's Guide</seealso> has more information on
+ FIPS, Engines and Algorithm Details like key lengths.
+ </p>
+ </description>
- <code>rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] </code>
- <p>Where E is the public exponent, N is public modulus and D is
- the private exponent. The longer key format contains redundant
- information that will make the calculation faster. P1,P2 are first
- and second prime factors. E1,E2 are first and second exponents. C
- is the CRT coefficient. Terminology is taken from <url href="http://www.ietf.org/rfc/rfc3477.txt"> RFC 3447</url>.</p>
+ <datatypes>
+ <datatype_title>Ciphers</datatype_title>
+ <datatype>
+ <name name="stream_cipher"/>
+ <desc>
+ <p>Stream ciphers for
+ <seealso marker="#stream_encrypt-2">stream_encrypt/2</seealso> and
+ <seealso marker="#stream_decrypt-2">stream_decrypt/2</seealso> .
+ </p>
+ </desc>
+ </datatype>
- <code>dss_public() = [key_value()] = [P, Q, G, Y] </code>
- <p>Where P, Q and G are the dss parameters and Y is the public key.</p>
+ <datatype>
+ <name name="block_cipher_with_iv"/>
+ <name name="cbc_cipher"/>
+ <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>
- <code>dss_private() = [key_value()] = [P, Q, G, X] </code>
- <p>Where P, Q and G are the dss parameters and X is the private key.</p>
+ <datatype>
+ <name name="block_cipher_without_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>
+ </desc>
+ </datatype>
- <code>srp_public() = key_value() </code>
- <p>Where is <c>A</c> or <c>B</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
+ <datatype>
+ <name name="aead_cipher"/>
+ <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> .
+ </p>
+ </desc>
+ </datatype>
- <code>srp_private() = key_value() </code>
- <p>Where is <c>a</c> or <c>b</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
+ <datatype_title>Digests</datatype_title>
+ <datatype>
+ <name name="sha1"/>
+ <name name="sha2"/>
+ <name name="sha3"/>
+ <desc>
+ </desc>
+ </datatype>
- <p>Where Verifier is <c>v</c>, Generator is <c>g</c> and Prime is<c> N</c>, DerivedKey is <c>X</c>, and Scrambler is
- <c>u</c> (optional will be generated if not provided) from <url href="http://srp.stanford.edu/design.html">SRP design</url>
- Version = '3' | '6' | '6a'
- </p>
+ <datatype>
+ <name name="compatibility_only_hash"/>
+ <desc>
+ <p>The <c>compatibility_only_hash()</c> algorithms are recommended only for compatibility with existing applications.</p>
+ </desc>
+ </datatype>
- <code>dh_public() = key_value() </code>
+ <datatype>
+ <name name="rsa_digest_type"/>
+ <desc>
+ </desc>
+ </datatype>
- <code>dh_private() = key_value() </code>
+ <datatype>
+ <name name="dss_digest_type"/>
+ <desc>
+ </desc>
+ </datatype>
- <code>dh_params() = [key_value()] = [P, G] | [P, G, PrivateKeyBitLength]</code>
+ <datatype>
+ <name name="ecdsa_digest_type"/>
+ <desc>
+ </desc>
+ </datatype>
- <code>ecdh_public() = key_value() </code>
+ <datatype_title>Elliptic Curves</datatype_title>
+ <datatype>
+ <name name="ec_named_curve"/>
+ <name name="edwards_curve"/>
+ <desc>
+ <p>Note that some curves are disabled if FIPS is enabled.</p>
+ </desc>
+ </datatype>
- <code>ecdh_private() = key_value() </code>
+ <datatype>
+ <name name="ec_explicit_curve"/>
+ <name name="ec_field"/>
+ <name name="ec_curve"/>
+ <desc>
+ <p>Parametric curve definition.</p>
+ </desc>
+ </datatype>
- <code>ecdh_params() = ec_named_curve() | ec_explicit_curve()</code>
+ <datatype>
+ <name name="ec_prime_field"/>
+ <name name="ec_characteristic_two_field"/>
+ <name name="ec_basis"/>
+ <desc>
+ <p>Curve definition details.</p>
+ </desc>
+ </datatype>
- <code>ed_named_curves_ecdh() -> x448 | x25519</code>
- <p>Note that the curves are only supported if the underlying OpenSSL has support for them.</p>
+ <datatype_title>Keys</datatype_title>
+ <datatype>
+ <name name="key"/>
+ <name name="des3_key"/>
+ <desc>
+ <p>For keylengths, iv-sizes and blocksizes see the
+ <seealso marker="crypto:algorithm_details#ciphers">User's Guide</seealso>.
+ </p>
+ <p>A key for des3 is a list of three iolists</p>
+ </desc>
+ </datatype>
- <code>ec_explicit_curve() =
- {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(),
- CoFactor :: none | integer()} </code>
+ <datatype>
+ <name name="key_integer"/>
+ <desc>
+ <p>Always <c>binary()</c> when used as return value</p>
+ </desc>
+ </datatype>
- <code>ec_field() = {prime_field, Prime :: integer()} |
- {characteristic_two_field, M :: integer(), Basis :: ec_basis()}</code>
+ <datatype_title>Public/Private Keys</datatype_title>
+ <datatype>
+ <name name="rsa_public"/>
+ <name name="rsa_private"/>
+ <name name="rsa_params"/>
+ <desc>
+ <code>rsa_public() = [E, N]</code>
+ <code>rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</code>
+ <p>Where E is the public exponent, N is public modulus and D is
+ the private exponent. The longer key format contains redundant
+ information that will make the calculation faster. P1,P2 are first
+ and second prime factors. E1,E2 are first and second exponents. C
+ is the CRT coefficient. Terminology is taken from <url href="http://www.ietf.org/rfc/rfc3477.txt"> RFC 3447</url>.</p>
+ </desc>
+ </datatype>
- <code>ec_basis() = {tpbasis, K :: non_neg_integer()} |
- {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} |
- onbasis</code>
+ <datatype>
+ <name name="dss_public"/>
+ <name name="dss_private"/>
+ <desc>
+ <code>dss_public() = [P, Q, G, Y] </code>
+ <p>Where P, Q and G are the dss parameters and Y is the public key.</p>
- <code>ec_named_curve() ->
- sect571r1| sect571k1| sect409r1| sect409k1| secp521r1| secp384r1| secp224r1| secp224k1|
- secp192k1| secp160r2| secp128r2| secp128r1| sect233r1| sect233k1| sect193r2| sect193r1|
- sect131r2| sect131r1| sect283r1| sect283k1| sect163r2| secp256k1| secp160k1| secp160r1|
- secp112r2| secp112r1| sect113r2| sect113r1| sect239k1| sect163r1| sect163k1| secp256r1|
- secp192r1|
- brainpoolP160r1| brainpoolP160t1| brainpoolP192r1| brainpoolP192t1| brainpoolP224r1|
- brainpoolP224t1| brainpoolP256r1| brainpoolP256t1| brainpoolP320r1| brainpoolP320t1|
- brainpoolP384r1| brainpoolP384t1| brainpoolP512r1| brainpoolP512t1
- </code>
- <p>Note that the <em>sect</em> curves are GF2m (characteristic two) curves and are only supported if the
- underlying OpenSSL has support for them.
- See also <seealso marker="#supports-0">crypto:supports/0</seealso>
- </p>
+ <code>dss_private() = [P, Q, G, X] </code>
+ <p>Where P, Q and G are the dss parameters and X is the private key.</p>
+ </desc>
+ </datatype>
- <marker id="type-engine_key_ref"/>
- <marker id="engine_key_ref_type"/>
- <code>engine_key_ref() = #{engine := engine_ref(),
- key_id := key_id(),
- password => password()}</code>
+ <datatype>
+ <name name="ecdsa_public"/>
+ <name name="ecdsa_private"/>
+ <name name="ecdsa_params"/>
+ <desc>
+ </desc>
+ </datatype>
- <code>engine_ref() = term()</code>
- <p>The result of a call to for example <seealso marker="#engine_load-3">engine_load/3</seealso>.
- </p>
+ <datatype>
+ <name name="srp_public"/>
+ <name name="srp_private"/>
+ <desc>
+ <code>srp_public() = key_integer() </code>
+ <p>Where is <c>A</c> or <c>B</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
+
+ <code>srp_private() = key_integer() </code>
+ <p>Where is <c>a</c> or <c>b</c> from <url href="http://srp.stanford.edu/design.html">SRP design</url></p>
+ </desc>
+ </datatype>
- <code>key_id() = string() | binary()</code>
- <p>Identifies the key to be used. The format depends on the loaded engine. It is passed to
- the <c>ENGINE_load_(private|public)_key</c> functions in libcrypto.
- </p>
+ <datatype>
+ <name name="srp_gen_params"/>
+ <name name="srp_comp_params"/>
+ <desc>
+ <marker id="type-srp_user_gen_params"/>
+ <code>srp_user_gen_params() = [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom()]</code>
+ <marker id="type-srp_host_gen_params"/>
+ <code>srp_host_gen_params() = [Verifier::binary(), Prime::binary(), Version::atom() ]</code>
+ <marker id="type-srp_user_comp_params"/>
+ <code>srp_user_comp_params() = [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom() | ScramblerArg::list()]</code>
+ <marker id="type-srp_host_comp_params"/>
+ <code>srp_host_comp_params() = [Verifier::binary(), Prime::binary(), Version::atom() | ScramblerArg::list()]</code>
+ <p>Where Verifier is <c>v</c>, Generator is <c>g</c> and Prime is<c> N</c>, DerivedKey is <c>X</c>, and Scrambler is
+ <c>u</c> (optional will be generated if not provided) from <url href="http://srp.stanford.edu/design.html">SRP design</url>
+ Version = '3' | '6' | '6a'
+ </p>
+ </desc>
+ </datatype>
- <code>password() = string() | binary()</code>
- <p>The key's password
- </p>
+ <datatype_title>Public Key Ciphers</datatype_title>
- <code>stream_cipher() = rc4 | aes_ctr | chacha20 </code>
+ <datatype>
+ <name name="pk_encrypt_decrypt_algs"/>
+ <desc>
+ <p>Algorithms for public key encrypt/decrypt. Only RSA is supported.</p>
+ </desc>
+ </datatype>
- <code>block_cipher() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc |
- blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc </code>
+ <datatype>
+ <name name="pk_encrypt_decrypt_opts"/>
+ <name name="rsa_opt"/>
+ <name name="rsa_padding"/>
+ <desc>
+ <p>Options for public key encrypt/decrypt. Only RSA is supported.</p>
+ </desc>
+ </datatype>
- <code>aead_cipher() = aes_gcm | chacha20_poly1305 </code>
- <p>Note that the actual supported algorithms depends on the underlying crypto library.</p>
+ <datatype>
+ <name name="rsa_compat_opts"/>
+ <desc>
+ <p>Those option forms are kept only for compatibility and should not be used in new code.</p>
+ </desc>
+ </datatype>
- <code>stream_key() = aes_key() | rc4_key() </code>
+ <datatype_title>Public Key Sign and Verify</datatype_title>
- <code>block_key() = aes_key() | blowfish_key() | des_key()| des3_key() </code>
+ <datatype>
+ <name name="pk_sign_verify_algs"/>
+ <desc>
+ <p>Algorithms for sign and verify.</p>
+ </desc>
+ </datatype>
- <code>aes_key() = iodata() </code> <p>Key length is 128, 192 or 256 bits</p>
+ <datatype>
+ <name name="pk_sign_verify_opts"/>
+ <name name="rsa_sign_verify_opt"/>
+ <name name="rsa_sign_verify_padding"/>
+ <desc>
+ <p>Options for sign and verify.</p>
+ </desc>
+ </datatype>
- <code>rc4_key() = iodata() </code> <p>Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)</p>
+ <datatype_title>Diffie-Hellman Keys and parameters</datatype_title>
+ <datatype>
+ <name name="dh_public"/>
+ <name name="dh_private"/>
+ <desc>
+ </desc>
+ </datatype>
- <code>blowfish_key() = iodata() </code> <p>Variable key length from 32 bits up to 448 bits</p>
+ <datatype>
+ <name name="dh_params"/>
+ <desc>
+ <code>dh_params() = [P, G] | [P, G, PrivateKeyBitLength]</code>
+ </desc>
+ </datatype>
- <code>des_key() = iodata() </code> <p>Key length is 64 bits (in CBC mode only 8 bits are used)</p>
+ <datatype>
+ <name name="ecdh_public"/>
+ <name name="ecdh_private"/>
+ <name name="ecdh_params"/>
+ <desc>
+ </desc>
+ </datatype>
- <code>des3_key() = [binary(), binary(), binary()] </code> <p>Each key part is 64 bits (in CBC mode only 8 bits are used)</p>
+ <datatype_title>Types for Engines</datatype_title>
- <code>digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512</code>
+ <datatype>
+ <name name="engine_key_ref"/>
+ <name name="engine_ref"/>
+ <desc>
+ <p>The result of a call to <seealso marker="#engine_load-3">engine_load/3</seealso>.
+ </p>
+ </desc>
+ </datatype>
- <code>rsa_digest_type() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512</code>
+ <datatype>
+ <name name="key_id"/>
+ <desc>
+ <p>Identifies the key to be used. The format depends on the loaded engine. It is passed to
+ the <c>ENGINE_load_(private|public)_key</c> functions in libcrypto.
+ </p>
+ </desc>
+ </datatype>
- <code>dss_digest_type() = sha | sha224 | sha256 | sha384 | sha512</code> <p>Note that the actual supported
- dss_digest_type depends on the underlying crypto library. In OpenSSL version >= 1.0.1 the listed digest are supported, while in 1.0.0 only sha, sha224 and sha256 are supported. In version 0.9.8 only sha is supported.</p>
+ <datatype>
+ <name name="password"/>
+ <desc>
+ <p>The password of the key stored in an engine.
+ </p>
+ </desc>
+ </datatype>
- <code>ecdsa_digest_type() = sha | sha224 | sha256 | sha384 | sha512</code>
+ <datatype>
+ <name name="engine_method_type"/>
+ </datatype>
- <code>sign_options() = [{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}]</code>
+ <datatype>
+ <name name="engine_cmnd"/>
+ <desc>
+ <p>Pre and Post commands for <seealso marker="#engine_load-3">engine_load/3 and /4</seealso>.
+ </p>
+ </desc>
+ </datatype>
- <code>rsa_sign_padding() = rsa_pkcs1_padding | rsa_pkcs1_pss_padding</code>
+ <datatype_title>Internal data types</datatype_title>
- <code> hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 |
- sha3_224 | sha3_256 | sha3_384 | sha3_512 </code>
- <p>md4 is also supported for hash_init/1 and hash/2.
- Note that both md4 and md5 are recommended only for compatibility with existing applications.
- Note that the actual supported hash_algorithms depends on the underlying crypto library.
- </p>
- <code> cipher_algorithms() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ctr | aes_gcm |
- aes_ige256 | blowfish_cbc | blowfish_cfb64 | chacha20 | chacha20_poly1305 | des_cbc |
- des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc | rc4 </code>
- <code> mac_algorithms() = hmac | cmac | poly1305</code>
- <code> public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m</code>
- <p>Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported
- with ecdsa and ecdh.
- </p>
- <code>engine_method_type() = engine_method_rsa | engine_method_dsa | engine_method_dh |
- engine_method_rand | engine_method_ecdh | engine_method_ecdsa |
- engine_method_ciphers | engine_method_digests | engine_method_store |
- engine_method_pkey_meths | engine_method_pkey_asn1_meths</code>
+ <datatype>
+ <name name="stream_state"/>
+ <name name="hmac_state"/>
+ <name name="hash_state"/>
+ <desc>
+ <p>Contexts with an internal state that should not be manipulated but passed between function calls.
+ </p>
+ </desc>
+ </datatype>
- </section>
+ </datatypes>
+ <!--================ FUNCTIONS ================-->
<funcs>
<func>
- <name>block_encrypt(Type, Key, PlainText) -> CipherText</name>
+ <name name="block_encrypt" arity="3"/>
<fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
- <type>
- <v>Type = des_ecb | blowfish_ecb | aes_ecb </v>
- <v>Key = block_key() </v>
- <v>PlainText = iodata() </v>
- </type>
<desc>
- <p>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher.</p>
- <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying OpenSSL implementation.</p>
+ <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>block_decrypt(Type, Key, CipherText) -> PlainText</name>
+ <name name="block_decrypt" arity="3"/>
<fsummary>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher</fsummary>
- <type>
- <v>Type = des_ecb | blowfish_ecb | aes_ecb </v>
- <v>Key = block_key() </v>
- <v>PlainText = iodata() </v>
- </type>
<desc>
<p>Decrypt <c>CipherText</c> according to <c>Type</c> block cipher.</p>
- <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying OpenSSL implementation.</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>
@@ -251,10 +423,10 @@
<name>block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag}</name>
<fsummary>Encrypt <c>PlainText</c> according to <c>Type</c> block cipher</fsummary>
<type>
- <v>Type = block_cipher() </v>
- <v>AeadType = aead_cipher() </v>
- <v>Key = block_key() </v>
- <v>PlainText = iodata() </v>
+ <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>
</type>
@@ -264,8 +436,11 @@
<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 throw exception <c>notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying OpenSSL implementation.</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>
@@ -274,10 +449,10 @@
<name>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 = block_cipher() </v>
- <v>AeadType = aead_cipher() </v>
- <v>Key = block_key() </v>
- <v>PlainText = iodata() </v>
+ <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>
</type>
<desc>
@@ -287,19 +462,17 @@
<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 throw exception <c>notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying OpenSSL implementation.</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>bytes_to_integer(Bin) -> Integer </name>
+ <name name="bytes_to_integer" arity="1"/>
<fsummary>Convert binary representation, of an integer, to an Erlang integer.</fsummary>
- <type>
- <v>Bin = binary() - as returned by crypto functions</v>
-
- <v>Integer = integer() </v>
- </type>
<desc>
<p>Convert binary representation, of an integer, to an Erlang integer.
</p>
@@ -307,17 +480,8 @@
</func>
<func>
- <name>compute_key(Type, OthersPublicKey, MyKey, Params) -> SharedSecret</name>
+ <name name="compute_key" arity="4"/>
<fsummary>Computes the shared secret</fsummary>
- <type>
- <v> Type = dh | ecdh | srp </v>
- <v>OthersPublicKey = dh_public() | ecdh_public() | srp_public() </v>
- <v>MyKey = dh_private() | ecdh_private() | {srp_public(),srp_private()}</v>
- <v>Params = dh_params() | ecdh_params() | ed_named_curves_ecdh() | SrpUserParams | SrpHostParams</v>
- <v>SrpUserParams = {user, [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom() | [Scrambler:binary()]]} </v>
- <v>SrpHostParams = {host, [Verifier::binary(), Prime::binary(), Version::atom() | [Scrambler::binary]]} </v>
- <v>SharedSecret = binary()</v>
- </type>
<desc>
<p>Computes the shared secret from the private key and the other party's public key.
See also <seealso marker="public_key:public_key#compute_key-2">public_key:compute_key/2</seealso>
@@ -326,85 +490,61 @@
</func>
<func>
- <name>exor(Data1, Data2) -> Result</name>
+ <name name="exor" arity="2"/>
<fsummary>XOR data</fsummary>
- <type>
- <v>Data1, Data2 = iodata()</v>
- <v>Result = binary()</v>
- </type>
<desc>
<p>Performs bit-wise XOR (exclusive or) on the data supplied.</p>
</desc>
</func>
- <func>
- <name>generate_key(Type, Params) -> {PublicKey, PrivKeyOut} </name>
- <name>generate_key(Type, Params, PrivKeyIn) -> {PublicKey, PrivKeyOut} </name>
+
+ <func>
+ <name name="generate_key" arity="2"/>
+ <name name="generate_key" arity="3"/>
<fsummary>Generates a public key of type <c>Type</c></fsummary>
- <type>
- <v> Type = dh | ecdh | rsa | srp </v>
- <v>Params = dh_params() | ecdh_params() | ed_named_curves_ecdh()| RsaParams | SrpUserParams | SrpHostParams </v>
- <v>RsaParams = {ModulusSizeInBits::integer(), PublicExponent::key_value()}</v>
- <v>SrpUserParams = {user, [Generator::binary(), Prime::binary(), Version::atom()]}</v>
- <v>SrpHostParams = {host, [Verifier::binary(), Generator::binary(), Prime::binary(), Version::atom()]}</v>
- <v>PublicKey = dh_public() | ecdh_public() | rsa_public() | srp_public() </v>
- <v>PrivKeyIn = undefined | dh_private() | ecdh_private() | srp_private() </v>
- <v>PrivKeyOut = dh_private() | ecdh_private() | rsa_private() | srp_private() </v>
- </type>
<desc>
<p>Generates a public key of type <c>Type</c>.
See also <seealso marker="public_key:public_key#generate_key-1">public_key:generate_key/1</seealso>.
- May throw exception an exception of class <c>error</c>:
+ May raise exception:
</p>
<list type="bulleted">
- <item><c>badarg</c>: an argument is of wrong type or has an illegal value,</item>
- <item><c>low_entropy</c>: the random generator failed due to lack of secure "randomness",</item>
- <item><c>computation_failed</c>: the computation fails of another reason than <c>low_entropy</c>.</item>
+ <item><c>error:badarg</c>: an argument is of wrong type or has an illegal value,</item>
+ <item><c>error:low_entropy</c>: the random generator failed due to lack of secure "randomness",</item>
+ <item><c>error:computation_failed</c>: the computation fails of another reason than <c>low_entropy</c>.</item>
</list>
<note>
<p>RSA key generation is only available if the runtime was
built with dirty scheduler support. Otherwise, attempting to
- generate an RSA key will throw exception <c>error:notsup</c>.</p>
+ generate an RSA key will raise exception <c>error:notsup</c>.</p>
</note>
</desc>
</func>
<func>
- <name>hash(Type, Data) -> Digest</name>
+ <name name="hash" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Type = md4 | hash_algorithms()</v>
- <v>Data = iodata()</v>
- <v>Digest = binary()</v>
- </type>
<desc>
<p>Computes a message digest of type <c>Type</c> from <c>Data</c>.</p>
- <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying OpenSSL implementation.</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>
</desc>
</func>
<func>
- <name>hash_init(Type) -> Context</name>
+ <name name="hash_init" arity="1"/>
<fsummary></fsummary>
- <type>
- <v>Type = md4 | hash_algorithms()</v>
- </type>
<desc>
<p>Initializes the context for streaming hash operations. <c>Type</c> determines
which digest to use. The returned context should be used as argument
to <seealso marker="#hash_update-2">hash_update</seealso>.</p>
- <p>May throw exception <c>notsup</c> in case the chosen <c>Type</c>
- is not supported by the underlying OpenSSL implementation.</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>
</desc>
</func>
<func>
- <name>hash_update(Context, Data) -> NewContext</name>
+ <name name="hash_update" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Data = iodata()</v>
- </type>
<desc>
<p>Updates the digest represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c>
must have been generated using <seealso marker="#hash_init-1">hash_init</seealso>
@@ -413,12 +553,10 @@
or <seealso marker="#hash_final-1">hash_final</seealso>.</p>
</desc>
</func>
+
<func>
- <name>hash_final(Context) -> Digest</name>
+ <name name="hash_final" arity="1"/>
<fsummary></fsummary>
- <type>
- <v>Digest = binary()</v>
- </type>
<desc>
<p>Finalizes the hash operation referenced by <c>Context</c> returned
from a previous call to <seealso marker="#hash_update-2">hash_update</seealso>.
@@ -428,16 +566,9 @@
</func>
<func>
- <name>hmac(Type, Key, Data) -> Mac</name>
- <name>hmac(Type, Key, Data, MacLength) -> Mac</name>
+ <name name="hmac" arity="3"/>
+ <name name="hmac" arity="4"/>
<fsummary></fsummary>
- <type>
- <v>Type = hash_algorithms() - except ripemd160</v>
- <v>Key = iodata()</v>
- <v>Data = iodata()</v>
- <v>MacLength = integer()</v>
- <v>Mac = binary()</v>
- </type>
<desc>
<p>Computes a HMAC of type <c>Type</c> from <c>Data</c> using
<c>Key</c> as the authentication key.</p> <p><c>MacLength</c>
@@ -446,13 +577,8 @@
</func>
<func>
- <name>hmac_init(Type, Key) -> Context</name>
+ <name name="hmac_init" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Type = hash_algorithms() - except ripemd160</v>
- <v>Key = iodata()</v>
- <v>Context = binary()</v>
- </type>
<desc>
<p>Initializes the context for streaming HMAC operations. <c>Type</c> determines
which hash function to use in the HMAC operation. <c>Key</c> is the authentication
@@ -461,12 +587,8 @@
</func>
<func>
- <name>hmac_update(Context, Data) -> NewContext</name>
+ <name name="hmac_update" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Context = NewContext = binary()</v>
- <v>Data = iodata()</v>
- </type>
<desc>
<p>Updates the HMAC represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c>
must have been generated using an HMAC init function (such as
@@ -479,16 +601,13 @@
call to hmac_update or hmac_final. The semantics of reusing old contexts
in any way is undefined and could even crash the VM in earlier releases.
The reason for this limitation is a lack of support in the underlying
- OpenSSL API.</p></warning>
+ libcrypto API.</p></warning>
</desc>
</func>
<func>
- <name>hmac_final(Context) -> Mac</name>
+ <name name="hmac_final" arity="1"/>
<fsummary></fsummary>
- <type>
- <v>Context = Mac = binary()</v>
- </type>
<desc>
<p>Finalizes the HMAC operation referenced by <c>Context</c>. The size of the resultant MAC is
determined by the type of hash function used to generate it.</p>
@@ -496,12 +615,8 @@
</func>
<func>
- <name>hmac_final_n(Context, HashLen) -> Mac</name>
+ <name name="hmac_final_n" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Context = Mac = binary()</v>
- <v>HashLen = non_neg_integer()</v>
- </type>
<desc>
<p>Finalizes the HMAC operation referenced by <c>Context</c>. <c>HashLen</c> must be greater than
zero. <c>Mac</c> will be a binary with at most <c>HashLen</c> bytes. Note that if HashLen is greater than the actual number of bytes returned from the underlying hash, the returned hash will have fewer than <c>HashLen</c> bytes.</p>
@@ -509,16 +624,9 @@
</func>
<func>
- <name>cmac(Type, Key, Data) -> Mac</name>
- <name>cmac(Type, Key, Data, MacLength) -> Mac</name>
+ <name name="cmac" arity="3"/>
+ <name name="cmac" arity="4"/>
<fsummary>Calculates the Cipher-based Message Authentication Code.</fsummary>
- <type>
- <v>Type = block_cipher()</v>
- <v>Key = iodata()</v>
- <v>Data = iodata()</v>
- <v>MacLength = integer()</v>
- <v>Mac = binary()</v>
- </type>
<desc>
<p>Computes a CMAC of type <c>Type</c> from <c>Data</c> using
<c>Key</c> as the authentication key.</p> <p><c>MacLength</c>
@@ -527,20 +635,21 @@
</func>
<func>
- <name>info_fips() -> Status</name>
+ <name name="info_fips" arity="0"/>
<fsummary>Provides information about the FIPS operating status.</fsummary>
- <type>
- <v>Status = enabled | not_enabled | not_supported</v>
- </type>
<desc>
<p>Provides information about the FIPS operating status of
- crypto and the underlying OpenSSL library. If crypto was built
+ crypto and the underlying libcrypto library. If crypto was built
with FIPS support this can be either <c>enabled</c> (when
running in FIPS mode) or <c>not_enabled</c>. For other builds
- this value is always <c>not_supported</c>.</p>
+ this value is always <c>not_supported</c>.
+ </p>
+ <p>See <seealso marker="#enable_fips_mode-1">enable_fips_mode/1</seealso> about how to enable
+ FIPS mode.
+ </p>
<warning>
<p>In FIPS mode all non-FIPS compliant algorithms are
- disabled and throw exception <c>not_supported</c>. Check
+ disabled and raise exception <c>error:notsup</c>. Check
<seealso marker="#supports-0">supports</seealso> that in
FIPS mode returns the restricted list of available
algorithms.</p>
@@ -549,13 +658,23 @@
</func>
<func>
- <name>info_lib() -> [{Name,VerNum,VerStr}]</name>
+ <name name="enable_fips_mode" arity="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
+ the operation was successful or <c>false</c> otherwise.
+ </p>
+ <p>Note that to enable FIPS mode succesfully, OTP must be built with the configure option <c>--enable-fips</c>,
+ and the underlying libcrypto must also support FIPS.
+ </p>
+ <p>See also <seealso marker="#info_fips-0">info_fips/0</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="info_lib" arity="0"/>
<fsummary>Provides information about the libraries used by crypto.</fsummary>
- <type>
- <v>Name = binary()</v>
- <v>VerNum = integer()</v>
- <v>VerStr = binary()</v>
- </type>
<desc>
<p>Provides the name and version of the libraries used by crypto.</p>
<p><c>Name</c> is the name of the library. <c>VerNum</c> is
@@ -568,50 +687,36 @@
<note><p>
From OTP R16 the <em>numeric version</em> represents the version of the OpenSSL
<em>header files</em> (<c>openssl/opensslv.h</c>) used when crypto was compiled.
- The text variant represents the OpenSSL library used at runtime.
+ The text variant represents the libcrypto library used at runtime.
In earlier OTP versions both numeric and text was taken from the library.
</p></note>
</desc>
</func>
<func>
- <name>mod_pow(N, P, M) -> Result</name>
+ <name name="mod_pow" arity="3"/>
<fsummary>Computes the function: N^P mod M</fsummary>
- <type>
- <v>N, P, M = binary() | integer()</v>
- <v>Result = binary() | error</v>
- </type>
<desc>
<p>Computes the function <c>N^P mod M</c>.</p>
</desc>
</func>
<func>
- <name>next_iv(Type, Data) -> NextIVec</name>
- <name>next_iv(Type, Data, IVec) -> NextIVec</name>
- <fsummary></fsummary>
- <type>
- <v>Type = des_cbc | des3_cbc | aes_cbc | des_cfb</v>
- <v>Data = iodata()</v>
- <v>IVec = NextIVec = binary()</v>
- </type>
- <desc>
- <p>Returns the initialization vector to be used in the next
- iteration of encrypt/decrypt of type <c>Type</c>. <c>Data</c> is the
- encrypted data from the previous iteration step. The <c>IVec</c>
- argument is only needed for <c>des_cfb</c> as the vector used
- in the previous iteration step.</p>
- </desc>
+ <name name="next_iv" arity="2"/>
+ <name name="next_iv" arity="3"/>
+ <fsummary></fsummary>
+ <desc>
+ <p>Returns the initialization vector to be used in the next
+ iteration of encrypt/decrypt of type <c>Type</c>. <c>Data</c> is the
+ encrypted data from the previous iteration step. The <c>IVec</c>
+ argument is only needed for <c>des_cfb</c> as the vector used
+ in the previous iteration step.</p>
+ </desc>
</func>
<func>
- <name>poly1305(Key, Data) -> Mac</name>
+ <name name="poly1305" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Key = iodata()</v>
- <v>Data = iodata()</v>
- <v>Mac = binary()</v>
- </type>
<desc>
<p>Computes a POLY1305 message authentication code (<c>Mac</c>) from <c>Data</c> using
<c>Key</c> as the authentication key.</p>
@@ -619,15 +724,8 @@
</func>
<func>
- <name>private_decrypt(Type, CipherText, PrivateKey, Padding) -> PlainText</name>
+ <name name="private_decrypt" arity="4"/>
<fsummary>Decrypts CipherText using the private Key.</fsummary>
- <type>
- <v>Type = rsa</v>
- <v>CipherText = binary()</v>
- <v>PrivateKey = rsa_private() | engine_key_ref()</v>
- <v>Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding</v>
- <v>PlainText = binary()</v>
- </type>
<desc>
<p>Decrypts the <c>CipherText</c>, encrypted with
<seealso marker="#public_encrypt-4">public_encrypt/4</seealso> (or equivalent function)
@@ -640,34 +738,8 @@
</func>
<func>
- <name>privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey</name>
- <fsummary>Fetches a public key from an Engine stored private key.</fsummary>
- <type>
- <v>Type = rsa | dss</v>
- <v>EnginePrivateKeyRef = engine_key_ref()</v>
- <v>PublicKey = rsa_public() | dss_public()</v>
- </type>
- <desc>
- <p>Fetches the corresponding public key from a private key stored in an Engine.
- The key must be of the type indicated by the Type parameter.
- </p>
- </desc>
- </func>
-
- <func>
- <name>private_encrypt(Type, PlainText, PrivateKey, Padding) -> CipherText</name>
+ <name name="private_encrypt" arity="4"/>
<fsummary>Encrypts PlainText using the private Key.</fsummary>
- <type>
- <v>Type = rsa</v>
- <v>PlainText = binary()</v>
- <d> The size of the <c>PlainText</c> must be less
- than <c>byte_size(N)-11</c> if <c>rsa_pkcs1_padding</c> is
- used, and <c>byte_size(N)</c> if <c>rsa_no_padding</c> is
- used, where N is public modulus of the RSA key.</d>
- <v>PrivateKey = rsa_private() | engine_key_ref()</v>
- <v>Padding = rsa_pkcs1_padding | rsa_no_padding</v>
- <v>CipherText = binary()</v>
- </type>
<desc>
<p>Encrypts the <c>PlainText</c> using the <c>PrivateKey</c>
and returns the ciphertext. This is a low level signature operation
@@ -677,16 +749,10 @@
</p>
</desc>
</func>
+
<func>
- <name>public_decrypt(Type, CipherText, PublicKey, Padding) -> PlainText</name>
+ <name name="public_decrypt" arity="4"/>
<fsummary>Decrypts CipherText using the public Key.</fsummary>
- <type>
- <v>Type = rsa</v>
- <v>CipherText = binary()</v>
- <v>PublicKey = rsa_public() | engine_key_ref()</v>
- <v>Padding = rsa_pkcs1_padding | rsa_no_padding</v>
- <v>PlainText = binary()</v>
- </type>
<desc>
<p>Decrypts the <c>CipherText</c>, encrypted with
<seealso marker="#private_encrypt-4">private_encrypt/4</seealso>(or equivalent function)
@@ -699,19 +765,8 @@
</func>
<func>
- <name>public_encrypt(Type, PlainText, PublicKey, Padding) -> CipherText</name>
+ <name name="public_encrypt" arity="4"/>
<fsummary>Encrypts PlainText using the public Key.</fsummary>
- <type>
- <v>Type = rsa</v>
- <v>PlainText = binary()</v>
- <d> The size of the <c>PlainText</c> must be less
- than <c>byte_size(N)-11</c> if <c>rsa_pkcs1_padding</c> is
- used, and <c>byte_size(N)</c> if <c>rsa_no_padding</c> is
- used, where N is public modulus of the RSA key.</d>
- <v>PublicKey = rsa_public() | engine_key_ref()</v>
- <v>Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding</v>
- <v>CipherText = binary()</v>
- </type>
<desc>
<p>Encrypts the <c>PlainText</c> (message digest) using the <c>PublicKey</c>
and returns the <c>CipherText</c>. This is a low level signature operation
@@ -722,18 +777,15 @@
</func>
<func>
- <name>rand_seed(Seed) -> ok</name>
+ <name name="rand_seed" arity="1"/>
<fsummary>Set the seed for random bytes generation</fsummary>
- <type>
- <v>Seed = binary()</v>
- </type>
<desc>
<p>Set the seed for PRNG to the given binary. This calls the
RAND_seed function from openssl. Only use this if the system
you are running on does not have enough "randomness" built in.
Normally this is when
<seealso marker="#strong_rand_bytes/1">strong_rand_bytes/1</seealso>
- throws <c>low_entropy</c></p>
+ raises <c>error:low_entropy</c></p>
</desc>
</func>
@@ -751,36 +803,15 @@
</func>
<func>
- <name>sign(Algorithm, DigestType, Msg, Key) -> binary()</name>
- <name>sign(Algorithm, DigestType, Msg, Key, Options) -> binary()</name>
- <fsummary> Create digital signature.</fsummary>
- <type>
- <v>Algorithm = rsa | dss | ecdsa </v>
- <v>Msg = binary() | {digest,binary()}</v>
- <d>The msg is either the binary "cleartext" data to be
- signed or it is the hashed value of "cleartext" i.e. the
- digest (plaintext).</d>
- <v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v>
- <v>Key = rsa_private() | dss_private() | [ecdh_private(),ecdh_params()] | engine_key_ref()</v>
- <v>Options = sign_options()</v>
- </type>
- <desc>
- <p>Creates a digital signature.</p>
- <p>Algorithm <c>dss</c> can only be used together with digest type
- <c>sha</c>.</p>
- <p>See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name>start() -> ok</name>
+ <name name="start" arity="0"/>
<fsummary> Equivalent to application:start(crypto). </fsummary>
<desc>
<p> Equivalent to application:start(crypto).</p>
</desc>
</func>
+
<func>
- <name>stop() -> ok</name>
+ <name name="stop" arity="0"/>
<fsummary> Equivalent to application:stop(crypto).</fsummary>
<desc>
<p> Equivalent to application:stop(crypto).</p>
@@ -788,23 +819,20 @@
</func>
<func>
- <name>strong_rand_bytes(N) -> binary()</name>
+ <name name="strong_rand_bytes" arity="1"/>
<fsummary>Generate a binary of random bytes</fsummary>
- <type>
- <v>N = integer()</v>
- </type>
<desc>
<p>Generates N bytes randomly uniform 0..255, and returns the
result in a binary. Uses a cryptographically secure prng seeded and
periodically mixed with operating system provided entropy. By default
this is the <c>RAND_bytes</c> method from OpenSSL.</p>
- <p>May throw exception <c>low_entropy</c> in case the random generator
+ <p>May raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".</p>
</desc>
</func>
<func>
- <name>rand_seed() -> rand:state()</name>
+ <name name="rand_seed" arity="0"/>
<fsummary>Strong random number generation plugin state</fsummary>
<desc>
<p>
@@ -820,7 +848,7 @@
<p>
When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
- may throw exception <c>low_entropy</c> in case the random generator
+ may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
</p>
<p><em>Example</em></p>
@@ -832,7 +860,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>rand_seed_s() -> rand:state()</name>
+ <name name="rand_seed_s" arity="0"/>
<fsummary>Strong random number generation plugin state</fsummary>
<desc>
<p>
@@ -846,7 +874,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<p>
When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
- may throw exception <c>low_entropy</c> in case the random generator
+ may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
</p>
<note>
@@ -885,7 +913,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<p>
When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
- may throw exception <c>low_entropy</c> in case the random generator
+ may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
</p>
<p>
@@ -930,7 +958,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<p>
When using the state object from this function the
<seealso marker="stdlib:rand">rand</seealso> functions using it
- may throw exception <c>low_entropy</c> in case the random generator
+ may raise exception <c>error:low_entropy</c> in case the random generator
failed due to lack of secure "randomness".
</p>
<p>
@@ -961,45 +989,36 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>stream_init(Type, Key) -> State</name>
+ <name name="stream_init" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Type = rc4 </v>
- <v>State = opaque() </v>
- <v>Key = iodata()</v>
- </type>
<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>stream_init(Type, Key, IVec) -> State</name>
+ <name name="stream_init" arity="3"/>
<fsummary></fsummary>
- <type>
- <v>Type = aes_ctr | chacha20</v>
- <v>State = opaque() </v>
- <v>Key = iodata()</v>
- <v>IVec = binary()</v>
- </type>
<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>stream_encrypt(State, PlainText) -> { NewState, CipherText}</name>
+ <name name="stream_encrypt" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>Text = iodata()</v>
- <v>CipherText = binary()</v>
- </type>
<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
@@ -1009,12 +1028,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>stream_decrypt(State, CipherText) -> { NewState, PlainText }</name>
+ <name name="stream_decrypt" arity="2"/>
<fsummary></fsummary>
- <type>
- <v>CipherText = iodata()</v>
- <v>PlainText = binary()</v>
- </type>
<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
@@ -1024,60 +1039,54 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>supports() -> AlgorithmList </name>
+ <name name="supports" arity="0"/>
<fsummary>Provide a list of available crypto algorithms.</fsummary>
- <type>
- <v> AlgorithmList = [{hashs, [hash_algorithms()]},
- {ciphers, [cipher_algorithms()]},
- {public_keys, [public_key_algorithms()]},
- {macs, [mac_algorithms()]}]
- </v>
- </type>
<desc>
<p> Can be used to determine which crypto algorithms that are supported
- by the underlying OpenSSL library</p>
+ by the underlying libcrypto library</p>
</desc>
</func>
<func>
- <name>ec_curves() -> EllipticCurveList </name>
+ <name name="ec_curves" arity="0"/>
<fsummary>Provide a list of available named elliptic curves.</fsummary>
- <type>
- <v>EllipticCurveList = [ec_named_curve()]</v>
- </type>
<desc>
<p>Can be used to determine which named elliptic curves are supported.</p>
</desc>
</func>
<func>
- <name>ec_curve(NamedCurve) -> EllipticCurve </name>
+ <name name="ec_curve" arity="1"/>
<fsummary>Get the defining parameters of a elliptic curve.</fsummary>
- <type>
- <v>NamedCurve = ec_named_curve()</v>
- <v>EllipticCurve = ec_explicit_curve()</v>
- </type>
<desc>
<p>Return the defining parameters of a elliptic curve.</p>
</desc>
</func>
- <func>
- <name>verify(Algorithm, DigestType, Msg, Signature, Key) -> boolean()</name>
- <name>verify(Algorithm, DigestType, Msg, Signature, Key, Options) -> boolean()</name>
+ <func>
+ <name name="sign" arity="4"/>
+ <name name="sign" arity="5"/>
+ <fsummary> Create digital signature.</fsummary>
+ <desc>
+ <p>Creates a digital signature.</p>
+ <p>The msg is either the binary "cleartext" data to be
+ signed or it is the hashed value of "cleartext" i.e. the
+ digest (plaintext).</p>
+ <p>Algorithm <c>dss</c> can only be used together with digest type
+ <c>sha</c>.</p>
+ <p>See also <seealso marker="public_key:public_key#sign-3">public_key:sign/3</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="verify" arity="5"/>
+ <name name="verify" arity="6"/>
<fsummary>Verifies a digital signature.</fsummary>
- <type>
- <v> Algorithm = rsa | dss | ecdsa </v>
- <v>Msg = binary() | {digest,binary()}</v>
- <d>The msg is either the binary "cleartext" data
- or it is the hashed value of "cleartext" i.e. the digest (plaintext).</d>
- <v>DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()</v>
- <v>Signature = binary()</v>
- <v>Key = rsa_public() | dss_public() | [ecdh_public(),ecdh_params()] | engine_key_ref()</v>
- <v>Options = sign_options()</v>
- </type>
<desc>
<p>Verifies a digital signature</p>
+ <p>The msg is either the binary "cleartext" data to be
+ signed or it is the hashed value of "cleartext" i.e. the
+ digest (plaintext).</p>
<p>Algorithm <c>dss</c> can only be used together with digest type
<c>sha</c>.</p>
@@ -1087,17 +1096,24 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<!-- Engine functions -->
<func>
- <name>engine_get_all_methods() -> Result</name>
+ <name name="privkey_to_pubkey" arity="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.
+ The key must be of the type indicated by the Type parameter.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="engine_get_all_methods" arity="0"/>
<fsummary>Return list of all possible engine methods</fsummary>
- <type>
- <v>Result = [EngineMethod::atom()]</v>
- </type>
<desc>
<p>
Returns a list of all possible engine methods.
</p>
<p>
- May throw exception notsup in case there is
+ May raise exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1108,13 +1124,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>engine_load(EngineId, PreCmds, PostCmds) -> Result</name>
+ <name name="engine_load" arity="3"/>
<fsummary>Dynamical load an encryption engine</fsummary>
- <type>
- <v>EngineId = unicode:chardata()</v>
- <v>PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}]</v>
- <v>Result = {ok, Engine::engine_ref()} | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Loads the OpenSSL engine given by <c>EngineId</c> if it is available and then returns ok and
@@ -1123,8 +1134,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
returned if the engine can't be loaded.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1135,22 +1146,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>engine_load(EngineId, PreCmds, PostCmds, EngineMethods) -> Result</name>
+ <name name="engine_load" arity="4"/>
<fsummary>Dynamical load an encryption engine</fsummary>
- <type>
- <v>EngineId = unicode:chardata()</v>
- <v>PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}]</v>
- <v>EngineMethods = [engine_method_type()]</v>
- <v>Result = {ok, Engine::engine_ref()} | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Loads the OpenSSL engine given by <c>EngineId</c> if it is available and then returns ok and
an engine handle. An error tuple is returned if the engine can't be loaded.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1161,20 +1166,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>engine_unload(Engine) -> Result</name>
+ <name name="engine_unload" arity="1"/>
<fsummary>Dynamical load an encryption engine</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Unloads the OpenSSL engine given by <c>Engine</c>.
An error tuple is returned if the engine can't be unloaded.
</p>
<p>
- The function throws a badarg if the parameter is in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameter is in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1185,20 +1186,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>engine_by_id(EngineId) -> Result</name>
+ <name name="engine_by_id" arity="1"/>
<fsummary>Get a reference to an already loaded engine</fsummary>
- <type>
- <v>EngineID = unicode:chardata()engine_ref()</v>
- <v>Result = {ok, Engine::engine_ref()} | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Get a reference to an already loaded engine with <c>EngineId</c>.
An error tuple is returned if the engine can't be unloaded.
</p>
<p>
- The function throws a badarg if the parameter is in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameter is in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1209,14 +1206,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> Result</name>
+ <name name="engine_ctrl_cmd_string" arity="3"/>
<fsummary>Sends ctrl commands to an OpenSSL engine</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>CmdName = unicode:chardata()</v>
- <v>CmdArg = unicode:chardata()</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Sends ctrl commands to the OpenSSL engine given by <c>Engine</c>.
@@ -1224,23 +1215,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<c>Optional</c> set to <c>false</c>.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> Result</name>
+ <name name="engine_ctrl_cmd_string" arity="4"/>
<fsummary>Sends ctrl commands to an OpenSSL engine</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>CmdName = unicode:chardata()</v>
- <v>CmdArg = unicode:chardata()</v>
- <v>Optional = boolean()</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Sends ctrl commands to the OpenSSL engine given by <c>Engine</c>.
@@ -1252,91 +1236,72 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
<c>false</c>.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>engine_add(Engine) -> Result</name>
+ <name name="engine_add" arity="1"/>
<fsummary>Add engine to OpenSSL internal list</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>Add the engine to OpenSSL's internal list.</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>engine_remove(Engine) -> Result</name>
+ <name name="engine_remove" arity="1"/>
<fsummary>Remove engine to OpenSSL internal list</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>Remove the engine from OpenSSL's internal list.</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>engine_get_id(Engine) -> EngineId</name>
+ <name name="engine_get_id" arity="1"/>
<fsummary>Fetch engine ID</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>EngineId = unicode:chardata()</v>
- </type>
<desc>
<p>Return the ID for the engine, or an empty binary if there is no id set.</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>engine_get_name(Engine) -> EngineName</name>
+ <name name="engine_get_name" arity="1"/>
<fsummary>Fetch engine name</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>EngineName = unicode:chardata()</v>
- </type>
<desc>
<p>Return the name (eg a description) for the engine, or an empty binary if there is no name set.</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>engine_list() -> Result</name>
+ <name name="engine_list" arity="0"/>
<fsummary>List the known engine ids</fsummary>
- <type>
- <v>Result = [EngineId::unicode:chardata()]</v>
- </type>
<desc>
<p>List the id's of all engines in OpenSSL's internal list.</p>
<p>
- It may also throw the exception notsup in case there is
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1344,20 +1309,15 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
in the User's Guide.
</p>
<p>
- May throw exception notsup in case engine functionality is not supported by the underlying
+ May raise exception <c>error:notsup</c> in case engine functionality is not supported by the underlying
OpenSSL implementation.
</p>
</desc>
</func>
<func>
- <name>ensure_engine_loaded(EngineId, LibPath) -> Result</name>
+ <name name="ensure_engine_loaded" arity="2"/>
<fsummary>Ensure encryption engine just loaded once</fsummary>
- <type>
- <v>EngineId = unicode:chardata()</v>
- <v>LibPath = unicode:chardata()</v>
- <v>Result = {ok, Engine::engine_ref()} | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Loads the OpenSSL engine given by <c>EngineId</c> and the path to the dynamic library
@@ -1366,8 +1326,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
returned if the engine can't be loaded.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1378,14 +1338,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> Result</name>
+ <name name="ensure_engine_loaded" arity="3"/>
<fsummary>Ensure encryption engine just loaded once</fsummary>
- <type>
- <v>EngineId = unicode:chardata()</v>
- <v>LibPath = unicode:chardata()</v>
- <v>EngineMethods = [engine_method_type()]</v>
- <v>Result = {ok, Engine::engine_ref()} | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Loads the OpenSSL engine given by <c>EngineId</c> and the path to the dynamic library
@@ -1395,8 +1349,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
An error tuple is returned if the engine can't be loaded.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1407,12 +1361,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>ensure_engine_unloaded(Engine) -> Result</name>
+ <name name="ensure_engine_unloaded" arity="1"/>
<fsummary>Unload an engine loaded with the ensure function</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Unloads an engine loaded with the <c>ensure_engine_loaded</c> function.
@@ -1422,8 +1372,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
returned if the engine can't be unloaded.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1434,13 +1384,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</func>
<func>
- <name>ensure_engine_unloaded(Engine, EngineMethods) -> Result</name>
+ <name name="ensure_engine_unloaded" arity="2"/>
<fsummary>Unload an engine loaded with the ensure function</fsummary>
- <type>
- <v>Engine = engine_ref()</v>
- <v>EngineMethods = [engine_method_type()]</v>
- <v>Result = ok | {error, Reason::term()}</v>
- </type>
<desc>
<p>
Unloads an engine loaded with the <c>ensure_engine_loaded</c> function.
@@ -1448,8 +1393,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
An error tuple is returned if the engine can't be unloaded.
</p>
<p>
- The function throws a badarg if the parameters are in wrong format.
- It may also throw the exception notsup in case there is
+ The function raises a <c>error:badarg</c> if the parameters are in wrong format.
+ It may also raise the exception <c>error:notsup</c> in case there is
no engine support in the underlying OpenSSL implementation.
</p>
<p>
@@ -1461,75 +1406,5 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[</pre>
</funcs>
- <!-- Maybe put this in the users guide -->
- <!-- <section> -->
- <!-- <title>DES in CBC mode</title> -->
- <!-- <p>The Data Encryption Standard (DES) defines an algorithm for -->
- <!-- encrypting and decrypting an 8 byte quantity using an 8 byte key -->
- <!-- (actually only 56 bits of the key is used). -->
- <!-- </p> -->
- <!-- <p>When it comes to encrypting and decrypting blocks that are -->
- <!-- multiples of 8 bytes various modes are defined (NIST SP -->
- <!-- 800-38A). One of those modes is the Cipher Block Chaining (CBC) -->
- <!-- mode, where the encryption of an 8 byte segment depend not only -->
- <!-- of the contents of the segment itself, but also on the result of -->
- <!-- encrypting the previous segment: the encryption of the previous -->
- <!-- segment becomes the initializing vector of the encryption of the -->
- <!-- current segment. -->
- <!-- </p> -->
- <!-- <p>Thus the encryption of every segment depends on the encryption -->
- <!-- key (which is secret) and the encryption of the previous -->
- <!-- segment, except the first segment which has to be provided with -->
- <!-- an initial initializing vector. That vector could be chosen at -->
- <!-- random, or be a counter of some kind. It does not have to be -->
- <!-- secret. -->
- <!-- </p> -->
- <!-- <p>The following example is drawn from the old FIPS 81 standard -->
- <!-- (replaced by NIST SP 800-38A), where both the plain text and the -->
- <!-- resulting cipher text is settled. The following code fragment -->
- <!-- returns `true'. -->
- <!-- </p> -->
- <!-- <pre><![CDATA[ -->
-
- <!-- Key = <<16#01,16#23,16#45,16#67,16#89,16#ab,16#cd,16#ef>>, -->
- <!-- IVec = <<16#12,16#34,16#56,16#78,16#90,16#ab,16#cd,16#ef>>, -->
- <!-- P = "Now is the time for all ", -->
- <!-- C = crypto:des_cbc_encrypt(Key, IVec, P), -->
- <!-- % Which is the same as -->
- <!-- P1 = "Now is t", P2 = "he time ", P3 = "for all ", -->
- <!-- C1 = crypto:des_cbc_encrypt(Key, IVec, P1), -->
- <!-- C2 = crypto:des_cbc_encrypt(Key, C1, P2), -->
- <!-- C3 = crypto:des_cbc_encrypt(Key, C2, P3), -->
-
- <!-- C = <<C1/binary, C2/binary, C3/binary>>, -->
- <!-- C = <<16#e5,16#c7,16#cd,16#de,16#87,16#2b,16#f2,16#7c, -->
- <!-- 16#43,16#e9,16#34,16#00,16#8c,16#38,16#9c,16#0f, -->
- <!-- 16#68,16#37,16#88,16#49,16#9a,16#7c,16#05,16#f6>>, -->
- <!-- <<"Now is the time for all ">> == -->
- <!-- crypto:des_cbc_decrypt(Key, IVec, C). -->
- <!-- ]]></pre> -->
- <!-- <p>The following is true for the DES CBC mode. For all -->
- <!-- decompositions <c>P1 ++ P2 = P</c> of a plain text message -->
- <!-- <c>P</c> (where the length of all quantities are multiples of 8 -->
- <!-- bytes), the encryption <c>C</c> of <c>P</c> is equal to <c>C1 ++ -->
- <!-- C2</c>, where <c>C1</c> is obtained by encrypting <c>P1</c> with -->
- <!-- <c>Key</c> and the initializing vector <c>IVec</c>, and where -->
- <!-- <c>C2</c> is obtained by encrypting <c>P2</c> with <c>Key</c> -->
- <!-- and the initializing vector <c>last8(C1)</c>, -->
- <!-- where <c>last(Binary)</c> denotes the last 8 bytes of the -->
- <!-- binary <c>Binary</c>. -->
- <!-- </p> -->
- <!-- <p>Similarly, for all decompositions <c>C1 ++ C2 = C</c> of a -->
- <!-- cipher text message <c>C</c> (where the length of all quantities -->
- <!-- are multiples of 8 bytes), the decryption <c>P</c> of <c>C</c> -->
- <!-- is equal to <c>P1 ++ P2</c>, where <c>P1</c> is obtained by -->
- <!-- decrypting <c>C1</c> with <c>Key</c> and the initializing vector -->
- <!-- <c>IVec</c>, and where <c>P2</c> is obtained by decrypting -->
- <!-- <c>C2</c> with <c>Key</c> and the initializing vector -->
- <!-- <c>last8(C1)</c>, where <c>last8(Binary)</c> is as above. -->
- <!-- </p> -->
- <!-- <p>For DES3 (which uses three 64 bit keys) the situation is the -->
- <!-- same. -->
- <!-- </p> -->
- <!-- </section> -->
+
</erlref>
diff --git a/lib/crypto/doc/src/engine_keys.xml b/lib/crypto/doc/src/engine_keys.xml
index 38714fed8a..4f7b0243fb 100644
--- a/lib/crypto/doc/src/engine_keys.xml
+++ b/lib/crypto/doc/src/engine_keys.xml
@@ -62,7 +62,7 @@
on the Engine loaded
</item>
<item>an Erlang map is constructed with the Engine reference, the key reference and possibly a key passphrase if
- needed by the Engine. See the <seealso marker="crypto:crypto#engine_key_ref_type">Reference Manual</seealso> for
+ needed by the Engine. See the <seealso marker="crypto:crypto#type-engine_key_ref">Reference Manual</seealso> for
details of the map.
</item>
</list>
diff --git a/lib/crypto/doc/src/specs.xml b/lib/crypto/doc/src/specs.xml
new file mode 100644
index 0000000000..66c79a906b
--- /dev/null
+++ b/lib/crypto/doc/src/specs.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<specs xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../specs/specs_crypto.xml"/>
+</specs>
diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml
index 0124121433..2dfc966609 100644
--- a/lib/crypto/doc/src/usersguide.xml
+++ b/lib/crypto/doc/src/usersguide.xml
@@ -50,4 +50,5 @@
<xi:include href="fips.xml"/>
<xi:include href="engine_load.xml"/>
<xi:include href="engine_keys.xml"/>
+ <xi:include href="algorithm_details.xml"/>
</part>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 17351d10ea..c64586897e 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -66,12 +66,31 @@
ensure_engine_unloaded/2
]).
+-export_type([ %% A minimum exported: only what public_key needs.
+ dh_private/0,
+ dh_public/0,
+ dss_digest_type/0,
+ ec_named_curve/0,
+ ecdsa_digest_type/0,
+ pk_encrypt_decrypt_opts/0,
+ pk_sign_verify_opts/0,
+ rsa_digest_type/0,
+ sha1/0,
+ sha2/0
+ ]).
+
-export_type([engine_ref/0,
key_id/0,
password/0
]).
-
+%%% Opaque types must be exported :(
+-export_type([
+ stream_state/0,
+ hmac_state/0,
+ hash_state/0
+ ]).
+
%% Private. For tests.
-export([packed_openssl_version/4, engine_methods_convert_to_bitmask/2, get_test_engine/0]).
@@ -83,16 +102,187 @@
%% Used by strong_rand_float/0
-define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53)
-%%-type ecdsa_digest_type() :: 'md5' | 'sha' | 'sha256' | 'sha384' | 'sha512'.
+
+%%% ===== BEGIN NEW TYPING ====
+
+%%% Basic
+-type key_integer() :: integer() | binary(). % Always binary() when used as return value
+
+%%% Keys
+-type rsa_public() :: [key_integer()] . % [E, N]
+-type rsa_private() :: [key_integer()] . % [E, N, D] | [E, N, D, P1, P2, E1, E2, C]
+-type rsa_params() :: {ModulusSizeInBits::integer(), PublicExponent::key_integer()} .
+
+-type dss_public() :: [key_integer()] . % [P, Q, G, Y]
+-type dss_private() :: [key_integer()] . % [P, Q, G, X]
+
+-type ecdsa_public() :: key_integer() .
+-type ecdsa_private() :: key_integer() .
+-type ecdsa_params() :: ec_named_curve() | edwards_curve() | ec_explicit_curve() .
+
+-type srp_public() :: key_integer() .
+-type srp_private() :: key_integer() .
+-type srp_gen_params() :: {user,srp_user_gen_params()} | {host,srp_host_gen_params()}.
+-type srp_comp_params() :: {user,srp_user_comp_params()} | {host,srp_host_comp_params()}.
+-type srp_user_gen_params() :: list(binary() | atom() | list()) .
+-type srp_host_gen_params() :: list(binary() | atom() | list()) .
+-type srp_user_comp_params() :: list(binary() | atom()) .
+-type srp_host_comp_params() :: list(binary() | atom()) .
+
+-type dh_public() :: key_integer() .
+-type dh_private() :: key_integer() .
+-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength]
+
+-type ecdh_public() :: key_integer() .
+-type ecdh_private() :: key_integer() .
+-type ecdh_params() :: ec_named_curve() | edwards_curve() | ec_explicit_curve() .
+
+
+%%% Curves
+
+-type ec_explicit_curve() :: {Field :: ec_field(),
+ Curve :: ec_curve(),
+ BasePoint :: binary(),
+ Order :: binary(),
+ CoFactor :: none | % FIXME: Really?
+ binary()
+ } .
+
+-type ec_curve() :: {A :: binary(),
+ B :: binary(),
+ Seed :: none | binary()
+ } .
+
+-type ec_field() :: ec_prime_field() | ec_characteristic_two_field() .
+
+-type ec_prime_field() :: {prime_field, Prime :: integer()} .
+-type ec_characteristic_two_field() :: {characteristic_two_field, M :: integer(), Basis :: ec_basis()} .
+
+-type ec_basis() :: {tpbasis, K :: non_neg_integer()}
+ | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()}
+ | onbasis .
+
+-type ec_named_curve() :: brainpoolP160r1
+ | brainpoolP160t1
+ | brainpoolP192r1
+ | brainpoolP192t1
+ | brainpoolP224r1
+ | brainpoolP224t1
+ | brainpoolP256r1
+ | brainpoolP256t1
+ | brainpoolP320r1
+ | brainpoolP320t1
+ | brainpoolP384r1
+ | brainpoolP384t1
+ | brainpoolP512r1
+ | brainpoolP512t1
+ | c2pnb163v1
+ | c2pnb163v2
+ | c2pnb163v3
+ | c2pnb176v1
+ | c2pnb208w1
+ | c2pnb272w1
+ | c2pnb304w1
+ | c2pnb368w1
+ | c2tnb191v1
+ | c2tnb191v2
+ | c2tnb191v3
+ | c2tnb239v1
+ | c2tnb239v2
+ | c2tnb239v3
+ | c2tnb359v1
+ | c2tnb431r1
+ | ipsec3
+ | ipsec4
+ | prime192v1
+ | prime192v2
+ | prime192v3
+ | prime239v1
+ | prime239v2
+ | prime239v3
+ | prime256v1
+ | secp112r1
+ | secp112r2
+ | secp128r1
+ | secp128r2
+ | secp160k1
+ | secp160r1
+ | secp160r2
+ | secp192k1
+ | secp192r1
+ | secp224k1
+ | secp224r1
+ | secp256k1
+ | secp256r1
+ | secp384r1
+ | secp521r1
+ | sect113r1
+ | sect113r2
+ | sect131r1
+ | sect131r2
+ | sect163k1
+ | sect163r1
+ | sect163r2
+ | sect193r1
+ | sect193r2
+ | sect233k1
+ | sect233r1
+ | sect239k1
+ | sect283k1
+ | sect283r1
+ | sect409k1
+ | sect409r1
+ | sect571k1
+ | sect571r1
+ | wtls1
+ | wtls10
+ | wtls11
+ | wtls12
+ | wtls3
+ | wtls4
+ | wtls5
+ | wtls6
+ | wtls7
+ | wtls8
+ | wtls9
+ .
+
+-type edwards_curve() :: x25519
+ | x448 .
+
+%%%
+-type block_cipher_with_iv() :: cbc_cipher()
+ | cfb_cipher()
+ | aes_cbc128
+ | aes_cbc256
+ | aes_ige256
+ | blowfish_ofb64
+ | des3_cbf % cfb misspelled
+ | des_ede3
+ | rc2_cbc .
+
+-type cbc_cipher() :: des_cbc | des3_cbc | aes_cbc | blowfish_cbc .
+-type aead_cipher() :: aes_gcm | chacha20_poly1305 .
+-type cfb_cipher() :: aes_cfb128 | aes_cfb8 | blowfish_cfb64 | des3_cfb | des_cfb .
+
+-type block_cipher_without_iv() :: ecb_cipher() .
+-type ecb_cipher() :: des_ecb | blowfish_ecb | aes_ecb .
+
+-type key() :: iodata().
+-type des3_key() :: [key()].
+
+%%%
+-type rsa_digest_type() :: sha1() | sha2() | md5 | ripemd160 .
+-type dss_digest_type() :: sha1() | sha2() .
+-type ecdsa_digest_type() :: sha1() | sha2() .
+
+-type sha1() :: sha .
+-type sha2() :: sha224 | sha256 | sha384 | sha512 .
+-type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 .
+
+-type compatibility_only_hash() :: md5 | md4 .
+
-type crypto_integer() :: binary() | integer().
-%%-type ec_named_curve() :: atom().
-%%-type ec_point() :: crypto_integer().
-%%-type ec_basis() :: {tpbasis, K :: non_neg_integer()} | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} | onbasis.
-%%-type ec_field() :: {prime_field, Prime :: integer()} | {characteristic_two_field, M :: integer(), Basis :: ec_basis()}.
-%%-type ec_prime() :: {A :: crypto_integer(), B :: crypto_integer(), Seed :: binary() | none}.
-%%-type ec_curve_spec() :: {Field :: ec_field(), Prime :: ec_prime(), Point :: crypto_integer(), Order :: integer(), CoFactor :: none | integer()}.
-%%-type ec_curve() :: ec_named_curve() | ec_curve_spec().
-%%-type ec_key() :: {Curve :: ec_curve(), PrivKey :: binary() | undefined, PubKey :: ec_point() | undefined}.
-compile(no_native).
-on_load(on_load/0).
@@ -108,14 +298,36 @@ nif_stub_error(Line) ->
%% Crypto app version history:
%% (no version): Driver implementation
%% 2.0 : NIF implementation, requires OTP R14
+
+%% When generating documentation from crypto.erl, the macro ?CRYPTO_VSN is not defined.
+%% That causes the doc generation to stop...
+-ifndef(CRYPTO_VSN).
+-define(CRYPTO_VSN, "??").
+-endif.
version() -> ?CRYPTO_VSN.
+-spec start() -> ok | {error, Reason::term()}.
start() ->
application:start(crypto).
+-spec stop() -> ok | {error, Reason::term()}.
stop() ->
application:stop(crypto).
+-spec supports() -> [Support]
+ when Support :: {hashs, Hashs}
+ | {ciphers, Ciphers}
+ | {public_keys, PKs}
+ | {macs, Macs}
+ | {curves, Curves},
+ Hashs :: [sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash()],
+ Ciphers :: [stream_cipher()
+ | block_cipher_with_iv() | block_cipher_without_iv()
+ | aead_cipher()
+ ],
+ PKs :: [rsa | dss | ecdsa | dh | ecdh | ec_gf2m],
+ Macs :: [hmac | cmac | poly1305],
+ Curves :: [ec_named_curve() | edwards_curve()].
supports()->
{Hashs, PubKeys, Ciphers, Macs, Curves} = algorithms(),
[{hashs, Hashs},
@@ -125,95 +337,163 @@ supports()->
{curves, Curves}
].
+-spec info_lib() -> [{Name,VerNum,VerStr}] when Name :: binary(),
+ VerNum :: integer(),
+ VerStr :: binary() .
info_lib() -> ?nif_stub.
-spec info_fips() -> not_supported | not_enabled | enabled.
info_fips() -> ?nif_stub.
--spec enable_fips_mode(boolean()) -> boolean().
-
+-spec enable_fips_mode(Enable) -> Result when Enable :: boolean(),
+ Result :: boolean().
enable_fips_mode(_) -> ?nif_stub.
--spec hash(_, iodata()) -> binary().
+%%%================================================================
+%%%
+%%% Hashing
+%%%
+%%%================================================================
-hash(Hash, Data0) ->
- Data = iolist_to_binary(Data0),
- MaxBytes = max_bytes(),
- hash(Hash, Data, erlang:byte_size(Data), MaxBytes).
+-define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash() ).
--spec hash_init('md5'|'md4'|'ripemd160'|
- 'sha'|'sha224'|'sha256'|'sha384'|'sha512'|
- 'sha3_224' | 'sha3_256' | 'sha3_384' | 'sha3_512') -> any().
+-spec hash(Type, Data) -> Digest when Type :: ?HASH_HASH_ALGORITHM,
+ Data :: iodata(),
+ Digest :: binary().
+hash(Type, Data) ->
+ Data1 = iolist_to_binary(Data),
+ MaxBytes = max_bytes(),
+ hash(Type, Data1, erlang:byte_size(Data1), MaxBytes).
-hash_init(Hash) ->
- notsup_to_error(hash_init_nif(Hash)).
+-opaque hash_state() :: reference().
--spec hash_update(_, iodata()) -> any().
+-spec hash_init(Type) -> State when Type :: ?HASH_HASH_ALGORITHM,
+ State :: hash_state().
+hash_init(Type) ->
+ notsup_to_error(hash_init_nif(Type)).
-hash_update(State, Data0) ->
- Data = iolist_to_binary(Data0),
+-spec hash_update(State, Data) -> NewState when State :: hash_state(),
+ NewState :: hash_state(),
+ Data :: iodata() .
+hash_update(Context, Data) ->
+ Data1 = iolist_to_binary(Data),
MaxBytes = max_bytes(),
- hash_update(State, Data, erlang:byte_size(Data), MaxBytes).
+ hash_update(Context, Data1, erlang:byte_size(Data1), MaxBytes).
--spec hash_final(_) -> binary().
+-spec hash_final(State) -> Digest when State :: hash_state(),
+ Digest :: binary().
+hash_final(Context) ->
+ notsup_to_error(hash_final_nif(Context)).
-hash_final(State) ->
- notsup_to_error(hash_final_nif(State)).
+%%%================================================================
+%%%
+%%% MACs (Message Authentication Codes)
+%%%
+%%%================================================================
+%%%---- HMAC
--spec hmac(_, iodata(), iodata()) -> binary().
--spec hmac(_, iodata(), iodata(), integer()) -> binary().
--spec hmac_init(atom(), iodata()) -> binary().
--spec hmac_update(binary(), iodata()) -> binary().
--spec hmac_final(binary()) -> binary().
--spec hmac_final_n(binary(), integer()) -> binary().
+-define(HMAC_HASH_ALGORITHM, sha1() | sha2() | sha3() | compatibility_only_hash()).
-hmac(Type, Key, Data0) ->
- Data = iolist_to_binary(Data0),
- hmac(Type, Key, Data, undefined, erlang:byte_size(Data), max_bytes()).
-hmac(Type, Key, Data0, MacSize) ->
- Data = iolist_to_binary(Data0),
- hmac(Type, Key, Data, MacSize, erlang:byte_size(Data), max_bytes()).
+%%%---- hmac/3,4
+
+-spec hmac(Type, Key, Data) ->
+ Mac when Type :: ?HMAC_HASH_ALGORITHM,
+ Key :: iodata(),
+ Data :: iodata(),
+ Mac :: binary() .
+hmac(Type, Key, Data) ->
+ Data1 = iolist_to_binary(Data),
+ hmac(Type, Key, Data1, undefined, erlang:byte_size(Data1), max_bytes()).
+
+-spec hmac(Type, Key, Data, MacLength) ->
+ Mac when Type :: ?HMAC_HASH_ALGORITHM,
+ Key :: iodata(),
+ Data :: iodata(),
+ MacLength :: integer(),
+ Mac :: binary() .
+hmac(Type, Key, Data, MacLength) ->
+ Data1 = iolist_to_binary(Data),
+ hmac(Type, Key, Data1, MacLength, erlang:byte_size(Data1), max_bytes()).
+
+%%%---- hmac_init, hamc_update, hmac_final
+
+-opaque hmac_state() :: binary().
+
+-spec hmac_init(Type, Key) ->
+ State when Type :: ?HMAC_HASH_ALGORITHM,
+ Key :: iodata(),
+ State :: hmac_state() .
hmac_init(Type, Key) ->
notsup_to_error(hmac_init_nif(Type, Key)).
+%%%---- hmac_update
+
+-spec hmac_update(State, Data) -> NewState when Data :: iodata(),
+ State :: hmac_state(),
+ NewState :: hmac_state().
hmac_update(State, Data0) ->
Data = iolist_to_binary(Data0),
hmac_update(State, Data, erlang:byte_size(Data), max_bytes()).
+%%%---- hmac_final
+
+-spec hmac_final(State) -> Mac when State :: hmac_state(),
+ Mac :: binary().
hmac_final(Context) ->
notsup_to_error(hmac_final_nif(Context)).
+
+-spec hmac_final_n(State, HashLen) -> Mac when State :: hmac_state(),
+ HashLen :: integer(),
+ Mac :: binary().
hmac_final_n(Context, HashLen) ->
notsup_to_error(hmac_final_nif(Context, HashLen)).
--spec cmac(_, iodata(), iodata()) -> binary().
--spec cmac(_, iodata(), iodata(), integer()) -> binary().
+%%%---- CMAC
+-define(CMAC_CIPHER_ALGORITHM, cbc_cipher() | cfb_cipher() | blowfish_cbc | des_ede3 | rc2_cbc ).
+
+-spec cmac(Type, Key, Data) ->
+ Mac when Type :: ?CMAC_CIPHER_ALGORITHM,
+ Key :: iodata(),
+ Data :: iodata(),
+ Mac :: binary().
cmac(Type, Key, Data) ->
notsup_to_error(cmac_nif(Type, Key, Data)).
-cmac(Type, Key, Data, MacSize) ->
- erlang:binary_part(cmac(Type, Key, Data), 0, MacSize).
--spec poly1305(iodata(), iodata()) -> binary().
+-spec cmac(Type, Key, Data, MacLength) ->
+ Mac when Type :: ?CMAC_CIPHER_ALGORITHM,
+ Key :: iodata(),
+ Data :: iodata(),
+ MacLength :: integer(),
+ Mac :: binary().
+cmac(Type, Key, Data, MacLength) ->
+ erlang:binary_part(cmac(Type, Key, Data), 0, MacLength).
+
+%%%---- POLY1305
+
+-spec poly1305(iodata(), iodata()) -> Mac when Mac :: binary().
poly1305(Key, Data) ->
poly1305_nif(Key, Data).
-%% Ecrypt/decrypt %%%
+%%%================================================================
+%%%
+%%% Encrypt/decrypt
+%%%
+%%%================================================================
+
+%%%---- Block ciphers
--spec block_encrypt(des_cbc | des_cfb |
- des3_cbc | des3_cbf | des3_cfb | des_ede3 |
- blowfish_cbc | blowfish_cfb64 | blowfish_ofb64 |
- aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | aes_ige256 |
- aes_cbc |
- rc2_cbc,
- Key::iodata(), Ivec::binary(), Data::iodata()) -> binary();
- (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata()}) -> {binary(), binary()};
- (aes_gcm, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata(), TagLength::1..16}) -> {binary(), binary()}.
+-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary();
+ (Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
+ {binary(), binary()};
+ (aes_gcm, Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata(), TagLength::1..16}) ->
+ {binary(), binary()}.
-block_encrypt(Type, Key, Ivec, Data) when Type =:= des_cbc;
+block_encrypt(Type, Key, Ivec, PlainText) when Type =:= des_cbc;
Type =:= des_cfb;
Type =:= blowfish_cbc;
Type =:= blowfish_cfb64;
@@ -224,34 +504,28 @@ block_encrypt(Type, Key, Ivec, Data) when Type =:= des_cbc;
Type =:= aes_cbc256;
Type =:= aes_cbc;
Type =:= rc2_cbc ->
- block_crypt_nif(Type, Key, Ivec, Data, true);
-block_encrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc;
+ block_crypt_nif(Type, Key, Ivec, PlainText, true);
+block_encrypt(Type, Key0, Ivec, PlainText) when Type =:= des3_cbc;
Type =:= des_ede3 ->
Key = check_des3_key(Key0),
- block_crypt_nif(des_ede3_cbc, Key, Ivec, Data, true);
-block_encrypt(des3_cbf, Key0, Ivec, Data) ->
+ block_crypt_nif(des_ede3_cbc, Key, Ivec, PlainText, true);
+block_encrypt(des3_cbf, Key0, Ivec, PlainText) -> % cfb misspelled
Key = check_des3_key(Key0),
- block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, true);
-block_encrypt(des3_cfb, Key0, Ivec, Data) ->
+ block_crypt_nif(des_ede3_cbf, Key, Ivec, PlainText, true);
+block_encrypt(des3_cfb, Key0, Ivec, PlainText) ->
Key = check_des3_key(Key0),
- block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, true);
-block_encrypt(aes_ige256, Key, Ivec, Data) ->
- notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, true));
-block_encrypt(aes_gcm, Key, Ivec, {AAD, Data}) ->
- aes_gcm_encrypt(Key, Ivec, AAD, Data);
-block_encrypt(aes_gcm, Key, Ivec, {AAD, Data, TagLength}) ->
- aes_gcm_encrypt(Key, Ivec, AAD, Data, TagLength);
-block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, Data}) ->
- chacha20_poly1305_encrypt(Key, Ivec, AAD, Data).
-
--spec block_decrypt(des_cbc | des_cfb |
- des3_cbc | des3_cbf | des3_cfb | des_ede3 |
- blowfish_cbc | blowfish_cfb64 | blowfish_ofb64 |
- aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | aes_ige256 |
- aes_cbc |
- rc2_cbc,
- Key::iodata(), Ivec::binary(), Data::iodata()) -> binary();
- (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(),
+ block_crypt_nif(des_ede3_cfb, Key, Ivec, PlainText, true);
+block_encrypt(aes_ige256, Key, Ivec, PlainText) ->
+ notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true));
+block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText}) ->
+ aes_gcm_encrypt(Key, Ivec, AAD, PlainText);
+block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText, TagLength}) ->
+ aes_gcm_encrypt(Key, Ivec, AAD, PlainText, TagLength);
+block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, PlainText}) ->
+ chacha20_poly1305_encrypt(Key, Ivec, AAD, PlainText).
+
+-spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) -> binary();
+ (Type::aead_cipher(), Key::iodata(), Ivec::binary(),
{AAD::binary(), Data::iodata(), Tag::binary()}) -> binary() | error.
block_decrypt(Type, Key, Ivec, Data) when Type =:= des_cbc;
Type =:= des_cfb;
@@ -269,7 +543,7 @@ block_decrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc;
Type =:= des_ede3 ->
Key = check_des3_key(Key0),
block_crypt_nif(des_ede3_cbc, Key, Ivec, Data, false);
-block_decrypt(des3_cbf, Key0, Ivec, Data) ->
+block_decrypt(des3_cbf, Key0, Ivec, Data) -> % cfb misspelled
Key = check_des3_key(Key0),
block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, false);
block_decrypt(des3_cfb, Key0, Ivec, Data) ->
@@ -282,18 +556,23 @@ block_decrypt(aes_gcm, Key, Ivec, {AAD, Data, Tag}) ->
block_decrypt(chacha20_poly1305, Key, Ivec, {AAD, Data, Tag}) ->
chacha20_poly1305_decrypt(Key, Ivec, AAD, Data, Tag).
--spec block_encrypt(des_ecb | blowfish_ecb | aes_ecb, Key::iodata(), Data::iodata()) -> binary().
-block_encrypt(Type, Key, Data) ->
- block_crypt_nif(Type, Key, Data, true).
--spec block_decrypt(des_ecb | blowfish_ecb | aes_ecb, Key::iodata(), Data::iodata()) -> binary().
+-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary().
+
+block_encrypt(Type, Key, PlainText) ->
+ block_crypt_nif(Type, Key, PlainText, true).
+
+
+-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary().
block_decrypt(Type, Key, Data) ->
block_crypt_nif(Type, Key, Data, false).
--spec next_iv(des_cbc | des3_cbc | aes_cbc | aes_ige, Data::iodata()) -> binary().
+-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige,
+ Data :: iodata(),
+ NextIVec :: binary().
next_iv(Type, Data) when is_binary(Data) ->
IVecSize = case Type of
des_cbc -> 8;
@@ -308,7 +587,9 @@ next_iv(Type, Data) when is_binary(Data) ->
next_iv(Type, Data) when is_list(Data) ->
next_iv(Type, list_to_binary(Data)).
--spec next_iv(des_cfb, Data::iodata(), Ivec::binary()) -> binary().
+-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(),
+ IVec :: binary(),
+ NextIVec :: binary().
next_iv(des_cfb, Data, IVec) ->
IVecAndData = list_to_binary([IVec, Data]),
@@ -317,41 +598,57 @@ next_iv(des_cfb, Data, IVec) ->
next_iv(Type, Data, _Ivec) ->
next_iv(Type, Data).
+%%%---- Stream ciphers
+
+-opaque stream_state() :: {stream_cipher(), reference()}.
+
+-type stream_cipher() :: rc4 | aes_ctr | chacha20 .
+
+-spec stream_init(Type, Key, IVec) -> State when Type :: aes_ctr | chacha20,
+ Key :: iodata(),
+ IVec :: binary(),
+ State :: stream_state() .
stream_init(aes_ctr, Key, Ivec) ->
{aes_ctr, aes_ctr_stream_init(Key, Ivec)};
stream_init(chacha20, Key, Ivec) ->
{chacha20, chacha20_stream_init(Key,Ivec)}.
+-spec stream_init(Type, Key) -> State when Type :: rc4,
+ Key :: iodata(),
+ State :: stream_state() .
stream_init(rc4, Key) ->
{rc4, notsup_to_error(rc4_set_key(Key))}.
+-spec stream_encrypt(State, PlainText) -> {NewState, CipherText}
+ when State :: stream_state(),
+ PlainText :: iodata(),
+ NewState :: stream_state(),
+ CipherText :: iodata() .
stream_encrypt(State, Data0) ->
Data = iolist_to_binary(Data0),
MaxByts = max_bytes(),
stream_crypt(fun do_stream_encrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []).
+-spec stream_decrypt(State, CipherText) -> {NewState, PlainText}
+ when State :: stream_state(),
+ CipherText :: iodata(),
+ NewState :: stream_state(),
+ PlainText :: iodata() .
stream_decrypt(State, Data0) ->
Data = iolist_to_binary(Data0),
MaxByts = max_bytes(),
stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []).
-%%
-%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
-%%
+
+%%%================================================================
+%%%
+%%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
+%%%
+%%%================================================================
-type rand_cache_seed() ::
nonempty_improper_list(non_neg_integer(), binary()).
--spec strong_rand_bytes(non_neg_integer()) -> binary().
--spec rand_seed() -> rand:state().
--spec rand_seed_s() -> rand:state().
--spec rand_seed_alg(Alg :: atom()) ->
- {rand:alg_handler(),
- atom() | rand_cache_seed()}.
--spec rand_seed_alg_s(Alg :: atom()) ->
- {rand:alg_handler(),
- atom() | rand_cache_seed()}.
--spec rand_uniform(crypto_integer(), crypto_integer()) ->
- crypto_integer().
+-spec strong_rand_bytes(N::non_neg_integer()) -> binary().
strong_rand_bytes(Bytes) ->
case strong_rand_bytes_nif(Bytes) of
false -> erlang:error(low_entropy);
@@ -360,16 +657,24 @@ strong_rand_bytes(Bytes) ->
strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
+-spec rand_seed() -> rand:state().
rand_seed() ->
rand:seed(rand_seed_s()).
+-spec rand_seed_s() -> rand:state().
rand_seed_s() ->
rand_seed_alg_s(?MODULE).
+-spec rand_seed_alg(Alg :: atom()) ->
+ {rand:alg_handler(),
+ atom() | rand_cache_seed()}.
rand_seed_alg(Alg) ->
rand:seed(rand_seed_alg_s(Alg)).
-define(CRYPTO_CACHE_BITS, 56).
+-spec rand_seed_alg_s(Alg :: atom()) ->
+ {rand:alg_handler(),
+ atom() | rand_cache_seed()}.
rand_seed_alg_s(?MODULE) ->
{#{ type => ?MODULE,
bits => 64,
@@ -427,7 +732,9 @@ strong_rand_float() ->
WholeRange = strong_rand_range(1 bsl 53),
?HALF_DBL_EPSILON * bytes_to_integer(WholeRange).
-rand_uniform(From,To) when is_binary(From), is_binary(To) ->
+-spec rand_uniform(crypto_integer(), crypto_integer()) ->
+ crypto_integer().
+rand_uniform(From, To) when is_binary(From), is_binary(To) ->
case rand_uniform_nif(From,To) of
<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
<<(Len + 1):32/integer, 0, MSB, Rest/binary>>;
@@ -462,116 +769,228 @@ rand_seed(Seed) when is_binary(Seed) ->
rand_seed_nif(_Seed) -> ?nif_stub.
--spec mod_pow(binary()|integer(), binary()|integer(), binary()|integer()) -> binary() | error.
-mod_pow(Base, Exponent, Prime) ->
- case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of
- <<0>> -> error;
- R -> R
- end.
+%%%================================================================
+%%%
+%%% Sign/verify
+%%%
+%%%================================================================
+-type pk_sign_verify_algs() :: rsa | dss | ecdsa .
-verify(Algorithm, Type, Data, Signature, Key) ->
- verify(Algorithm, Type, Data, Signature, Key, []).
+-type pk_sign_verify_opts() :: [ rsa_sign_verify_opt() ] .
+
+-type rsa_sign_verify_opt() :: {rsa_padding, rsa_sign_verify_padding()}
+ | {rsa_pss_saltlen, integer()} .
+
+-type rsa_sign_verify_padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding
+ | rsa_x931_padding | rsa_no_padding
+ .
-%% Backwards compatible
-verify(Algorithm = dss, none, Digest, Signature, Key, Options) ->
- verify(Algorithm, sha, {digest, Digest}, Signature, Key, Options);
-verify(Algorithm, Type, Data, Signature, Key, Options) ->
- case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of
- notsup -> erlang:error(notsup);
- Boolean -> Boolean
- end.
+%%%----------------------------------------------------------------
+%%% Sign
+
+-spec sign(Algorithm, DigestType, Msg, Key)
+ -> Signature
+ when Algorithm :: pk_sign_verify_algs(),
+ DigestType :: rsa_digest_type()
+ | dss_digest_type()
+ | ecdsa_digest_type(),
+ Msg :: binary() | {digest,binary()},
+ Key :: rsa_private()
+ | dss_private()
+ | [ecdsa_private()|ecdsa_params()]
+ | engine_key_ref(),
+ Signature :: binary() .
sign(Algorithm, Type, Data, Key) ->
sign(Algorithm, Type, Data, Key, []).
-%% Backwards compatible
-sign(Algorithm = dss, none, Digest, Key, Options) ->
- sign(Algorithm, sha, {digest, Digest}, Key, Options);
-sign(Algorithm, Type, Data, Key, Options) ->
+
+-spec sign(Algorithm, DigestType, Msg, Key, Options)
+ -> Signature
+ when Algorithm :: pk_sign_verify_algs(),
+ DigestType :: rsa_digest_type()
+ | dss_digest_type()
+ | ecdsa_digest_type()
+ | none,
+ Msg :: binary() | {digest,binary()},
+ Key :: rsa_private()
+ | dss_private()
+ | [ecdsa_private() | ecdsa_params()]
+ | engine_key_ref(),
+ Options :: pk_sign_verify_opts(),
+ Signature :: binary() .
+
+sign(Algorithm0, Type0, Data, Key, Options) ->
+ {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
case pkey_sign_nif(Algorithm, Type, Data, format_pkey(Algorithm, Key), Options) of
error -> erlang:error(badkey, [Algorithm, Type, Data, Key, Options]);
notsup -> erlang:error(notsup);
Signature -> Signature
end.
+pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub.
+%%%----------------------------------------------------------------
+%%% Verify
+
+-spec verify(Algorithm, DigestType, Msg, Signature, Key)
+ -> Result
+ when Algorithm :: pk_sign_verify_algs(),
+ DigestType :: rsa_digest_type()
+ | dss_digest_type()
+ | ecdsa_digest_type(),
+ Msg :: binary() | {digest,binary()},
+ Signature :: binary(),
+ Key :: rsa_private()
+ | dss_private()
+ | [ecdsa_private() | ecdsa_params()]
+ | engine_key_ref(),
+ Result :: boolean().
--type key_id() :: string() | binary() .
--type password() :: string() | binary() .
-
--type engine_key_ref() :: #{engine := engine_ref(),
- key_id := key_id(),
- password => password(),
- term() => term()
- }.
-
--type pk_algs() :: rsa | ecdsa | dss .
--type pk_key() :: engine_key_ref() | [integer() | binary()] .
--type pk_opt() :: list() | rsa_padding() .
-
--spec public_encrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary().
--spec public_decrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary().
--spec private_encrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary().
--spec private_decrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary().
+verify(Algorithm, Type, Data, Signature, Key) ->
+ verify(Algorithm, Type, Data, Signature, Key, []).
-public_encrypt(Algorithm, In, Key, Options) when is_list(Options) ->
- case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, false, true) of
- error -> erlang:error(encrypt_failed, [Algorithm, In, Key, Options]);
+-spec verify(Algorithm, DigestType, Msg, Signature, Key, Options)
+ -> Result
+ when Algorithm :: pk_sign_verify_algs(),
+ DigestType :: rsa_digest_type()
+ | dss_digest_type()
+ | ecdsa_digest_type(),
+ Msg :: binary() | {digest,binary()},
+ Signature :: binary(),
+ Key :: rsa_public()
+ | dss_public()
+ | [ecdsa_public() | ecdsa_params()]
+ | engine_key_ref(),
+ Options :: pk_sign_verify_opts(),
+ Result :: boolean().
+
+verify(Algorithm0, Type0, Data, Signature, Key, Options) ->
+ {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
+ case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of
notsup -> erlang:error(notsup);
- Out -> Out
- end;
-%% Backwards compatible
-public_encrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) ->
- public_encrypt(Algorithm, In, Key, [{rsa_padding, Padding}]).
+ Boolean -> Boolean
+ end.
-private_decrypt(Algorithm, In, Key, Options) when is_list(Options) ->
- case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, true, false) of
- error -> erlang:error(decrypt_failed, [Algorithm, In, Key, Options]);
- notsup -> erlang:error(notsup);
- Out -> Out
- end;
-%% Backwards compatible
-private_decrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) ->
- private_decrypt(Algorithm, In, Key, [{rsa_padding, Padding}]).
+pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub.
-private_encrypt(Algorithm, In, Key, Options) when is_list(Options) ->
- case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, true, true) of
- error -> erlang:error(encrypt_failed, [Algorithm, In, Key, Options]);
- notsup -> erlang:error(notsup);
- Out -> Out
- end;
-%% Backwards compatible
-private_encrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) ->
- private_encrypt(Algorithm, In, Key, [{rsa_padding, Padding}]).
+%% Backwards compatible:
+sign_verify_compatibility(dss, none, Digest) ->
+ {sha, {digest, Digest}};
+sign_verify_compatibility(Algorithm0, Type0, _Digest) ->
+ {Algorithm0, Type0}.
-public_decrypt(Algorithm, In, Key, Options) when is_list(Options) ->
- case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, false, false) of
- error -> erlang:error(decrypt_failed, [Algorithm, In, Key, Options]);
+%%%================================================================
+%%%
+%%% Public/private encrypt/decrypt
+%%%
+%%% Only rsa works so far (although ecdsa | dss should do it)
+%%%================================================================
+-type pk_encrypt_decrypt_algs() :: rsa .
+
+-type pk_encrypt_decrypt_opts() :: [rsa_opt()] | rsa_compat_opts().
+
+-type rsa_compat_opts() :: [{rsa_pad, rsa_padding()}]
+ | rsa_padding() .
+
+-type rsa_padding() :: rsa_pkcs1_padding
+ | rsa_pkcs1_oaep_padding
+ | rsa_sslv23_padding
+ | rsa_x931_padding
+ | rsa_no_padding.
+
+-type rsa_opt() :: {rsa_padding, rsa_padding()}
+ | {signature_md, atom()}
+ | {rsa_mgf1_md, sha}
+ | {rsa_oaep_label, binary()}
+ | {rsa_oaep_md, sha} .
+
+%%%---- Encrypt with public key
+
+-spec public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
+ CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
+ PlainText :: binary(),
+ PublicKey :: rsa_public() | engine_key_ref(),
+ Options :: pk_encrypt_decrypt_opts(),
+ CipherText :: binary().
+public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
+ pkey_crypt(Algorithm, PlainText, PublicKey, Options, false, true).
+
+%%%---- Decrypt with private key
+
+-spec private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
+ PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
+ CipherText :: binary(),
+ PrivateKey :: rsa_private() | engine_key_ref(),
+ Options :: pk_encrypt_decrypt_opts(),
+ PlainText :: binary() .
+private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
+ pkey_crypt(Algorithm, CipherText, PrivateKey, Options, true, false).
+
+%%%---- Encrypt with private key
+
+-spec private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
+ CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
+ PlainText :: binary(),
+ PrivateKey :: rsa_private() | engine_key_ref(),
+ Options :: pk_encrypt_decrypt_opts(),
+ CipherText :: binary().
+private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
+ pkey_crypt(Algorithm, PlainText, PrivateKey, Options, true, true).
+
+%%%---- Decrypt with public key
+
+-spec public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
+ PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
+ CipherText :: binary(),
+ PublicKey :: rsa_public() | engine_key_ref(),
+ Options :: pk_encrypt_decrypt_opts(),
+ PlainText :: binary() .
+public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
+ pkey_crypt(Algorithm, CipherText, PublicKey, Options, false, false).
+
+%%%---- Call the nif, but fix a compatibility issue first
+
+%% Backwards compatible (rsa_pad -> rsa_padding is handled by the pkey_crypt_nif):
+pkey_crypt(rsa, Text, Key, Padding, PubPriv, EncDec) when is_atom(Padding) ->
+ pkey_crypt(rsa, Text, Key, [{rsa_padding, Padding}], PubPriv, EncDec);
+
+pkey_crypt(Alg, Text, Key, Options, PubPriv, EncDec) ->
+ case pkey_crypt_nif(Alg, Text, format_pkey(Alg,Key), Options, PubPriv, EncDec) of
+ error when EncDec==true -> erlang:error(encrypt_failed, [Alg, Text, Key, Options]);
+ error when EncDec==false -> erlang:error(decrypt_failed, [Alg, Text, Key, Options]);
notsup -> erlang:error(notsup);
Out -> Out
- end;
-%% Backwards compatible
-public_decrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) ->
- public_decrypt(Algorithm, In, Key, [{rsa_padding, Padding}]).
-
-
-%%
-%% XOR - xor to iolists and return a binary
-%% NB doesn't check that they are the same size, just concatenates
-%% them and sends them to the driver
-%%
--spec exor(iodata(), iodata()) -> binary().
+ end.
-exor(Bin1, Bin2) ->
- Data1 = iolist_to_binary(Bin1),
- Data2 = iolist_to_binary(Bin2),
- MaxBytes = max_bytes(),
- exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []).
+pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub.
+%%%================================================================
+%%%
+%%%
+%%%
+%%%================================================================
+
+-spec generate_key(Type, Params)
+ -> {PublicKey, PrivKeyOut}
+ when Type :: dh | ecdh | rsa | srp,
+ PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
+ PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
+ Params :: dh_params() | ecdh_params() | rsa_params() | srp_gen_params()
+ .
generate_key(Type, Params) ->
generate_key(Type, Params, undefined).
+-spec generate_key(Type, Params, PrivKeyIn)
+ -> {PublicKey, PrivKeyOut}
+ when Type :: dh | ecdh | rsa | srp,
+ PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
+ PrivKeyIn :: undefined | dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
+ PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
+ Params :: dh_params() | ecdh_params() | rsa_params() | srp_comp_params()
+ .
+
generate_key(dh, DHParameters0, PrivateKey) ->
{DHParameters, Len} =
case DHParameters0 of
@@ -618,6 +1037,14 @@ generate_key(ecdh, Curve, PrivKey) ->
evp_generate_key_nif(_Curve) -> ?nif_stub.
+-spec compute_key(Type, OthersPublicKey, MyPrivateKey, Params)
+ -> SharedSecret
+ when Type :: dh | ecdh | srp,
+ SharedSecret :: binary(),
+ OthersPublicKey :: dh_public() | ecdh_public() | srp_public(),
+ MyPrivateKey :: dh_private() | ecdh_private() | {srp_public(),srp_private()},
+ Params :: dh_params() | ecdh_params() | srp_comp_params()
+ .
compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
@@ -670,9 +1097,59 @@ compute_key(ecdh, Others, My, Curve) ->
evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub.
-%%======================================================================
-%% Engine functions
-%%======================================================================
+
+%%%================================================================
+%%%
+%%% XOR - xor to iolists and return a binary
+%%% NB doesn't check that they are the same size, just concatenates
+%%% them and sends them to the driver
+%%%
+%%%================================================================
+
+-spec exor(iodata(), iodata()) -> binary().
+
+exor(Bin1, Bin2) ->
+ Data1 = iolist_to_binary(Bin1),
+ Data2 = iolist_to_binary(Bin2),
+ MaxBytes = max_bytes(),
+ exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []).
+
+
+%%%================================================================
+%%%
+%%% Exponentiation modulo
+%%%
+%%%================================================================
+
+-spec mod_pow(N, P, M) -> Result when N :: binary() | integer(),
+ P :: binary() | integer(),
+ M :: binary() | integer(),
+ Result :: binary() | error .
+mod_pow(Base, Exponent, Prime) ->
+ case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of
+ <<0>> -> error;
+ R -> R
+ end.
+
+%%%======================================================================
+%%%
+%%% Engine functions
+%%%
+%%%======================================================================
+
+%%%---- Refering to keys stored in an engine:
+-type key_id() :: string() | binary() .
+-type password() :: string() | binary() .
+
+-type engine_key_ref() :: #{engine := engine_ref(),
+ key_id := key_id(),
+ password => password(),
+ term() => term()
+ }.
+
+%%%---- Commands:
+-type engine_cmnd() :: {unicode:chardata(), unicode:chardata()}.
+
%%----------------------------------------------------------------------
%% Function: engine_get_all_methods/0
%%----------------------------------------------------------------------
@@ -684,18 +1161,18 @@ evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub.
-type engine_ref() :: term().
--spec engine_get_all_methods() ->
- [engine_method_type()].
+-spec engine_get_all_methods() -> Result when Result :: [engine_method_type()].
engine_get_all_methods() ->
notsup_to_error(engine_get_all_methods_nif()).
%%----------------------------------------------------------------------
%% Function: engine_load/3
%%----------------------------------------------------------------------
--spec engine_load(EngineId::unicode:chardata(),
- PreCmds::[{unicode:chardata(), unicode:chardata()}],
- PostCmds::[{unicode:chardata(), unicode:chardata()}]) ->
- {ok, Engine::engine_ref()} | {error, Reason::term()}.
+-spec engine_load(EngineId, PreCmds, PostCmds) ->
+ Result when EngineId::unicode:chardata(),
+ PreCmds::[engine_cmnd()],
+ PostCmds::[engine_cmnd()],
+ Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds),
is_list(PostCmds) ->
engine_load(EngineId, PreCmds, PostCmds, engine_get_all_methods()).
@@ -703,11 +1180,12 @@ engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds),
%%----------------------------------------------------------------------
%% Function: engine_load/4
%%----------------------------------------------------------------------
--spec engine_load(EngineId::unicode:chardata(),
- PreCmds::[{unicode:chardata(), unicode:chardata()}],
- PostCmds::[{unicode:chardata(), unicode:chardata()}],
- EngineMethods::[engine_method_type()]) ->
- {ok, Engine::term()} | {error, Reason::term()}.
+-spec engine_load(EngineId, PreCmds, PostCmds, EngineMethods) ->
+ Result when EngineId::unicode:chardata(),
+ PreCmds::[engine_cmnd()],
+ PostCmds::[engine_cmnd()],
+ EngineMethods::[engine_method_type()],
+ Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
engine_load(EngineId, PreCmds, PostCmds, EngineMethods) when is_list(PreCmds),
is_list(PostCmds) ->
try
@@ -752,13 +1230,14 @@ engine_load_2(Engine, PostCmds, EngineMethods) ->
%%----------------------------------------------------------------------
%% Function: engine_unload/1
%%----------------------------------------------------------------------
--spec engine_unload(Engine::term()) ->
- ok | {error, Reason::term()}.
+-spec engine_unload(Engine) -> Result when Engine :: engine_ref(),
+ Result :: ok | {error, Reason::term()}.
engine_unload(Engine) ->
engine_unload(Engine, engine_get_all_methods()).
--spec engine_unload(Engine::term(), EngineMethods::[engine_method_type()]) ->
- ok | {error, Reason::term()}.
+-spec engine_unload(Engine, EngineMethods) -> Result when Engine :: engine_ref(),
+ EngineMethods :: [engine_method_type()],
+ Result :: ok | {error, Reason::term()}.
engine_unload(Engine, EngineMethods) ->
try
[ok = engine_nif_wrapper(engine_unregister_nif(Engine, engine_method_atom_to_int(Method))) ||
@@ -775,6 +1254,8 @@ engine_unload(Engine, EngineMethods) ->
%%----------------------------------------------------------------------
%% Function: engine_by_id/1
%%----------------------------------------------------------------------
+-spec engine_by_id(EngineId) -> Result when EngineId :: unicode:chardata(),
+ Result :: {ok, Engine::engine_ref()} | {error, Reason::term()} .
engine_by_id(EngineId) ->
try
notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)))
@@ -786,32 +1267,39 @@ engine_by_id(EngineId) ->
%%----------------------------------------------------------------------
%% Function: engine_add/1
%%----------------------------------------------------------------------
+-spec engine_add(Engine) -> Result when Engine :: engine_ref(),
+ Result :: ok | {error, Reason::term()} .
engine_add(Engine) ->
notsup_to_error(engine_add_nif(Engine)).
%%----------------------------------------------------------------------
%% Function: engine_remove/1
%%----------------------------------------------------------------------
+-spec engine_remove(Engine) -> Result when Engine :: engine_ref(),
+ Result :: ok | {error, Reason::term()} .
engine_remove(Engine) ->
notsup_to_error(engine_remove_nif(Engine)).
%%----------------------------------------------------------------------
%% Function: engine_get_id/1
%%----------------------------------------------------------------------
+-spec engine_get_id(Engine) -> EngineId when Engine :: engine_ref(),
+ EngineId :: unicode:chardata().
engine_get_id(Engine) ->
notsup_to_error(engine_get_id_nif(Engine)).
%%----------------------------------------------------------------------
%% Function: engine_get_name/1
%%----------------------------------------------------------------------
+-spec engine_get_name(Engine) -> EngineName when Engine :: engine_ref(),
+ EngineName :: unicode:chardata().
engine_get_name(Engine) ->
notsup_to_error(engine_get_name_nif(Engine)).
%%----------------------------------------------------------------------
%% Function: engine_list/0
%%----------------------------------------------------------------------
--spec engine_list() ->
- [EngineId::binary()].
+-spec engine_list() -> Result when Result :: [EngineId::unicode:chardata()].
engine_list() ->
case notsup_to_error(engine_get_first_nif()) of
{ok, <<>>} ->
@@ -841,21 +1329,23 @@ engine_list(Engine0, IdList) ->
%%----------------------------------------------------------------------
%% Function: engine_ctrl_cmd_string/3
%%----------------------------------------------------------------------
--spec engine_ctrl_cmd_string(Engine::term(),
- CmdName::unicode:chardata(),
- CmdArg::unicode:chardata()) ->
- ok | {error, Reason::term()}.
+-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
+ Result when Engine::term(),
+ CmdName::unicode:chardata(),
+ CmdArg::unicode:chardata(),
+ Result :: ok | {error, Reason::term()}.
engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
engine_ctrl_cmd_string(Engine, CmdName, CmdArg, false).
%%----------------------------------------------------------------------
%% Function: engine_ctrl_cmd_string/4
%%----------------------------------------------------------------------
--spec engine_ctrl_cmd_string(Engine::term(),
- CmdName::unicode:chardata(),
- CmdArg::unicode:chardata(),
- Optional::boolean()) ->
- ok | {error, Reason::term()}.
+-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
+ Result when Engine::term(),
+ CmdName::unicode:chardata(),
+ CmdArg::unicode:chardata(),
+ Optional::boolean(),
+ Result :: ok | {error, Reason::term()}.
engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
case engine_ctrl_cmd_strings_nif(Engine,
ensure_bin_cmds([{CmdName, CmdArg}]),
@@ -872,6 +1362,10 @@ engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
%% Function: ensure_engine_loaded/2
%% Special version of load that only uses dynamic engine to load
%%----------------------------------------------------------------------
+-spec ensure_engine_loaded(EngineId, LibPath) ->
+ Result when EngineId :: unicode:chardata(),
+ LibPath :: unicode:chardata(),
+ Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
ensure_engine_loaded(EngineId, LibPath) ->
ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()).
@@ -879,6 +1373,11 @@ ensure_engine_loaded(EngineId, LibPath) ->
%% Function: ensure_engine_loaded/3
%% Special version of load that only uses dynamic engine to load
%%----------------------------------------------------------------------
+-spec ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
+ Result when EngineId :: unicode:chardata(),
+ LibPath :: unicode:chardata(),
+ EngineMethods :: [engine_method_type()],
+ Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
try
List = crypto:engine_list(),
@@ -930,12 +1429,18 @@ ensure_engine_loaded_2(Engine, Methods) ->
%%----------------------------------------------------------------------
%% Function: ensure_engine_unloaded/1
%%----------------------------------------------------------------------
+-spec ensure_engine_unloaded(Engine) -> Result when Engine :: engine_ref(),
+ Result :: ok | {error, Reason::term()}.
ensure_engine_unloaded(Engine) ->
ensure_engine_unloaded(Engine, engine_get_all_methods()).
%%----------------------------------------------------------------------
%% Function: ensure_engine_unloaded/2
%%----------------------------------------------------------------------
+-spec ensure_engine_unloaded(Engine, EngineMethods) ->
+ Result when Engine :: engine_ref(),
+ EngineMethods :: [engine_method_type()],
+ Result :: ok | {error, Reason::term()}.
ensure_engine_unloaded(Engine, EngineMethods) ->
case engine_remove(Engine) of
ok ->
@@ -1010,9 +1515,13 @@ path2bin(Path) when is_list(Path) ->
Bin
end.
-%%--------------------------------------------------------------------
+%%%================================================================
+%%%================================================================
+%%%
%%% Internal functions
-%%--------------------------------------------------------------------
+%%%
+%%%================================================================
+
max_bytes() ->
?MAX_BYTES_TO_NIF.
@@ -1151,14 +1660,6 @@ do_stream_decrypt({chacha20, State0}, Data) ->
%%
%% AES - in counter mode (CTR) with state maintained for multi-call streaming
%%
--type ctr_state() :: { iodata(), binary(), binary(), integer() } | binary().
-
--spec aes_ctr_stream_init(iodata(), binary()) -> ctr_state().
--spec aes_ctr_stream_encrypt(ctr_state(), binary()) ->
- { ctr_state(), binary() }.
--spec aes_ctr_stream_decrypt(ctr_state(), binary()) ->
- { ctr_state(), binary() }.
-
aes_ctr_stream_init(_Key, _IVec) -> ?nif_stub.
aes_ctr_stream_encrypt(_State, _Data) -> ?nif_stub.
aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub.
@@ -1172,11 +1673,6 @@ rc4_encrypt_with_state(_State, _Data) -> ?nif_stub.
%%
%% CHACHA20 - stream cipher
%%
--type chacha20_state() :: term().
--spec chacha20_stream_init(iodata(), binary()) -> chacha20_state().
--spec chacha20_stream_encrypt(chacha20_state(), binary()) -> {chacha20_state(), binary()}.
--spec chacha20_stream_decrypt(chacha20_state(), binary()) -> {chacha20_state(), binary()}.
-
chacha20_stream_init(_Key, _IVec) -> ?nif_stub.
chacha20_stream_encrypt(_State, _Data) -> ?nif_stub.
chacha20_stream_decrypt(_State, _Data) -> ?nif_stub.
@@ -1247,11 +1743,6 @@ srp_user_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?
srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub.
-%% Digital signatures --------------------------------------------------------------------
-
-pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub.
-pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub.
-
%% Public Keys --------------------------------------------------------------------
%% RSA Rivest-Shamir-Adleman functions
%%
@@ -1273,13 +1764,20 @@ ec_key_generate(_Curve, _Key) -> ?nif_stub.
ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.
+-spec ec_curves() -> [EllipticCurve] when EllipticCurve :: ec_named_curve() | edwards_curve() .
+
ec_curves() ->
crypto_ec_curves:curves().
+-spec ec_curve(CurveName) -> ExplicitCurve when CurveName :: ec_named_curve(),
+ ExplicitCurve :: ec_explicit_curve() .
ec_curve(X) ->
crypto_ec_curves:curve(X).
+-spec privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey when Type :: rsa | dss,
+ EnginePrivateKeyRef :: engine_key_ref(),
+ PublicKey :: rsa_public() | dss_public() .
privkey_to_pubkey(Alg, EngineMap) when Alg == rsa; Alg == dss; Alg == ecdsa ->
try privkey_to_pubkey_nif(Alg, format_pkey(Alg,EngineMap))
of
@@ -1305,10 +1803,16 @@ term_to_nif_prime({prime_field, Prime}) ->
{prime_field, ensure_int_as_bin(Prime)};
term_to_nif_prime(PrimeField) ->
PrimeField.
+
term_to_nif_curve({A, B, Seed}) ->
{ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}.
+
nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) ->
- {term_to_nif_prime(PrimeField), term_to_nif_curve(Curve), ensure_int_as_bin(BasePoint), ensure_int_as_bin(Order), ensure_int_as_bin(CoFactor)};
+ {term_to_nif_prime(PrimeField),
+ term_to_nif_curve(Curve),
+ ensure_int_as_bin(BasePoint),
+ ensure_int_as_bin(Order),
+ ensure_int_as_bin(CoFactor)};
nif_curve_params(Curve) when is_atom(Curve) ->
%% named curve
case Curve of
@@ -1348,6 +1852,7 @@ int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
int_to_bin_neg(X,Ds) ->
int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
+-spec bytes_to_integer(binary()) -> integer() .
bytes_to_integer(Bin) ->
bin_to_int(Bin).
@@ -1395,9 +1900,6 @@ format_pwd(M) -> M.
%%--------------------------------------------------------------------
%%
--type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'.
-
-pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub.
%% large integer in a binary with 32bit length
%% MP representaion (SSH2)