From 344c3602bfdfc71670b80c9f9f9345b86e637989 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 27 Mar 2019 13:58:01 +0100
Subject: crypto: Misc C-changes,

error fixes, better error reporting (file and line), make aead more robust and like the _ng api.
---
 lib/crypto/c_src/aead.c   | 248 ++++++++++++++++++----------------------------
 lib/crypto/c_src/aead.h   |   3 +-
 lib/crypto/c_src/api_ng.c |  19 ++--
 lib/crypto/c_src/api_ng.h |   2 +-
 lib/crypto/c_src/cipher.c |  40 ++++----
 lib/crypto/c_src/cipher.h |   2 +
 lib/crypto/c_src/common.h |   5 +-
 lib/crypto/c_src/crypto.c |   5 +-
 8 files changed, 142 insertions(+), 182 deletions(-)

diff --git a/lib/crypto/c_src/aead.c b/lib/crypto/c_src/aead.c
index 4ed16615a5..ab0e609130 100644
--- a/lib/crypto/c_src/aead.c
+++ b/lib/crypto/c_src/aead.c
@@ -22,36 +22,65 @@
 #include "aes.h"
 #include "cipher.h"
 
-ERL_NIF_TERM aead_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Type,Key,Iv,AAD,In) */
+
+
+ERL_NIF_TERM aead_cipher(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/*
+   (Type,Key,Iv,AAD,In,TagLen,true)
+   (Type,Key,Iv,AAD,In,Tag,false)
+ */
 #if defined(HAVE_AEAD)
     const struct cipher_type_t *cipherp;
     EVP_CIPHER_CTX *ctx = NULL;
     const EVP_CIPHER *cipher = NULL;
-    ErlNifBinary key, iv, aad, in;
+    ErlNifBinary key, iv, aad, in, tag;
     unsigned int tag_len;
-    unsigned char *outp, *tagp;
-    ERL_NIF_TERM type, out, out_tag, ret;
-    int len, ctx_ctrl_set_ivlen, ctx_ctrl_get_tag, ctx_ctrl_set_tag;
+    unsigned char *outp, *tagp, *tag_data;
+    ERL_NIF_TERM type, out, out_tag, ret, encflg_arg;
+    int len, encflg;
+
+    encflg_arg = argv[6];
+
+    /* Fetch the flag telling if we are going to encrypt (=true) or decrypt (=false) */
+    if (encflg_arg == atom_true)
+        encflg = 1;
+    else if (encflg_arg == atom_false)
+        encflg = 0;
+    else if (encflg_arg == atom_undefined)
+        /* For compat funcs in crypto.erl */
+        encflg = -1;
+    else
+        {
+            ret = EXCP_BADARG(env, "Bad enc flag");
+            goto done;
+        }
 
     type = argv[0];
 
-    ASSERT(argc == 6);
-
     if (!enif_is_atom(env, type))
         {ret = EXCP_BADARG(env, "non-atom cipher type"); goto done;}
     if (!enif_inspect_iolist_as_binary(env, argv[1], &key))
         {ret = EXCP_BADARG(env, "non-binary key"); goto done;}
-    if (!enif_inspect_binary(env, argv[2], &iv))
+    if (!enif_inspect_iolist_as_binary(env, argv[2], &iv))
         {ret = EXCP_BADARG(env, "non-binary iv"); goto done;}
-    if (!enif_inspect_iolist_as_binary(env, argv[3], &aad))
-        {ret = EXCP_BADARG(env, "non-binary AAD"); goto done;}
-    if (!enif_inspect_iolist_as_binary(env, argv[4], &in))
+    if (!enif_inspect_iolist_as_binary(env, argv[3], &in))
         {ret = EXCP_BADARG(env, "non-binary text"); goto done;}
-    if (!enif_get_uint(env, argv[5], &tag_len))
-        {ret = EXCP_BADARG(env, ""); goto done;}
+    if (!enif_inspect_iolist_as_binary(env, argv[4], &aad))
+        {ret = EXCP_BADARG(env, "non-binary AAD"); goto done;}
+
+    if (encflg) {
+        if (!enif_get_uint(env, argv[5], &tag_len))
+            {ret = EXCP_BADARG(env, "Bad Tag length"); goto done;}
+        tag_data = NULL;
+    } else {
+        if (!enif_inspect_iolist_as_binary(env, argv[5], &tag))
+            {ret = EXCP_BADARG(env, "non-binary Tag"); goto done;}
+        tag_len = tag.size;
+        tag_data = tag.data;
+    }
 
     if (tag_len > INT_MAX
+        || key.size > INT_MAX
         || iv.size > INT_MAX
         || in.size > INT_MAX
         || aad.size > INT_MAX)
@@ -66,167 +95,88 @@ ERL_NIF_TERM aead_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
     if ((cipher = cipherp->cipher.p) == NULL)
         {ret = EXCP_NOTSUP(env, "Cipher not supported in this libcrypto version"); goto done;}
 
-    ctx_ctrl_set_ivlen = cipherp->extra.aead.ctx_ctrl_set_ivlen;
-    ctx_ctrl_get_tag =  cipherp->extra.aead.ctx_ctrl_get_tag;
-    ctx_ctrl_set_tag =  cipherp->extra.aead.ctx_ctrl_set_tag;
-    
+#if defined(HAVE_GCM_EVP_DECRYPT_BUG)
+    if ( !encflg && (cipherp->flags & GCM_MODE))
+        return aes_gcm_decrypt_NO_EVP(env, argc, argv);
+#endif
+
     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
-        {ret = EXCP_ERROR(env, ""); goto done;}
+        {ret = EXCP_ERROR(env, "Can't allocate ctx"); goto done;}
 
-    if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-    if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_ivlen, (int)iv.size, NULL) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
+    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encflg) != 1)
+        {ret = EXCP_ERROR(env, "CipherInit failed"); goto done;}
+    if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_set_ivlen, (int)iv.size, NULL) != 1)
+        {ret = EXCP_BADARG(env, "Bad IV length"); goto done;}
 
 #if defined(HAVE_CCM)
-    if (type == atom_aes_ccm) {
-        if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_tag, (int)tag_len, NULL) != 1)
-            {ret = EXCP_ERROR(env, ""); goto done;}
-        if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
-            {ret = EXCP_ERROR(env, ""); goto done;}
-        if (EVP_EncryptUpdate(ctx, NULL, &len, NULL, (int)in.size) != 1)
-            {ret = EXCP_ERROR(env, ""); goto done;}
+    if (cipherp->flags & CCM_MODE) {
+        if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_set_tag, (int)tag_len, tag_data) != 1)
+            {ret = EXCP_BADARG(env, "Can't set tag"); goto done;}
+        if (EVP_CipherInit_ex(ctx, NULL, NULL, key.data, iv.data, -1) != 1)
+            {ret = EXCP_BADARG(env, "Can't set key or iv"); goto done;}
+        if (EVP_CipherUpdate(ctx, NULL, &len, NULL, (int)in.size) != 1)
+            {ret = EXCP_BADARG(env, "Can't set text size"); goto done;}
     } else
 #endif
         {
-            if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
-                {ret = EXCP_ERROR(env, ""); goto done;}
+            if (EVP_CipherInit_ex(ctx, NULL, NULL, key.data, iv.data, -1) != 1)
+                {ret = EXCP_BADARG(env, "Can't set key or iv"); goto done;}
         }
 
-    if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, (int)aad.size) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
+    if (EVP_CipherUpdate(ctx, NULL, &len, aad.data, (int)aad.size) != 1)
+        {ret = EXCP_BADARG(env, "Can't set AAD"); goto done;}
 
     if ((outp = enif_make_new_binary(env, in.size, &out)) == NULL)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-
-    if (EVP_EncryptUpdate(ctx, outp, &len, in.data, (int)in.size) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-    if (EVP_EncryptFinal_ex(ctx, outp/*+len*/, &len) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-
-    if ((tagp = enif_make_new_binary(env, tag_len, &out_tag)) == NULL)
-        {ret = EXCP_ERROR(env, ""); goto done;}
+        {ret = EXCP_ERROR(env, "Can't make 'Out' binary"); goto done;}
 
-    if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_get_tag, (int)tag_len, tagp) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-
-    CONSUME_REDS(env, in);
-    ret = enif_make_tuple2(env, out, out_tag);
-
- done:
-    if (ctx)
-        EVP_CIPHER_CTX_free(ctx);
-    return ret;
-
-#else
-    return EXCP_NOTSUP(env, "");
-#endif
-}
-
-ERL_NIF_TERM aead_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Type,Key,Iv,AAD,In,Tag) */
-#if defined(HAVE_AEAD)
-    const struct cipher_type_t *cipherp;
-    EVP_CIPHER_CTX *ctx = NULL;
-    const EVP_CIPHER *cipher = NULL;
-    ErlNifBinary key, iv, aad, in, tag;
-    unsigned char *outp;
-    ERL_NIF_TERM type, out, ret;
-    int len, ctx_ctrl_set_ivlen, ctx_ctrl_set_tag;
-
-    ASSERT(argc == 6);
-
-    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))
-        {ret = EXCP_BADARG(env, "non-atom cipher type"); goto done;}
-    if (!enif_inspect_iolist_as_binary(env, argv[1], &key))
-        {ret = EXCP_BADARG(env, "non-binary key"); goto done;}
-    if (!enif_inspect_binary(env, argv[2], &iv))
-        {ret = EXCP_BADARG(env, "non-binary iv"); goto done;}
-    if (!enif_inspect_iolist_as_binary(env, argv[3], &aad))
-        {ret = EXCP_BADARG(env, "non-binary AAD"); goto done;}
-    if (!enif_inspect_iolist_as_binary(env, argv[4], &in))
-        {ret = EXCP_BADARG(env, ""); goto done;}
-    if (!enif_inspect_iolist_as_binary(env, argv[5], &tag))
-        {ret = EXCP_BADARG(env, "non-binary text"); goto done;}
-
-    if (tag.size > INT_MAX
-        || key.size > INT_MAX
-        || iv.size > INT_MAX
-        || in.size > INT_MAX
-        || aad.size > INT_MAX)
-        {ret = EXCP_BADARG(env, "binary too long"); goto done;}
-
-    if ((cipherp = get_cipher_type(type, key.size)) == NULL)
-        {ret = EXCP_BADARG(env, "Unknown cipher"); goto done;}
-    if (cipherp->flags & NON_EVP_CIPHER)
-        {ret = EXCP_BADARG(env, "Bad cipher"); goto done;}
-    if ( !(cipherp->flags & AEAD_CIPHER) )
-        {ret = EXCP_BADARG(env, "Not aead cipher"); goto done;}
-    if ((cipher = cipherp->cipher.p) == NULL)
-        {ret = EXCP_NOTSUP(env, "Cipher not supported in this libcrypto version"); goto done;}
+    if (EVP_CipherUpdate(ctx, outp, &len, in.data, (int)in.size) != 1)
+        {
+            if (encflg)
+                ret = EXCP_BADARG(env, "Can't set in-text");
+            else
+                /* Decrypt error */
+                ret = atom_error;
+            goto done;
+        }
 
-    ctx_ctrl_set_ivlen = cipherp->extra.aead.ctx_ctrl_set_ivlen;
-    ctx_ctrl_set_tag =  cipherp->extra.aead.ctx_ctrl_set_tag;
+    if (encflg)
+        {
+            if (EVP_CipherFinal_ex(ctx, outp/*+len*/, &len) != 1)
+                {ret = EXCP_ERROR(env, "Encrypt error"); goto done;}
 
-    if ((outp = enif_make_new_binary(env, in.size, &out)) == NULL)
-        {ret = EXCP_ERROR(env, ""); goto done;}
+            if ((tagp = enif_make_new_binary(env, tag_len, &out_tag)) == NULL)
+                {ret = EXCP_ERROR(env, "Can't make 'Out' binary"); goto done;}
 
-    if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-    if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-    if (EVP_CIPHER_CTX_ctrl(ctx,  ctx_ctrl_set_ivlen, (int)iv.size, NULL) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
+            if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_get_tag, (int)tag_len, tagp) != 1)
+                {ret = EXCP_ERROR(env, "Can't get Tag"); goto done;}
 
