From 0a833d0339fe5bb4c26c30430d74f83d7f2b6519 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 22 Aug 2018 16:50:15 +0200 Subject: crypto: A user's guide chapter on algorithm details Such as keylengths, blocksizes and IV lengths are hard to find otherwise Conflicts: lib/crypto/doc/src/crypto.xml --- lib/crypto/doc/src/Makefile | 2 +- lib/crypto/doc/src/algorithm_details.xml | 290 +++++++++++++++++++++++++++++++ lib/crypto/doc/src/usersguide.xml | 1 + 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 lib/crypto/doc/src/algorithm_details.xml (limited to 'lib/crypto') diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index 2148062e78..3203324954 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 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 @@ + + + + +
+ + 20142017 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + Algorithm Details + Hans Nilsson + + 2018-08-22 + A + algorithm_details.xml +
+

+ This chapter describes details of algorithms in the crypto application. +

+

The tables only documents the supported cryptos and key lengths. The user should not draw any conclusion + on security from the supplied tables. +

+ +
+ Ciphers +
+ Block Ciphers +

To be used in + block_encrypt/3, + block_encrypt/4, + block_decrypt/3 and + block_decrypt/4. +

+

Available in all OpenSSL compatible with Erlang CRYPTO if not disabled by configuration. +

+

To dynamically check availability, check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value of + crypto:supports(). +

+ + Cipher and ModeKey length
[bytes]
IV length
[bytes]
Block size
[bytes]
+ aes_cbc 16, 24, 321616 + aes_cbc128161616 + aes_cbc256321616 + + aes_cfb8 16, 24, 3216any + + aes_ecb16, 24, 32 16 + + aes_ige256163216 + blowfish_cbc 4-56 8 8 + blowfish_cfb64 1- 8 any + blowfish_ecb1- 8 + blowfish_ofb641-8any + + des3_cbc
(=DES EDE3 CBC)
[8,8,8]88
+ des3_cfb
(=DES EDE3 CFB)
[8,8,8]8any
+ + des_cbc88 8 + des_cfb88any + des_ecb8 8 + des_ede3
(=DES EDE3 CBC)
[8,8,8]88
+ rc2_cbc1-88 + Block cipher key lengths +
+
+ +
+ AEAD Ciphers +

To be used in block_encrypt/4 and + block_decrypt/4. +

+

To dynamically check availability, check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value of + crypto:supports(). +

+ + Cipher and ModeKey length
[bytes]
IV length
[bytes]
AAD length
[bytes]
Block size
[bytes]
Supported with
OpenSSL versions
+ aes_gcm 16 16 0-16 any1.0.1 - + chacha20_poly130532 1-16 any any1.1.0 - + AEAD cipher key lengths +
+
+ +
+ Stream Ciphers +

To be used in stream_init/2 and + stream_init/3. +

+

To dynamically check availability, check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value of + crypto:supports(). +

+ + Cipher and ModeKey length
[bytes]
IV length
[bytes]
Supported with
OpenSSL versions
+ aes_ctr16, 24, 32161.0.1 - + rc41- all + Stream cipher key lengths +
+
+
+ +
+ Message Authentication Codes (MACs) + +
+ CMAC +

To be used in cmac/3 and + cmac/4. +

+

CMAC with the following ciphers are available with OpenSSL 1.0.1 or later if not disabled by configuration. +

+ +

To dynamically check availability, check that the name cmac is present in the + list with the macs tag in the return value of + crypto:supports(). + Also check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value. +

+ + Cipher and ModeKey length
[bytes]
Max Mac Length
[bytes]
+ aes_cbc 16, 24, 3216 + aes_cbc1281616 + aes_cbc2563216 + + aes_cfb8 161 + + blowfish_cbc 4-56 8 + blowfish_cfb64 1- 1 + blowfish_ecb1- 8 + blowfish_ofb641- 1 + + des3_cbc
(=DES EDE3 CBC)
[8,8,8]8
+ des3_cfb
(=DES EDE3 CFB)
[8,8,8]1
+ + des_cbc88 + + des_cfb81 + des_ecb81 + rc2_cbc1-8 + CMAC cipher key lengths +
+
+ +
+ HMAC +

Available in all OpenSSL compatible with Erlang CRYPTO if not disabled by configuration. +

+

To dynamically check availability, check that the name hmac is present in the + list with the macs tag in the return value of + crypto:supports(). +

+
+ +
+ POLY1305 +

POLY1305 is available with OpenSSL 1.1.1 or later if not disabled by configuration. +

+

To dynamically check availability, check that the name poly1305 is present in the + list with the macs tag in the return value of + crypto:supports(). +

+
+ +
+ +
+ Hash + +

To dynamically check availability, check that the wanted name in the Names column is present in the + list with the hashs tag in the return value of + crypto:supports(). +

