aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto/c_src')
-rw-r--r--lib/crypto/c_src/crypto.c473
-rw-r--r--lib/crypto/c_src/otp_test_engine.c3
2 files changed, 250 insertions, 226 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 096f749f7f..d40d285f86 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -149,12 +149,15 @@
#endif
// SHA3:
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,1)
+// An error in beta releases of 1.1.1 fixed in production release
# ifdef NID_sha3_224
-//Error # define HAVE_SHA3_224
+# define HAVE_SHA3_224
# endif
# ifdef NID_sha3_256
-//Error # define HAVE_SHA3_256
+# define HAVE_SHA3_256
# endif
+#endif
# ifdef NID_sha3_384
# define HAVE_SHA3_384
# endif
@@ -173,7 +176,6 @@
#if OPENSSL_VERSION_NUMBER >= (PACKED_OPENSSL_VERSION_PLAIN(1,1,1) - 7) \
&& !defined(HAS_LIBRESSL) \
&& defined(HAVE_EC)
-// EXPERIMENTAL:
# define HAVE_ED_CURVE_DH
#endif
@@ -183,7 +185,9 @@
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,1)
# define HAVE_EVP_AES_CTR
+# define HAVE_AEAD
# define HAVE_GCM
+# define HAVE_CCM
# define HAVE_CMAC
# if OPENSSL_VERSION_NUMBER < PACKED_OPENSSL_VERSION(1,0,1,'d')
# define HAVE_GCM_EVP_DECRYPT_BUG
@@ -209,10 +213,16 @@
# define HAVE_ECB_IVEC_BUG
#endif
-#define HAVE_RSA_SSLV23_PADDING
-#if defined(HAS_LIBRESSL) \
- && LIBRESSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(2,6,1)
-# undef HAVE_RSA_SSLV23_PADDING
+#ifndef HAS_LIBRESSL
+# ifdef RSA_SSLV23_PADDING
+# define HAVE_RSA_SSLV23_PADDING
+# endif
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
+# ifdef RSA_PKCS1_PSS_PADDING
+# define HAVE_RSA_PKCS1_PSS_PADDING
+# endif
#endif
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION(0,9,8,'h') \
@@ -537,15 +547,12 @@ static ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF
static ERL_NIF_TERM rand_seed_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aead_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aead_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
#ifdef HAVE_GCM_EVP_DECRYPT_BUG
static ERL_NIF_TERM aes_gcm_decrypt_NO_EVP(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
#endif
-static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-
static ERL_NIF_TERM chacha20_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM chacha20_stream_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -635,11 +642,8 @@ static ErlNifFunc nif_funcs[] = {
{"rand_seed_nif", 1, rand_seed_nif},
- {"aes_gcm_encrypt", 5, aes_gcm_encrypt},
- {"aes_gcm_decrypt", 5, aes_gcm_decrypt},
-
- {"chacha20_poly1305_encrypt", 4, chacha20_poly1305_encrypt},
- {"chacha20_poly1305_decrypt", 5, chacha20_poly1305_decrypt},
+ {"aead_encrypt", 6, aead_encrypt},
+ {"aead_decrypt", 6, aead_decrypt},
{"chacha20_stream_init", 2, chacha20_stream_init},
{"chacha20_stream_encrypt", 2, chacha20_stream_crypt},
@@ -710,6 +714,15 @@ static ERL_NIF_TERM atom_onbasis;
static ERL_NIF_TERM atom_aes_cfb8;
static ERL_NIF_TERM atom_aes_cfb128;
+#ifdef HAVE_GCM
+static ERL_NIF_TERM atom_aes_gcm;
+#endif
+#ifdef HAVE_CCM
+static ERL_NIF_TERM atom_aes_ccm;
+#endif
+#ifdef HAVE_CHACHA20_POLY1305
+static ERL_NIF_TERM atom_chacha20_poly1305;
+#endif
#ifdef HAVE_ECB_IVEC_BUG
static ERL_NIF_TERM atom_aes_ecb;
static ERL_NIF_TERM atom_des_ecb;
@@ -1150,6 +1163,15 @@ static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info)
#endif
atom_aes_cfb8 = enif_make_atom(env, "aes_cfb8");
atom_aes_cfb128 = enif_make_atom(env, "aes_cfb128");
+#ifdef HAVE_GCM
+ atom_aes_gcm = enif_make_atom(env, "aes_gcm");
+#endif
+#ifdef HAVE_CCM
+ atom_aes_ccm = enif_make_atom(env, "aes_ccm");
+#endif
+#ifdef HAVE_CHACHA20_POLY1305
+ atom_chacha20_poly1305 = enif_make_atom(env,"chacha20_poly1305");
+#endif
#ifdef HAVE_ECB_IVEC_BUG
atom_aes_ecb = enif_make_atom(env, "aes_ecb");
atom_des_ecb = enif_make_atom(env, "des_ecb");
@@ -1312,11 +1334,13 @@ static ERL_NIF_TERM algo_hash[12]; /* increase when extending the list */
static int algo_pubkey_cnt, algo_pubkey_fips_cnt;
static ERL_NIF_TERM algo_pubkey[11]; /* increase when extending the list */
static int algo_cipher_cnt, algo_cipher_fips_cnt;
-static ERL_NIF_TERM algo_cipher[24]; /* increase when extending the list */
+static ERL_NIF_TERM algo_cipher[25]; /* increase when extending the list */
static int algo_mac_cnt, algo_mac_fips_cnt;
static ERL_NIF_TERM algo_mac[3]; /* increase when extending the list */
static int algo_curve_cnt, algo_curve_fips_cnt;
static ERL_NIF_TERM algo_curve[87]; /* increase when extending the list */
+static int algo_rsa_opts_cnt, algo_rsa_opts_fips_cnt;
+static ERL_NIF_TERM algo_rsa_opts[10]; /* increase when extending the list */
static void init_algorithms_types(ErlNifEnv* env)
{
@@ -1388,6 +1412,9 @@ static void init_algorithms_types(ErlNifEnv* env)
#if defined(HAVE_GCM)
algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_gcm");
#endif
+#if defined(HAVE_CCM)
+ algo_cipher[algo_cipher_cnt++] = enif_make_atom(env,"aes_ccm");
+#endif
// Non-validated algorithms follow
algo_cipher_fips_cnt = algo_cipher_cnt;
#ifdef HAVE_AES_IGE
@@ -1528,12 +1555,36 @@ static void init_algorithms_types(ErlNifEnv* env)
algo_curve[algo_curve_cnt++] = enif_make_atom(env,"x448");
#endif
+ // Validated algorithms first
+ algo_rsa_opts_cnt = 0;
+#ifdef HAS_EVP_PKEY_CTX
+# ifdef HAVE_RSA_PKCS1_PSS_PADDING
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_pkcs1_pss_padding");
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_pss_saltlen");
+# endif
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_mgf1_md");
+# ifdef HAVE_RSA_OAEP_MD
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_oaep_label");
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_oaep_md");
+# endif
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"signature_md");
+#endif
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_pkcs1_padding");
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_x931_padding");
+#ifdef HAVE_RSA_SSLV23_PADDING
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_sslv23_padding");
+#endif
+ algo_rsa_opts[algo_rsa_opts_cnt++] = enif_make_atom(env,"rsa_no_padding");
+ algo_rsa_opts_fips_cnt = algo_rsa_opts_cnt;
+
+
// Check that the max number of algos is updated
ASSERT(algo_hash_cnt <= sizeof(algo_hash)/sizeof(ERL_NIF_TERM));
ASSERT(algo_pubkey_cnt <= sizeof(algo_pubkey)/sizeof(ERL_NIF_TERM));
ASSERT(algo_cipher_cnt <= sizeof(algo_cipher)/sizeof(ERL_NIF_TERM));
ASSERT(algo_mac_cnt <= sizeof(algo_mac)/sizeof(ERL_NIF_TERM));
ASSERT(algo_curve_cnt <= sizeof(algo_curve)/sizeof(ERL_NIF_TERM));
+ ASSERT(algo_rsa_opts_cnt <= sizeof(algo_rsa_opts)/sizeof(ERL_NIF_TERM));
}
static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -1545,19 +1596,22 @@ static ERL_NIF_TERM algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
int cipher_cnt = fips_mode ? algo_cipher_fips_cnt : algo_cipher_cnt;
int mac_cnt = fips_mode ? algo_mac_fips_cnt : algo_mac_cnt;
int curve_cnt = fips_mode ? algo_curve_fips_cnt : algo_curve_cnt;
+ int rsa_opts_cnt = fips_mode ? algo_rsa_opts_fips_cnt : algo_rsa_opts_cnt;
#else
int hash_cnt = algo_hash_cnt;
int pubkey_cnt = algo_pubkey_cnt;
int cipher_cnt = algo_cipher_cnt;
int mac_cnt = algo_mac_cnt;
int curve_cnt = algo_curve_cnt;
+ int rsa_opts_cnt = algo_rsa_opts_cnt;
#endif
- return enif_make_tuple5(env,
+ return enif_make_tuple6(env,
enif_make_list_from_array(env, algo_hash, hash_cnt),
enif_make_list_from_array(env, algo_pubkey, pubkey_cnt),
enif_make_list_from_array(env, algo_cipher, cipher_cnt),
enif_make_list_from_array(env, algo_mac, mac_cnt),
- enif_make_list_from_array(env, algo_curve, curve_cnt)
+ enif_make_list_from_array(env, algo_curve, curve_cnt),
+ enif_make_list_from_array(env, algo_rsa_opts, rsa_opts_cnt)
);
}
@@ -2514,66 +2568,102 @@ static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_N
}
#endif /* !HAVE_EVP_AES_CTR */
-static ERL_NIF_TERM aes_gcm_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key,Iv,AAD,In) */
-#if defined(HAVE_GCM)
+static ERL_NIF_TERM aead_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Type,Key,Iv,AAD,In) */
+#if defined(HAVE_AEAD)
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher = NULL;
ErlNifBinary key, iv, aad, in;
unsigned int tag_len;
unsigned char *outp, *tagp;
- ERL_NIF_TERM out, out_tag;
- int len;
+ ERL_NIF_TERM type, out, out_tag;
+ int len, ctx_ctrl_set_ivlen, ctx_ctrl_get_tag;
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
- || (key.size != 16 && key.size != 24 && key.size != 32)
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0
- || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
- || !enif_inspect_iolist_as_binary(env, argv[3], &in)
- || !enif_get_uint(env, argv[4], &tag_len) || tag_len < 1 || tag_len > 16) {
+ type = argv[0];
+
+ if (!enif_is_atom(env, type)
+ || !enif_inspect_iolist_as_binary(env, argv[1], &key)
+ || !enif_inspect_binary(env, argv[2], &iv)
+ || !enif_inspect_iolist_as_binary(env, argv[3], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[4], &in)
+ || !enif_get_uint(env, argv[5], &tag_len)) {
return enif_make_badarg(env);
}
- if (key.size == 16)
- cipher = EVP_aes_128_gcm();
- else if (key.size == 24)
- cipher = EVP_aes_192_gcm();
- else if (key.size == 32)
- cipher = EVP_aes_256_gcm();
-
+ /* Use cipher_type some day. Must check block_encrypt|decrypt first */
+#if defined(HAVE_GCM)
+ if (type == atom_aes_gcm) {
+ if ((iv.size > 0)
+ && (1 <= tag_len && tag_len <= 16)) {
+ ctx_ctrl_set_ivlen = EVP_CTRL_GCM_SET_IVLEN;
+ ctx_ctrl_get_tag = EVP_CTRL_GCM_GET_TAG;
+ if (key.size == 16) cipher = EVP_aes_128_gcm();
+ else if (key.size == 24) cipher = EVP_aes_192_gcm();
+ else if (key.size == 32) cipher = EVP_aes_256_gcm();
+ else enif_make_badarg(env);
+ } else
+ enif_make_badarg(env);
+ } else
+#endif
+#if defined(HAVE_CCM)
+ if (type == atom_aes_ccm) {
+ if ((7 <= iv.size && iv.size <= 13)
+ && (4 <= tag_len && tag_len <= 16)
+ && ((tag_len & 1) == 0)
+ ) {
+ ctx_ctrl_set_ivlen = EVP_CTRL_CCM_SET_IVLEN;
+ ctx_ctrl_get_tag = EVP_CTRL_CCM_GET_TAG;
+ if (key.size == 16) cipher = EVP_aes_128_ccm();
+ else if (key.size == 24) cipher = EVP_aes_192_ccm();
+ else if (key.size == 32) cipher = EVP_aes_256_ccm();
+ else enif_make_badarg(env);
+ } else
+ enif_make_badarg(env);
+ } else
+#endif
+#if defined(HAVE_CHACHA20_POLY1305)
+ if (type == atom_chacha20_poly1305) {
+ if ((key.size == 32)
+ && (1 <= iv.size && iv.size <= 16)
+ && (tag_len == 16)
+ ) {
+ ctx_ctrl_set_ivlen = EVP_CTRL_AEAD_SET_IVLEN;
+ ctx_ctrl_get_tag = EVP_CTRL_AEAD_GET_TAG,
+ cipher = EVP_chacha20_poly1305();
+ } else enif_make_badarg(env);
+ } else
+#endif
+ return enif_raise_exception(env, atom_notsup);
+
ctx = EVP_CIPHER_CTX_new();
+ if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) goto out_err;
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_ivlen, iv.size, NULL) != 1) goto out_err;
+
+#if defined(HAVE_CCM)
+ if (type == atom_aes_ccm) {
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL) != 1) goto out_err;
+ if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1) goto out_err;
+ if (EVP_EncryptUpdate(ctx, NULL, &len, NULL, in.size) != 1) goto out_err;
+ } else
+#endif
+ if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1) goto out_err;
- if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
- goto out_err;
-
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size, NULL) != 1)
- goto out_err;
- if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
- goto out_err;
- if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
- goto out_err;
+ if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1) goto out_err;
outp = enif_make_new_binary(env, in.size, &out);
- if (EVP_EncryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
- goto out_err;
- if (EVP_EncryptFinal_ex(ctx, outp+len, &len) != 1)
- goto out_err;
+ if (EVP_EncryptUpdate(ctx, outp, &len, in.data, in.size) != 1) goto out_err;
+ if (EVP_EncryptFinal_ex(ctx, outp/*+len*/, &len) != 1) goto out_err;
tagp = enif_make_new_binary(env, tag_len, &out_tag);
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tagp) != 1)
- goto out_err;
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_get_tag, tag_len, tagp) != 1) goto out_err;
EVP_CIPHER_CTX_free(ctx);
-
CONSUME_REDS(env, in);
-
return enif_make_tuple2(env, out, out_tag);
-out_err:
+out_err:
EVP_CIPHER_CTX_free(ctx);
return atom_error;
@@ -2582,58 +2672,103 @@ out_err:
#endif
}
-static ERL_NIF_TERM aes_gcm_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key,Iv,AAD,In,Tag) */
-#if defined(HAVE_GCM_EVP_DECRYPT_BUG)
- return aes_gcm_decrypt_NO_EVP(env, argc, argv);
-#elif defined(HAVE_GCM)
+static ERL_NIF_TERM aead_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Type,Key,Iv,AAD,In,Tag) */
+#if defined(HAVE_AEAD)
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher = NULL;
ErlNifBinary key, iv, aad, in, tag;
unsigned char *outp;
- ERL_NIF_TERM out;
- int len;
+ ERL_NIF_TERM type, out;
+ int len, ctx_ctrl_set_ivlen, ctx_ctrl_set_tag;
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
- || (key.size != 16 && key.size != 24 && key.size != 32)
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0
- || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
- || !enif_inspect_iolist_as_binary(env, argv[3], &in)
- || !enif_inspect_iolist_as_binary(env, argv[4], &tag)) {
+ type = argv[0];
+#if defined(HAVE_GCM_EVP_DECRYPT_BUG)
+ if (type == atom_aes_gcm)
+ return aes_gcm_decrypt_NO_EVP(env, argc, argv);
+#endif
+
+ if (!enif_is_atom(env, type)
+ || !enif_inspect_iolist_as_binary(env, argv[1], &key)
+ || !enif_inspect_binary(env, argv[2], &iv)
+ || !enif_inspect_iolist_as_binary(env, argv[3], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[4], &in)
+ || !enif_inspect_iolist_as_binary(env, argv[5], &tag)) {
return enif_make_badarg(env);
}
- if (key.size == 16)
- cipher = EVP_aes_128_gcm();
- else if (key.size == 24)
- cipher = EVP_aes_192_gcm();
- else if (key.size == 32)
- cipher = EVP_aes_256_gcm();
+ /* Use cipher_type some day. Must check block_encrypt|decrypt first */
+#if defined(HAVE_GCM)
+ if (type == atom_aes_gcm) {
+ if (iv.size > 0) {
+ ctx_ctrl_set_ivlen = EVP_CTRL_GCM_SET_IVLEN;
+ ctx_ctrl_set_tag = EVP_CTRL_GCM_SET_TAG;
+ if (key.size == 16) cipher = EVP_aes_128_gcm();
+ else if (key.size == 24) cipher = EVP_aes_192_gcm();
+ else if (key.size == 32) cipher = EVP_aes_256_gcm();
+ else enif_make_badarg(env);
+ } else
+ enif_make_badarg(env);
+ } else
+#endif
+#if defined(HAVE_CCM)
+ if (type == atom_aes_ccm) {
+ if (iv.size > 0) {
+ ctx_ctrl_set_ivlen = EVP_CTRL_CCM_SET_IVLEN;
+ if (key.size == 16) cipher = EVP_aes_128_ccm();
+ else if (key.size == 24) cipher = EVP_aes_192_ccm();
+ else if (key.size == 32) cipher = EVP_aes_256_ccm();
+ else enif_make_badarg(env);
+ } else
+ enif_make_badarg(env);
+ } else
+#endif
+#if defined(HAVE_CHACHA20_POLY1305)
+ if (type == atom_chacha20_poly1305) {
+ if ((key.size == 32)
+ && (1 <= iv.size && iv.size <= 16)
+ && tag.size == 16
+ ) {
+ ctx_ctrl_set_ivlen = EVP_CTRL_AEAD_SET_IVLEN;
+ ctx_ctrl_set_tag = EVP_CTRL_AEAD_SET_TAG;
+ cipher = EVP_chacha20_poly1305();
+ } else enif_make_badarg(env);
+ } else
+#endif
+ return enif_raise_exception(env, atom_notsup);
+
+ outp = enif_make_new_binary(env, in.size, &out);
ctx = EVP_CIPHER_CTX_new();
+ if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) goto out_err;
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_ivlen, iv.size, NULL) != 1) goto out_err;
- if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
- goto out_err;
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size, NULL) != 1)
- goto out_err;
- if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
- goto out_err;
- if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
- goto out_err;
+#if defined(HAVE_CCM)
+ if (type == atom_aes_ccm) {
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag.size, tag.data) != 1) goto out_err;
+ }
+#endif
- outp = enif_make_new_binary(env, in.size, &out);
+ if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1) goto out_err;
- if (EVP_DecryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
- goto out_err;
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag.size, tag.data) != 1)
- goto out_err;
- if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1)
- goto out_err;
+#if defined(HAVE_CCM)
+ if (type == atom_aes_ccm) {
+ if (1 != EVP_DecryptUpdate(ctx, NULL, &len, NULL, in.size)) goto out_err;
+ }
+#endif
+
+ if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1) goto out_err;
+ if (EVP_DecryptUpdate(ctx, outp, &len, in.data, in.size) != 1) goto out_err;
+#if defined(HAVE_GCM) || defined(HAVE_CHACHA20_POLY1305)
+ if (type == atom_aes_gcm) {
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_tag, tag.size, tag.data) != 1) goto out_err;
+ if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1) goto out_err;
+ }
+#endif
EVP_CIPHER_CTX_free(ctx);
CONSUME_REDS(env, in);
-
return out;
out_err:
@@ -2646,19 +2781,19 @@ out_err:
#ifdef HAVE_GCM_EVP_DECRYPT_BUG
static ERL_NIF_TERM aes_gcm_decrypt_NO_EVP(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
+{/* (Type,Key,Iv,AAD,In,Tag) */
GCM128_CONTEXT *ctx;
ErlNifBinary key, iv, aad, in, tag;
AES_KEY aes_key;
unsigned char *outp;
ERL_NIF_TERM out;
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
+ if (!enif_inspect_iolist_as_binary(env, argv[1], &key)
|| AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0
- || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
- || !enif_inspect_iolist_as_binary(env, argv[3], &in)
- || !enif_inspect_iolist_as_binary(env, argv[4], &tag)) {
+ || !enif_inspect_binary(env, argv[2], &iv) || iv.size == 0
+ || !enif_inspect_iolist_as_binary(env, argv[3], &aad)
+ || !enif_inspect_iolist_as_binary(env, argv[4], &in)
+ || !enif_inspect_iolist_as_binary(env, argv[5], &tag)) {
return enif_make_badarg(env);
}
@@ -2692,120 +2827,6 @@ out_err:
#endif /* HAVE_GCM_EVP_DECRYPT_BUG */
-static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key,Iv,AAD,In) */
-#if defined(HAVE_CHACHA20_POLY1305)
- EVP_CIPHER_CTX *ctx;
- const EVP_CIPHER *cipher = NULL;
- ErlNifBinary key, iv, aad, in;
- unsigned char *outp, *tagp;
- ERL_NIF_TERM out, out_tag;
- int len;
-
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || iv.size > 16
- || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
- || !enif_inspect_iolist_as_binary(env, argv[3], &in)) {
- return enif_make_badarg(env);
- }
-
- cipher = EVP_chacha20_poly1305();
-
- ctx = EVP_CIPHER_CTX_new();
-
- if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
- goto out_err;
-
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv.size, NULL) != 1)
- goto out_err;
- if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
- goto out_err;
- if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
- goto out_err;
-
- outp = enif_make_new_binary(env, in.size, &out);
-
- if (EVP_EncryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
- goto out_err;
- if (EVP_EncryptFinal_ex(ctx, outp+len, &len) != 1)
- goto out_err;
-
- tagp = enif_make_new_binary(env, 16, &out_tag);
-
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tagp) != 1)
- goto out_err;
-
- EVP_CIPHER_CTX_free(ctx);
-
- CONSUME_REDS(env, in);
-
- return enif_make_tuple2(env, out, out_tag);
-
-out_err:
- EVP_CIPHER_CTX_free(ctx);
- return atom_error;
-#else
- return enif_raise_exception(env, atom_notsup);
-#endif
-}
-
-static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key,Iv,AAD,In,Tag) */
-#if defined(HAVE_CHACHA20_POLY1305)
- EVP_CIPHER_CTX *ctx;
- const EVP_CIPHER *cipher = NULL;
- ErlNifBinary key, iv, aad, in, tag;
- unsigned char *outp;
- ERL_NIF_TERM out;
- int len;
-
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32
- || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || iv.size > 16
- || !enif_inspect_iolist_as_binary(env, argv[2], &aad)
- || !enif_inspect_iolist_as_binary(env, argv[3], &in)
- || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != 16) {
- return enif_make_badarg(env);
- }
-
- cipher = EVP_chacha20_poly1305();
-
- ctx = EVP_CIPHER_CTX_new();
-
- if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
- goto out_err;
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv.size, NULL) != 1)
- goto out_err;
- if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
- goto out_err;
- if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1)
- goto out_err;
-
- outp = enif_make_new_binary(env, in.size, &out);
-
- if (EVP_DecryptUpdate(ctx, outp, &len, in.data, in.size) != 1)
- goto out_err;
- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag.size, tag.data) != 1)
- goto out_err;
- if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1)
- goto out_err;
-
- EVP_CIPHER_CTX_free(ctx);
-
- CONSUME_REDS(env, in);
-
- return out;
-
-out_err:
- EVP_CIPHER_CTX_free(ctx);
- return atom_error;
-#else
- return enif_raise_exception(env, atom_notsup);
-#endif
-}
-
-
static ERL_NIF_TERM chacha20_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key, IV) */
#if defined(HAVE_CHACHA20)
@@ -4148,7 +4169,6 @@ out_err:
#endif
}
-// EXPERIMENTAL!
static ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* (Curve, PeerBin, MyBin) */
{
@@ -4204,7 +4224,6 @@ static ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
#endif
}
-// EXPERIMENTAL!
static ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* (Curve) */
{
@@ -4221,22 +4240,20 @@ static ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF
if (!(ctx = EVP_PKEY_CTX_new_id(type, NULL))) return enif_make_badarg(env);
- if (!EVP_PKEY_keygen_init(ctx)) return enif_make_atom(env,"EVP_PKEY_keygen_init failed");
- if (!EVP_PKEY_keygen(ctx, &pkey)) return enif_make_atom(env,"EVP_PKEY_keygen failed");
+ if (!EVP_PKEY_keygen_init(ctx)) return atom_error;
+ if (!EVP_PKEY_keygen(ctx, &pkey)) return atom_error;
- if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &key_len))
- return enif_make_atom(env,"EVP_PKEY_get_raw_public_key 1 failed");
+ if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &key_len)) return atom_error;
if (!EVP_PKEY_get_raw_public_key(pkey,
enif_make_new_binary(env, key_len, &ret_pub),
&key_len))
- return enif_make_atom(env,"EVP_PKEY_get_raw_public_key 2 failed");
+ return atom_error;
- if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &key_len))
- return enif_make_atom(env,"EVP_PKEY_get_raw_private_key 1 failed");
+ if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &key_len)) return atom_error;
if (!EVP_PKEY_get_raw_private_key(pkey,
enif_make_new_binary(env, key_len, &ret_prv),
&key_len))
- return enif_make_atom(env,"EVP_PKEY_get_raw_private_key 2 failed");
+ return atom_error;
return enif_make_tuple2(env, ret_pub, ret_prv);
#else
@@ -4387,7 +4404,7 @@ static int get_pkey_sign_options(ErlNifEnv *env, ERL_NIF_TERM algorithm, ERL_NIF
if (tpl_terms[1] == atom_rsa_pkcs1_padding) {
opt->rsa_padding = RSA_PKCS1_PADDING;
} else if (tpl_terms[1] == atom_rsa_pkcs1_pss_padding) {
-#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0)
+#ifdef HAVE_RSA_PKCS1_PSS_PADDING
opt->rsa_padding = RSA_PKCS1_PSS_PADDING;
if (opt->rsa_mgf1_md == NULL) {
opt->rsa_mgf1_md = md;
@@ -4676,6 +4693,7 @@ printf("\r\n");
if (argv[0] == atom_rsa) {
if (EVP_PKEY_CTX_set_rsa_padding(ctx, sig_opt.rsa_padding) <= 0) goto badarg;
+#ifdef HAVE_RSA_PKCS1_PSS_PADDING
if (sig_opt.rsa_padding == RSA_PKCS1_PSS_PADDING) {
if (sig_opt.rsa_mgf1_md != NULL) {
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,1)
@@ -4690,6 +4708,7 @@ printf("\r\n");
&& EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sig_opt.rsa_pss_saltlen) <= 0)
goto badarg;
}
+#endif
}
if (EVP_PKEY_sign(ctx, NULL, &siglen, tbs, tbslen) <= 0) goto badarg;
@@ -5208,7 +5227,10 @@ static ERL_NIF_TERM pkey_crypt_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM
unsigned char *p;
if (rsa == NULL) goto badarg;
tmplen = RSA_size(rsa);
- if (!enif_alloc_binary(tmplen, &tmp_bin)) goto badarg;
+ if (!enif_alloc_binary(tmplen, &tmp_bin)) {
+ RSA_free(rsa);
+ goto badarg;
+ }
p = out_bin.data;
p++;
i = RSA_padding_check_SSLv23(tmp_bin.data, tmplen, p, out_bin.size - 1, tmplen);
@@ -5219,6 +5241,7 @@ static ERL_NIF_TERM pkey_crypt_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM
tmp_bin = in_bin;
i = 1;
}
+ RSA_free(rsa);
}
#endif
}
diff --git a/lib/crypto/c_src/otp_test_engine.c b/lib/crypto/c_src/otp_test_engine.c
index b6c9067964..34c825059f 100644
--- a/lib/crypto/c_src/otp_test_engine.c
+++ b/lib/crypto/c_src/otp_test_engine.c
@@ -64,7 +64,8 @@ static int test_init(ENGINE *e) {
printf("OTP Test Engine Initializatzion!\r\n");
/* Load all digest and cipher algorithms. Needed for password protected private keys */
- OpenSSL_add_all_algorithms();
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
return 111;
}