-#if defined(HAVE_CCM)
-    if (type == atom_aes_ccm) {
-        if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_tag, (int)tag.size, tag.data) != 1)
-            {ret = EXCP_ERROR(env, ""); goto done;}
-        if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
-            {ret = EXCP_ERROR(env, ""); goto done;}
-        if (EVP_DecryptUpdate(ctx, NULL, &len, NULL, (int)in.size) != 1)
-            {ret = EXCP_ERROR(env, ""); goto done;}
-    }
+            ret = enif_make_tuple2(env, out, out_tag);
+        }
     else
-#endif
         {
-            if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1)
-                {ret = EXCP_ERROR(env, ""); goto done;}
-        }
-
-    if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, (int)aad.size) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-    if (EVP_DecryptUpdate(ctx, outp, &len, in.data, (int)in.size) != 1)
-        {ret = EXCP_ERROR(env, ""); goto done;}
-
 #if defined(HAVE_GCM)
-    if (type == atom_aes_gcm) {
-        if (EVP_CIPHER_CTX_ctrl(ctx, ctx_ctrl_set_tag, (int)tag.size, tag.data) != 1)
-            goto err;
-        if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1)
-            goto err;
-    }
+            if (cipherp->flags & GCM_MODE) {
+                if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_set_tag, (int)tag_len, tag.data) != 1)
+                    /* Decrypt error */
+                    {ret = atom_error; goto done;}
+                if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1)
+                    /* Decrypt error */
+                    {ret = atom_error; goto done;}
+            }
 #endif
-    CONSUME_REDS(env, in);
-    ret = out;
-    goto done;
+            ret = out;
+        }
 
- err:
-    /* Decrypt failed, that is, wrong tag */
-    ret = atom_error;
+    CONSUME_REDS(env, in);
 
- done:
+done:
     if (ctx)
         EVP_CIPHER_CTX_free(ctx);
     return ret;
 
 #else
-    return EXCP_NOTSUP(env, "");
+    return EXCP_NOTSUP(env, "Unsupported Cipher");
 #endif
 }
+
+
diff --git a/lib/crypto/c_src/aead.h b/lib/crypto/c_src/aead.h
index 54c0711535..2ec7a8a930 100644
--- a/lib/crypto/c_src/aead.h
+++ b/lib/crypto/c_src/aead.h
@@ -23,7 +23,6 @@
 
 #include "common.h"
 