+ + + + Type + Names + Supported with
OpenSSL versions
+
+ SHA1shaall + SHA2sha224, sha256, sha384, sha512all + SHA3sha3_224, sha3_256, sha3_384, sha3_5121.1.1 - + MD4md4all + MD5md5all + RIPEMDripemd160all + +
+
+ +
+ Public Key Cryptography + +
+ RSA +

RSA is available with all OpenSSL versions compatible with Erlang CRYPTO if not disabled by configuration. + To dynamically check availability, check that the atom rsa is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+ + + Option sign/verify encrypt/decrypt Supported with
OpenSSL versions
+ {rsa_mgf1_md,atom()} x x 1.0.1 + {rsa_oaep_label, binary()} x + {rsa_oaep_md, atom()} x + {rsa_padding,rsa_pkcs1_pss_padding} x 1.0.0 + {rsa_pss_saltlen, -2..} x 1.0.0 + {rsa_padding,rsa_no_padding} x x + {rsa_padding,rsa_pkcs1_padding} x x + {rsa_padding,rsa_sslv23_padding} x + {rsa_padding,rsa_x931_padding} x + +
+
+ +
+ DSS +

DSS is available with OpenSSL versions compatible with Erlang CRYPTO if not disabled by configuration. + To dynamically check availability, check that the atom dss is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+
+ +
+ ECDSA +

ECDSA is available with OpenSSL 0.9.8o or later if not disabled by configuration. + To dynamically check availability, check that the atom ecdsa is present in the + list with the public_keys tag in the return value of + crypto:supports(). + If the atom ec_gf2m characteristic two field curves are available. +

+

The actual supported named curves could be checked by examining the list with the + curves tag in the return value of + crypto:supports(). +

+
+ +
+ Diffie-Hellman +

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 dh is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+
+ +
+ Elliptic Curve Diffie-Hellman +

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 ecdh is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+ +

The Edward curves x25519 and x448 are supported with OpenSSL 1.1.1 or later + if not disabled by configuration. +

+ +

The actual supported named curves could be checked by examining the list with the + curves tag in the return value of + crypto:supports(). +

+
+ +
+ + +
+ + + + + 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 @@ + -- cgit v1.2.3 From fa60c386364e4a1852151a56ec6942e394545983 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:04:42 +0200 Subject: crypto: Setup for doc generation --- lib/crypto/doc/specs/.gitignore | 1 + lib/crypto/doc/src/Makefile | 7 +++++++ lib/crypto/doc/src/specs.xml | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 lib/crypto/doc/specs/.gitignore create mode 100644 lib/crypto/doc/src/specs.xml (limited to 'lib/crypto') 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 3203324954..cbcafb7375 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -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/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 @@ + + + + -- cgit v1.2.3 From 35848c8ba5968b0d9aec3f7aaac6d31000e4da15 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:07:21 +0200 Subject: crypto: Rework -type and -spec Check code and documentation and write -type/-spec or adjust existing. Prepare for doc generation --- lib/crypto/src/crypto.erl | 976 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 739 insertions(+), 237 deletions(-) (limited to 'lib/crypto') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 17351d10ea..a841f0f168 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,6 +337,9 @@ 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. @@ -135,85 +350,150 @@ info_fips() -> ?nif_stub. 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 <> 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() ] . -%% 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. +-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 + . + + +%%%---------------------------------------------------------------- +%%% 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) -- cgit v1.2.3 From cb654518a4fa58fa65f46e1386ff91c6375f6f5a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:08:13 +0200 Subject: crypto: Generate refman from types and specs and fix links in engine chapter for generated crypto module refman --- lib/crypto/doc/src/crypto.xml | 1104 ++++++++++++++++-------------------- lib/crypto/doc/src/engine_keys.xml | 2 +- 2 files changed, 481 insertions(+), 625 deletions(-) (limited to 'lib/crypto') diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 4289bd4a64..9d436847ac 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -46,6 +46,12 @@

Block ciphers - DES and AES in Block Cipher Modes - ECB, CBC, CFB, OFB, CTR and GCM

+ +

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. +

+

RSA encryption RFC 1321

@@ -56,192 +62,358 @@

Secure Remote Password Protocol (SRP - RFC 2945)

- -

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.

-
- -
- DATA TYPES - - key_value() = integer() | binary() -

Always binary() when used as return value

+ +

The actual supported algorithms and features depends on their availability in the actual libcrypto used. + See the crypto (App) about dependencies. +

+

Enabling FIPS mode will also disable algorithms and features. +

+
- rsa_public() = [key_value()] = [E, N] -

Where E is the public exponent and N is public modulus.

+

The CRYPTO User's Guide has more information on + FIPS, Engines and Algorithm Details like key lengths. +

+ - rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] -

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 RFC 3447.

+ + Ciphers + + + +

