[openssl] master update

Dr. Paul Dale pauli at openssl.org
Mon Apr 12 05:00:00 UTC 2021


The branch master has been updated
       via  d36114d7cd363d505940326f5a2512d9661a67ea (commit)
       via  13eaa4ecaab528e9fd815a1019406335d241d643 (commit)
       via  810a169eb2b642e5ca1e337bc6a9847defea62da (commit)
       via  e3c2a55d470a313c2fc5f2fb625c086d0cb953ea (commit)
      from  b1c908f421b3466aecf980603132bcab89d1ce99 (commit)


- Log -----------------------------------------------------------------
commit d36114d7cd363d505940326f5a2512d9661a67ea
Author: Pauli <pauli at openssl.org>
Date:   Fri Apr 9 16:36:18 2021 +1000

    kmac: update the documention for the customisation string maximum length
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14810)

commit 13eaa4ecaab528e9fd815a1019406335d241d643
Author: Pauli <pauli at openssl.org>
Date:   Fri Apr 9 16:20:15 2021 +1000

    kmac: fix customistation string overflow bug
    
    Previously there was an off by two error allowing a stack buffer overrun.
    Avoided this by allocating a correct sized buffer on the stack.  A side effect
    is that the maximum size of the customisation string can be increased.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14810)

commit 810a169eb2b642e5ca1e337bc6a9847defea62da
Author: Pauli <pauli at openssl.org>
Date:   Fri Apr 9 15:20:16 2021 +1000

    kmac: add long customisation string example
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14810)

commit e3c2a55d470a313c2fc5f2fb625c086d0cb953ea
Author: Pauli <pauli at openssl.org>
Date:   Sat Apr 10 12:40:59 2021 +1000

    Add additional KMAC error
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14810)

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

Summary of changes:
 crypto/err/openssl.txt                          |   1 +
 doc/man7/EVP_MAC-KMAC.pod                       |   2 +-
 include/openssl/proverr.h                       |   1 +
 providers/common/provider_err.c                 |   1 +
 providers/implementations/macs/kmac_prov.c      | 124 +++++++++++++++---------
 test/recipes/30-test_evp_data/evpmac_common.txt |  19 ++++
 6 files changed, 102 insertions(+), 46 deletions(-)

diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 07439f7c4a..ee17b68405 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1006,6 +1006,7 @@ PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest
 PROV_R_IN_ERROR_STATE:192:in error state
 PROV_R_KEY_SETUP_FAILED:101:key setup failed
 PROV_R_KEY_SIZE_TOO_SMALL:171:key size too small
+PROV_R_LENGTH_TOO_LARGE:202:length too large
 PROV_R_MISSING_CEK_ALG:144:missing cek alg
 PROV_R_MISSING_CIPHER:155:missing cipher
 PROV_R_MISSING_CONFIG_DATA:213:missing config data
diff --git a/doc/man7/EVP_MAC-KMAC.pod b/doc/man7/EVP_MAC-KMAC.pod
index 6b02e94ef8..85986d5449 100644
--- a/doc/man7/EVP_MAC-KMAC.pod
+++ b/doc/man7/EVP_MAC-KMAC.pod
@@ -42,7 +42,7 @@ Setting this parameter is identical to passing a I<key> to L<EVP_MAC_init(3)>.
 =item "custom" (B<OSSL_MAC_PARAM_CUSTOM>) <octet string>
 
 Sets the custom value.
-It is an optional value of at most 127 bytes, and is empty by default.
+It is an optional value of at most 256 bytes, and is empty by default.
 
 =item "size" (B<OSSL_MAC_PARAM_SIZE>) <unsigned integer>
 
diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h
index 99a937f1e3..c40815a03b 100644
--- a/include/openssl/proverr.h
+++ b/include/openssl/proverr.h
@@ -79,6 +79,7 @@
 # define PROV_R_IN_ERROR_STATE                            192
 # define PROV_R_KEY_SETUP_FAILED                          101
 # define PROV_R_KEY_SIZE_TOO_SMALL                        171
