From 16788a3c10298a6a68b2e1e6362be05780f910cf Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 27 Mar 2019 14:02:53 +0100 Subject: crypto: User's Guide and Reference Manual for the new api --- lib/crypto/doc/src/Makefile | 3 +- lib/crypto/doc/src/crypto.xml | 501 ++++++++++++++++++++++++++------------ lib/crypto/doc/src/new_api.xml | 209 ++++++++++++++++ lib/crypto/doc/src/usersguide.xml | 1 + 4 files changed, 557 insertions(+), 157 deletions(-) create mode 100644 lib/crypto/doc/src/new_api.xml (limited to 'lib') diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index cbcafb7375..8da494dad6 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -39,7 +39,8 @@ XML_REF3_FILES = crypto.xml XML_REF6_FILES = crypto_app.xml XML_PART_FILES = usersguide.xml -XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml algorithm_details.xml +XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml \ + algorithm_details.xml new_api.xml BOOK_FILES = book.xml diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 8a4fad67de..14efc5c6f6 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -42,7 +42,7 @@ SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions [FIPS PUB 202] - + BLAKE2 @@ -190,70 +190,101 @@ - Ciphers + Ciphers, new API - - -

Ciphers known byt the CRYPTO application. Note that this list might be reduced if the - underlying libcrypto does not support all of them.

- - - + -

Stream ciphers for - stream_init/3 and - stream_init/2 . -

+
+
+ + + + + + + + +

Ciphers known by the CRYPTO application when using the + new API.

+

Note that this list might be reduced if the underlying libcrypto does not support all of them.

+ Ciphers, old API + + + + + + + + + + + + + + + + + + + + - + + + + -

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

- - - + -

Names that are replaced by more common names. They may deprecated in futer releases.

-

des3_cbc and des_ede3 should be replaced by des_ede3_cbc

-

des_ede3_cbf, des3_cbf and des3_cfb should be replaced by des_ede3_cfb.

-

aes_cbc128 should be replaced by aes_128_cbc.

-

aes_cbc256 should be replaced by aes_256_cbc.

- - -

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

+

Ciphers known by the CRYPTO application when using the + old API.

+

Note that this list might be reduced if the underlying libcrypto does not support all of them.

- + + + + + + -

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

Alternative, old names of ciphers known by the CRYPTO application when using the + old API. + See Retired cipher names for names to + use instead to be prepared for an easy convertion to the + new API.

+

Note that this list might be reduced if the underlying libcrypto does not support all of them.

@@ -547,6 +578,7 @@ +

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

@@ -575,117 +607,171 @@

This is a more developed variant of the older run_time_error().

+

The exception is:

+
+	  {Tag, {C_FileName,LineNumber}, Description}
+
+	   Tag = badarg | notsup | error
+	   C_FileName = string()
+	   LineNumber = integer()
+	   Description = string()
+	
+

It is like the older type an exception of the error class. In addition they contain a descriptive text in English. That text is targeted to a developer. Examples are "Bad key size" or "Cipher id is not an atom".

-

The exceptions are:

+

The exception tags are:

- {badarg, Description::string()} + badarg

Signifies that one or more arguments are of wrong data type or are otherwise badly formed.

- {notsup, Description::string()} + notsup

Signifies that the algorithm is known but is not supported by current underlying libcrypto or explicitly disabled when building that one.

- {error, Description::string()} + error

An error condition that should not occur, for example a memory allocation failed or the underlying cryptolib returned an error code, for example "Can't initialize context, step 1". Thoose text usually needs searching the C-code to be understood.

+

To catch the exception, use for example:

+ + try crypto:crypto_init(Ciph, Key, IV, true) + catch + error:{Tag, {C_FileName,LineNumber}, Description} -> + do_something(......) + ..... + end +
+
+ New API +
+ - - Encrypt PlainText according to Type block cipher + + Initializes a series of encryptions or decryptions -

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

As crypto_init/4 but for ciphers without IVs.

+
+
+ + + + Initializes a series of encryptions or decryptions + +

Part of the new API. + Initializes a series of encryptions or decryptions. + The actual encryption or decryption is done by + crypto_update/2. +

+

For encryption, set the EncryptFlag to true. +

+

See examples in the User's Guide.

- - Decrypt CipherText according to Type block cipher + + Initializes a series of encryptions or decryptions where the IV is provided later -

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

Part of the new API. + Initializes a series of encryptions or decryptions where the IV is provided later. + The actual encryption or decryption is done by + crypto_update_dyn_iv/3. +

+