-ERL_NIF_TERM aead_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-ERL_NIF_TERM aead_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM aead_cipher(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
 
 #endif /* E_AEAD_H__ */
diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c
index 5d063c3ae4..201c14dfba 100644
--- a/lib/crypto/c_src/api_ng.c
+++ b/lib/crypto/c_src/api_ng.c
@@ -27,7 +27,7 @@
  *
  */
 ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM ng_crypto_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
 
 #ifdef HAVE_ECB_IVEC_BUG
     /* <= 0.9.8l returns faulty ivec length */
@@ -93,6 +93,13 @@ static int get_init_args(ErlNifEnv* env,
             goto err;
         }
 
+    if ((*cipherp)->flags &  AEAD_CIPHER)
+        {
+            *return_term = EXCP_BADARG(env, "Missing arguments for this cipher");
+            goto err;
+        }
+
+
     if (FORBIDDEN_IN_FIPS(*cipherp))
         {
             *return_term = EXCP_NOTSUP(env, "Forbidden in FIPS");
@@ -504,7 +511,7 @@ ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
 /* One shot                                                              */
 /*************************************************************************/
 
-ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+ERL_NIF_TERM ng_crypto_one_time(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 {/* (Cipher, Key, IVec, Data, Encrypt) */
     struct evp_cipher_ctx ctx_res;
     const struct cipher_type_t *cipherp;
@@ -521,7 +528,7 @@ ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
     return ret;
 }
 
-ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+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 = <<>>
   */
     ErlNifBinary   data_bin;
@@ -536,10 +543,10 @@ ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
 
     /* Run long jobs on a dirty scheduler to not block the current emulator thread */
     if (data_bin.size > MAX_BYTES_TO_NIF) {
-        return enif_schedule_nif(env, "ng_crypto_one_shot",
+        return enif_schedule_nif(env, "ng_crypto_one_time",
                                  ERL_NIF_DIRTY_JOB_CPU_BOUND,
-                                 ng_crypto_one_shot, argc, argv);
+                                 ng_crypto_one_time, argc, argv);
     }
 
-    return ng_crypto_one_shot(env, argc, argv);
+    return ng_crypto_one_time(env, argc, argv);
 }
diff --git a/lib/crypto/c_src/api_ng.h b/lib/crypto/c_src/api_ng.h
index 5c7d9af3c5..aaf67524ae 100644
--- a/lib/crypto/c_src/api_ng.h
+++ b/lib/crypto/c_src/api_ng.h
@@ -25,6 +25,6 @@
 
 ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
 ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM ng_crypto_one_time_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
 
 #endif /* E_AES_H__ */
diff --git a/lib/crypto/c_src/cipher.c b/lib/crypto/c_src/cipher.c
index 2652e1db4e..13de3562e8 100644
--- a/lib/crypto/c_src/cipher.c
+++ b/lib/crypto/c_src/cipher.c
@@ -117,31 +117,31 @@ static struct cipher_type_t cipher_types[] =
 #endif
 
 #if defined(HAVE_GCM)
-    {{"aes_gcm"},     {&EVP_aes_128_gcm}, 16, AEAD_CIPHER, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
-    {{"aes_gcm"},     {&EVP_aes_192_gcm}, 24, AEAD_CIPHER, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
-    {{"aes_gcm"},     {&EVP_aes_256_gcm}, 32, AEAD_CIPHER, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
-    {{"aes_128_gcm"}, {&EVP_aes_128_gcm}, 16, AEAD_CIPHER, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
-    {{"aes_192_gcm"}, {&EVP_aes_192_gcm}, 24, AEAD_CIPHER, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
-    {{"aes_256_gcm"}, {&EVP_aes_256_gcm}, 32, AEAD_CIPHER, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
+    {{"aes_gcm"},     {&EVP_aes_128_gcm}, 16, AEAD_CIPHER|GCM_MODE, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
+    {{"aes_gcm"},     {&EVP_aes_192_gcm}, 24, AEAD_CIPHER|GCM_MODE, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
+    {{"aes_gcm"},     {&EVP_aes_256_gcm}, 32, AEAD_CIPHER|GCM_MODE, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
+    {{"aes_128_gcm"}, {&EVP_aes_128_gcm}, 16, AEAD_CIPHER|GCM_MODE, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
+    {{"aes_192_gcm"}, {&EVP_aes_192_gcm}, 24, AEAD_CIPHER|GCM_MODE, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
+    {{"aes_256_gcm"}, {&EVP_aes_256_gcm}, 32, AEAD_CIPHER|GCM_MODE, {{EVP_CTRL_GCM_SET_IVLEN,EVP_CTRL_GCM_GET_TAG,EVP_CTRL_GCM_SET_TAG}}},
 #else
-    {{"aes_gcm"},     {NULL},  0, AEAD_CIPHER, {{0,0,0}}},
-    {{"aes_128_gcm"}, {NULL}, 16, AEAD_CIPHER, {{0,0,0}}},
-    {{"aes_192_gcm"}, {NULL}, 24, AEAD_CIPHER, {{0,0,0}}},
-    {{"aes_256_gcm"}, {NULL}, 32, AEAD_CIPHER, {{0,0,0}}},
+    {{"aes_gcm"},     {NULL},  0, AEAD_CIPHER|GCM_MODE, {{0,0,0}}},
+    {{"aes_128_gcm"}, {NULL}, 16, AEAD_CIPHER|GCM_MODE, {{0,0,0}}},
+    {{"aes_192_gcm"}, {NULL}, 24, AEAD_CIPHER|GCM_MODE, {{0,0,0}}},
+    {{"aes_256_gcm"}, {NULL}, 32, AEAD_CIPHER|GCM_MODE, {{0,0,0}}},
 #endif
 
 #if defined(HAVE_CCM)
-    {{"aes_ccm"},     {&EVP_aes_128_ccm}, 16, AEAD_CIPHER, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
-    {{"aes_ccm"},     {&EVP_aes_192_ccm}, 24, AEAD_CIPHER, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
-    {{"aes_ccm"},     {&EVP_aes_256_ccm}, 32, AEAD_CIPHER, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
-    {{"aes_128_ccm"}, {&EVP_aes_128_ccm}, 16, AEAD_CIPHER, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
-    {{"aes_192_ccm"}, {&EVP_aes_192_ccm}, 24, AEAD_CIPHER, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
-    {{"aes_256_ccm"}, {&EVP_aes_256_ccm}, 32, AEAD_CIPHER, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
+    {{"aes_ccm"},     {&EVP_aes_128_ccm}, 16, AEAD_CIPHER|CCM_MODE, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
+    {{"aes_ccm"},     {&EVP_aes_192_ccm}, 24, AEAD_CIPHER|CCM_MODE, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
+    {{"aes_ccm"},     {&EVP_aes_256_ccm}, 32, AEAD_CIPHER|CCM_MODE, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
+    {{"aes_128_ccm"}, {&EVP_aes_128_ccm}, 16, AEAD_CIPHER|CCM_MODE, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
+    {{"aes_192_ccm"}, {&EVP_aes_192_ccm}, 24, AEAD_CIPHER|CCM_MODE, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
+    {{"aes_256_ccm"}, {&EVP_aes_256_ccm}, 32, AEAD_CIPHER|CCM_MODE, {{EVP_CTRL_CCM_SET_IVLEN,EVP_CTRL_CCM_GET_TAG,EVP_CTRL_CCM_SET_TAG}}},
 #else
-    {{"aes_ccm"},     {NULL},  0, AEAD_CIPHER, {{0,0,0}}},
-    {{"aes_128_ccm"}, {NULL}, 16, AEAD_CIPHER, {{0,0,0}}},
-    {{"aes_192_ccm"}, {NULL}, 24, AEAD_CIPHER, {{0,0,0}}},
-    {{"aes_256_ccm"}, {NULL}, 32, AEAD_CIPHER, {{0,0,0}}},
+    {{"aes_ccm"},     {NULL},  0, AEAD_CIPHER|CCM_MODE, {{0,0,0}}},
+    {{"aes_128_ccm"}, {NULL}, 16, AEAD_CIPHER|CCM_MODE, {{0,0,0}}},
+    {{"aes_192_ccm"}, {NULL}, 24, AEAD_CIPHER|CCM_MODE, {{0,0,0}}},
+    {{"aes_256_ccm"}, {NULL}, 32, AEAD_CIPHER|CCM_MODE, {{0,0,0}}},
 #endif
 
     /*==== Specialy handled ciphers, only for inclusion in algorithm's list ====*/
diff --git a/lib/crypto/c_src/cipher.h b/lib/crypto/c_src/cipher.h
index b94873940f..0e51c410eb 100644
--- a/lib/crypto/c_src/cipher.h
+++ b/lib/crypto/c_src/cipher.h
@@ -46,6 +46,8 @@ struct cipher_type_t {
 #define AEAD_CIPHER 8
 #define NON_EVP_CIPHER 16
 #define AES_CTR_COMPAT 32
+#define CCM_MODE 64
+#define GCM_MODE 128
 
 
 #ifdef FIPS_SUPPORT
diff --git a/lib/crypto/c_src/common.h b/lib/crypto/c_src/common.h
index 0bf7f09f4f..a7e59d5d01 100644
--- a/lib/crypto/c_src/common.h
+++ b/lib/crypto/c_src/common.h
@@ -38,8 +38,11 @@
 
 /* All nif functions return a valid value or throws an exception */
 #define EXCP(Env, Id, Str)  enif_raise_exception((Env), \
-                                enif_make_tuple2((Env), \
+                                enif_make_tuple3((Env), \
                                                  (Id),  \
+                                                 enif_make_tuple2((Env), \
+                                                                  enif_make_string((Env),__FILE__,(ERL_NIF_LATIN1)), \
+                                                                  enif_make_int((Env), __LINE__)), \
                                                  enif_make_string((Env),(Str),(ERL_NIF_LATIN1)) ))
 
 #define EXCP_NOTSUP(Env, Str) EXCP((Env), atom_notsup, (Str))
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 4aed06a489..a8014745c8 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -81,7 +81,7 @@ static ErlNifFunc nif_funcs[] = {
     {"ng_crypto_init_nif", 4, ng_crypto_init_nif, 0},
     {"ng_crypto_update_nif", 2, ng_crypto_update_nif, 0},
     {"ng_crypto_update_nif", 3, ng_crypto_update_nif, 0},
-    {"ng_crypto_one_shot_nif", 5, ng_crypto_one_shot_nif, 0},
+    {"ng_crypto_one_time_nif", 5, ng_crypto_one_time_nif, 0},
     {"strong_rand_bytes_nif", 1, strong_rand_bytes_nif, 0},
     {"strong_rand_range_nif", 1, strong_rand_range_nif, 0},
     {"rand_uniform_nif", 2, rand_uniform_nif, 0},
@@ -105,8 +105,7 @@ static ErlNifFunc nif_funcs[] = {
 
     {"rand_seed_nif", 1, rand_seed_nif, 0},
 
-    {"aead_encrypt", 6, aead_encrypt, 0},
-    {"aead_decrypt", 6, aead_decrypt, 0},
+    {"aead_cipher", 7, aead_cipher, 0},
 
     {"poly1305_nif", 2, poly1305_nif, 0},
 
-- 
cgit v1.2.3


From 927bd1c8d567145a1e09a172eae27ba084c8e63b Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 27 Mar 2019 14:01:52 +0100
Subject: crypto: Rename new api and rework the typing

Split conceptually into an OLD and a NEW api with separate typing.
The NEW api will in general not provide types for ciphers without key length like aes_ctr. Use aes_128_ctr etc.

Later the C-code will not accept them either.
---
 lib/crypto/src/crypto.erl | 313 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 227 insertions(+), 86 deletions(-)

diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index fd13481951..04b2f62266 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -58,7 +58,8 @@
 %% New interface
 -export([crypto_init/4, crypto_init/3,
          crypto_update/2,
-         crypto_one_shot/5,
+         crypto_one_time/4, crypto_one_time/5,
+         crypto_aead/6, crypto_aead/7,
          crypto_init_dyn_iv/3,
          crypto_update_dyn_iv/3
         ]).
@@ -276,48 +277,153 @@
 
 -type edwards_curve_ed() :: ed25519 | ed448 .
 
-%%% 
--type cipher() :: block_cipher()
-                | stream_cipher()
-                | aead_cipher() .
+%%%----------------------------------------------------------------
+%%% New cipher schema
+%%%
+-type cipher() :: cipher_no_iv()
+                | cipher_iv() 
+                | cipher_aead() .
 
--type block_cipher() :: block_cipher_iv() | block_cipher_no_iv() .
+-type cipher_no_iv() :: aes_128_ecb
+                      | aes_192_ecb
+                      | aes_256_ecb
 
--type block_cipher_iv() :: cbc_cipher()
-                              | cfb_cipher()
-                              | aes_ige256
-                              | blowfish_ofb64
-                              | rc2_cbc .
+                      | blowfish_ecb
+                      | des_ecb
+                      | rc4 .
 
--type cbc_cipher()  :: des_cbc | des_ede3_cbc
-                     | blowfish_cbc
-                     | aes_cbc | aes_128_cbc  | aes_192_cbc | aes_256_cbc
-                     | alias_cbc() .
--type alias_cbc() :: des3_cbc | des_ede3
-                   | aes_cbc128  | aes_cbc256 .
+-type cipher_iv() :: aes_128_cbc
+                   | aes_192_cbc
+                   | aes_256_cbc
+
+                   | aes_128_cfb128
+                   | aes_192_cfb128
+                   | aes_256_cfb128
+
+                   | aes_128_cfb8
+                   | aes_192_cfb8
+                   | aes_256_cfb8
 
--type aead_cipher() :: aes_gcm
+                   | aes_128_ctr
+                   | aes_192_ctr
+                   | aes_256_ctr
+
+                   | aes_ige256
+
+                   | blowfish_cbc
+                   | blowfish_cfb64
+                   | blowfish_ofb64
+                   | chacha20
+                   | des_ede3_cbc
+                   | des_ede3_cfb
+
+                   | des_cbc
+                   | des_cfb
+                   | rc2_cbc .
+
+
+-type cipher_aead() :: aes_128_ccm
+                     | aes_192_ccm
+                     | aes_256_ccm
+                       
                      | aes_128_gcm
                      | aes_192_gcm
                      | aes_256_gcm
-                     | aes_ccm
-                     | aes_128_ccm
-                     | aes_192_ccm
-                     | aes_256_ccm
+
                      | chacha20_poly1305 .
 
--type cfb_cipher()  :: aes_cfb8
-                     | aes_cfb128
-                     | blowfish_cfb64
-                     | des_cfb
-                     | des_ede3_cfb
-                     | alias_cfb() .
--type alias_cfb() :: des_ede3_cbf | des3_cbf
-                   | des3_cfb .
 
+%% -type retired_cipher_no_iv_aliases() :: aes_ecb .
+
+%% -type retired_cipher_iv_aliases() :: aes_cbc
+%%                                    | aes_cbc128  % aes_128_cbc
+%%                                    | aes_cbc256  % aes_256_cbc
+%%                                    | aes_cfb128
+%%                                    | aes_cfb8
+%%                                    | aes_ctr
+%%                                    | des3_cbc     % des_ede3_cbc
+%%                                    | des_ede3     % des_ede3_cbc
+%%                                    | des_ede3_cbf % des_ede3_cfb
+%%                                    | des3_cbf     % des_ede3_cfb
+%%                                    | des3_cfb .   % des_ede3_cfb 
+
+%% -type retired_cipher_aead_aliases() :: aes_ccm
+%%                                      | aes_gcm .
 
--type block_cipher_no_iv() :: ecb_cipher() .
--type ecb_cipher()  :: des_ecb | blowfish_ecb | aes_ecb .
+%%%----------------------------------------------------------------
+%%% Old cipher scheme
+%%%
+%%%
+-type block_cipher_without_iv() :: ecb_cipher() .
+
+-type block_cipher_with_iv() :: cbc_cipher()
+                              | cfb_cipher()
+                              | blowfish_ofb64
+                              | aes_ige256 .
+
+-type stream_cipher() :: ctr_cipher()
+                       | chacha20
+                       | rc4 .
+                         
+
+%%%----
+-type cbc_cipher()  :: aes_128_cbc
+                     | aes_192_cbc
+                     | aes_256_cbc
+                     | blowfish_cbc
+                     | des_cbc
+                     | des_ede3_cbc
+                     | rc2_cbc 
+                     | retired_cbc_cipher_aliases() .
+
+-type retired_cbc_cipher_aliases() :: aes_cbc      % aes_*_cbc
+                                    | aes_cbc128   % aes_128_cbc
+                                    | aes_cbc256   % aes_256_cbc
+                                    | des3_cbc     % des_ede3_cbc
+                                    | des_ede3 .   % des_ede3_cbc
+                                    
+%%%----
+-type cfb_cipher() :: aes_128_cfb128
+                    | aes_192_cfb128
+                    | aes_256_cfb128
+                    | aes_128_cfb8
+                    | aes_192_cfb8
+                    | aes_256_cfb8
+                    | blowfish_cfb64
+                    | des_cfb
+                    | des_ede3_cfb
+                    | retired_cfb_cipher_aliases() .
+
+-type retired_cfb_cipher_aliases() :: aes_cfb8      % aes_*_cfb8
+                                    | aes_cfb128    % aes_*_cfb128
+                                    | des3_cbf      % des_ede3_cfb, cfb misspelled
+                                    | des3_cfb      % des_ede3_cfb 
+                                    | des_ede3_cbf .% cfb misspelled
+
+
+%%%----
+-type ctr_cipher() :: aes_128_ctr
+                    | aes_192_ctr
+                    | aes_256_ctr
+                    | retired_ctr_cipher_aliases() .
+
+-type retired_ctr_cipher_aliases() :: aes_ctr .  % aes_*_ctr
+
+%%%----
+-type ecb_cipher() :: aes_128_ecb
+                    | aes_192_ecb
+                    | aes_256_ecb
+                    | blowfish_ecb
+                    | retired_ecb_cipher_aliases() .
+
+-type retired_ecb_cipher_aliases() :: aes_ecb .
+
+%%%----
+-type aead_cipher() :: aes_gcm | aes_ccm | chacha20_poly1305 .
+
+
+%%%----- end old cipher schema ------------------------------------
+%%%----------------------------------------------------------------
 
 -type key() :: iodata().
 -type des3_key() :: [key()].
@@ -564,9 +670,9 @@ poly1305(Key, Data) ->
 -define(COMPAT(CALL),
         try begin CALL end
         catch
-            error:{error,_} ->
+            error:{error, {_File,_Line}, _Reason} ->
                 error(badarg);
-            error:{E,_Reason} when E==notsup ; E==badarg ->
+            error:{E, {_File,_Line}, _Reason} when E==notsup ; E==badarg ->
                 error(E)
         end).
 
@@ -611,7 +717,7 @@ cipher_info(Type) ->
 
 %%%---- Block ciphers
 %%%----------------------------------------------------------------
--spec block_encrypt(Type::block_cipher_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) ->
+-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) ->
                            binary() | run_time_error();
                    (Type::aead_cipher(),  Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
                            {binary(), binary()} | run_time_error();
@@ -627,34 +733,24 @@ block_encrypt(Type, Key0, Ivec, Data) ->
     ?COMPAT(
        case Data of
            {AAD, PlainText} ->
-               aead_encrypt(alias(Type,Key), Key, Ivec, AAD, PlainText, aead_tag_len(Type));
+               crypto_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, true);
            {AAD, PlainText, TagLength} ->
-               aead_encrypt(alias(Type,Key), Key, Ivec, AAD, PlainText, TagLength);
+               crypto_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, TagLength, true);
            PlainText ->
-               crypto_one_shot(alias(Type,Key), Key, Ivec, PlainText, true)
+               crypto_one_time(alias(Type,Key), Key, Ivec, PlainText, true)
        end).
 
--spec block_encrypt(Type::block_cipher_no_iv(), Key::key(), PlainText::iodata()) ->
+-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) ->
                            binary() | run_time_error().
 
 block_encrypt(Type, Key0, PlainText) ->
     Key = iolist_to_binary(Key0),
-    ?COMPAT(crypto_one_shot(alias(Type,Key), Key, <<>>, PlainText, true)).
+    ?COMPAT(crypto_one_time(alias(Type,Key), Key, PlainText, true)).
 
 
-aead_tag_len(chacha20_poly1305) -> 16;
-aead_tag_len(aes_ccm) -> 12;
-aead_tag_len(aes_128_ccm) -> 12;
-aead_tag_len(aes_192_ccm) -> 12;
-aead_tag_len(aes_256_ccm) -> 12;
-aead_tag_len(aes_gcm) -> 16;
-aead_tag_len(aes_128_gcm) -> 16;
-aead_tag_len(aes_192_gcm) -> 16;
-aead_tag_len(aes_256_gcm) -> 16.
-
 %%%----------------------------------------------------------------
 %%%----------------------------------------------------------------
--spec block_decrypt(Type::block_cipher_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) ->
+-spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) ->
                            binary() | run_time_error();
 		   (Type::aead_cipher(), Key::iodata(), Ivec::binary(),
 		    {AAD::binary(), Data::iodata(), Tag::binary()}) ->
@@ -668,18 +764,18 @@ block_decrypt(Type, Key0, Ivec, Data) ->
     ?COMPAT(
        case Data of
            {AAD, CryptoText, Tag} ->
-               aead_decrypt(alias(Type,Key), Key, Ivec, AAD, CryptoText, Tag);
+               crypto_aead(alias(Type,Key), Key, Ivec, CryptoText, AAD, Tag, false);
            CryptoText ->
-               crypto_one_shot(alias(Type,Key), Key, Ivec, CryptoText, false)
+               crypto_one_time(alias(Type,Key), Key, Ivec, CryptoText, false)
        end).
 
 
--spec block_decrypt(Type::block_cipher_no_iv(), Key::key(), Data::iodata()) ->
+-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) ->
                            binary() | run_time_error().
 
 block_decrypt(Type, Key0, CryptoText) ->
     Key = iolist_to_binary(Key0),
-    ?COMPAT(crypto_one_shot(alias(Type,Key), Key, <<>>, CryptoText, false)).
+    ?COMPAT(crypto_one_time(alias(Type,Key), Key, CryptoText, false)).
 
 %%%-------- Stream ciphers API
 
@@ -687,17 +783,9 @@ block_decrypt(Type, Key0, CryptoText) ->
                            crypto_state() | {crypto_state(),flg_undefined}
                           }.
 
--type stream_cipher() :: stream_cipher_iv() | stream_cipher_no_iv() .
--type stream_cipher_no_iv() :: rc4 .
--type stream_cipher_iv() :: aes_ctr
-                          | aes_128_ctr
-                          | aes_192_ctr
-                          | aes_256_ctr
-                          | chacha20 .
-
 %%%---- stream_init
 -spec stream_init(Type, Key, IVec) -> State | run_time_error()
-                                          when Type :: stream_cipher_iv(),
+                                          when Type :: stream_cipher(),
                                                Key :: iodata(),
                                                IVec ::binary(),
                                                State :: stream_state() .
@@ -711,7 +799,7 @@ stream_init(Type, Key0, IVec) when is_binary(IVec) ->
 
 
 -spec stream_init(Type, Key) -> State | run_time_error()
-                                    when Type :: stream_cipher_no_iv(),
+                                    when Type :: rc4,
                                          Key :: iodata(),
                                          State :: stream_state() .
 stream_init(rc4 = Type, Key0) ->
@@ -792,38 +880,35 @@ next_iv(Type, Data, _Ivec) ->
 %%% 
 
 -spec crypto_init(Cipher, Key, EncryptFlag) -> State | descriptive_error()
-                                                   when Cipher :: block_cipher_no_iv()
-                                                                | stream_cipher_no_iv(),
+                                                   when Cipher :: cipher_no_iv(),
                                                         Key :: iodata(),
                                                         EncryptFlag :: boolean(),
                                                         State :: crypto_state() .
 crypto_init(Cipher, Key, EncryptFlag) ->
     %% The IV is supposed to be supplied by calling crypto_update/3
-    ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), <<>>, EncryptFlag).
+    ng_crypto_init_nif(Cipher, iolist_to_binary(Key), <<>>, EncryptFlag).
 
 
 -spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | descriptive_error()
-                                                       when Cipher :: stream_cipher_iv()
-                                                                    | block_cipher_iv(),
+                                                       when Cipher :: cipher_iv(),
                                                             Key :: iodata(),
                                                             IV :: iodata(),
                                                             EncryptFlag :: boolean(),
                                                             State :: crypto_state() .
 crypto_init(Cipher, Key, IV, EncryptFlag) ->
-    ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag).
+    ng_crypto_init_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag).
 
 
 
 %%%----------------------------------------------------------------
 -spec crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> State | descriptive_error()
-                                                          when Cipher :: stream_cipher_iv()
-                                                                       | block_cipher_iv(),
+                                                          when Cipher :: cipher_iv(),
                                                                Key :: iodata(),
                                                                EncryptFlag :: boolean(),
                                                                State :: crypto_state() .
 crypto_init_dyn_iv(Cipher, Key, EncryptFlag) ->
     %% The IV is supposed to be supplied by calling crypto_update/3
-    ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), undefined, EncryptFlag).
+    ng_crypto_init_nif(Cipher, iolist_to_binary(Key), undefined, EncryptFlag).
 
 %%%----------------------------------------------------------------
 %%%
@@ -866,29 +951,86 @@ crypto_update_dyn_iv(State, Data0, IV) ->
 %%% The size must be an integer multiple of the crypto's blocksize.
 %%% 
 
--spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) ->
+-spec crypto_one_time(Cipher, Key, Data, EncryptFlag) ->
                              Result | descriptive_error()
-                                 when Cipher :: stream_cipher()
-                                              | block_cipher(),
+                                 when Cipher :: cipher_no_iv(),
                                       Key :: iodata(),
-                                      IV :: iodata() | undefined,
                                       Data :: iodata(),
                                       EncryptFlag :: boolean(),
                                       Result :: binary() .
 
-crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) ->
-    crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag);
+crypto_one_time(Cipher, Key, Data, EncryptFlag) ->
+    crypto_one_time(Cipher, Key, <<>>, Data, EncryptFlag).
 
-crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) ->
+-spec crypto_one_time(Cipher, Key, IV, Data, EncryptFlag) ->
+                             Result | descriptive_error()
+                                 when Cipher :: cipher_iv(),
+                                      Key :: iodata(),
+                                      IV :: iodata(),
+                                      Data :: iodata(),
+                                      EncryptFlag :: boolean(),
+                                      Result :: binary() .
+
+crypto_one_time(Cipher, Key, IV, Data0, EncryptFlag) ->
     case iolist_to_binary(Data0) of
         <<>> ->
             <<>>;                           % Known to fail on OpenSSL 0.9.8h
         Data ->
-            ng_crypto_one_shot_nif(alias(Cipher),
+            ng_crypto_one_time_nif(Cipher,
                                    iolist_to_binary(Key), iolist_to_binary(IV), Data,
                                    EncryptFlag)
     end.
 
+
+-spec crypto_aead(Cipher, Key, IV, InText, AAD, EncFlag::true) ->
+                             Result | descriptive_error()
+                                 when Cipher :: cipher_aead(),
+                                      Key :: iodata(),
+                                      IV :: iodata(),
+                                      InText :: iodata(),
+                                      AAD :: iodata(),
+                                      Result :: EncryptResult,
+                                      EncryptResult :: {OutCryptoText, OutTag},
+                                      OutCryptoText :: binary(),
+                                      OutTag :: binary().
+
+crypto_aead(Cipher, Key, IV, PlainText, AAD, true) ->
+    crypto_aead(Cipher, Key, IV, PlainText, AAD, aead_tag_len(Cipher), true).
+
+
+-spec crypto_aead(Cipher, Key, IV, InText, AAD, TagOrTagLength, EncFlag) ->
+                             Result | descriptive_error()
+                                 when Cipher :: cipher_aead(),
+                                      Key :: iodata(),
+                                      IV :: iodata(),
+                                      InText :: iodata(),
+                                      AAD :: iodata(),
+                                      TagOrTagLength :: EncryptTagLength | DecryptTag,
+                                      EncryptTagLength :: non_neg_integer(), % or pos_integer() 1..
+                                      DecryptTag :: iodata(),
+                                      EncFlag :: boolean(),
+                                      Result :: EncryptResult | DecryptResult,
+                                      EncryptResult :: {OutCryptoText, OutTag},
+                                      DecryptResult :: OutPlainText | error,
+                                      OutCryptoText :: binary(),
+                                      OutTag :: binary(),
+                                      OutPlainText :: binary().
+
+crypto_aead(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg) ->
+    aead_cipher(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg).
+
+
+aead_tag_len(chacha20_poly1305) -> 16;
+aead_tag_len(aes_ccm    ) -> 12;
+aead_tag_len(aes_128_ccm) -> 12;
+aead_tag_len(aes_192_ccm) -> 12;
+aead_tag_len(aes_256_ccm) -> 12;
+aead_tag_len(aes_gcm    ) -> 16;
+aead_tag_len(aes_128_gcm) -> 16;
+aead_tag_len(aes_192_gcm) -> 16;
+aead_tag_len(aes_256_gcm) -> 16;
+aead_tag_len(_) -> error({badarg, "Not an AEAD cipher"}).
+
 %%%----------------------------------------------------------------
 %%% NIFs
 
@@ -909,9 +1051,9 @@ ng_crypto_update_nif(_State, _Data) -> ?nif_stub.
 ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub.
 
 
--spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) ->
+-spec ng_crypto_one_time_nif(atom(), binary(), binary(), binary(), boolean() ) ->
                                     binary() | descriptive_error().
-ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub.
+ng_crypto_one_time_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub.
 
 %%%----------------------------------------------------------------
 %%% Cipher aliases
@@ -2060,8 +2202,7 @@ cipher_info_nif(_Type) -> ?nif_stub.
 %% AES - in Galois/Counter Mode (GCM)
 %%
 %% The default tag length is EVP_GCM_TLS_TAG_LEN(16),
-aead_encrypt(_Type, _Key, _Ivec, _AAD, _In, _TagLength) -> ?nif_stub.
-aead_decrypt(_Type, _Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub.
+aead_cipher(_Type, _Key, _Ivec, _AAD, _In, _TagOrTagLength, _EncFlg) -> ?nif_stub.
 
 %%
 %% AES - with 256 bit key in infinite garble extension mode (IGE)
-- 
cgit v1.2.3


From 22e0ab68c78b67a753cc93ff31a2072abae36270 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 27 Mar 2019 14:03:38 +0100
Subject: crypto: Fixup lots of tests

---
 lib/crypto/test/crypto_SUITE.erl | 693 ++++++++++++++++++++++++---------------
 1 file changed, 429 insertions(+), 264 deletions(-)

diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index ce5097de47..6a2727a622 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -45,6 +45,42 @@ all() ->
      hash_info
     ].
 
+-define(NEW_CIPHER_TYPE_SCHEMA,
+        {group, des_ede3_cbc},
+        {group, des_ede3_cfb},
+        {group, aes_128_cbc},
+        {group, aes_192_cbc},
+        {group, aes_256_cbc},
+        {group, aes_128_ctr},
+        {group, aes_192_ctr},
+        {group, aes_256_ctr},
+        {group, aes_128_ccm},
+        {group, aes_192_ccm},
+        {group, aes_256_ccm},
+        {group, aes_128_ecb},
+        {group, aes_192_ecb},
+        {group, aes_256_ecb},
+        {group, aes_128_gcm},
+        {group, aes_192_gcm},
+        {group, aes_256_gcm},
+        {group, des_ede3_cbc},
+        {group, des_ede3_cfb}
+       ).
+        
+-define(RETIRED_TYPE_ALIASES,
+        {group, aes_cbc},
+        {group, aes_cbc128},
+        {group, aes_cbc256},
+        {group, aes_ccm},
+        {group, aes_ctr},
+        {group, aes_gcm},
+        {group, aes_ecb},
+        {group, des3_cfb},
+        {group, des3_cbc},
+        {group, des3_cbf},
+        {group, des_ede3}
+       ).
+
 groups() ->
     [{non_fips, [], [
                      {group, blake2b},
@@ -67,35 +103,29 @@ groups() ->
                      {group, sha3_512},
                      {group, sha512},
                      {group, sha},
+                     {group, poly1305},
 
                      {group, dh},
                      {group, ecdh},
                      {group, srp},
 
-		     {group, aes_cbc},
-		     {group, aes_ccm},
-		     {group, aes_gcm},
 		     {group, chacha20_poly1305},
 		     {group, chacha20},
-		     {group, des3_cfb},
-                     {group, aes_cbc128},
-                     {group, aes_cbc256},
-                     {group, aes_cfb128},
-                     {group, aes_cfb8},
-                     {group, aes_ctr},
-                     {group, aes_ige256},
                      {group, blowfish_cbc},
                      {group, blowfish_cfb64},
                      {group, blowfish_ecb},
                      {group, blowfish_ofb64},
-                     {group, des3_cbc},
-                     {group, des3_cbf},
+
+                     {group, aes_cfb128},
+                     {group, aes_cfb8},
+                     {group, aes_ige256},
                      {group, des_cbc},
                      {group, des_cfb},
-                     {group, des_ede3},
-                     {group, poly1305},
                      {group, rc2_cbc},
-                     {group, rc4}
+                     {group, rc4},
+
+                     ?NEW_CIPHER_TYPE_SCHEMA,
+                     ?RETIRED_TYPE_ALIASES
                     ]},
      {fips, [], [
                  {group, no_blake2b},
@@ -114,123 +144,142 @@ groups() ->
                  {group, sha256},
                  {group, sha384},
                  {group, sha512},
+                 {group, no_poly1305},
 
                  {group, dh},
                  {group, ecdh},
                  {group, no_srp},
 
-		 {group, aes_cbc},
-		 {group, aes_ccm},
-		 {group, aes_gcm},
 		 {group, no_chacha20_poly1305},
 		 {group, no_chacha20},
-		 {group, des3_cfb},
-                 {group, aes_cbc128},
-                 {group, aes_cbc256},
-                 {group, no_aes_cfb128},
-                 {group, no_aes_cfb8},
-                 {group, aes_ctr},
-                 {group, no_aes_ige256},
                  {group, no_blowfish_cbc},
                  {group, no_blowfish_cfb64},
                  {group, no_blowfish_ecb},
                  {group, no_blowfish_ofb64},
-                 {group, des3_cbc},
-                 {group, des3_cbf},
+
+                 {group, no_aes_cfb128},
+                 {group, no_aes_cfb8},
+                 {group, no_aes_ige256},
                  {group, no_des_cbc},
                  {group, no_des_cfb},
-                 {group, des_ede3},
-                 {group, no_poly1305},
                  {group, no_rc2_cbc},
-                 {group, no_rc4}
+                 {group, no_rc4},
+
+                 ?NEW_CIPHER_TYPE_SCHEMA,
+                 ?RETIRED_TYPE_ALIASES
                 ]},
-     {md4, [], [hash]},
-     {md5, [], [hash, hmac]},
-     {ripemd160, [], [hash]},
-     {sha, [], [hash, hmac]},
-     {sha224, [], [hash, hmac]},
-     {sha256, [], [hash, hmac]},
-     {sha384, [], [hash, hmac]},
-     {sha512, [], [hash, hmac]},
-     {sha3_224, [], [hash, hmac]},
-     {sha3_256, [], [hash, hmac]},
-     {sha3_384, [], [hash, hmac]},
-     {sha3_512, [], [hash, hmac]},
-     {blake2b, [], [hash, hmac]},
-     {blake2s, [], [hash, hmac]},
-     {no_blake2b, [], [no_hash, no_hmac]},
-     {no_blake2s, [], [no_hash, no_hmac]},
-     {rsa, [], [sign_verify,
-                public_encrypt,
-                private_encrypt,
-                generate
-               ]},
-     {dss, [], [sign_verify
-                %% Does not work yet:  ,public_encrypt, private_encrypt
-               ]},
-     {ecdsa, [], [sign_verify
-                %% Does not work yet:  ,public_encrypt, private_encrypt
-                 ]},
-     {ed25519, [], [sign_verify
-                %% Does not work yet:  ,public_encrypt, private_encrypt
-                 ]},
-     {ed448, [], [sign_verify
-                %% Does not work yet:  ,public_encrypt, private_encrypt
-                 ]},
-     {dh, [], [generate_compute,
-               compute_bug]},
-     {ecdh, [], [use_all_elliptic_curves, compute, generate]},
-     {srp, [], [generate_compute]},
-     {des_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {des_cfb, [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {des3_cbc,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {des_ede3,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {des3_cbf,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {des3_cfb,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {rc2_cbc,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {aes_cbc128,[], [block, api_ng, api_ng_one_shot, api_ng_tls, cmac]},
-     {aes_cfb8,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {aes_cfb128,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {aes_cbc256,[], [block, api_ng, api_ng_one_shot, api_ng_tls, cmac]},
-     {aes_ecb,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {aes_ige256,[], [block]},
-     {blowfish_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {blowfish_ecb, [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {blowfish_cfb64, [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {blowfish_ofb64,[], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {rc4, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
-     {aes_ctr, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
-     {aes_ccm, [], [aead]},
-     {aes_gcm, [], [aead]},
-     {chacha20_poly1305, [], [aead]},
-     {chacha20, [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
-     {poly1305, [], [poly1305]},
-     {no_poly1305, [], [no_poly1305]},
-     {aes_cbc, [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
-     {no_aes_cfb8,[], [no_support, no_block]},
-     {no_aes_cfb128,[], [no_support, no_block]},
-     {no_md4, [], [no_support, no_hash]},
-     {no_md5, [], [no_support, no_hash, no_hmac]},
-     {no_ed25519, [], [no_support, no_sign_verify
-                %% Does not work yet:  ,public_encrypt, private_encrypt
-                 ]},
-     {no_ed448, [], [no_support, no_sign_verify
-                %% Does not work yet:  ,public_encrypt, private_encrypt
-                 ]},
-     {no_ripemd160, [], [no_support, no_hash]},
-     {no_srp, [], [no_support, no_generate_compute]},
-     {no_des_cbc, [], [no_support, no_block]},
-     {no_des_cfb, [], [no_support, no_block]},
-     {no_blowfish_cbc, [], [no_support, no_block]},
-     {no_blowfish_ecb, [], [no_support, no_block]},
-     {no_blowfish_cfb64, [], [no_support, no_block]},
-     {no_blowfish_ofb64, [], [no_support, no_block]},
-     {no_aes_ige256, [], [no_support, no_block]},
+
+     {md4,                  [], [hash]},
+     {md5,                  [], [hash, hmac]},
+     {ripemd160,            [], [hash]},
+     {sha,                  [], [hash, hmac]},
+     {sha224,               [], [hash, hmac]},
+     {sha256,               [], [hash, hmac]},
+     {sha384,               [], [hash, hmac]},
+     {sha512,               [], [hash, hmac]},
+     {sha3_224,             [], [hash, hmac]},
+     {sha3_256,             [], [hash, hmac]},
+     {sha3_384,             [], [hash, hmac]},
+     {sha3_512,             [], [hash, hmac]},
+     {blake2b,              [], [hash, hmac]},
+     {blake2s,              [], [hash, hmac]},
+     {no_blake2b,           [], [no_hash, no_hmac]},
+     {no_blake2s,           [], [no_hash, no_hmac]},
+     {rsa,                  [], [sign_verify,
+                                 public_encrypt,
+                                 private_encrypt,
+                                 generate
+                                ]},
+     {dss,                  [], [sign_verify
+                                 %% Does not work yet:  ,public_encrypt, private_encrypt
+                                ]},
+     {ecdsa,                [], [sign_verify
+                                 %% Does not work yet:  ,public_encrypt, private_encrypt
+                                ]},
+     {ed25519,              [], [sign_verify
+                                 %% Does not work yet:  ,public_encrypt, private_encrypt
+                              ]},
+     {ed448,                [], [sign_verify
+                                 %% Does not work yet:  ,public_encrypt, private_encrypt
+                                ]},
+     {dh,                   [], [generate_compute, compute_bug]},
+     {ecdh,                 [], [use_all_elliptic_curves, compute, generate]},
+     {srp,                  [], [generate_compute]},
+     {des_cbc,              [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {des_cfb,              [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {des_ede3_cbc,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {des_ede3_cfb,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {rc2_cbc,              [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_cfb8,             [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {no_aes_cfb8,          [], [no_support, no_block]},
+     {aes_cfb128,           [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {no_aes_cfb128,        [], [no_support, no_block]},
+     {aes_ige256,           [], [block]},
+     {no_aes_ige256,        [], [no_support, no_block]},
+     {blowfish_cbc,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {blowfish_ecb,         [], [block, api_ng, api_ng_one_shot]},
+     {blowfish_cfb64,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {blowfish_ofb64,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
+     {rc4,                  [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_ctr,              [], [stream]},
+     {chacha20_poly1305,    [], [aead]},
+     {chacha20,             [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
+     {poly1305,             [], [poly1305]},
+     {no_poly1305,          [], [no_poly1305]},
+     {no_aes_cfb128,        [], [no_support, no_block]},
+     {no_md4,               [], [no_support, no_hash]},
+     {no_md5,               [], [no_support, no_hash, no_hmac]},
+     {no_ed25519,           [], [no_support, no_sign_verify
+                                 %% Does not work yet:  ,public_encrypt, private_encrypt
+                                ]},
+     {no_ed448,             [], [no_support, no_sign_verify
+                                 %% Does not work yet:  ,public_encrypt, private_encrypt
+                                ]},
+     {no_ripemd160,         [], [no_support, no_hash]},
+     {no_srp,               [], [no_support, no_generate_compute]},
+     {no_des_cbc,           [], [no_support, no_block]},
+     {no_des_cfb,           [], [no_support, no_block]},
+     {no_blowfish_cbc,      [], [no_support, no_block]},
+     {no_blowfish_ecb,      [], [no_support, no_block]},
+     {no_blowfish_cfb64,    [], [no_support, no_block]},
+     {no_blowfish_ofb64,    [], [no_support, no_block]},
+     {no_aes_ige256,        [], [no_support, no_block]},
      {no_chacha20_poly1305, [], [no_support, no_aead]},
-     {no_chacha20, [], [no_support, no_stream_ivec]},
-     {no_rc2_cbc, [], [no_support, no_block]},
-     {no_rc4, [], [no_support, no_stream]},
-     {api_errors, [], [api_errors_ecdh]}
+     {no_chacha20,          [], [no_support, no_stream_ivec]},
+     {no_rc2_cbc,           [], [no_support, no_block]},
+     {no_rc4,               [], [no_support, no_stream]},
+     {api_errors,           [], [api_errors_ecdh]},
+
+     %% New cipher nameing schema
+     {des_ede3_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {des_ede3_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_128_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_192_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_256_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_128_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_192_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_256_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
+     {aes_128_ccm,  [], [aead]},
+     {aes_192_ccm,  [], [aead]},
+     {aes_256_ccm,  [], [aead]},
+     {aes_128_ecb,  [], [api_ng, api_ng_one_shot]},
+     {aes_192_ecb,  [], [api_ng, api_ng_one_shot]},
+     {aes_256_ecb,  [], [api_ng, api_ng_one_shot]},
+     {aes_128_gcm,  [], [aead]},
+     {aes_192_gcm,  [], [aead]},
+     {aes_256_gcm,  [], [aead]},
+
+     %% Retired aliases
+     {aes_cbc,    [], [block]},
+     {aes_cbc128, [], [block]},
+     {aes_cbc256, [], [block]},
+     {aes_ccm,    [], [aead]},
+     {aes_ecb,    [], [block]},
+     {aes_gcm,    [], [aead]},
+     {des3_cbc,             [], [block]},
+     {des_ede3,             [], [block]},
+     {des3_cbf,             [], [block]},
+     {des3_cfb,             [], [block]}
     ].
 
 %%-------------------------------------------------------------------
@@ -430,7 +479,6 @@ poly1305(Config) ->
 no_poly1305() ->
     [{doc, "Test disabled poly1305 function"}].
 no_poly1305(Config) ->
-    Type = ?config(type, Config),
     Key = <<133,214,190,120,87,85,109,51,127,68,82,254,66,213,6,168,1,
             3,128,138,251,13,178,253,74,191,246,175,65,73,245,27>>,
     Txt = <<"Cryptographic Forum Research Group">>,
@@ -440,7 +488,7 @@ no_poly1305(Config) ->
 block() ->
      [{doc, "Test block ciphers"}].
 block(Config) when is_list(Config) ->
-    Blocks = lazy_eval(proplists:get_value(block, Config)),
+    [_|_] = Blocks = lazy_eval(proplists:get_value(cipher, Config)),
     lists:foreach(fun block_cipher/1, Blocks),
     lists:foreach(fun block_cipher/1, block_iolistify(Blocks)),
     lists:foreach(fun block_cipher_increment/1, block_iolistify(Blocks)).
@@ -449,7 +497,7 @@ block(Config) when is_list(Config) ->
 no_block() ->
      [{doc, "Test disabled block ciphers"}].
 no_block(Config) when is_list(Config) ->
-    Blocks = lazy_eval(proplists:get_value(block, Config)),
+    [_|_] = Blocks = lazy_eval(proplists:get_value(cipher, Config)),
     Args = case Blocks of
 	       [{_Type, _Key, _PlainText} = A | _] ->
 		   tuple_to_list(A);
@@ -466,10 +514,8 @@ api_ng() ->
      [{doc, "Test new api"}].
 
 api_ng(Config) when is_list(Config) ->
-    Blocks = lazy_eval(proplists:get_value(block, Config, [])),
-    Streams = lazy_eval(proplists:get_value(stream, Config, [])),
-    lists:foreach(fun api_ng_cipher_increment/1, Blocks++Streams).
-
+    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
+    lists:foreach(fun api_ng_cipher_increment/1, Ciphers).
 
 api_ng_cipher_increment({Type, Key, PlainTexts}=_X) ->
     ct:log("~p",[_X]),
@@ -523,9 +569,8 @@ api_ng_one_shot() ->
      [{doc, "Test new api"}].
 
 api_ng_one_shot(Config) when is_list(Config) ->
-    Blocks = lazy_eval(proplists:get_value(block, Config, [])),
-    Streams = lazy_eval(proplists:get_value(stream, Config, [])),
-    lists:foreach(fun do_api_ng_one_shot/1, Blocks++Streams).
+    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
+    lists:foreach(fun do_api_ng_one_shot/1, Ciphers).
 
 do_api_ng_one_shot({Type, Key, PlainTexts}=_X) ->
     ct:log("~p",[_X]),
@@ -537,8 +582,8 @@ do_api_ng_one_shot({Type, Key, IV, PlainTexts}=_X) ->
 
 do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
     ct:log("~p",[_X]),
-    PlainText = iolist_to_binary(PlainText0),
-    EncTxt = crypto:crypto_one_shot(Type, Key, IV, PlainText, true),
+    PlainText = iolist_to_binary(lazy_eval(PlainText0)),
+    EncTxt = crypto:crypto_one_time(Type, Key, IV, PlainText, true),
     case ExpectedEncText of
         undefined ->
             ok;
@@ -546,14 +591,14 @@ do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
             ok;
         _ ->
             ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, EncTxt]),
-            ct:fail("api_ng_one_shot (encode)",[])
+            ct:fail("api_ng_one_time (encode)",[])
     end,
-    case crypto:crypto_one_shot(Type, Key, IV, EncTxt, false) of
+    case crypto:crypto_one_time(Type, Key, IV, EncTxt, false) of
         PlainText ->
             ok;
         OtherPT ->
             ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]),
-            ct:fail("api_ng_one_shot (decode)",[])
+            ct:fail("api_ng_one_time (decode)",[])
     end.
 
 %%--------------------------------------------------------------------
@@ -561,9 +606,8 @@ api_ng_tls() ->
      [{doc, "Test special tls api"}].
 
 api_ng_tls(Config) when is_list(Config) ->
-    Blocks = lazy_eval(proplists:get_value(block, Config, [])),
-    Streams = lazy_eval(proplists:get_value(stream, Config, [])),
-    lists:foreach(fun do_api_ng_tls/1, Blocks++Streams).
+    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
+    lists:foreach(fun do_api_ng_tls/1, Ciphers).
 
 
 do_api_ng_tls({Type, Key, PlainTexts}=_X) ->
@@ -576,7 +620,7 @@ 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(PlainText0),
+    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),
@@ -616,7 +660,7 @@ no_aead() ->
      [{doc, "Test disabled aead ciphers"}].
 no_aead(Config) when is_list(Config) ->
     EncArg4 =
-        case lazy_eval(proplists:get_value(aead, Config)) of
+        case lazy_eval(proplists:get_value(cipher, Config)) of
             [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag, TagLen, _Info} | _] ->
                 {AAD, PlainText, TagLen};
             [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag, _Info} | _] ->
@@ -631,7 +675,7 @@ no_aead(Config) when is_list(Config) ->
 stream() ->
       [{doc, "Test stream ciphers"}].
 stream(Config) when is_list(Config) ->
-    Streams = lazy_eval(proplists:get_value(stream, Config)),
+    [_|_] = Streams = lazy_eval(proplists:get_value(cipher, Config)),
 
     lists:foreach(fun stream_cipher/1, Streams),
     lists:foreach(fun stream_cipher/1, stream_iolistify(Streams)),
@@ -654,8 +698,7 @@ no_stream_ivec(Config) when is_list(Config) ->
 aead() ->
       [{doc, "Test AEAD ciphers"}].
 aead(Config) when is_list(Config) ->
-    AEADs = lazy_eval(proplists:get_value(aead, Config)),
-
+    [_|_] = AEADs = lazy_eval(proplists:get_value(cipher, Config)),
     FilteredAEADs =
 	case proplists:get_bool(fips, Config) of
 	    false ->
@@ -668,7 +711,6 @@ aead(Config) when is_list(Config) ->
 			  IVLen >= 12
 		  end, AEADs)
 	end,
-
     lists:foreach(fun aead_cipher/1, FilteredAEADs).
 
 %%-------------------------------------------------------------------- 
@@ -985,13 +1027,27 @@ block_cipher({Type, Key, IV, PlainText, CipherText}) ->
 	    ct:fail({{crypto, block_decrypt, [Type, Key, IV, CipherText]}, {expected, Plain}, {got, Other1}})
     end.
 
-block_cipher_increment({Type, Key, IV, PlainTexts})
-  when Type == des_cbc; Type == aes_cbc; Type == des3_cbc ->
+block_cipher_increment({Type, Key, IV, PlainTexts}) when Type == des_cbc ;
+                                                         Type == des3_cbc ;
+                                                         Type == aes_128_cbc ;
+                                                         Type == aes_192_cbc ;
+                                                         Type == aes_256_cbc
+                                                         ->
     block_cipher_increment(Type, Key, IV, IV, PlainTexts, iolist_to_binary(PlainTexts), []);
-block_cipher_increment({Type, Key, IV, PlainTexts, CipherText})
-  when Type == des_cbc; Type == des3_cbc ->
+block_cipher_increment({Type, Key, IV, PlainTexts, CipherText}) when Type == des_cbc; 
+                                                                     Type == des_ede3_cbc ;
+                                                                     Type == des3_cbc ;
+                                                                     Type == des_ede3 ;
+                                                                     Type == des_ede3_cfb ;
+                                                                     Type == des_ede3_cbf ;
+                                                                     Type == des3_cbf ;
+                                                                     Type == des3_cfb
+                                                                     ->
     block_cipher_increment(Type, Key, IV, IV, PlainTexts, iolist_to_binary(PlainTexts), CipherText, []);
-block_cipher_increment({Type, Key, IV, PlainTexts, _CipherText}) when Type == aes_cbc ->
+block_cipher_increment({Type, Key, IV, PlainTexts, _CipherText}) when Type == aes_128_cbc ;
+                                                                      Type == aes_192_cbc ;
+                                                                      Type == aes_256_cbc 
+                                                                      ->
     Plain = iolist_to_binary(PlainTexts),
     Blocks = [iolistify(Block) || << Block:128/bitstring >> <= Plain],
     block_cipher_increment(Type, Key, IV, IV, Blocks, Plain, []);
@@ -1025,8 +1081,9 @@ block_cipher_increment(Type, Key, IV0, IV, [PlainText | PlainTexts], Plain, Ciph
     NextIV = crypto:next_iv(Type, CT),
     block_cipher_increment(Type, Key, IV0, NextIV, PlainTexts, Plain, CipherText, [CT | Acc]).
 
-stream_cipher({Type, Key, PlainText}) ->
-    Plain = iolist_to_binary(PlainText),
+stream_cipher({Type, Key, PlainText0}) ->
+    PlainText = lazy_eval(PlainText0),
+    Plain = iolist_to_binary(lazy_eval(PlainText)),
     StateE = crypto:stream_init(Type, Key),
     StateD = crypto:stream_init(Type, Key),
     {_, CipherText} = crypto:stream_encrypt(StateE, PlainText),
@@ -1036,7 +1093,8 @@ stream_cipher({Type, Key, PlainText}) ->
 	Other ->
 	    ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other}})
     end;
-stream_cipher({Type, Key, IV, PlainText}) ->
+stream_cipher({Type, Key, IV, PlainText0}) ->
+    PlainText = lazy_eval(PlainText0),
     Plain = iolist_to_binary(PlainText),
     StateE = crypto:stream_init(Type, Key, IV),
     StateD = crypto:stream_init(Type, Key, IV),
@@ -1047,7 +1105,8 @@ stream_cipher({Type, Key, IV, PlainText}) ->
 	Other ->
 	    ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other}})
     end;
-stream_cipher({Type, Key, IV, PlainText, CipherText}) ->
+stream_cipher({Type, Key, IV, PlainText0, CipherText}) ->
+    PlainText = lazy_eval(PlainText0),
     Plain = iolist_to_binary(PlainText),
     StateE = crypto:stream_init(Type, Key, IV),
     StateD = crypto:stream_init(Type, Key, IV),
@@ -1112,7 +1171,7 @@ aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, Info}) ->
 aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}) ->
     <<TruncatedCipherTag:TagLen/binary, _/binary>> = CipherTag,
     Plain = iolist_to_binary(PlainText),
-    case crypto:block_encrypt(Type, Key, IV, {AAD, Plain, TagLen}) of
+    try crypto:block_encrypt(Type, Key, IV, {AAD, Plain, TagLen}) of
 	{CipherText, TruncatedCipherTag} ->
 	    ok;
 	Other0 ->
@@ -1121,6 +1180,18 @@ aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}
                       [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}, {taglen,TagLen}]},
                      {expected, {CipherText, TruncatedCipherTag}},
                      {got, Other0}})
+    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)
+            of
+                RR ->
+                    ct:log("Works: ~p",[RR])
+            catch
+                CC:EE ->
+                    ct:log("~p:~p", [CC,EE])
+            end,
+            ct:fail("~p",[E])
     end,
     case crypto:block_decrypt(Type, Key, IV, {AAD, CipherText, TruncatedCipherTag}) of
 	Plain ->
@@ -1369,16 +1440,15 @@ do_stream_iolistify({Type, Key, IV, PlainText}) ->
     {Type, iolistify(Key), IV, iolistify(PlainText)};
 do_stream_iolistify({Type, Key, IV, PlainText, CipherText}) ->
     {Type, iolistify(Key), IV, iolistify(PlainText), CipherText}.
-
-do_block_iolistify({des_cbc = Type, Key, IV, PlainText}) ->
-    {Type, Key, IV, des_iolistify(PlainText)};
-do_block_iolistify({des3_cbc = Type, Key, IV, PlainText}) ->
-    {Type, Key, IV, des_iolistify(PlainText)};
-do_block_iolistify({des3_cbf = Type, Key, IV, PlainText}) ->
-    {Type, Key, IV, des_iolistify(PlainText)};
-do_block_iolistify({des3_cfb = Type, Key, IV, PlainText}) ->
-    {Type, Key, IV, des_iolistify(PlainText)};
-do_block_iolistify({des_ede3 = Type, Key, IV, PlainText}) ->
+do_block_iolistify({Type, Key, IV, PlainText}) when Type == des_cbc ;
+                                                    Type == des_ede3_cbc ;
+                                                    Type == des3_cbc ;
+                                                    Type == des_ede3 ;
+                                                    Type == des_ede3_cfb ;
+                                                    Type == des_ede3_cbf ;
+                                                    Type == des3_cbf ;
+                                                    Type == des3_cfb
+                                                    ->
     {Type, Key, IV, des_iolistify(PlainText)};
 do_block_iolistify({Type, Key, PlainText}) ->
     {Type, iolistify(Key), iolistify(PlainText)};
@@ -1387,10 +1457,13 @@ do_block_iolistify({Type, Key, IV, PlainText}) ->
 do_block_iolistify({Type, Key, IV, PlainText, CipherText}) ->
     {Type, iolistify(Key), IV, iolistify(PlainText), CipherText}.
 
-iolistify(<<"Test With Truncation">>)->
+iolistify(X) ->
+    iolistify1(lazy_eval(X)).
+
+iolistify1(<<"Test With Truncation">>)->
     %% Do not iolistify as it spoils this special case
     <<"Test With Truncation">>;
-iolistify(Msg) when is_binary(Msg) ->
+iolistify1(Msg) when is_binary(Msg) ->
     Length = erlang:byte_size(Msg),
     Split = Length div 2,
     List0 = binary_to_list(Msg),
@@ -1400,8 +1473,8 @@ iolistify(Msg) when is_binary(Msg) ->
        {List1, List2}->
 	   [List1, List2]
    end;
-iolistify(Msg) ->
-    iolistify(list_to_binary(Msg)).
+iolistify1(Msg) when is_list(Msg) ->
+    iolistify1(list_to_binary(Msg)).
 
 des_iolistify(Msg) ->    
     des_iolist(erlang:byte_size(Msg) div 8, Msg, []).
@@ -1710,7 +1783,6 @@ group_config(dss = Type, Config) ->
     MsgPubEnc = <<"7896345786348 Asldi">>,
     PubPrivEnc = [{dss, Public, Private, MsgPubEnc, []}],
     [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc}  | Config];
-
 group_config(ecdsa = Type, Config) ->
     {Private, Public} = ec_key_named(),
     Msg = ec_msg(),
@@ -1722,15 +1794,13 @@ group_config(ecdsa = Type, Config) ->
     MsgPubEnc = <<"7896345786348 Asldi">>,
     PubPrivEnc = [{ecdsa, Public, Private, MsgPubEnc, []}],
     [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc} | Config];
-
 group_config(Type, Config) when Type == ed25519 ; Type == ed448 ->
     TestVectors = eddsa(Type),
     [{sign_verify,TestVectors} | Config]; 
-
-
 group_config(srp, Config) ->
     GenerateCompute = [srp3(), srp6(), srp6a(), srp6a_smaller_prime()],
     [{generate_compute, GenerateCompute} | Config];
+
 group_config(ecdh, Config) ->
     Compute = ecdh(),
     Generate = ecc(),
@@ -1738,77 +1808,19 @@ group_config(ecdh, Config) ->
 group_config(dh, Config) ->
     GenerateCompute = [dh()],
     [{generate_compute, GenerateCompute} | Config];
-group_config(des_cbc, Config) ->
-    Block = des_cbc(),
-    [{block, Block} | Config];
-group_config(des_cfb, Config) ->
-    Block = des_cfb(),
-    [{block, Block} | Config];
-group_config(des3_cbc, Config) ->
-    Block = des3_cbc(),
-    [{block, Block} | Config];
-group_config(des3_cbf, Config) ->
-    Block = des3_cbf(),
-    [{block, Block} | Config];
-group_config(des3_cfb, Config) ->
-    Block = des3_cfb(),
-    [{block, Block} | Config];
-group_config(des_ede3, Config) ->
-    Block = des_ede3(),
-    [{block, Block} | Config];
-group_config(rc2_cbc, Config) ->
-    Block = rc2_cbc(),
-    [{block, Block} | Config];
+
 group_config(aes_cbc128 = Type, Config) ->
     Block = fun() -> aes_cbc128(Config) end,
     Pairs = fun() -> cmac_nist(Config, Type) end,
-    [{block, Block}, {cmac, Pairs} | Config];
+    [{cipher, Block}, {cmac, Pairs} | Config];
 group_config(aes_cbc256 = Type, Config) ->
     Block = fun() -> aes_cbc256(Config) end,
     Pairs = fun() -> cmac_nist(Config, Type) end,
-    [{block, Block}, {cmac, Pairs} | Config];
-group_config(aes_ecb, Config) ->
-    Block = fun() -> aes_ecb(Config) end,
-    [{block, Block} | Config];
-group_config(aes_ige256, Config) ->
-    Block = aes_ige256(),
-    [{block, Block} | Config];
-group_config(aes_cfb8, Config) ->
-    Block = fun() -> aes_cfb8(Config) end,
-    [{block, Block} | Config];
-group_config(aes_cfb128, Config) ->
-    Block = fun() -> aes_cfb128(Config) end,
-    [{block, Block} | Config];
-group_config(blowfish_cbc, Config) ->
-    Block = blowfish_cbc(),
-    [{block, Block} | Config];
-group_config(blowfish_ecb, Config) ->
-    Block = blowfish_ecb(),
-    [{block, Block} | Config];
-group_config(blowfish_cfb64, Config) ->
-    Block = blowfish_cfb64(),
-    [{block, Block} | Config];
-group_config(blowfish_ofb64, Config) ->
-    Block = blowfish_ofb64(),
-    [{block, Block} | Config];
-group_config(rc4, Config) ->
-    Stream = rc4(),
-    [{stream, Stream} | Config];
-group_config(aes_ctr, Config) ->
-    Stream = aes_ctr(),
-    [{stream, Stream} | Config];
-group_config(aes_ccm, Config) ->
-    AEAD = fun() -> aes_ccm(Config) end,
-    [{aead, AEAD} | Config];
-group_config(aes_gcm, Config) ->
-    AEAD = fun() -> aes_gcm(Config) end,
-    [{aead, AEAD} | Config];
+    [{cipher, Block}, {cmac, Pairs} | Config];
 group_config(chacha20_poly1305, Config) ->
-    AEAD = chacha20_poly1305(),
-    [{aead, AEAD} | Config];
-group_config(chacha20, Config) ->
-    Stream = chacha20(),
-    [{stream, Stream} | Config];
+    AEAD = chacha20_poly1305(Config),
+    [{cipher, AEAD} | Config];
+
 group_config(poly1305, Config) ->
     V = [%% {Key, Txt, Expect}
          {%% RFC7539 2.5.2
@@ -1818,11 +1830,12 @@ group_config(poly1305, Config) ->
          }
         ],
     [{poly1305,V} | Config];
-group_config(aes_cbc, Config) ->
-    Block = aes_cbc(Config),
-    [{block, Block} | Config];
-group_config(_, Config) ->
-    Config.
+
+group_config(F, Config) ->
+    TestVectors = fun() -> ?MODULE:F(Config) end,
+    [{cipher, TestVectors} | Config].
+
+
 
 rsa_sign_verify_tests(Config, Msg, Public, Private, PublicS, PrivateS, OptsToTry) ->
         case ?config(fips, Config) of
@@ -2413,19 +2426,19 @@ rfc4231_hmac_sha512() ->
 		"debd71f8867289865df5a32d20cdc944"
 		"b6022cac3c4982b10d5eeb55c3e4de15"
 		"134676fb6de0446065c97440fa8c6a58")].
-des_cbc() ->
+des_cbc(_) ->
     [{des_cbc, 
      hexstr2bin("0123456789abcdef"), 
      hexstr2bin("1234567890abcdef"),
      <<"Now is the time for all ">> }].
       
-des_cfb() ->
+des_cfb(_) ->
     [{des_cfb, 
      hexstr2bin("0123456789abcdef"),
      hexstr2bin("1234567890abcdef"),
      <<"Now is the">>}].
 
-des3_cbc() ->
+des3_cbc(_) ->
     [{des3_cbc,
      [hexstr2bin("0123456789abcdef"), 
       hexstr2bin("fedcba9876543210"),
@@ -2434,7 +2447,7 @@ des3_cbc() ->
      <<"Now is the time for all ">>
      }].
 
-des_ede3() ->
+des_ede3(_) ->
     [{des_ede3,
      [hexstr2bin("8000000000000000"),
       hexstr2bin("4000000000000000"),
@@ -2443,7 +2456,23 @@ des_ede3() ->
       hexstr2bin("0000000000000000")
      }].
 
-des3_cbf() ->
+des_ede3_cbc(_) ->
+    [{des_ede3_cbc,
+     [hexstr2bin("0123456789abcdef"), 
+      hexstr2bin("fedcba9876543210"),
+      hexstr2bin("0f2d4b6987a5c3e1")],
+     hexstr2bin("1234567890abcdef"),
+     <<"Now is the time for all ">>
+     },
+     {des_ede3_cbc,
+     [hexstr2bin("8000000000000000"),
+      hexstr2bin("4000000000000000"),
+      hexstr2bin("2000000000000000")],
+      hexstr2bin("7AD16FFB79C45926"),
+      hexstr2bin("0000000000000000")
+     }].
+
+des3_cbf(_) ->
     [{des3_cbf,
      [hexstr2bin("0123456789abcdef"),
       hexstr2bin("fedcba9876543210"),
@@ -2452,7 +2481,7 @@ des3_cbf() ->
      <<"Now is the time for all ">>
      }].
 
-des3_cfb() ->
+des3_cfb(_) ->
     [{des3_cfb,
      [hexstr2bin("0123456789abcdef"),
       hexstr2bin("fedcba9876543210"),
@@ -2461,7 +2490,16 @@ des3_cfb() ->
      <<"Now is the time for all ">>
      }].
 
-rc2_cbc() ->
+des_ede3_cfb(_) ->
+    [{des_ede3_cfb,
+     [hexstr2bin("0123456789abcdef"),
+      hexstr2bin("fedcba9876543210"),
+      hexstr2bin("0f2d4b6987a5c3e1")],
+     hexstr2bin("1234567890abcdef"),
+     <<"Now is the time for all ">>
+     }].
+
+rc2_cbc(_) ->
     [{rc2_cbc,
      <<146,210,160,124,215,227,153,239,227,17,222,140,3,93,27,191>>,
       <<72,91,135,182,25,42,35,210>>,
@@ -2470,7 +2508,8 @@ rc2_cbc() ->
 
 %% AES CBC test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
 aes_cbc(Config) ->
-   read_rsp(Config, aes_cbc,
+    %% RETIRED aes_*_cbc
+    read_rsp(Config, aes_cbc,
             ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
              "CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
              "CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
@@ -2478,15 +2517,32 @@ aes_cbc(Config) ->
             ]).
 
 aes_cbc128(Config) ->
+    %% RETIRED aes_128_cbc
     read_rsp(Config, aes_cbc128,
              ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
               "CBCMMT128.rsp"]).
 
 aes_cbc256(Config) ->
+    %% RETIRED aes_256_cbc
     read_rsp(Config, aes_cbc256,
              ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
               "CBCMMT256.rsp"]).
 
+aes_128_cbc(Config) ->
+    read_rsp(Config, aes_128_cbc,
+             ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
+              "CBCMMT128.rsp"]).
+
+aes_192_cbc(Config) ->
+    read_rsp(Config, aes_192_cbc,
+             ["CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
+              "CBCMMT192.rsp"]).
+
+aes_256_cbc(Config) ->
+    read_rsp(Config, aes_256_cbc,
+             ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
+              "CBCMMT256.rsp"]).
+
 aes_ecb(Config) ->
     read_rsp(Config, aes_ecb,
              ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
@@ -2494,7 +2550,22 @@ aes_ecb(Config) ->
               "ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
               "ECBMMT128.rsp", "ECBMMT192.rsp", "ECBMMT256.rsp"]).
 
-aes_ige256() ->
+aes_128_ecb(Config) ->
+    read_rsp(Config, aes_128_ecb,
+             ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
+              "ECBMMT128.rsp"]).
+
+aes_192_ecb(Config) ->
+    read_rsp(Config, aes_192_ecb,
+             ["ECBVarTxt192.rsp", "ECBVarKey192.rsp", "ECBGFSbox192.rsp", "ECBKeySbox192.rsp",
+              "ECBMMT192.rsp"]).
+
+aes_256_ecb(Config) ->
+    read_rsp(Config, aes_256_ecb,
+             ["ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
+              "ECBMMT256.rsp"]).
+
+aes_ige256(_) ->
     [{aes_ige256,
       hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
       hexstr2bin("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"),
@@ -2527,14 +2598,14 @@ aes_cfb128(Config) ->
               "CFB128VarTxt256.rsp", "CFB128VarKey256.rsp", "CFB128GFSbox256.rsp", "CFB128KeySbox256.rsp",
               "CFB128MMT128.rsp", "CFB128MMT192.rsp", "CFB128MMT256.rsp"]).
 
-blowfish_cbc() ->
+blowfish_cbc(_) ->
     [{blowfish_cbc,
       hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"), 
       hexstr2bin("FEDCBA9876543210"),
       hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000000000")
      }].
 
-blowfish_ecb() ->
+blowfish_ecb(_) ->
     [
      {blowfish_ecb,
       hexstr2bin("0000000000000000"), 
@@ -2631,26 +2702,26 @@ blowfish_ecb() ->
       hexstr2bin("FFFFFFFFFFFFFFFF")}
     ].
 
-blowfish_cfb64() ->
+blowfish_cfb64(_) ->
     [{blowfish_cfb64,
       hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"), 
       hexstr2bin("FEDCBA9876543210"),
       hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000")
      }].
-blowfish_ofb64() ->
+blowfish_ofb64(_) ->
     [{blowfish_ofb64,
       hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"), 
       hexstr2bin("FEDCBA9876543210"),
       hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000")
      }].
 
-rc4() ->
+rc4(_) ->
     [{rc4, <<"apaapa">>, <<"Yo baby yo">>},
      {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))},
      {rc4, <<"apaapa">>, long_msg()}
     ].
 
-aes_ctr() ->
+aes_ctr(_) ->
     [  %% F.5.3  CTR-AES192.Encrypt
        {aes_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), 
 	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 
@@ -2699,24 +2770,109 @@ aes_ctr() ->
     ].
 
 
+aes_128_ctr(_) ->
+    [  %% F.5.3  CTR-AES192.Encrypt
+       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), 
+	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 
+	hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
+       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), 
+	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"), 
+	hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
+       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), 
+	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"), 
+	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef") },
+       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), 
+	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"), 
+	hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
+    ].
+       
+aes_192_ctr(_) ->
+    [ %% F.5.3  CTR-AES192.Encrypt
+      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 
+       hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
+      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"), 
+       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
+      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"), 
+	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
+      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"), 
+       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
+    ].
+       
+aes_256_ctr(_) ->
+    [ %% F.5.5  CTR-AES256.Encrypt
+      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 
+       hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
+      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"), 
+       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
+      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"), 
+       hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
+      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), 
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"), 
+       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
+
+      {aes_256_ctr,  hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
+       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
+       long_msg()}
+    ].
+
+
 aes_gcm(Config) ->
-   read_rsp(Config, aes_gcm,
+    %% RETIRED aes_*_gcm
+    read_rsp(Config, aes_gcm,
+             ["gcmDecrypt128.rsp",
+              "gcmDecrypt192.rsp",
+              "gcmDecrypt256.rsp",
+              "gcmEncryptExtIV128.rsp",
+              "gcmEncryptExtIV192.rsp",
+              "gcmEncryptExtIV256.rsp"]).
+
+aes_128_gcm(Config) ->
+   read_rsp(Config, aes_128_gcm,
             ["gcmDecrypt128.rsp",
-             "gcmDecrypt192.rsp",
-             "gcmDecrypt256.rsp",
-             "gcmEncryptExtIV128.rsp",
-             "gcmEncryptExtIV192.rsp",
+             "gcmEncryptExtIV128.rsp"]).
+
+aes_192_gcm(Config) ->
+   read_rsp(Config, aes_192_gcm,
+            ["gcmDecrypt192.rsp",
+             "gcmEncryptExtIV192.rsp"]).
+
+aes_256_gcm(Config) ->
+   read_rsp(Config, aes_256_gcm,
+            ["gcmDecrypt256.rsp",
              "gcmEncryptExtIV256.rsp"]).
 
+
 aes_ccm(Config) ->
-   read_rsp(Config, aes_ccm,
-            ["VADT128.rsp", "VADT192.rsp", "VADT256.rsp",
-             "VNT128.rsp",  "VNT192.rsp",  "VNT256.rsp",
-             "VPT128.rsp",  "VPT192.rsp",  "VPT256.rsp"
-            ]).
+    %% RETIRED aes_*_ccm
+    read_rsp(Config, aes_ccm,
+             ["VADT128.rsp", "VADT192.rsp", "VADT256.rsp",
+              "VNT128.rsp",  "VNT192.rsp",  "VNT256.rsp",
+              "VPT128.rsp",  "VPT192.rsp",  "VPT256.rsp"
+             ]).
+
+aes_128_ccm(Config) ->
+    read_rsp(Config, aes_128_ccm,
+            ["VADT128.rsp", "VNT128.rsp", "VPT128.rsp"]).
+
+aes_192_ccm(Config) ->
+   read_rsp(Config, aes_192_ccm,
+            ["VADT192.rsp", "VNT192.rsp", "VPT192.rsp"]).
+
+aes_256_ccm(Config) ->
+   read_rsp(Config, aes_256_ccm,
+            ["VADT256.rsp", "VNT256.rsp", "VPT256.rsp"]).
+
+
 
 %% https://tools.ietf.org/html/rfc7539#appendix-A.5
-chacha20_poly1305() ->
+chacha20_poly1305(_) ->
     [
      {chacha20_poly1305,
       hexstr2bin("1c9240a5eb55d38af333888604f6b5f0"                      %% Key
@@ -2763,7 +2919,7 @@ chacha20_poly1305() ->
     ].
 
 
-chacha20() ->
+chacha20(_) ->
 %%% chacha20 (no mode) test vectors from RFC 7539 A.2
     [
      %% Test Vector #1:
@@ -3697,7 +3853,16 @@ parse_rsp(_Type, [], _State, Acc) ->
     Acc;
 parse_rsp(_Type, [<<"DECRYPT">>|_], _State, Acc) ->
     Acc;
+parse_rsp(_Type, [<<"ENCRYPT">>|_], _State, Acc) ->
+    Acc;
 %% AES format
+parse_rsp(Type, [<<"COUNT = ", _/binary>>,
+                 <<"KEY = ", Key/binary>>,
+                 <<"PLAINTEXT = ", PlainText/binary>>,
+                 <<"CIPHERTEXT = ", CipherText/binary>>|Next], State, Acc) ->
+    parse_rsp(Type, Next, State,
+              [{Type, hexstr2bin(Key), 
+                hexstr2bin(PlainText), hexstr2bin(CipherText)}|Acc]);
 parse_rsp(Type, [<<"COUNT = ", _/binary>>,
                  <<"KEY = ", Key/binary>>,
                  <<"IV = ", IV/binary>>,
-- 
cgit v1.2.3


From 6b8d1140d74a625ee0b629c924700ab190fe9f1a Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 27 Mar 2019 13:55:09 +0100
Subject: ssh: Use new crypto function names

---
 lib/ssh/src/ssh_transport.erl | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 1f4e281a30..2299346a30 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -170,7 +170,7 @@ supported_algorithms(cipher) ->
 	 {'AEAD_AES_256_GCM', [{ciphers,aes_256_gcm}]},
 	 {'AEAD_AES_128_GCM', [{ciphers,aes_128_gcm}]},
 	 {'aes128-cbc',       [{ciphers,aes_128_cbc}]},
-	 {'3des-cbc',         [{ciphers,des3_cbc}]}
+	 {'3des-cbc',         [{ciphers,des_ede3_cbc}]}
 	]
        ));
 supported_algorithms(mac) ->
@@ -1340,7 +1340,7 @@ cipher('AEAD_AES_256_GCM') ->
             pkt_type = aead};
 
 cipher('3des-cbc') ->
-    #cipher{impl = des3_cbc,
+    #cipher{impl = des_ede3_cbc,
             key_bytes = 24,
             iv_bytes = 8,
             block_bytes = 8};
@@ -1445,12 +1445,12 @@ encrypt(#ssh{encrypt = 'chacha20-poly1305@openssh.com',
         <<LenData:4/binary, PayloadData/binary>>) ->
     %% Encrypt length
     IV1 = <<0:8/unit:8, Seq:8/unit:8>>,
-    EncLen = crypto:crypto_one_shot(chacha20, K1, IV1, LenData, true),
+    EncLen = crypto:crypto_one_time(chacha20, K1, IV1, LenData, true),
     %% Encrypt payload
     IV2 = <<1:8/little-unit:8, Seq:8/unit:8>>,
-    EncPayloadData = crypto:crypto_one_shot(chacha20, K2, IV2, PayloadData, true),
+    EncPayloadData = crypto:crypto_one_time(chacha20, K2, IV2, PayloadData, true),
     %% MAC tag
-    PolyKey = crypto:crypto_one_shot(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>, <<0:32/unit:8>>, true),
+    PolyKey = crypto:crypto_one_time(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>, <<0:32/unit:8>>, true),
     EncBytes = <<EncLen/binary,EncPayloadData/binary>>,
     Ctag = crypto:poly1305(PolyKey, EncBytes),
     %% Result
@@ -1519,7 +1519,7 @@ decrypt(Ssh, <<>>) ->
 decrypt(#ssh{decrypt = 'chacha20-poly1305@openssh.com',
              decrypt_keys = {K1,_K2},
              recv_sequence = Seq} = Ssh, {length,EncryptedLen}) ->
-    PacketLenBin = crypto:crypto_one_shot(chacha20, K1, <<0:8/unit:8, Seq:8/unit:8>>, EncryptedLen, false),
+    PacketLenBin = crypto:crypto_one_time(chacha20, K1, <<0:8/unit:8, Seq:8/unit:8>>, EncryptedLen, false),
     {Ssh, PacketLenBin};
 
 decrypt(#ssh{decrypt = 'chacha20-poly1305@openssh.com',
@@ -1527,12 +1527,12 @@ decrypt(#ssh{decrypt = 'chacha20-poly1305@openssh.com',
              recv_sequence = Seq} = Ssh, {AAD,Ctext,Ctag}) ->
     %% The length is already decoded and used to divide the input
     %% Check the mac (important that it is timing-safe):
-    PolyKey = crypto:crypto_one_shot(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>, <<0:32/unit:8>>, false),
+    PolyKey = crypto:crypto_one_time(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>, <<0:32/unit:8>>, false),
     case equal_const_time(Ctag, crypto:poly1305(PolyKey, <<AAD/binary,Ctext/binary>>)) of
         true ->
             %% MAC is ok, decode
             IV2 = <<1:8/little-unit:8, Seq:8/unit:8>>,
-            PlainText = crypto:crypto_one_shot(chacha20, K2, IV2, Ctext, false),
+            PlainText = crypto:crypto_one_time(chacha20, K2, IV2, Ctext, false),
             {Ssh, PlainText};
         false ->
            {Ssh,error}
-- 
cgit v1.2.3


From 4334d5c6107d6b6380b61e9200471c28d6c63110 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 27 Mar 2019 16:42:54 +0100
Subject: crypto: Fix valgrind error for api_ng.c

---
 lib/crypto/c_src/api_ng.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c
index 201c14dfba..107723d2cb 100644
--- a/lib/crypto/c_src/api_ng.c
+++ b/lib/crypto/c_src/api_ng.c
@@ -420,13 +420,15 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
 ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 {/* (Context, Data [, IV]) */
     struct evp_cipher_ctx *ctx_res;
+    struct evp_cipher_ctx ctx_res_copy;
     ERL_NIF_TERM ret;
 
+    ctx_res_copy.ctx = NULL;
+
     if (!enif_get_resource(env, argv[0], (ErlNifResourceType*)evp_cipher_ctx_rtype, (void**)&ctx_res))
         return EXCP_BADARG(env, "Bad 1:st arg");
     
     if (argc == 3) {
-        struct evp_cipher_ctx ctx_res_copy;
         ErlNifBinary ivec_bin;
 
         memcpy(&ctx_res_copy, ctx_res, sizeof ctx_res_copy);
@@ -481,6 +483,9 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
         get_update_args(env, ctx_res, argv[1], &ret);
 
  err:
+    if (ctx_res_copy.ctx)
+        EVP_CIPHER_CTX_free(ctx_res_copy.ctx);
+
     return ret; /* Both success and error */
 }
 
-- 
cgit v1.2.3