+# define PROV_R_LENGTH_TOO_LARGE                          202
 # define PROV_R_MISSING_CEK_ALG                           144
 # define PROV_R_MISSING_CIPHER                            155
 # define PROV_R_MISSING_CONFIG_DATA                       213
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 30574f4c6c..dd1a98f935 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -110,6 +110,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SETUP_FAILED), "key setup failed"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SIZE_TOO_SMALL),
     "key size too small"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_LENGTH_TOO_LARGE), "length too large"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CIPHER), "missing cipher"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONFIG_DATA),
diff --git a/providers/implementations/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c
index 8735705f1b..d6fccf442f 100644
--- a/providers/implementations/macs/kmac_prov.c
+++ b/providers/implementations/macs/kmac_prov.c
@@ -78,17 +78,15 @@ static OSSL_FUNC_mac_update_fn kmac_update;
 static OSSL_FUNC_mac_final_fn kmac_final;
 
 #define KMAC_MAX_BLOCKSIZE ((1600 - 128*2) / 8) /* 168 */
-#define KMAC_MIN_BLOCKSIZE ((1600 - 256*2) / 8) /* 136 */
 
 /* Length encoding will be  a 1 byte size + length in bits (2 bytes max) */
 #define KMAC_MAX_ENCODED_HEADER_LEN 3
 
 /*
- * Custom string max size is chosen such that:
- *   len(encoded_string(custom) + len(kmac_encoded_string) <= KMAC_MIN_BLOCKSIZE
- *   i.e: (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_LEN) + 6 <= 136
+ * Restrict the maximum length of the customisation string.  This must not
+ * exceed 64 bits = 8k bytes.
  */
-#define KMAC_MAX_CUSTOM 127
+#define KMAC_MAX_CUSTOM 256
 
 /* Maximum size of encoded custom string */
 #define KMAC_MAX_CUSTOM_ENCODED (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_HEADER_LEN)
@@ -116,8 +114,8 @@ struct kmac_data_st {
     EVP_MD_CTX *ctx;
     PROV_DIGEST digest;
     size_t out_len;
-    int key_len;
-    int custom_len;
+    size_t key_len;
+    size_t custom_len;
     /* If xof_mode = 1 then we use right_encode(0) */
     int xof_mode;
     /* key and custom are stored in encoded form */
@@ -125,16 +123,16 @@ struct kmac_data_st {
     unsigned char custom[KMAC_MAX_CUSTOM_ENCODED];
 };
 
-static int encode_string(unsigned char *out, int *out_len,
-                         const unsigned char *in, int in_len);
-static int right_encode(unsigned char *out, int *out_len, size_t bits);
-static int bytepad(unsigned char *out, int *out_len,
-                   const unsigned char *in1, int in1_len,
-                   const unsigned char *in2, int in2_len,
-                   int w);
-static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
-                                   const unsigned char *in, int in_len,
-                                   int w);
+static int encode_string(unsigned char *out, size_t *out_len,
+                         const unsigned char *in, size_t in_len);
+static int right_encode(unsigned char *out, size_t *out_len, size_t bits);
+static int bytepad(unsigned char *out, size_t *out_len,
+                   const unsigned char *in1, size_t in1_len,
+                   const unsigned char *in2, size_t in2_len,
+                   size_t w);
+static int kmac_bytepad_encode_key(unsigned char *out, size_t *out_len,
+                                   const unsigned char *in, size_t in_len,
+                                   size_t w);
 
 static void kmac_free(void *vmacctx)
 {
@@ -245,13 +243,18 @@ static int kmac_setkey(struct kmac_data_st *kctx, const unsigned char *key,
                        size_t keylen)
 {
     const EVP_MD *digest = ossl_prov_digest_md(&kctx->digest);
+    int w = EVP_MD_block_size(digest);
 
     if (keylen < 4 || keylen > KMAC_MAX_KEY) {
         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
         return 0;
     }
+    if (w < 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
+        return 0;
+    }
     if (!kmac_bytepad_encode_key(kctx->key, &kctx->key_len,
-                                 key, keylen, EVP_MD_block_size(digest)))
+                                 key, keylen, (size_t)w))
         return 0;
     return 1;
 }