Stream ciphers for + stream_encrypt/2 and + stream_decrypt/2 . +

+
+
- dss_public() = [key_value()] = [P, Q, G, Y] -

Where P, Q and G are the dss parameters and Y is the public key.

+ + + + + +

Block ciphers with initialization vector for + block_encrypt/4 and + block_decrypt/4 . +

+
+
- dss_private() = [key_value()] = [P, Q, G, X] -

Where P, Q and G are the dss parameters and X is the private key.

+ + + + +

Block ciphers without initialization vector for + block_encrypt/3 and + block_decrypt/3 . +

+
+
- srp_public() = key_value() -

Where is A or B from SRP design

+ + + +

Ciphers with simultaneous MAC-calculation or MAC-checking. + block_encrypt/4 and + block_decrypt/4 . +

+
+
- srp_private() = key_value() -

Where is a or b from SRP design

+ Digests + + + + + + + -

Where Verifier is v, Generator is g and Prime is N, DerivedKey is X, and Scrambler is - u (optional will be generated if not provided) from SRP design - Version = '3' | '6' | '6a' -

+ + + +

The compatibility_only_hash() algorithms are recommended only for compatibility with existing applications.

+
+
- dh_public() = key_value() + + + + + - dh_private() = key_value() + + + + + - dh_params() = [key_value()] = [P, G] | [P, G, PrivateKeyBitLength] + + + + + - ecdh_public() = key_value() + Elliptic Curves + + + + +

Note that some curves are disabled if FIPS is enabled.

+
+
- ecdh_private() = key_value() + + + + + +

Parametric curve definition.

+
+
- ecdh_params() = ec_named_curve() | ec_explicit_curve() + + + + + +

Curve definition details.

+
+
- ed_named_curves_ecdh() -> x448 | x25519 -

Note that the curves are only supported if the underlying OpenSSL has support for them.

+ Keys + + + + +

For keylengths, iv-sizes and blocksizes see the + User's Guide. +

+

A key for des3 is a list of three iolists

+
+
- ec_explicit_curve() = - {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), - CoFactor :: none | integer()} + + + +

Always binary() when used as return value

+
+
- ec_field() = {prime_field, Prime :: integer()} | - {characteristic_two_field, M :: integer(), Basis :: ec_basis()} + Public/Private Keys + + + + + + rsa_public() = [E, N] + rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] +

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 RFC 3447.

+
+
- ec_basis() = {tpbasis, K :: non_neg_integer()} | - {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} | - onbasis + + + + + dss_public() = [P, Q, G, Y] +

Where P, Q and G are the dss parameters and Y is the public key.

- 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 - -

Note that the sect curves are GF2m (characteristic two) curves and are only supported if the - underlying OpenSSL has support for them. - See also crypto:supports/0 -

+ dss_private() = [P, Q, G, X] +

Where P, Q and G are the dss parameters and X is the private key.

+
+
- - - engine_key_ref() = #{engine := engine_ref(), - key_id := key_id(), - password => password()} + + + + + + + - engine_ref() = term() -

The result of a call to for example engine_load/3. -

+ + + + + srp_public() = key_integer() +

Where is A or B from SRP design

+ + srp_private() = key_integer() +

Where is a or b from SRP design

+
+
- key_id() = string() | binary() -

Identifies the key to be used. The format depends on the loaded engine. It is passed to - the ENGINE_load_(private|public)_key functions in libcrypto. -

+ + + + + + srp_user_gen_params() = [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom()] + + srp_host_gen_params() = [Verifier::binary(), Prime::binary(), Version::atom() ] + + srp_user_comp_params() = [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom() | ScramblerArg::list()] + + srp_host_comp_params() = [Verifier::binary(), Prime::binary(), Version::atom() | ScramblerArg::list()] +

Where Verifier is v, Generator is g and Prime is N, DerivedKey is X, and Scrambler is + u (optional will be generated if not provided) from SRP design + Version = '3' | '6' | '6a' +

+
+
- password() = string() | binary() -

The key's password -

+ Public Key Ciphers - stream_cipher() = rc4 | aes_ctr | chacha20 + + + +

Algorithms for public key encrypt/decrypt. Only RSA is supported.

+
+
- 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 + + + + + +

Options for public key encrypt/decrypt. Only RSA is supported.

+
+
- aead_cipher() = aes_gcm | chacha20_poly1305 -

Note that the actual supported algorithms depends on the underlying crypto library.

+ + + +

Those option forms are kept only for compatibility and should not be used in new code.

+
+
- stream_key() = aes_key() | rc4_key() + Public Key Sign and Verify - block_key() = aes_key() | blowfish_key() | des_key()| des3_key() + + + +

Algorithms for sign and verify.

+
+
- aes_key() = iodata()

Key length is 128, 192 or 256 bits

