aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2019-03-13 15:52:41 +0100
committerHans Nilsson <[email protected]>2019-03-19 12:45:55 +0100
commit27882b21c33396135ff7789cc14cc782c0c0e318 (patch)
tree89533cb686ea6cba1d90cacb343bc63e450a0a53 /lib/crypto/c_src
parent00dcdf6c9aec2a78f15bf673f56a1c044103b23e (diff)
downloadotp-27882b21c33396135ff7789cc14cc782c0c0e318.tar.gz
otp-27882b21c33396135ff7789cc14cc782c0c0e318.tar.bz2
otp-27882b21c33396135ff7789cc14cc782c0c0e318.zip
crypto: Fix bug for older cryptolib
Diffstat (limited to 'lib/crypto/c_src')
-rw-r--r--lib/crypto/c_src/api_ng.c89
1 files changed, 54 insertions, 35 deletions
diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c
index d970f45f94..393fee31ef 100644
--- a/lib/crypto/c_src/api_ng.c
+++ b/lib/crypto/c_src/api_ng.c
@@ -107,19 +107,37 @@ static int get_init_args(ErlNifEnv* env,
*return_term = EXCP_NOTSUP(env, "Forbidden in FIPS");
goto err;
}
-
- /* Fetch IV */
-#if !defined(HAVE_EVP_AES_CTR)
- /* This is code for OpenSSL 0.9.8. Therefore we could accept some ineficient code */
- ctx_res->env = NULL;
- ctx_res->state = atom_undefined;
- if (!((*cipherp)->cipher.p) && (*cipherp)->flags & AES_CTR_COMPAT)
- ivec_len = 16;
- else
-#endif
+ /* Get ivec_len for this cipher (if we found one) */
+#if !defined(HAVE_EVP_AES_CTR)
+ /* This code is for historic OpenSSL where EVP_aes_*_ctr is not defined.... */
+ if ((*cipherp)->cipher.p) {
+ /* Not aes_ctr compatibility code since EVP_*
+ was defined and assigned to (*cipherp)->cipher.p */
ivec_len = GET_IV_LEN(*cipherp);
+ } else {
+ /* No EVP_* was found */
+ if ((*cipherp)->flags & AES_CTR_COMPAT)
+ /* Use aes_ctr compatibility code later */
+ ivec_len = 16;
+ else {
+ /* Unsupported crypto */
+ *return_term = EXCP_NOTSUP(env, "Unsupported cipher");
+ goto err;
+ }
+ }
+#else
+ /* Normal code */
+ if (!((*cipherp)->cipher.p)) {
+ *return_term = EXCP_NOTSUP(env, "Unsupported cipher");
+ goto err;
+ }
+ ivec_len = GET_IV_LEN(*cipherp);
+#endif
+
+ /* (*cipherp)->cipher.p != NULL and ivec_len has a value */
+ /* Fetch IV */
if (ivec_len && (ivec_arg != atom_undefined)) {
if (!enif_inspect_iolist_as_binary(env, ivec_arg, &ivec_bin))
{
@@ -134,35 +152,36 @@ static int get_init_args(ErlNifEnv* env,
}
}
- ctx_res -> iv_len = ivec_len;
+ ctx_res->iv_len = ivec_len;
- if (!((*cipherp)->cipher.p))
- {
#if !defined(HAVE_EVP_AES_CTR)
- if ((*cipherp)->flags & AES_CTR_COMPAT)
- {
- ERL_NIF_TERM ecount_bin;
- unsigned char *outp;
- if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) {
- *return_term = EXCP_ERROR(env, "Can't allocate ecount_bin");
- goto err;
- }
- memset(outp, 0, AES_BLOCK_SIZE);
-
- ctx_res->env = enif_alloc_env();
- if (!ctx_res->env) {
- *return_term = EXCP_ERROR(env, "Can't allocate env");
- goto err;
- }
- ctx_res->state =
- enif_make_copy(ctx_res->env,
- enif_make_tuple4(env, key_arg, ivec_arg, ecount_bin, enif_make_int(env, 0)));
- goto success;
- }
-#endif
- *return_term = EXCP_NOTSUP(env, "Cipher");
+ if (!((*cipherp)->cipher.p)
+ && ((*cipherp)->flags & AES_CTR_COMPAT)
+ ) {
+ /* Must use aes_ctr compatibility code */
+ ERL_NIF_TERM ecount_bin;
+ unsigned char *outp;
+ if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) {
+ *return_term = EXCP_ERROR(env, "Can't allocate ecount_bin");
goto err;
}
+ memset(outp, 0, AES_BLOCK_SIZE);
+
+ ctx_res->env = enif_alloc_env();
+ if (!ctx_res->env) {
+ *return_term = EXCP_ERROR(env, "Can't allocate env");
+ goto err;
+ }
+ ctx_res->state =
+ enif_make_copy(ctx_res->env,
+ enif_make_tuple4(env, key_arg, ivec_arg, ecount_bin, enif_make_int(env, 0)));
+ goto success;
+ } else {
+ /* Flag for subsequent calls that no aes_ctr compatibility code should be called */
+ ctx_res->state = atom_undefined;
+ ctx_res->env = NULL;
+ }
+#endif
/* Initialize the EVP_CIPHER_CTX */