[openssl] master update

tmraz at fedoraproject.org tmraz at fedoraproject.org
Wed Dec 2 15:47:06 UTC 2020


The branch master has been updated
       via  c39f43534d4f359bdfee617f70f89b114c9f2cca (commit)
      from  b03da688a223c18b5a10b5a66abe229bbb590133 (commit)


- Log -----------------------------------------------------------------
commit c39f43534d4f359bdfee617f70f89b114c9f2cca
Author: Daiki Ueno <dueno at redhat.com>
Date:   Mon Oct 26 13:23:14 2020 +0100

    openssl dgst: add option to specify output length for XOF
    
    This adds the -xoflen option to control the output length of the XOF
    algorithms, such as SHAKE128 and SHAKE256.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13245)

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

Summary of changes:
 apps/dgst.c                  | 54 +++++++++++++++++++++++++++++++++++---------
 doc/man1/openssl-dgst.pod.in |  5 ++++
 test/recipes/20-test_dgst.t  | 18 +++++++++++++--
 3 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/apps/dgst.c b/apps/dgst.c
index badcfdf0e2..4adf9cd9b4 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -24,7 +24,7 @@
 #undef BUFSIZE
 #define BUFSIZE 1024*8
 
-int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen,
           EVP_PKEY *key, unsigned char *sigin, int siglen,
           const char *sig_name, const char *md_name,
           const char *file);
@@ -40,7 +40,7 @@ typedef enum OPTION_choice {
     OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
     OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL,
     OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT,
-    OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT,
+    OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, OPT_XOFLEN,
     OPT_DIGEST,
     OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
@@ -65,6 +65,7 @@ const OPTIONS dgst_options[] = {
     {"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"},
     {"hex", OPT_HEX, '-', "Print as hex dump"},
     {"binary", OPT_BINARY, '-', "Print in binary form"},
+    {"xoflen", OPT_XOFLEN, 'p', "Output length for XOF algorithms"},
     {"d", OPT_DEBUG, '-', "Print debug info"},
     {"debug", OPT_DEBUG, '-', "Print debug info"},
 
@@ -105,6 +106,7 @@ int dgst_main(int argc, char **argv)
     OPTION_CHOICE o;
     int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
     int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
+    int xoflen = 0;
     unsigned char *buf = NULL, *sigbuf = NULL;
     int engine_impl = 0;
     struct doall_dgst_digests dec;
@@ -180,6 +182,9 @@ int dgst_main(int argc, char **argv)
         case OPT_BINARY:
             out_bin = 1;
             break;
+        case OPT_XOFLEN:
+            xoflen = atoi(opt_arg());
+            break;
         case OPT_DEBUG:
             debug = 1;
             break;
@@ -399,9 +404,20 @@ int dgst_main(int argc, char **argv)
     if (md != NULL)
         md_name = EVP_MD_name(md);
 
+    if (xoflen > 0) {
+        if (!(EVP_MD_flags(md) & EVP_MD_FLAG_XOF)) {
+            BIO_printf(bio_err, "Length can only be specified for XOF\n");
+            goto end;
+        }
+        if (sigkey != NULL) {
+            BIO_printf(bio_err, "Signing key cannot be specified for XOF\n");
+            goto end;
+        }
+    }
+
     if (argc == 0) {
         BIO_set_fp(in, stdin, BIO_NOCLOSE);
-        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
+        ret = do_fp(out, buf, inp, separator, out_bin, xoflen, sigkey, sigbuf,
                     siglen, NULL, md_name, "stdin");
     } else {
         const char *sig_name = NULL;
@@ -417,8 +433,8 @@ int dgst_main(int argc, char **argv)
                 ret++;
                 continue;
             } else {
-                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
-                          siglen, sig_name, md_name, argv[i]);
+                r = do_fp(out, buf, inp, separator, out_bin, xoflen,
+                          sigkey, sigbuf, siglen, sig_name, md_name, argv[i]);
             }
             if (r)
                 ret = r;
@@ -504,14 +520,14 @@ static const char *newline_escape_filename(const char *file, int * backslash)
 }
 
 