+ + + + + +

Options for sign and verify.

+
+
- rc4_key() = iodata()

Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)

+ Diffie-Hellman Keys and parameters + + + + + + - blowfish_key() = iodata()

Variable key length from 32 bits up to 448 bits

+ + + + dh_params() = [P, G] | [P, G, PrivateKeyBitLength] + + - des_key() = iodata()

Key length is 64 bits (in CBC mode only 8 bits are used)

+ + + + + + + - des3_key() = [binary(), binary(), binary()]

Each key part is 64 bits (in CBC mode only 8 bits are used)

+ Types for Engines - digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512 + + + + +

The result of a call to engine_load/3. +

+
+
- rsa_digest_type() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 + + + +

Identifies the key to be used. The format depends on the loaded engine. It is passed to + the ENGINE_load_(private|public)_key functions in libcrypto. +

+
+
- dss_digest_type() = sha | sha224 | sha256 | sha384 | sha512

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.

+ + + +

The password of the key stored in an engine. +

+
+
- ecdsa_digest_type() = sha | sha224 | sha256 | sha384 | sha512 + + + - sign_options() = [{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}] + + + +

Pre and Post commands for engine_load/3 and /4. +

+
+
- rsa_sign_padding() = rsa_pkcs1_padding | rsa_pkcs1_pss_padding + Internal data types - hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 | - sha3_224 | sha3_256 | sha3_384 | sha3_512 -

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. -

- 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 - mac_algorithms() = hmac | cmac | poly1305 - public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m -

Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported - with ecdsa and ecdh. -

- 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 + + + + + +

Contexts with an internal state that should not be manipulated but passed between function calls. +

+
+
-
+ + - block_encrypt(Type, Key, PlainText) -> CipherText + Encrypt PlainText according to Type block cipher - - Type = des_ecb | blowfish_ecb | aes_ecb - Key = block_key() - PlainText = iodata() - -

Encrypt PlainText according to Type block cipher.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

Encrypt PlainText according to Type block cipher.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths and blocksizes see the + User's Guide. +

- block_decrypt(Type, Key, CipherText) -> PlainText + Decrypt CipherText according to Type block cipher - - Type = des_ecb | blowfish_ecb | aes_ecb - Key = block_key() - PlainText = iodata() -

Decrypt CipherText according to Type block cipher.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths and blocksizes see the + User's Guide. +

@@ -251,10 +423,10 @@ block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} Encrypt PlainText according to Type block cipher - Type = block_cipher() - AeadType = aead_cipher() - Key = block_key() - PlainText = iodata() + Type = block_cipher_with_iv() + AeadType = aead_cipher() + Key = key() | des3_key() + PlainText = iodata() AAD = IVec = CipherText = CipherTag = binary() TagLength = 1..16 @@ -264,8 +436,11 @@

In AEAD (Authenticated Encryption with Associated Data) mode, encrypt PlainTextaccording to Type block cipher and calculate CipherTag that also authenticates the AAD (Associated Authenticated Data).

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths, iv-sizes and blocksizes see the + User's Guide. +

@@ -274,10 +449,10 @@ block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | error Decrypt CipherText according to Type block cipher - Type = block_cipher() - AeadType = aead_cipher() - Key = block_key() - PlainText = iodata() + Type = block_cipher_with_iv() + AeadType = aead_cipher() + Key = key() | des3_key() + PlainText = iodata() AAD = IVec = CipherText = CipherTag = binary() @@ -287,19 +462,17 @@ CipherTextaccording to Type block cipher and check the authenticity the PlainText and AAD (Associated Authenticated Data) using the CipherTag. May return error if the decryption or validation fail's

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths, iv-sizes and blocksizes see the + User's Guide. +

- bytes_to_integer(Bin) -> Integer + Convert binary representation, of an integer, to an Erlang integer. - - Bin = binary() - as returned by crypto functions - - Integer = integer() -

Convert binary representation, of an integer, to an Erlang integer.

@@ -307,17 +480,8 @@
- compute_key(Type, OthersPublicKey, MyKey, Params) -> SharedSecret + Computes the shared secret - - Type = dh | ecdh | srp - OthersPublicKey = dh_public() | ecdh_public() | srp_public() - MyKey = dh_private() | ecdh_private() | {srp_public(),srp_private()} - Params = dh_params() | ecdh_params() | ed_named_curves_ecdh() | SrpUserParams | SrpHostParams - SrpUserParams = {user, [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom() | [Scrambler:binary()]]} - SrpHostParams = {host, [Verifier::binary(), Prime::binary(), Version::atom() | [Scrambler::binary]]} - SharedSecret = binary() -

Computes the shared secret from the private key and the other party's public key. See also public_key:compute_key/2 @@ -326,85 +490,61 @@ - exor(Data1, Data2) -> Result + XOR data - - Data1, Data2 = iodata() - Result = binary() -