For encryption, set the EncryptFlag to true. +

+

See examples in the User's Guide.

- block_encrypt(Type, Key, Ivec, PlainText) -> CipherText | Error - block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag} | Error - block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} | Error - Encrypt PlainText according to Type block cipher - - Type = block_cipher_iv() - AeadType = aead_cipher() - Key = key() | des3_key() - PlainText = iodata() - AAD = IVec = CipherText = CipherTag = binary() - TagLength = 1..16 - Error = run_time_error() - + + Do an actual crypto operation on a part of the full text -

Encrypt PlainText according to Type block cipher. - IVec is an arbitrary initializing vector.

-

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

Part of the new API. + Do an actual crypto operation on a part of the full text. + The State should be created with + crypto_init/3 + or + crypto_init/4. +

+

See examples in the User's Guide.

- block_decrypt(Type, Key, Ivec, CipherText) -> PlainText | Error - block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | Error - Decrypt CipherText according to Type block cipher - - Type = block_cipher_iv() - AeadType = aead_cipher() - Key = key() | des3_key() - PlainText = iodata() - AAD = IVec = CipherText = CipherTag = binary() - Error = BadTag | run_time_error() - BadTag = error - + + Do an actual crypto operation on a part of the full text and the IV is supplied for each part -

Decrypt CipherText according to Type block cipher. - IVec is an arbitrary initializing vector.

-

In AEAD (Authenticated Encryption with Associated Data) mode, decrypt - 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 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. +

Part of the new API. + Do an actual crypto operation on a part of the full text and the IV is supplied for each part. + The State should be created with + crypto_init_dyn_iv/3. +

+

See examples in the User's Guide.

- + + + Do a complete encrypt or decrypt of the full text + +

As crypto_one_time/5 but for ciphers without IVs.

+
+
+ + + + Do a complete encrypt or decrypt of the full text + +

Part of the new API. + Do a complete encrypt or decrypt of the full text. +

+

For encryption, set the EncryptFlag to true. +

+

See examples in the User's Guide. +

+
+
+ + + + + Do a complete encrypt or decrypt with an AEAD cipher of the full text + +

Part of the new API. + Do a complete encrypt or decrypt with an AEAD cipher of the full text. +

+

For encryption, set the EncryptFlag to true. +

+

See examples in the User's Guide. +

+
+
+
+ +
+ API kept from previous versions +
+ + + Convert binary representation, of an integer, to an Erlang integer. @@ -928,7 +1014,7 @@ cipher algorithm in question.

-

The ciphers aes_cbc, aes_cfb8, aes_cfb128, aes_ctr, +

The ciphers aes_cbc, aes_cfb8, aes_cfb128, aes_ctr, aes_ecb, aes_gcm and aes_ccm has no keylength in the Type as opposed to for example aes_128_ctr. They adapt to the length of the key provided in the encrypt and decrypt function. Therefor it is impossible to return a valid keylength @@ -1094,7 +1180,7 @@ rand_seed_s/0.

- When using the state object from this function the + When using the state object from this function the rand functions using it may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness". @@ -1120,7 +1206,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ rand:seed_s/1.

- When using the state object from this function the + When using the state object from this function the rand functions using it may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness". @@ -1129,7 +1215,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

The state returned from this function cannot be used to get a reproducable random sequence as from - the other + the other rand functions, since reproducability does not match cryptographically safe. @@ -1160,7 +1246,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ rand_seed_alg_s/1.

- When using the state object from this function the + When using the state object from this function the rand functions using it may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness". @@ -1227,7 +1313,7 @@ FloatValue = rand:uniform(). % again of 56 bits that makes calculations fast on 64 bit machines.

- When using the state object from this function the + When using the state object from this function the rand functions using it may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness". @@ -1248,7 +1334,7 @@ FloatValue = rand:uniform(). % again

The state returned from this function cannot be used to get a reproducable random sequence as from - the other + the other rand functions, since reproducability does not match cryptographically safe. @@ -1331,56 +1417,6 @@ FloatValue = rand:uniform(). % again - - - - -

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

-

For keylengths see the - User's Guide. -

-
-
- - - - - -

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

-
-
- - - - - -

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 - stream_init. - NewState must be passed into the next call to stream_encrypt.

-
-
- - - - - -

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 - stream_init. - NewState must be passed into the next call to stream_decrypt.

-
-
- Provide a list of available crypto algorithms. @@ -1440,6 +1476,12 @@ FloatValue = rand:uniform(). % again +
+
+ Engine API +
+ + @@ -1752,5 +1794,152 @@ FloatValue = rand:uniform(). % again +
+ Old API +
+ + + + + Encrypt PlainText according to Type block cipher + +

