mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-04-27 02:04:37 +00:00
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@openssl.org> Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13245)
This commit is contained in:
parent
b03da688a2
commit
c39f43534d
54
apps/dgst.c
54
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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)");
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user