Performs bit-wise XOR (exclusive or) on the data supplied.

- - generate_key(Type, Params) -> {PublicKey, PrivKeyOut} - generate_key(Type, Params, PrivKeyIn) -> {PublicKey, PrivKeyOut} + + + + Generates a public key of type Type - - Type = dh | ecdh | rsa | srp - Params = dh_params() | ecdh_params() | ed_named_curves_ecdh()| RsaParams | SrpUserParams | SrpHostParams - RsaParams = {ModulusSizeInBits::integer(), PublicExponent::key_value()} - SrpUserParams = {user, [Generator::binary(), Prime::binary(), Version::atom()]} - SrpHostParams = {host, [Verifier::binary(), Generator::binary(), Prime::binary(), Version::atom()]} - PublicKey = dh_public() | ecdh_public() | rsa_public() | srp_public() - PrivKeyIn = undefined | dh_private() | ecdh_private() | srp_private() - PrivKeyOut = dh_private() | ecdh_private() | rsa_private() | srp_private() -

Generates a public key of type Type. See also public_key:generate_key/1. - May throw exception an exception of class error: + May raise exception:

- badarg: an argument is of wrong type or has an illegal value, - low_entropy: the random generator failed due to lack of secure "randomness", - computation_failed: the computation fails of another reason than low_entropy. + error:badarg: an argument is of wrong type or has an illegal value, + error:low_entropy: the random generator failed due to lack of secure "randomness", + error:computation_failed: the computation fails of another reason than low_entropy.

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 error:notsup.

+ generate an RSA key will raise exception error:notsup.

- hash(Type, Data) -> Digest + - - Type = md4 | hash_algorithms() - Data = iodata() - Digest = binary() -

Computes a message digest of type Type from Data.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

- hash_init(Type) -> Context + - - Type = md4 | hash_algorithms() -

Initializes the context for streaming hash operations. Type determines which digest to use. The returned context should be used as argument to hash_update.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

- hash_update(Context, Data) -> NewContext + - - Data = iodata() -

Updates the digest represented by Context using the given Data. Context must have been generated using hash_init @@ -413,12 +553,10 @@ or hash_final.

+ - hash_final(Context) -> Digest + - - Digest = binary() -

Finalizes the hash operation referenced by Context returned from a previous call to hash_update. @@ -428,16 +566,9 @@ - hmac(Type, Key, Data) -> Mac - hmac(Type, Key, Data, MacLength) -> Mac + + - - Type = hash_algorithms() - except ripemd160 - Key = iodata() - Data = iodata() - MacLength = integer() - Mac = binary() -

Computes a HMAC of type Type from Data using Key as the authentication key.

MacLength @@ -446,13 +577,8 @@ - hmac_init(Type, Key) -> Context + - - Type = hash_algorithms() - except ripemd160 - Key = iodata() - Context = binary() -

Initializes the context for streaming HMAC operations. Type determines which hash function to use in the HMAC operation. Key is the authentication @@ -461,12 +587,8 @@ - hmac_update(Context, Data) -> NewContext + - - Context = NewContext = binary() - Data = iodata() -

Updates the HMAC represented by Context using the given Data. Context 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.

+ libcrypto API.

- hmac_final(Context) -> Mac + - - Context = Mac = binary() -

Finalizes the HMAC operation referenced by Context. The size of the resultant MAC is determined by the type of hash function used to generate it.

@@ -496,12 +615,8 @@
- hmac_final_n(Context, HashLen) -> Mac + - - Context = Mac = binary() - HashLen = non_neg_integer() -

Finalizes the HMAC operation referenced by Context. HashLen must be greater than zero. Mac will be a binary with at most HashLen 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 HashLen bytes.

@@ -509,16 +624,9 @@
- cmac(Type, Key, Data) -> Mac - cmac(Type, Key, Data, MacLength) -> Mac + + Calculates the Cipher-based Message Authentication Code. - - Type = block_cipher() - Key = iodata() - Data = iodata() - MacLength = integer() - Mac = binary() -

Computes a CMAC of type Type from Data using Key as the authentication key.

MacLength @@ -527,20 +635,17 @@ - info_fips() -> Status + Provides information about the FIPS operating status. - - Status = enabled | not_enabled | not_supported -

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 enabled (when running in FIPS mode) or not_enabled. For other builds this value is always not_supported.

In FIPS mode all non-FIPS compliant algorithms are - disabled and throw exception not_supported. Check + disabled and raise exception error:notsup. Check supports that in FIPS mode returns the restricted list of available algorithms.

@@ -549,13 +654,8 @@
- info_lib() -> [{Name,VerNum,VerStr}] + Provides information about the libraries used by crypto. - - Name = binary() - VerNum = integer() - VerStr = binary() -