-int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen,
           EVP_PKEY *key, unsigned char *sigin, int siglen,
           const char *sig_name, const char *md_name,
           const char *file)
 {
     size_t len = BUFSIZE;
     int i, backslash = 0, ret = 1;
-    unsigned char *sigbuf = NULL;
+    unsigned char *allocated_buf = NULL;
 
     while (BIO_pending(bp) || !BIO_eof(bp)) {
         i = BIO_read(bp, (char *)buf, BUFSIZE);
@@ -552,14 +568,30 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
         }
         if (tmplen > BUFSIZE) {
             len = tmplen;
-            sigbuf = app_malloc(len, "Signature buffer");
-            buf = sigbuf;
+            allocated_buf = app_malloc(len, "Signature buffer");
+            buf = allocated_buf;
         }
         if (!EVP_DigestSignFinal(ctx, buf, &len)) {
             BIO_printf(bio_err, "Error Signing Data\n");
             ERR_print_errors(bio_err);
             goto end;
         }
+    } else if (xoflen > 0) {
+        EVP_MD_CTX *ctx;
+
+        len = xoflen;
+        if (len > BUFSIZE) {
+            allocated_buf = app_malloc(len, "Digest buffer");
+            buf = allocated_buf;
+        }
+
+        BIO_get_md_ctx(bp, &ctx);
+
+        if (!EVP_DigestFinalXOF(ctx, buf, len)) {
+            BIO_printf(bio_err, "Error Digesting Data\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
     } else {
         len = BIO_gets(bp, (char *)buf, BUFSIZE);
         if ((int)len < 0) {
@@ -602,8 +634,8 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
 
     ret = 0;
  end:
-    if (sigbuf != NULL)
-        OPENSSL_clear_free(sigbuf, len);
+    if (allocated_buf != NULL)
+        OPENSSL_clear_free(allocated_buf, len);
 
     return ret;
 }
diff --git a/doc/man1/openssl-dgst.pod.in b/doc/man1/openssl-dgst.pod.in
index 4667aeea34..533f30725c 100644
--- a/doc/man1/openssl-dgst.pod.in
+++ b/doc/man1/openssl-dgst.pod.in
@@ -16,6 +16,7 @@ B<openssl> B<dgst>|I<digest>
 [B<-list>]
 [B<-hex>]
 [B<-binary>]
+[B<-xoflen> I<length>]
 [B<-r>]
 [B<-out> I<filename>]
 [B<-sign> I<filename>]
@@ -84,6 +85,10 @@ signatures using B<-hex>.
 
 Output the digest or signature in binary form.
 
+=item B<-xoflen> I<length>
+
+Set the output length for XOF algorithms, such as B<shake128>.
+
 =item B<-r>
 
 =for openssl foreign manual sha1sum(1)
diff --git a/test/recipes/20-test_dgst.t b/test/recipes/20-test_dgst.t
index 4c29877e62..0c19c029a0 100644
--- a/test/recipes/20-test_dgst.t
+++ b/test/recipes/20-test_dgst.t
@@ -17,7 +17,7 @@ use OpenSSL::Test::Utils;
 
 setup("test_dgst");
 
-plan tests => 6;
+plan tests => 7;
 
 sub tsignverify {
     my $testtext = shift;
@@ -111,8 +111,22 @@ subtest "HMAC generation with `dgst` CLI" => sub {
     my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac', '123456',
                             $testdata, $testdata]), capture => 1);
     chomp(@hmacdata);
-    my $expected = qr/HMAC-SHA256\([^\)]*data.bin\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
+    my $expected = qr/HMAC-SHA256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
     ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
     ok($hmacdata[1] =~ $expected,
        "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
 };
+
+subtest "Custom length XOF digest generation with `dgst` CLI" => sub {
+    plan tests => 2;
+
+    my $testdata = srctop_file('test', 'data.bin');
+    #Digest the data twice to check consistency
+    my @xofdata = run(app(['openssl', 'dgst', '-shake128', '-xoflen', '64',
+                           $testdata, $testdata]), capture => 1);
+    chomp(@xofdata);
+    my $expected = qr/SHAKE128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa64ffd0b3e2bf8cd73d5182dfba19b6a8a2eab96d2df854b647b3795ef090582abe41ba4e0717dc4df40bc4e17d88e4677/;
+    ok($xofdata[0] =~ $expected, "XOF: Check digest value is as expected ($xofdata[0]) vs ($expected)");
+    ok($xofdata[1] =~ $expected,
+       "XOF: Check second digest value is consistent with the first ($xofdata[1]) vs ($expected)");
+};


More information about the openssl-commits mailing list