[openssl] master update

Matt Caswell matt at openssl.org
Wed May 8 10:06:31 UTC 2019


The branch master has been updated
       via  67c81ec311d696464bdbf4c6d6f8a887a3ddf9f8 (commit)
      from  36e619d70f86f9dd52c57b6ac8a3bfea3c0a2745 (commit)


- Log -----------------------------------------------------------------
commit 67c81ec311d696464bdbf4c6d6f8a887a3ddf9f8
Author: Tobias Nießen <tniessen at tnie.de>
Date:   Fri Sep 14 21:49:34 2018 +0200

    Allow specifying the tag after AAD in CCM mode
    
    This change allows to pass the authentication tag after specifying
    the AAD in CCM mode. This is already true for the other two supported
    AEAD modes (GCM and OCB) and it seems appropriate to match the
    behavior.
    
    GCM and OCB also support to set the tag at any point before the call
    to `EVP_*Final`, but this won't work for CCM due to a restriction
    imposed by section 2.6 of RFC3610: The tag must be set before
    actually decrypting data.
    
    This commit also adds a test case for setting the tag after supplying
    plaintext length and AAD.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/7243)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/e_aes.c                        |  7 +++++--
 doc/man3/EVP_EncryptInit.pod              |  4 +++-
 test/evp_test.c                           | 29 ++++++++++++++++++++---------
 test/recipes/30-test_evp_data/evpciph.txt | 11 +++++++++++
 4 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index 16ffe4d..6d8d437 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -3792,8 +3792,6 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     if (!cctx->iv_set)
         return -1;
 
-    if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
-        return -1;
     if (!out) {
         if (!in) {
             if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
@@ -3808,6 +3806,11 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
         CRYPTO_ccm128_aad(ccm, in, len);
         return len;
     }
+
+    /* The tag must be set before actually decrypting data */
+    if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
+        return -1;
+
     /* If not set length yet do it */
     if (!cctx->len_set) {
         if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod
index 9cb863b..3c2e36b 100644
--- a/doc/man3/EVP_EncryptInit.pod
+++ b/doc/man3/EVP_EncryptInit.pod
@@ -412,7 +412,9 @@ The following I<ctrl>s are supported in CCM mode.
 This call is made to set the expected B<CCM> tag value when decrypting or
 the length of the tag (with the C<tag> parameter set to NULL) when encrypting.
 The tag length is often referred to as B<M>. If not set a default value is
-used (12 for AES).
+used (12 for AES). When decrypting, the tag needs to be set before passing
+in data to be decrypted, but as in GCM and OCB mode, it can be set after
+passing additional authenticated data (see L<AEAD Interface>).
 
 =item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, ivlen, NULL)
 
diff --git a/test/evp_test.c b/test/evp_test.c
index 1836ddb..fa9cde8 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -463,6 +463,7 @@ typedef struct cipher_data_st {
     size_t aad_len[AAD_NUM];
     unsigned char *tag;
     size_t tag_len;
+    int tag_late;
 } CIPHER_DATA;
 
 static int cipher_test_init(EVP_TEST *t, const char *alg)
@@ -535,6 +536,15 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
         }
         if (strcmp(keyword, "Tag") == 0)
             return parse_bin(value, &cdat->tag, &cdat->tag_len);
+        if (strcmp(keyword, "SetTagLate") == 0) {
+            if (strcmp(value, "TRUE") == 0)
+                cdat->tag_late = 1;
+            else if (strcmp(value, "FALSE") == 0)
+                cdat->tag_late = 0;
+            else
+                return 0;
+            return 1;
+        }
     }
 
     if (strcmp(keyword, "Operation") == 0) {
@@ -620,7 +630,7 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
          * If encrypting or OCB just set tag length initially, otherwise
          * set tag length and value.
          */
-        if (enc || expected->aead == EVP_CIPH_OCB_MODE) {
+        if (enc || expected->aead == EVP_CIPH_OCB_MODE || expected->tag_late) {
             t->err = "TAG_LENGTH_SET_ERROR";
             tag = NULL;
         } else {
@@ -643,14 +653,6 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
         goto err;
     }
 
-    if (!enc && expected->aead == EVP_CIPH_OCB_MODE) {
-        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
-                                 expected->tag_len, expected->tag)) {
-            t->err = "TAG_SET_ERROR";
-            goto err;
-        }
-    }
-
     if (expected->aead == EVP_CIPH_CCM_MODE) {
         if (!EVP_CipherUpdate(ctx, NULL, &tmplen, NULL, out_len)) {
             t->err = "CCM_PLAINTEXT_LENGTH_SET_ERROR";
@@ -689,6 +691,15 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
             }
         }
     }
+
+    if (!enc && (expected->aead == EVP_CIPH_OCB_MODE || expected->tag_late)) {
+        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+                                 expected->tag_len, expected->tag)) {
+            t->err = "TAG_SET_ERROR";
+            goto err;
+        }
+    }
+
     EVP_CIPHER_CTX_set_padding(ctx, 0);
     t->err = "CIPHERUPDATE_ERROR";
     tmplen = 0;
diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt
index 553bee5..916ba15 100644
--- a/test/recipes/30-test_evp_data/evpciph.txt
+++ b/test/recipes/30-test_evp_data/evpciph.txt
@@ -733,6 +733,17 @@ Ciphertext = 9a5fcccdb4cf04e7293d2775cc76a488f042382d949b43b7d6bb2b9864786726
 Operation = DECRYPT
 Result = CIPHERUPDATE_ERROR
 
+# Test that the tag can be set after specifying AAD.
+Cipher = aes-256-ccm
+Key = 1bde3251d41a8b5ea013c195ae128b218b3e0306376357077ef1c1c78548b92e
+IV = 5b8e40746f6b98e00f1d13ff41
+AAD = c17a32514eb6103f3249e076d4c871dc97e04b286699e54491dc18f6d734d4c0
+Tag = 2024931d73bca480c24a24ece6b6c2bf
+SetTagLate = TRUE
+Operation = DECRYPT
+Plaintext = 53bd72a97089e312422bf72e242377b3c6ee3e2075389b999c4ef7f28bd2b80a
+Ciphertext = 9a5fcccdb4cf04e7293d2775cc76a488f042382d949b43b7d6bb2b9864786726
+
 # AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
 Cipher = aes-128-gcm
 Key = 00000000000000000000000000000000


More information about the openssl-commits mailing list