Provides the name and version of the libraries used by crypto.

Name is the name of the library. VerNum is @@ -568,50 +668,36 @@

From OTP R16 the numeric version represents the version of the OpenSSL header files (openssl/opensslv.h) 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.

- mod_pow(N, P, M) -> Result + Computes the function: N^P mod M - - N, P, M = binary() | integer() - Result = binary() | error -

Computes the function N^P mod M.

- next_iv(Type, Data) -> NextIVec - next_iv(Type, Data, IVec) -> NextIVec - - - Type = des_cbc | des3_cbc | aes_cbc | des_cfb - Data = iodata() - IVec = NextIVec = binary() - - -

Returns the initialization vector to be used in the next - iteration of encrypt/decrypt of type Type. Data is the - encrypted data from the previous iteration step. The IVec - argument is only needed for des_cfb as the vector used - in the previous iteration step.

-
+ + + + +

Returns the initialization vector to be used in the next + iteration of encrypt/decrypt of type Type. Data is the + encrypted data from the previous iteration step. The IVec + argument is only needed for des_cfb as the vector used + in the previous iteration step.

+
- poly1305(Key, Data) -> Mac + - - Key = iodata() - Data = iodata() - Mac = binary() -

Computes a POLY1305 message authentication code (Mac) from Data using Key as the authentication key.

@@ -619,15 +705,8 @@
- private_decrypt(Type, CipherText, PrivateKey, Padding) -> PlainText + Decrypts CipherText using the private Key. - - Type = rsa - CipherText = binary() - PrivateKey = rsa_private() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding - PlainText = binary() -

Decrypts the CipherText, encrypted with public_encrypt/4 (or equivalent function) @@ -640,34 +719,8 @@ - privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey - Fetches a public key from an Engine stored private key. - - Type = rsa | dss - EnginePrivateKeyRef = engine_key_ref() - PublicKey = rsa_public() | dss_public() - - -

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. -

-
-
- - - private_encrypt(Type, PlainText, PrivateKey, Padding) -> CipherText + Encrypts PlainText using the private Key. - - Type = rsa - PlainText = binary() - The size of the PlainText must be less - than byte_size(N)-11 if rsa_pkcs1_padding is - used, and byte_size(N) if rsa_no_padding is - used, where N is public modulus of the RSA key. - PrivateKey = rsa_private() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_no_padding - CipherText = binary() -

Encrypts the PlainText using the PrivateKey and returns the ciphertext. This is a low level signature operation @@ -677,16 +730,10 @@

+ - public_decrypt(Type, CipherText, PublicKey, Padding) -> PlainText + Decrypts CipherText using the public Key. - - Type = rsa - CipherText = binary() - PublicKey = rsa_public() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_no_padding - PlainText = binary() -

Decrypts the CipherText, encrypted with private_encrypt/4(or equivalent function) @@ -699,19 +746,8 @@ - public_encrypt(Type, PlainText, PublicKey, Padding) -> CipherText + Encrypts PlainText using the public Key. - - Type = rsa - PlainText = binary() - The size of the PlainText must be less - than byte_size(N)-11 if rsa_pkcs1_padding is - used, and byte_size(N) if rsa_no_padding is - used, where N is public modulus of the RSA key. - PublicKey = rsa_public() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding - CipherText = binary() -

Encrypts the PlainText (message digest) using the PublicKey and returns the CipherText. This is a low level signature operation @@ -722,18 +758,15 @@ - rand_seed(Seed) -> ok + Set the seed for random bytes generation - - Seed = binary() -

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 strong_rand_bytes/1 - throws low_entropy

+ raises error:low_entropy

@@ -751,36 +784,15 @@
- sign(Algorithm, DigestType, Msg, Key) -> binary() - sign(Algorithm, DigestType, Msg, Key, Options) -> binary() - Create digital signature. - - Algorithm = rsa | dss | ecdsa - Msg = binary() | {digest,binary()} - The msg is either the binary "cleartext" data to be - signed or it is the hashed value of "cleartext" i.e. the - digest (plaintext). - DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Key = rsa_private() | dss_private() | [ecdh_private(),ecdh_params()] | engine_key_ref() - Options = sign_options() - - -

Creates a digital signature.

-

Algorithm dss can only be used together with digest type - sha.

-

See also public_key:sign/3.

-
-
- - - start() -> ok + Equivalent to application:start(crypto).

Equivalent to application:start(crypto).

+ - stop() -> ok + Equivalent to application:stop(crypto).

Equivalent to application:stop(crypto).

@@ -788,23 +800,20 @@
- strong_rand_bytes(N) -> binary() + Generate a binary of random bytes - - N = integer() -

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 RAND_bytes method from OpenSSL.

-

May throw exception low_entropy in case the random generator +

May raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