Don't use this function for new programs! Use the-new-api.

+

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

+
+
+ + + + Decrypt CipherText according to Type block cipher + +

Don't use this function for new programs! Use the new api.

+

Decrypt CipherText 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_encrypt(Type, Key, Ivec, PlainText) -> CipherText | Error + block_encrypt(AeadType, Key, Ivec, {AAD, PlainText}) -> {CipherText, CipherTag} | Error + block_encrypt(aes_gcm | aes_ccm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} | Error + Encrypt PlainText according to Type block cipher + + Type = block_cipher_with_iv() + AeadType = aead_cipher() + Key = key() | des3_key() + PlainText = iodata() + AAD = IVec = CipherText = CipherTag = binary() + TagLength = 1..16 + Error = run_time_error() + + +

Don't use this function for new programs! Use the new api.

+

Encrypt PlainText according to Type block cipher. + IVec is an arbitrary initializing vector.

+

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

+
+
+ + + block_decrypt(Type, Key, Ivec, CipherText) -> PlainText | Error + block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | Error + Decrypt CipherText according to Type block cipher + + Type = block_cipher_with_iv() + AeadType = aead_cipher() + Key = key() | des3_key() + PlainText = iodata() + AAD = IVec = CipherText = CipherTag = binary() + Error = BadTag | run_time_error() + BadTag = error + + +

Don't use this function for new programs! Use the new api.

+

Decrypt CipherText according to Type block cipher. + IVec is an arbitrary initializing vector.

+

In AEAD (Authenticated Encryption with Associated Data) mode, decrypt + 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 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. +

+
+
+ + + + + +

Don't use this function for new programs! Use the new api.

+

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

+

For keylengths see the + User's Guide. +

+
+
+ + + + + +

Don't use this function for new programs! Use the new api.

+

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

+
+
+ + + + + +

Don't use this function for new programs! Use the new api.

+

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 + stream_init. + NewState must be passed into the next call to stream_encrypt.

+
+
+ + + + + +

Don't use this function for new programs! Use the new api.

+

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 + stream_init. + NewState must be passed into the next call to stream_decrypt.

+
+
+ +
+ diff --git a/lib/crypto/doc/src/new_api.xml b/lib/crypto/doc/src/new_api.xml new file mode 100644 index 0000000000..66eeefb692 --- /dev/null +++ b/lib/crypto/doc/src/new_api.xml @@ -0,0 +1,209 @@ + + + + +
+ + 20142019 + 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. + + + + New and Old API + Hans Nilsson + + 2019-08-22 + A + new_api.xml +
+

+ This chapter describes the new api to encryption and decryption. +

+ +
+ Background +

The CRYPTO app has evolved during its lifetime. Since also the OpenSSL cryptolib has changed the + API several times, there are parts of the CRYPTO app that uses a very old one internally and + other parts that uses the latest one. The internal definitions of e.g cipher names was a bit hard + to maintain. +

+

It turned out that using the old api in the new way (more about that later), and still keep it + backwards compatible was not possible. Specially as more precision in the error messages was wanted + it could not be combined with the old standard. +

+

Therefore the old api (see next section) is kept for now but internally implemented with new primitives. +

+
+ +
+ The old API +

The old functions - not recommended for new programs - are:

+ + block_encrypt/3 + block_encrypt/4 + block_decrypt/3 + block_decrypt/4 + stream_init/2 + stream_init/3 + stream_encrypt/2 + stream_decrypt/2 + +

They are not deprecated for now, but may be in a future. +

+
+ +
+ The new API +

The new functions for encrypting or decrypting one single text in one binary are: +

+ + crypto_one_time/4 + crypto_one_time/5 + crypto_aead/6 + crypto_aead/7 + +

The crypto_aead functions are for the ciphers of mode ccm or + gcm, and for the cipher chacha20-poly1305. +

+

For repeated encryption or decryption of a text divided in parts, where the parts are handled + one by one but in sequence, the functions are: +

+ + crypto_init/4 + crypto_init/3 + crypto_update/2 + +

The crypto_init initialies a cipher operation and one or more calls of + crypto_update does the acual encryption or decryption. Note that AEAD ciphers + can't be handled this way due to their nature. +

+

Finally, for repeated encryption or decryption of a text divided in parts where the + same cipher and same key is used, but a new initialization vector (nounce) should be applied + for each part, the functions are: +