@@ -266,11 +269,13 @@ static int kmac_init(void *vmacctx, const unsigned char *key,
 {
     struct kmac_data_st *kctx = vmacctx;
     EVP_MD_CTX *ctx = kctx->ctx;
-    unsigned char out[KMAC_MAX_BLOCKSIZE];
-    int out_len, block_len;
+    unsigned char *out;
+    size_t out_len, block_len;
+    int res, t;
 
     if (!ossl_prov_is_running() || !kmac_set_ctx_params(kctx, params))
         return 0;
+
     if (key != NULL) {
         if (!kmac_setkey(kctx, key, keylen))
             return 0;
@@ -283,9 +288,12 @@ static int kmac_init(void *vmacctx, const unsigned char *key,
                            NULL))
         return 0;
 
-    block_len = EVP_MD_block_size(ossl_prov_digest_md(&kctx->digest));
-    if (block_len < 0)
+    t = EVP_MD_block_size(ossl_prov_digest_md(&kctx->digest));
+    if (t < 0) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
         return 0;
+    }
+    block_len = t;
 
     /* Set default custom string if it is not already set */
     if (kctx->custom_len == 0) {
@@ -296,10 +304,22 @@ static int kmac_init(void *vmacctx, const unsigned char *key,
         (void)kmac_set_ctx_params(kctx, cparams);
     }
 
-    return bytepad(out, &out_len, kmac_string, sizeof(kmac_string),
-                   kctx->custom, kctx->custom_len, block_len)
-           && EVP_DigestUpdate(ctx, out, out_len)
-           && EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
+    if (!bytepad(NULL, &out_len, kmac_string, sizeof(kmac_string),
+                 kctx->custom, kctx->custom_len, block_len)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    out = OPENSSL_malloc(out_len);
+    if (out == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    res = bytepad(out, NULL, kmac_string, sizeof(kmac_string),
+                  kctx->custom, kctx->custom_len, block_len)
+          && EVP_DigestUpdate(ctx, out, out_len)
+          && EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
+    OPENSSL_free(out);
+    return res;
 }
 
 static int kmac_update(void *vmacctx, const unsigned char *data,
@@ -315,7 +335,7 @@ static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl,
 {
     struct kmac_data_st *kctx = vmacctx;
     EVP_MD_CTX *ctx = kctx->ctx;
-    int lbits, len;
+    size_t lbits, len;
     unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN];
     int ok;
 
@@ -431,14 +451,16 @@ static unsigned int get_encode_size(size_t bits)
  * e.g if bits = 32, out[2] = { 0x20, 0x01 }
  *
  */
-static int right_encode(unsigned char *out, int *out_len, size_t bits)
+static int right_encode(unsigned char *out, size_t *out_len, size_t bits)
 {
     unsigned int len = get_encode_size(bits);
     int i;
 
     /* The length is constrained to a single byte: 2040/8 = 255 */
-    if (len > 0xFF)
+    if (len > 0xFF) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
         return 0;
+    }
 
     /* MSB's are at the start of the bytes array */
     for (i = len - 1; i >= 0; --i) {
@@ -460,18 +482,20 @@ static int right_encode(unsigned char *out, int *out_len, size_t bits)
  * e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 }
  *                                 len   bits    K     M     A     C
  */
-static int encode_string(unsigned char *out, int *out_len,
-                         const unsigned char *in, int in_len)
+static int encode_string(unsigned char *out, size_t *out_len,
+                         const unsigned char *in, size_t in_len)
 {
     if (in == NULL) {
         *out_len = 0;
     } else {
-        int i, bits, len;
+        size_t i, bits, len;
 
         bits = 8 * in_len;
         len = get_encode_size(bits);
-        if (len > 0xFF)
+        if (len > 0xFF) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE);
             return 0;
+        }
 
         out[0] = len;
         for (i = len; i > 0; --i) {
@@ -492,14 +516,24 @@ static int encode_string(unsigned char *out, int *out_len,
  * The returned output is:
  *    zero_padded(multiple of w, (left_encode(w) || in1 [|| in2])
  */
-static int bytepad(unsigned char *out, int *out_len,
-                   const unsigned char *in1, int in1_len,
-                   const unsigned char *in2, int in2_len, int w)
+static int bytepad(unsigned char *out, size_t *out_len,
+                   const unsigned char *in1, size_t in1_len,
+                   const unsigned char *in2, size_t in2_len, size_t w)
 {
     int len;
     unsigned char *p = out;
     int sz = w;
 
+    if (out == NULL) {
+        if (out_len == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+            return 0;
+        }
+        sz = 2 + in1_len + (in2 != NULL ? in2_len : 0);
+        *out_len = (sz + w - 1) / w * w;
+        return 1;
+    }
+
     /* Left encoded w */
     *p++ = 1;
     *p++ = w;
@@ -513,24 +547,24 @@ static int bytepad(unsigned char *out, int *out_len,
     }
     /* Figure out the pad size (divisible by w) */
     len = p - out;
-    while (len > sz) {
-        sz += w;
-    }
+    sz = (len + w - 1) / w * w;
     /* zero pad the end of the buffer */
-    memset(p, 0, sz - len);
-    *out_len = sz;
+    if (sz != len)
+        memset(p, 0, sz - len);
+    if (out_len != NULL)
+        *out_len = sz;
     return 1;
 }
 
 /*
  * Returns out = bytepad(encode_string(in), w)
  */
-static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
-                                   const unsigned char *in, int in_len,
-                                   int w)
+static int kmac_bytepad_encode_key(unsigned char *out, size_t *out_len,
+                                   const unsigned char *in, size_t in_len,
+                                   size_t w)
 {
     unsigned char tmp[KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN];
-    int tmp_len;
+    size_t tmp_len;
 
     if (!encode_string(tmp, &tmp_len, in, in_len))
         return 0;
diff --git a/test/recipes/30-test_evp_data/evpmac_common.txt b/test/recipes/30-test_evp_data/evpmac_common.txt
index 35bba4fcaa..7ddecefc2a 100644
--- a/test/recipes/30-test_evp_data/evpmac_common.txt
+++ b/test/recipes/30-test_evp_data/evpmac_common.txt
@@ -400,3 +400,22 @@ Custom = "My Tagged Application"
 Output = D5BE731C954ED7732846BB59DBE3A8E30F83E77A4BFF4459F2F1C2B4ECEBB8CE67BA01C62E8AB8578D2D499BD1BB276768781190020A306A97DE281DCC30305D
 Ctrl = size:64
 Ctrl = xof:1
+
+Title = KMAC long customisation string (from NIST ACVP)
+
+MAC = KMAC256
+Key = 9743DBF93102FAF11227B154B8ACD16CF142671F7AA16C559A393A38B4CEF461ED29A6A328D7379C99718790E38B54CA25E9E831CBEA463EE704D1689F94629AB795DF0C77F756DA743309C0E054596BA2D9CC1768ACF7CD351D9A7EB1ABD0A3
+Input = BA63AC9C711F143CCE7FF92D0322649D1BE437D805FD225C0A2879A008373EC3BCCDB09971FAD2BCE5F4347AF7E5238EF01A90ED34193D6AFC1D
+Custom = "]J&/.?L/c&}p(b!X|?>i7!]CAH6P at 1<R'6|uOu2Vu^kCM!$ Een^pn&Zlale){mQhKjqe,)'-fsX6:u at D6+ZA^b70A)n)LMxo:Y!62;:[hP*yLERjL at rq30+iRaD#9|"
+Output = 4057EFD76A63049418AFC54559589821322B6029808A3BCAE4D49E961F909F5F667ACAD56BBCFB8033DCB4CC10AF1B53F014B8
+Ctrl = size:51
+Ctrl = xof:1
+
+Title = KMAC long customisation string negative test
+
+MAC = KMAC128
+Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+Custom = ":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789::abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789::abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789::abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789::"
+Result = MAC_INIT_ERROR
+


More information about the openssl-commits mailing list