- rand_seed() -> rand:state() + Strong random number generation plugin state

@@ -820,7 +829,7 @@

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

Example

@@ -832,7 +841,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[
- rand_seed_s() -> rand:state() + Strong random number generation plugin state

@@ -846,7 +855,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

@@ -885,7 +894,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

@@ -930,7 +939,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

@@ -961,45 +970,36 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - stream_init(Type, Key) -> State + - - Type = rc4 - State = opaque() - Key = iodata() -

Initializes the state for use in RC4 stream encryption stream_encrypt and stream_decrypt

+

For keylengths see the + User's Guide. +

- stream_init(Type, Key, IVec) -> State + - - Type = aes_ctr | chacha20 - State = opaque() - Key = iodata() - IVec = binary() -

Initializes the state for use in streaming AES encryption using Counter mode (CTR). Key is the AES key and must be either 128, 192, or 256 bits long. IVec is an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with stream_encrypt and stream_decrypt.

+

For keylengths and iv-sizes see the + User's Guide. +

- stream_encrypt(State, PlainText) -> { NewState, CipherText} + - - Text = iodata() - CipherText = binary() -

Encrypts PlainText according to the stream cipher Type specified in stream_init/3. Text can be any number of bytes. The initial State is created using @@ -1009,12 +1009,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - stream_decrypt(State, CipherText) -> { NewState, PlainText } + - - CipherText = iodata() - PlainText = binary() -

Decrypts CipherText according to the stream cipher Type specified in stream_init/3. PlainText can be any number of bytes. The initial State is created using @@ -1024,60 +1020,54 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - supports() -> AlgorithmList + Provide a list of available crypto algorithms. - - AlgorithmList = [{hashs, [hash_algorithms()]}, - {ciphers, [cipher_algorithms()]}, - {public_keys, [public_key_algorithms()]}, - {macs, [mac_algorithms()]}] - -

Can be used to determine which crypto algorithms that are supported - by the underlying OpenSSL library

+ by the underlying libcrypto library

- ec_curves() -> EllipticCurveList + Provide a list of available named elliptic curves. - - EllipticCurveList = [ec_named_curve()] -

Can be used to determine which named elliptic curves are supported.

- ec_curve(NamedCurve) -> EllipticCurve + Get the defining parameters of a elliptic curve. - - NamedCurve = ec_named_curve() - EllipticCurve = ec_explicit_curve() -

Return the defining parameters of a elliptic curve.

- - verify(Algorithm, DigestType, Msg, Signature, Key) -> boolean() - verify(Algorithm, DigestType, Msg, Signature, Key, Options) -> boolean() + + + + Create digital signature. + +

Creates a digital signature.

+

The msg is either the binary "cleartext" data to be + signed or it is the hashed value of "cleartext" i.e. the + digest (plaintext).

+

Algorithm dss can only be used together with digest type + sha.

+

See also public_key:sign/3.

+
+
+ + + + Verifies a digital signature. - - Algorithm = rsa | dss | ecdsa - Msg = binary() | {digest,binary()} - The msg is either the binary "cleartext" data - or it is the hashed value of "cleartext" i.e. the digest (plaintext). - DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Signature = binary() - Key = rsa_public() | dss_public() | [ecdh_public(),ecdh_params()] | engine_key_ref() - Options = sign_options() -

Verifies a digital signature

+

The msg is either the binary "cleartext" data to be + signed or it is the hashed value of "cleartext" i.e. the + digest (plaintext).

Algorithm dss can only be used together with digest type sha.

@@ -1087,17 +1077,24 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_get_all_methods() -> Result + + Fetches a public key from an Engine stored private key. + +

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. +

+
+
+ + + Return list of all possible engine methods - - Result = [EngineMethod::atom()] -

Returns a list of all possible engine methods.

- May throw exception notsup in case there is + May raise exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1108,13 +1105,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_load(EngineId, PreCmds, PostCmds) -> Result + Dynamical load an encryption engine - - EngineId = unicode:chardata() - PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}] - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId if it is available and then returns ok and @@ -1123,8 +1115,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ returned if the engine can't be loaded.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1135,22 +1127,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_load(EngineId, PreCmds, PostCmds, EngineMethods) -> Result + Dynamical load an encryption engine - - EngineId = unicode:chardata() - PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}] - EngineMethods = [engine_method_type()] - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId if it is available and then returns ok and an engine handle. An error tuple is returned if the engine can't be loaded.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1161,20 +1147,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_unload(Engine) -> Result + Dynamical load an encryption engine - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Unloads the OpenSSL engine given by Engine. An error tuple is returned if the engine can't be unloaded.

- 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 error:badarg if the parameter is in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1185,20 +1167,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_by_id(EngineId) -> Result + Get a reference to an already loaded engine - - EngineID = unicode:chardata()engine_ref() - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Get a reference to an already loaded engine with EngineId. An error tuple is returned if the engine can't be unloaded.

