aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto')
-rw-r--r--lib/crypto/c_src/algorithms.c4
-rw-r--r--lib/crypto/c_src/api_ng.c12
-rw-r--r--lib/crypto/c_src/cipher.c13
-rw-r--r--lib/crypto/c_src/dh.c8
-rw-r--r--lib/crypto/c_src/dss.c4
-rw-r--r--lib/crypto/c_src/dss.h2
-rw-r--r--lib/crypto/c_src/openssl_config.h19
-rw-r--r--lib/crypto/c_src/otp_test_engine.c2
-rw-r--r--lib/crypto/c_src/pkey.c31
-rw-r--r--lib/crypto/doc/src/crypto.xml52
-rw-r--r--lib/crypto/doc/src/new_api.xml46
-rw-r--r--lib/crypto/doc/src/notes.xml16
-rw-r--r--lib/crypto/src/crypto.erl47
-rw-r--r--lib/crypto/test/crypto_SUITE.erl14
-rw-r--r--lib/crypto/test/engine_SUITE.erl30
-rw-r--r--lib/crypto/vsn.mk2
16 files changed, 222 insertions, 80 deletions
diff --git a/lib/crypto/c_src/algorithms.c b/lib/crypto/c_src/algorithms.c
index 1d45ed9df2..20707c0531 100644
--- a/lib/crypto/c_src/algorithms.c
+++ b/lib/crypto/c_src/algorithms.c
@@ -80,8 +80,12 @@ void init_algorithms_types(ErlNifEnv* env)
algo_pubkey_cnt = 0;
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "rsa");
+#ifdef HAVE_DSA
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "dss");
+#endif
+#ifdef HAVE_DH
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "dh");
+#endif
#if defined(HAVE_EC)
#if !defined(OPENSSL_NO_EC2M)
algo_pubkey[algo_pubkey_cnt++] = enif_make_atom(env, "ec_gf2m");
diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c
index 107723d2cb..3408ba1b88 100644
--- a/lib/crypto/c_src/api_ng.c
+++ b/lib/crypto/c_src/api_ng.c
@@ -522,6 +522,11 @@ ERL_NIF_TERM ng_crypto_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
const struct cipher_type_t *cipherp;
ERL_NIF_TERM ret;
+ ctx_res.ctx = NULL;
+#if !defined(HAVE_EVP_AES_CTR)
+ ctx_res.env = NULL;
+#endif
+
if (!get_init_args(env, &ctx_res, argv[0], argv[1], argv[2], argv[4], &cipherp, &ret))
goto ret;
@@ -530,9 +535,16 @@ ERL_NIF_TERM ng_crypto_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
ret:
if (ctx_res.ctx)
EVP_CIPHER_CTX_free(ctx_res.ctx);
+
+#if !defined(HAVE_EVP_AES_CTR)
+ if (ctx_res.env)
+ enif_free_env(ctx_res.env);
+#endif
+
return ret;
}
+
ERL_NIF_TERM ng_crypto_one_time_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Cipher, Key, IVec, Data, Encrypt) % if no IV for the Cipher, set IVec = <<>>
*/
diff --git a/lib/crypto/c_src/cipher.c b/lib/crypto/c_src/cipher.c
index 13de3562e8..8f0c93c5db 100644
--- a/lib/crypto/c_src/cipher.c
+++ b/lib/crypto/c_src/cipher.c
@@ -20,10 +20,10 @@
#include "cipher.h"
-#ifdef OPENSSL_NO_DES
-#define COND_NO_DES_PTR(Ptr) (NULL)
-#else
+#ifdef HAVE_DES
#define COND_NO_DES_PTR(Ptr) (Ptr)
+#else
+#define COND_NO_DES_PTR(Ptr) (NULL)
#endif
static struct cipher_type_t cipher_types[] =
@@ -50,10 +50,17 @@ static struct cipher_type_t cipher_types[] =
{{"des_ede3_cfb"}, {NULL}, 0, 0},
#endif
+#ifdef HAVE_BF
{{"blowfish_cbc"}, {&EVP_bf_cbc}, 0, NO_FIPS_CIPHER},
{{"blowfish_cfb64"}, {&EVP_bf_cfb64}, 0, NO_FIPS_CIPHER},
{{"blowfish_ofb64"}, {&EVP_bf_ofb}, 0, NO_FIPS_CIPHER},
{{"blowfish_ecb"}, {&EVP_bf_ecb}, 0, NO_FIPS_CIPHER | ECB_BUG_0_9_8L},
+#else
+ {{"blowfish_cbc"}, {NULL}, 0, 0},
+ {{"blowfish_cfb64"}, {NULL}, 0, 0},
+ {{"blowfish_ofb64"}, {NULL}, 0, 0},
+ {{"blowfish_ecb"}, {NULL}, 0, 0},
+#endif
{{"aes_cbc"}, {&EVP_aes_128_cbc}, 16, 0},
{{"aes_cbc"}, {&EVP_aes_192_cbc}, 24, 0},
diff --git a/lib/crypto/c_src/dh.c b/lib/crypto/c_src/dh.c
index 38eb534d99..13a2336f25 100644
--- a/lib/crypto/c_src/dh.c
+++ b/lib/crypto/c_src/dh.c
@@ -23,6 +23,7 @@
ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */
+#ifdef HAVE_DH
DH *dh_params = NULL;
unsigned int mpint; /* 0 or 4 */
ERL_NIF_TERM head, tail;
@@ -187,10 +188,14 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
#endif
return ret;
+#else
+ return enif_raise_exception(env, atom_notsup);
+#endif
}
ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */
+#ifdef HAVE_DH
BIGNUM *other_pub_key = NULL;
BIGNUM *dh_p = NULL;
BIGNUM *dh_g = NULL;
@@ -291,4 +296,7 @@ ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
DH_free(dh_priv);
return ret;
+#else
+ return enif_raise_exception(env, atom_notsup);
+#endif
}
diff --git a/lib/crypto/c_src/dss.c b/lib/crypto/c_src/dss.c
index 9bf8eb3ce0..63268f0f2b 100644
--- a/lib/crypto/c_src/dss.c
+++ b/lib/crypto/c_src/dss.c
@@ -21,6 +21,8 @@
#include "dss.h"
#include "bn.h"
+#ifdef HAVE_DSA
+
int get_dss_private_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa)
{
/* key=[P,Q,G,KEY] */
@@ -142,3 +144,5 @@ int get_dss_public_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa)
BN_free(dsa_y);
return 0;
}
+
+#endif
diff --git a/lib/crypto/c_src/dss.h b/lib/crypto/c_src/dss.h
index 3275657e98..07e28ca7c5 100644
--- a/lib/crypto/c_src/dss.h
+++ b/lib/crypto/c_src/dss.h
@@ -23,7 +23,9 @@
#include "common.h"
+#ifdef HAVE_DSA
int get_dss_private_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa);
int get_dss_public_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa);
+#endif
#endif /* E_DSS_H__ */
diff --git a/lib/crypto/c_src/openssl_config.h b/lib/crypto/c_src/openssl_config.h
index f926f8af13..339eb5b8f4 100644
--- a/lib/crypto/c_src/openssl_config.h
+++ b/lib/crypto/c_src/openssl_config.h
@@ -25,9 +25,8 @@
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
-#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
-#endif /* #ifndef OPENSSL_NO_DES */
+
/* #include <openssl/idea.h> This is not supported on the openssl OTP requires */
#include <openssl/dsa.h>
#include <openssl/rsa.h>
@@ -166,6 +165,22 @@
# define HAVE_BLAKE2
#endif
+#ifndef OPENSSL_NO_BF
+# define HAVE_BF
+#endif
+
+#ifndef OPENSSL_NO_DES
+# define HAVE_DES
+#endif
+
+#ifndef OPENSSL_NO_DH
+# define HAVE_DH
+#endif
+
+#ifndef OPENSSL_NO_DSA
+# define HAVE_DSA
+#endif
+
#ifndef OPENSSL_NO_MD4
# define HAVE_MD4
#endif
diff --git a/lib/crypto/c_src/otp_test_engine.c b/lib/crypto/c_src/otp_test_engine.c
index 4a155becf8..c3bd9dfb55 100644
--- a/lib/crypto/c_src/otp_test_engine.c
+++ b/lib/crypto/c_src/otp_test_engine.c
@@ -160,7 +160,7 @@ static int test_engine_md5_update(EVP_MD_CTX *ctx,const void *data, size_t count
static int test_engine_md5_final(EVP_MD_CTX *ctx,unsigned char *md) {
#ifdef OLD
- fprintf(stderr, "MD5 final size of EVP_MD: %lu\r\n", sizeof(EVP_MD));
+ fprintf(stderr, "MD5 final size of EVP_MD: %lu\r\n", (unsigned long)sizeof(EVP_MD));
if (!MD5_Final(md, data(ctx)))
goto err;
diff --git a/lib/crypto/c_src/pkey.c b/lib/crypto/c_src/pkey.c
index 638bb588fa..a1e2677b34 100644
--- a/lib/crypto/c_src/pkey.c
+++ b/lib/crypto/c_src/pkey.c
@@ -254,7 +254,9 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
{
EVP_PKEY *result = NULL;
RSA *rsa = NULL;
+#ifdef HAVE_DSA
DSA *dsa = NULL;
+#endif
#if defined(HAVE_EC)
EC_KEY *ec = NULL;
#endif
@@ -327,6 +329,7 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
return PKEY_NOTSUP;
#endif
} else if (algorithm == atom_dss) {
+#ifdef HAVE_DSA
if ((dsa = DSA_new()) == NULL)
goto err;
if (!get_dss_private_key(env, key, dsa))
@@ -340,9 +343,9 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
dsa = NULL;
} else {
+#endif
return PKEY_BADARG;
}
-
goto done;
err:
@@ -357,8 +360,10 @@ static int get_pkey_private_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_
enif_free(id);
if (rsa)
RSA_free(rsa);
+#ifdef HAVE_DSA
if (dsa)
DSA_free(dsa);
+#endif
#ifdef HAVE_EC
if (ec)
EC_KEY_free(ec);
@@ -377,7 +382,9 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
{
EVP_PKEY *result = NULL;
RSA *rsa = NULL;
+#ifdef HAVE_DSA
DSA *dsa = NULL;
+#endif
#if defined(HAVE_EC)
EC_KEY *ec = NULL;
#endif
@@ -449,6 +456,7 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
return PKEY_NOTSUP;
#endif
} else if (algorithm == atom_dss) {
+#ifdef HAVE_DSA
if ((dsa = DSA_new()) == NULL)
goto err;
@@ -461,7 +469,9 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
goto err;
/* On success, result owns dsa */
dsa = NULL;
-
+#else
+ return PKEY_NOTSUP;
+#endif
} else {
return PKEY_BADARG;
}
@@ -480,8 +490,10 @@ static int get_pkey_public_key(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF_T
enif_free(id);
if (rsa)
RSA_free(rsa);
+#ifdef HAVE_DSA
if (dsa)
DSA_free(dsa);
+#endif
#ifdef HAVE_EC
if (ec)
EC_KEY_free(ec);
@@ -518,7 +530,9 @@ ERL_NIF_TERM pkey_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
unsigned char *tbs; /* data to be signed */
size_t tbslen;
RSA *rsa = NULL;
+#ifdef HAVE_DSA
DSA *dsa = NULL;
+#endif
#if defined(HAVE_EC)
EC_KEY *ec = NULL;
#endif
@@ -706,8 +720,10 @@ enif_get_atom(env,argv[1],buf,1024,ERL_NIF_LATIN1); printf("hash=%s ",buf);
enif_release_binary(&sig_bin);
if (rsa)
RSA_free(rsa);
+#ifdef HAVE_DSA
if (dsa)
DSA_free(dsa);
+#endif
#ifdef HAVE_EC
if (ec)
EC_KEY_free(ec);
@@ -744,7 +760,9 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
size_t tbslen;
ERL_NIF_TERM ret;
RSA *rsa = NULL;
+#ifdef HAVE_DSA
DSA *dsa = NULL;
+#endif
#ifdef HAVE_EC
EC_KEY *ec = NULL;
#endif
@@ -890,8 +908,10 @@ ERL_NIF_TERM pkey_verify_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]
EVP_PKEY_free(pkey);
if (rsa)
RSA_free(rsa);
+#ifdef HAVE_DSA
if (dsa)
DSA_free(dsa);
+#endif
#ifdef HAVE_EC
if (ec)
EC_KEY_free(ec);
@@ -1358,7 +1378,9 @@ ERL_NIF_TERM privkey_to_pubkey_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ERL_NIF_TERM ret;
EVP_PKEY *pkey = NULL;
RSA *rsa = NULL;
+#ifdef HAVE_DSA
DSA *dsa = NULL;
+#endif
ERL_NIF_TERM result[8];
ASSERT(argc == 2);
@@ -1383,6 +1405,7 @@ ERL_NIF_TERM privkey_to_pubkey_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ret = enif_make_list_from_array(env, result, 2);
+#ifdef HAVE_DSA
} else if (argv[0] == atom_dss) {
const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
@@ -1402,7 +1425,7 @@ ERL_NIF_TERM privkey_to_pubkey_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
goto err;
ret = enif_make_list_from_array(env, result, 4);
-
+#endif
} else if (argv[0] == atom_ecdsa) {
#if defined(HAVE_EC)
/* not yet implemented
@@ -1452,8 +1475,10 @@ ERL_NIF_TERM privkey_to_pubkey_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
done:
if (rsa)
RSA_free(rsa);
+#ifdef HAVE_DSA
if (dsa)
DSA_free(dsa);
+#endif
if (pkey)
EVP_PKEY_free(pkey);
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 14efc5c6f6..641738247e 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -671,11 +671,12 @@
<fsummary>Initializes a series of encryptions or decryptions</fsummary>
<desc>
<p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
- Initializes a series of encryptions or decryptions.
+ Initializes a series of encryptions or decryptions and creates an internal state
+ with a reference that is returned.
The actual encryption or decryption is done by
<seealso marker="crypto#crypto_update/2">crypto_update/2</seealso>.
</p>
- <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>. For decryption, set it to <c>false</c>.
</p>
<p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
@@ -683,15 +684,17 @@
</func>
<func>
- <name name="crypto_init_dyn_iv" arity="3" since="OTP 22.0"/>
- <fsummary>Initializes a series of encryptions or decryptions where the IV is provided later</fsummary>
+ <name name="crypto_update" arity="2" since="OTP 22.0"/>
+ <fsummary>Do an actual crypto operation on a part of the full text</fsummary>
<desc>
<p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
- Initializes a series of encryptions or decryptions where the IV is provided later.
- The actual encryption or decryption is done by
- <seealso marker="crypto#crypto_update_dyn_iv/3">crypto_update_dyn_iv/3</seealso>.
- </p>
- <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ It does an actual crypto operation on a part of the full text. If the part is less
+ than a number of full blocks, only the full blocks (possibly none) are encrypted
+ or decrypted and the remaining bytes are saved to the next <c>crypto_update</c> operation.
+ The <c>State</c> should be created with
+ <seealso marker="crypto#crypto_init/3">crypto_init/3</seealso>
+ or
+ <seealso marker="crypto#crypto_init/4">crypto_init/4</seealso>.
</p>
<p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
@@ -699,15 +702,15 @@
</func>
<func>
- <name name="crypto_update" arity="2" since="OTP 22.0"/>
- <fsummary>Do an actual crypto operation on a part of the full text</fsummary>
+ <name name="crypto_dyn_iv_init" arity="3" since="OTP 22.0"/>
+ <fsummary>Initializes a series of encryptions or decryptions where the IV is provided later</fsummary>
<desc>
<p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
- Do an actual crypto operation on a part of the full text.
- The <c>State</c> should be created with
- <seealso marker="crypto#crypto_init/3">crypto_init/3</seealso>
- or
- <seealso marker="crypto#crypto_init/4">crypto_init/4</seealso>.
+ Initializes a series of encryptions or decryptions where the IV is provided later.
+ The actual encryption or decryption is done by
+ <seealso marker="crypto#crypto_dyn_iv_update/3">crypto_dyn_iv_update/3</seealso>.
+ </p>
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>. For decryption, set it to <c>false</c>.
</p>
<p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
@@ -715,13 +718,13 @@
</func>
<func>
- <name name="crypto_update_dyn_iv" arity="3" since="OTP 22.0"/>
+ <name name="crypto_dyn_iv_update" arity="3" since="OTP 22.0"/>
<fsummary>Do an actual crypto operation on a part of the full text and the IV is supplied for each part</fsummary>
<desc>
<p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
Do an actual crypto operation on a part of the full text and the IV is supplied for each part.
The <c>State</c> should be created with
- <seealso marker="crypto#crypto_init_dyn_iv/3">crypto_init_dyn_iv/3</seealso>.
+ <seealso marker="crypto#crypto_dyn_iv_init/3">crypto_dyn_iv_init/3</seealso>.
</p>
<p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
@@ -743,7 +746,7 @@
<p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
Do a complete encrypt or decrypt of the full text.
</p>
- <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>. For decryption, set it to <c>false</c>.
</p>
<p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
@@ -751,14 +754,19 @@
</func>
<func>
- <name name="crypto_aead" arity="6" since="OTP 22.0"/>
- <name name="crypto_aead" arity="7" since="OTP 22.0"/>
+ <name name="crypto_one_time_aead" arity="6" since="OTP 22.0"/>
+ <name name="crypto_one_time_aead" arity="7" since="OTP 22.0"/>
<fsummary>Do a complete encrypt or decrypt with an AEAD cipher of the full text</fsummary>
<desc>
<p>Part of the <seealso marker="crypto:new_api#the-new-api">new API</seealso>.
Do a complete encrypt or decrypt with an AEAD cipher of the full text.
</p>
- <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c>.
+ <p>For encryption, set the <c>EncryptFlag</c> to <c>true</c> and set the <c>TagOrTagLength</c>
+ to the wanted size of the tag, that is, the tag length. If the default length is wanted, the
+ <c>crypto_aead/6</c> form may be used.
+ </p>
+ <p>For decryption, set the <c>EncryptFlag</c> to <c>false</c> and put the tag to be checked
+ in the argument <c>TagOrTagLength</c>.
</p>
<p>See <seealso marker="crypto:new_api#the-new-api">examples in the User's Guide.</seealso>
</p>
diff --git a/lib/crypto/doc/src/new_api.xml b/lib/crypto/doc/src/new_api.xml
index 66eeefb692..79096b55e8 100644
--- a/lib/crypto/doc/src/new_api.xml
+++ b/lib/crypto/doc/src/new_api.xml
@@ -40,7 +40,7 @@
to maintain.
</p>
<p>It turned out that using the old api in the new way (more about that later), and still keep it
- backwards compatible was not possible. Specially as more precision in the error messages was wanted
+ backwards compatible, was not possible. Specially as more precision in the error messages was wanted
it could not be combined with the old standard.
</p>
<p>Therefore the old api (see next section) is kept for now but internally implemented with new primitives.
@@ -66,26 +66,31 @@
<section>
<title>The new API</title>
- <p>The new functions for encrypting or decrypting one single text in one binary are:
+ <p>The new functions for encrypting or decrypting one single binary are:
</p>
<list>
<item><seealso marker="crypto#crypto_one_time/4">crypto_one_time/4</seealso></item>
<item><seealso marker="crypto#crypto_one_time/5">crypto_one_time/5</seealso></item>
- <item><seealso marker="crypto#crypto_aead/6">crypto_aead/6</seealso></item>
- <item><seealso marker="crypto#crypto_aead/7">crypto_aead/7</seealso></item>
+ <item><seealso marker="crypto#crypto_one_time_aead/6">crypto_one_time_aead/6</seealso></item>
+ <item><seealso marker="crypto#crypto_one_time_aead/7">crypto_one_time_aead/7</seealso></item>
</list>
- <p>The <c>crypto_aead</c> functions are for the ciphers of mode <c>ccm</c> or
+ <p>In those functions the internal crypto state is first created and initialized
+ with the cipher type, the key and possibly other data. Then the data is encrypted or decrypted,
+ the crypto state is de-allocated and the result of the crypto operation is returned.
+ </p>
+ <p>The <c>crypto_one_time_aead</c> functions are for the ciphers of mode <c>ccm</c> or
<c>gcm</c>, and for the cipher <c>chacha20-poly1305</c>.
</p>
- <p>For repeated encryption or decryption of a text divided in parts, where the parts are handled
- one by one but in sequence, the functions are:
+ <p>For repeated encryption or decryption of a text divided in parts, where the internal
+ crypto state is initialized once, and then many binaries are encrypted or decrypted with
+ the same state, the functions are:
</p>
<list>
<item><seealso marker="crypto#crypto_init/4">crypto_init/4</seealso></item>
<item><seealso marker="crypto#crypto_init/3">crypto_init/3</seealso></item>
<item><seealso marker="crypto#crypto_update/2">crypto_update/2</seealso></item>
</list>
- <p>The <c>crypto_init</c> initialies a cipher operation and one or more calls of
+ <p>The <c>crypto_init</c> initialies an internal cipher state, and one or more calls of
<c>crypto_update</c> does the acual encryption or decryption. Note that AEAD ciphers
can't be handled this way due to their nature.
</p>
@@ -94,8 +99,8 @@
for each part, the functions are:
</p>
<list>
- <item><seealso marker="crypto#crypto_init_dyn_iv/3">crypto_init_dyn_iv/3</seealso></item>
- <item><seealso marker="crypto#crypto_update_dyn_iv/3">crypto_update_dyn_iv/3</seealso></item>
+ <item><seealso marker="crypto#crypto_dyn_iv_init/3">crypto_dyn_iv_init/3</seealso></item>
+ <item><seealso marker="crypto#crypto_dyn_iv_update/3">crypto_dyn_iv_update/3</seealso></item>
</list>
<p>An example of where those functions are needed, is when handling the TLS protocol.</p>
@@ -105,8 +110,8 @@
<code type="erl">
1> crypto:start().
ok
- 2> Key = &lt;&lt;1:128>>,
- 2> IV = &lt;&lt;0:128>>,
+ 2> Key = &lt;&lt;1:128>>.
+ 2> IV = &lt;&lt;0:128>>.
2> StateEnc = crypto:crypto_init(aes_128_ctr, Key, IV, true). % encrypt -> true
#Ref&lt;0.3768901617.1128660993.124047>
3> crypto:crypto_update(StateEnc, &lt;&lt;"First bytes">>).
@@ -125,8 +130,8 @@
&lt;&lt;"s">>
9>
</code>
- <p>Note that the data that the <c>StateEnc</c> and <c>StateDec</c> references are destructivly
- updated by the calls to <seealso marker="crypto#crypto_update/2">crypto_update/2</seealso>.
+ <p>Note that the internal data that the <c>StateEnc</c> and <c>StateDec</c> references are
+ destructivly updated by the calls to <seealso marker="crypto#crypto_update/2">crypto_update/2</seealso>.
This is to gain time in the calls of the nifs interfacing the cryptolib. In a loop where the
state is saved in the loop's state, it also saves one update of the loop state per crypto operation.
</p>
@@ -135,7 +140,7 @@
</p>
<code type="erl">
encode(Crypto, Key, IV) ->
- crypto_loop(crypto:crypto_init(Crypto, Key, IV, true)).
+ crypto_loop(crypto:crypto_init(Crypto, Key, IV, true)).
crypto_loop(State) ->
receive
@@ -144,20 +149,17 @@
loop(State)
end.
</code>
- <p>Note that the <c>State</c> is not updated. Such updates could be costly if the loop state
- is a tuple or record with many elements.
- </p>
- </section>
+ </section>
<section>
<title>Example of crypto_one_time/5</title>
- <p>The same eample as in the
+ <p>The same example as in the
<seealso marker="#examples-of-crypto_init-4-and-crypto_update-2">previous section</seealso>,
but now with one call to <c>crypto_one_time/5</c>:
</p>
<code>
- 2> Key = &lt;&lt;1:128>>,
- 2> IV = &lt;&lt;0:128>>,
+ 2> Key = &lt;&lt;1:128>>.
+ 2> IV = &lt;&lt;0:128>>.
2> Txt = [&lt;&lt;"First bytes">>,&lt;&lt;"Second bytes">>],
2> crypto:crypto_one_time(aes_128_ctr, Key, IV, Txt, true).
&lt;&lt;67,44,216,166,25,130,203,5,66,6,162,16,79,94,115,234,
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index c0b302734e..195c9d029d 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -31,6 +31,22 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 4.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed build link error on Windows. Unresolved symbol
+ 'bcmp'.</p>
+ <p>
+ Own Id: OTP-15750 Aux Id: ERL-905 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 4.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 04b2f62266..3b431cceba 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -59,9 +59,9 @@
-export([crypto_init/4, crypto_init/3,
crypto_update/2,
crypto_one_time/4, crypto_one_time/5,
- crypto_aead/6, crypto_aead/7,
- crypto_init_dyn_iv/3,
- crypto_update_dyn_iv/3
+ crypto_one_time_aead/6, crypto_one_time_aead/7,
+ crypto_dyn_iv_init/3,
+ crypto_dyn_iv_update/3
]).
@@ -733,9 +733,9 @@ block_encrypt(Type, Key0, Ivec, Data) ->
?COMPAT(
case Data of
{AAD, PlainText} ->
- crypto_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, true);
+ crypto_one_time_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, true);
{AAD, PlainText, TagLength} ->
- crypto_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, TagLength, true);
+ crypto_one_time_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, TagLength, true);
PlainText ->
crypto_one_time(alias(Type,Key), Key, Ivec, PlainText, true)
end).
@@ -764,7 +764,7 @@ block_decrypt(Type, Key0, Ivec, Data) ->
?COMPAT(
case Data of
{AAD, CryptoText, Tag} ->
- crypto_aead(alias(Type,Key), Key, Ivec, CryptoText, AAD, Tag, false);
+ crypto_one_time_aead(alias(Type,Key), Key, Ivec, CryptoText, AAD, Tag, false);
CryptoText ->
crypto_one_time(alias(Type,Key), Key, Ivec, CryptoText, false)
end).
@@ -901,12 +901,12 @@ crypto_init(Cipher, Key, IV, EncryptFlag) ->
%%%----------------------------------------------------------------
--spec crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> State | descriptive_error()
+-spec crypto_dyn_iv_init(Cipher, Key, EncryptFlag) -> State | descriptive_error()
when Cipher :: cipher_iv(),
Key :: iodata(),
EncryptFlag :: boolean(),
State :: crypto_state() .
-crypto_init_dyn_iv(Cipher, Key, EncryptFlag) ->
+crypto_dyn_iv_init(Cipher, Key, EncryptFlag) ->
%% The IV is supposed to be supplied by calling crypto_update/3
ng_crypto_init_nif(Cipher, iolist_to_binary(Key), undefined, EncryptFlag).
@@ -931,12 +931,12 @@ crypto_update(State, Data0) ->
%%%----------------------------------------------------------------
--spec crypto_update_dyn_iv(State, Data, IV) -> Result | descriptive_error()
+-spec crypto_dyn_iv_update(State, Data, IV) -> Result | descriptive_error()
when State :: crypto_state(),
Data :: iodata(),
IV :: iodata(),
Result :: binary() .
-crypto_update_dyn_iv(State, Data0, IV) ->
+crypto_dyn_iv_update(State, Data0, IV) ->
%% When State is from State = crypto_init(Cipher, Key, undefined, EncryptFlag)
case iolist_to_binary(Data0) of
<<>> ->
@@ -982,7 +982,7 @@ crypto_one_time(Cipher, Key, IV, Data0, EncryptFlag) ->
end.
--spec crypto_aead(Cipher, Key, IV, InText, AAD, EncFlag::true) ->
+-spec crypto_one_time_aead(Cipher, Key, IV, InText, AAD, EncFlag::true) ->
Result | descriptive_error()
when Cipher :: cipher_aead(),
Key :: iodata(),
@@ -994,11 +994,11 @@ crypto_one_time(Cipher, Key, IV, Data0, EncryptFlag) ->
OutCryptoText :: binary(),
OutTag :: binary().
-crypto_aead(Cipher, Key, IV, PlainText, AAD, true) ->
- crypto_aead(Cipher, Key, IV, PlainText, AAD, aead_tag_len(Cipher), true).
+crypto_one_time_aead(Cipher, Key, IV, PlainText, AAD, true) ->
+ crypto_one_time_aead(Cipher, Key, IV, PlainText, AAD, aead_tag_len(Cipher), true).
--spec crypto_aead(Cipher, Key, IV, InText, AAD, TagOrTagLength, EncFlag) ->
+-spec crypto_one_time_aead(Cipher, Key, IV, InText, AAD, TagOrTagLength, EncFlag) ->
Result | descriptive_error()
when Cipher :: cipher_aead(),
Key :: iodata(),
@@ -1016,7 +1016,7 @@ crypto_aead(Cipher, Key, IV, PlainText, AAD, true) ->
OutTag :: binary(),
OutPlainText :: binary().
-crypto_aead(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg) ->
+crypto_one_time_aead(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg) ->
aead_cipher(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg).
@@ -1058,8 +1058,21 @@ ng_crypto_one_time_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub.
%%%----------------------------------------------------------------
%%% Cipher aliases
%%%
-prepend_cipher_aliases(L) ->
- [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L].
+prepend_cipher_aliases(L0) ->
+ L =
+ case lists:member(des_ede3_cbc, L0) of
+ true ->
+ [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb | L0];
+ false ->
+ L0
+ end,
+ case lists:member(aes_128_cbc, L0) of
+ true ->
+ [aes_cbc128, aes_cbc256 | L];
+ false ->
+ L
+ end.
+
%%%---- des_ede3_cbc
alias(des3_cbc) -> des_ede3_cbc;
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 6a2727a622..880fd7ab0b 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -621,15 +621,15 @@ do_api_ng_tls({Type, Key, IV, PlainTexts}=_X) ->
do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
ct:log("~p",[_X]),
PlainText = iolist_to_binary(lazy_eval(PlainText0)),
- Renc = crypto:crypto_init_dyn_iv(Type, Key, true),
- Rdec = crypto:crypto_init_dyn_iv(Type, Key, false),
- EncTxt = crypto:crypto_update_dyn_iv(Renc, PlainText, IV),
+ Renc = crypto:crypto_dyn_iv_init(Type, Key, true),
+ Rdec = crypto:crypto_dyn_iv_init(Type, Key, false),
+ EncTxt = crypto:crypto_dyn_iv_update(Renc, PlainText, IV),
case ExpectedEncText of
undefined ->
ok;
EncTxt ->
%% Now check that the state is NOT updated:
- case crypto:crypto_update_dyn_iv(Renc, PlainText, IV) of
+ case crypto:crypto_dyn_iv_update(Renc, PlainText, IV) of
EncTxt ->
ok;
EncTxt2 ->
@@ -640,10 +640,10 @@ do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
ct:log("1st encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, OtherEnc]),
ct:fail("api_ng_tls (encode)",[])
end,
- case crypto:crypto_update_dyn_iv(Rdec, EncTxt, IV) of
+ case crypto:crypto_dyn_iv_update(Rdec, EncTxt, IV) of
PlainText ->
%% Now check that the state is NOT updated:
- case crypto:crypto_update_dyn_iv(Rdec, EncTxt, IV) of
+ case crypto:crypto_dyn_iv_update(Rdec, EncTxt, IV) of
PlainText ->
ok;
PlainText2 ->
@@ -1183,7 +1183,7 @@ aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}
catch
error:E ->
ct:log("~p",[{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}]),
- try crypto:crypto_aead(Type, Key, IV, PlainText, AAD, TagLen, true)
+ try crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, TagLen, true)
of
RR ->
ct:log("Works: ~p",[RR])
diff --git a/lib/crypto/test/engine_SUITE.erl b/lib/crypto/test/engine_SUITE.erl
index 3416fbd78d..41cd132734 100644
--- a/lib/crypto/test/engine_SUITE.erl
+++ b/lib/crypto/test/engine_SUITE.erl
@@ -148,8 +148,21 @@ end_per_group(_, Config) ->
end.
%%--------------------------------------------------------------------
-init_per_testcase(_Case, Config) ->
- Config.
+init_per_testcase(Case, Config) ->
+ case string:tokens(atom_to_list(Case),"_") of
+ ["sign","verify",Type|_] ->
+ skip_if_unsup(list_to_atom(Type), Config);
+
+ ["priv","encrypt","pub","decrypt",Type|_] ->
+ skip_if_unsup(list_to_atom(Type), Config);
+
+ ["get","pub","from","priv","key",Type|_] ->
+ skip_if_unsup(list_to_atom(Type), Config);
+
+ _ ->
+ Config
+ end.
+
end_per_testcase(_Case, _Config) ->
ok.
@@ -851,6 +864,19 @@ get_pub_from_priv_key_ecdsa(Config) ->
%%%================================================================
%%% Help for engine_stored_pub_priv_keys* test cases
%%%
+skip_if_unsup(Type, Config) ->
+ case pkey_supported(Type) of
+ false ->
+ {skip, "Unsupported in this cryptolib"};
+ true ->
+ Config
+ end.
+
+
+pkey_supported(Type) ->
+ lists:member(Type, proplists:get_value(public_keys, crypto:supports(), [])).
+
+
load_storage_engine(Config) ->
load_storage_engine(Config, []).
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index deba17fb66..0a3d9f45e4 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 4.4.1
+CRYPTO_VSN = 4.4.2