+ + crypto_init_dyn_iv/3 + crypto_update_dyn_iv/3 + +

An example of where those functions are needed, is when handling the TLS protocol.

+ +
+ Examples of crypto_init/4 and crypto_update/2 +

Encrypting two blocks:

+ + 1> crypto:start(). + ok + 2> Key = <<1:128>>, + 2> IV = <<0:128>>, + 2> StateEnc = crypto:crypto_init(aes_128_ctr, Key, IV, true). % encrypt -> true + #Ref<0.3768901617.1128660993.124047> + 3> crypto:crypto_update(StateEnc, <<"First bytes">>). + <<67,44,216,166,25,130,203,5,66,6,162>> + 4> crypto:crypto_update(StateEnc, <<"Second bytes">>). + <<16,79,94,115,234,197,94,253,16,144,151,41>> + 5> + 5> StateDec = crypto:crypto_init(aes_128_ctr, Key, IV, false). % decrypt -> false + #Ref<0.3768901617.1128660994.124255> + 6> crypto:crypto_update(StateDec, <<67,44,216,166,25,130,203>>). + <<"First b">> + 7> crypto:crypto_update(StateDec, <<5,66,6,162,16,79,94,115,234,197, + 94,253,16,144,151>>). + <<"ytesSecond byte">> + 8> crypto:crypto_update(StateDec, <<41>>). + <<"s">> + 9> + +

Note that the data that the StateEnc and StateDec references are destructivly + updated by the calls to crypto_update/2. + This is to gain time in the calls of the nifs interfacing the cryptolib. In a loop where the + state is saved in the loop's state, it also saves one update of the loop state per crypto operation. +

+

For example, a simple server receiving text parts to encrypt and send the result back to the + one who sent them (the Requester): +

+ + encode(Crypto, Key, IV) -> + crypto_loop(crypto:crypto_init(Crypto, Key, IV, true)). + + crypto_loop(State) -> + receive + {Text, Requester} -> + Requester ! crypto:crypto_update(State, Text), + loop(State) + end. + +

Note that the State is not updated. Such updates could be costly if the loop state + is a tuple or record with many elements. +

+
+ +
+ Example of crypto_one_time/5 +

The same eample as in the + previous section, + but now with one call to crypto_one_time/5: +

+ + 2> Key = <<1:128>>, + 2> IV = <<0:128>>, + 2> Txt = [<<"First bytes">>,<<"Second bytes">>], + 2> crypto:crypto_one_time(aes_128_ctr, Key, IV, Txt, true). + <<67,44,216,166,25,130,203,5,66,6,162,16,79,94,115,234, + 197,94,253,16,144,151,41>> + 3> + +

The [<<"First bytes">>,<<"Second bytes">>] could of course have been one + single binary: <<"First bytesSecond bytes">>. +

+
+
+ +
+ Retired cipher names +

This table lists the retired cipher names in the first column and suggests names to replace them with + in the second column. +

+

The new names follows the OpenSSL libcrypto names. The format is ALGORITM_KEYSIZE_MODE. +

+

Examples of algorithms are aes, chacha20 and des. The keysize is the number of bits + and examples of the mode are cbc, ctr and gcm. The mode may be followed by a number depending + on the mode. An example is the ccm mode which has a variant called ccm8 where the so called tag + has a length of eight bits. +

+

The old names had by time lost any common naming which the new names now introduces. The new names include + the key length which improves the error checking in the lower levels of the crypto application. +

+ + + Instead of: Use: + + aes_cbc128 aes_128_cbc + aes_cbc256 aes_256_cbc + aes_cbc aes_128_cbc, aes_192_cbc, aes_256_cbc + aes_ccm aes_128_ccm, aes_192_ccm, aes_256_ccm + aes_cfb128 aes_128_cfb128, aes_192_cfb128, aes_256_cfb128 + aes_cfb8 aes_128_cfb8, aes_192_cfb8, aes_256_cfb8 + aes_ctr aes_128_ctr, aes_192_ctr, aes_256_ctr + aes_gcm aes_128_gcm, aes_192_gcm, aes_256_gcm + des3_cbc des_ede3_cbc + des3_cbf des_ede3_cfb + des3_cfb des_ede3_cfb + des_ede3 des_ede3_cbc + des_ede3_cbf des_ede3_cfb + +
+
+ +
diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml index 2dfc966609..134f900d4c 100644 --- a/lib/crypto/doc/src/usersguide.xml +++ b/lib/crypto/doc/src/usersguide.xml @@ -51,4 +51,5 @@ + -- cgit v1.2.3