- 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 error:badarg if the parameter is in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1209,14 +1187,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> Result + Sends ctrl commands to an OpenSSL engine - - Engine = engine_ref() - CmdName = unicode:chardata() - CmdArg = unicode:chardata() - Result = ok | {error, Reason::term()} -

Sends ctrl commands to the OpenSSL engine given by Engine. @@ -1224,23 +1196,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ Optional set to false.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> Result + Sends ctrl commands to an OpenSSL engine - - Engine = engine_ref() - CmdName = unicode:chardata() - CmdArg = unicode:chardata() - Optional = boolean() - Result = ok | {error, Reason::term()} -

Sends ctrl commands to the OpenSSL engine given by Engine. @@ -1252,91 +1217,72 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ false.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_add(Engine) -> Result + Add engine to OpenSSL internal list - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Add the engine to OpenSSL's internal list.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_remove(Engine) -> Result + Remove engine to OpenSSL internal list - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Remove the engine from OpenSSL's internal list.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_get_id(Engine) -> EngineId + Fetch engine ID - - Engine = engine_ref() - EngineId = unicode:chardata() -

Return the ID for the engine, or an empty binary if there is no id set.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_get_name(Engine) -> EngineName + Fetch engine name - - Engine = engine_ref() - EngineName = unicode:chardata() -

Return the name (eg a description) for the engine, or an empty binary if there is no name set.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_list() -> Result + List the known engine ids - - Result = [EngineId::unicode:chardata()] -

List the id's of all engines in OpenSSL's internal list.

- It may also throw the exception notsup in case there is + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1344,20 +1290,15 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ in the User's Guide.

- May throw exception notsup in case engine functionality is not supported by the underlying + May raise exception error:notsup in case engine functionality is not supported by the underlying OpenSSL implementation.

- ensure_engine_loaded(EngineId, LibPath) -> Result + Ensure encryption engine just loaded once - - EngineId = unicode:chardata() - LibPath = unicode:chardata() - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId and the path to the dynamic library @@ -1366,8 +1307,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ returned if the engine can't be loaded.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1378,14 +1319,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> Result + Ensure encryption engine just loaded once - - EngineId = unicode:chardata() - LibPath = unicode:chardata() - EngineMethods = [engine_method_type()] - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId and the path to the dynamic library @@ -1395,8 +1330,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ An error tuple is returned if the engine can't be loaded.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1407,12 +1342,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - ensure_engine_unloaded(Engine) -> Result + Unload an engine loaded with the ensure function - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Unloads an engine loaded with the ensure_engine_loaded function. @@ -1422,8 +1353,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ returned if the engine can't be unloaded.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1434,13 +1365,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - ensure_engine_unloaded(Engine, EngineMethods) -> Result + Unload an engine loaded with the ensure function - - Engine = engine_ref() - EngineMethods = [engine_method_type()] - Result = ok | {error, Reason::term()} -

Unloads an engine loaded with the ensure_engine_loaded function. @@ -1448,8 +1374,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ An error tuple is returned if the engine can't be unloaded.

- 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 error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1461,75 +1387,5 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 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 an Erlang map is constructed with the Engine reference, the key reference and possibly a key passphrase if - needed by the Engine. See the Reference Manual for + needed by the Engine. See the Reference Manual for details of the map. -- cgit v1.2.3 From 882fa794883e6dbc0e56f22645cd3aec21920c53 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 7 Sep 2018 13:46:52 +0200 Subject: crypto: Add missing documentation for enable_fips_mode/1 --- lib/crypto/doc/src/crypto.xml | 21 ++++++++++++++++++++- lib/crypto/src/crypto.erl | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'lib/crypto') diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 9d436847ac..d5f5009297 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -642,7 +642,11 @@ crypto and the underlying libcrypto library. If crypto was built with FIPS support this can be either enabled (when running in FIPS mode) or not_enabled. For other builds - this value is always not_supported.

+ this value is always not_supported. +

+

See enable_fips_mode/1 about how to enable + FIPS mode. +

In FIPS mode all non-FIPS compliant algorithms are disabled and raise exception error:notsup. Check @@ -653,6 +657,21 @@ + + + Change FIPS mode. + +

Enables (Enable = true) or disables (Enable = false) FIPS mode. Returns true if + the operation was successful or false otherwise. +

+

Note that to enable FIPS mode succesfully, OTP must be built with the configure option --enable-fips, + and the underlying libcrypto must also support FIPS. +

+

See also info_fips/0. +

+
+
+ Provides information about the libraries used by crypto. diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index a841f0f168..c64586897e 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -346,8 +346,8 @@ info_lib() -> ?nif_stub. 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. %%%================================================================ -- cgit v1.2.3