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_XOFLEN,
+ OPT_HMAC, OPT_HMAC_ENV, OPT_HMAC_STDIN, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, OPT_XOFLEN,
OPT_DIGEST,
OPT_R_ENUM, OPT_PROV_ENUM
} OPTION_CHOICE;
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
{"signature", OPT_SIGNATURE, '<', "File with signature to verify"},
{"hmac", OPT_HMAC, 's', "Create hashed MAC with key"},
+ {"hmac-env", OPT_HMAC_ENV, 's', "Create hashed MAC with key from environment variable"},
+ {"hmac-stdin", OPT_HMAC_STDIN, '-', "Create hashed MAC with key from stdin"},
{"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"},
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"},
{"", OPT_DIGEST, '-', "Any supported digest"},
const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
const char *sigfile = NULL;
const char *md_name = NULL;
+ char *env_var = NULL;
+ char *new_opt = NULL;
+ char *key_from_stdin = NULL;
OPTION_CHOICE o;
int separator = 0, debug = 0, keyform = FORMAT_UNDEF, siglen = 0;
int i, ret = EXIT_FAILURE, out_bin = -1, want_pub = 0, do_verify = 0;
case OPT_HMAC:
hmac_key = opt_arg();
break;
+ case OPT_HMAC_ENV:
+ env_var = opt_arg();
+ hmac_key = getenv(env_var);
+ if (hmac_key == NULL) {
+ BIO_printf(bio_err, "No environment variable %s\n", env_var);
+ ret = EXIT_FAILURE;
+ goto end;
+ }
+ break;
+ case OPT_HMAC_STDIN:
+ if (key_from_stdin == NULL)
+ key_from_stdin = get_str_from_file(NULL);
+ if (key_from_stdin == NULL) {
+ ret = EXIT_FAILURE;
+ goto end;
+ }
+ if (strlen(key_from_stdin) == 0) {
+ BIO_printf(bio_err, "Empty key\n");
+ ret = EXIT_FAILURE;
+ goto end;
+ }
+ hmac_key = key_from_stdin;
+ break;
case OPT_MAC:
mac_name = opt_arg();
break;
goto opthelp;
break;
case OPT_MACOPT:
+ new_opt = process_additional_mac_key_arguments(opt_arg());
+ if (new_opt == NULL) {
+ ret = EXIT_FAILURE;
+ goto end;
+ }
if (!macopts)
macopts = sk_OPENSSL_STRING_new_null();
- if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
+ if (!macopts || !sk_OPENSSL_STRING_push(macopts, new_opt)) {
+ clear_free(new_opt);
goto opthelp;
+ }
break;
case OPT_DIGEST:
digestname = opt_unknown();
if (ret != EXIT_SUCCESS)
ERR_print_errors(bio_err);
OPENSSL_clear_free(buf, BUFSIZE);
+ if (key_from_stdin != NULL)
+ clear_free(key_from_stdin);
BIO_free(in);
OPENSSL_free(passin);
BIO_free_all(out);
EVP_PKEY_free(sigkey);
EVP_MD_CTX_free(signctx);
sk_OPENSSL_STRING_free(sigopts);
- sk_OPENSSL_STRING_free(macopts);
+ sk_OPENSSL_STRING_pop_free(macopts, clear_free);
OPENSSL_free(sigbuf);
BIO_free(bmd);
release_engine(e);
const char *keytype, const char *desc,
int suppress_decode_errors);
char *next_item(char *opt); /* in list separated by comma and/or space */
+char *process_additional_mac_key_arguments(const char *arg);
+char *get_str_from_file(const char *filename);
int load_cert_certs(const char *uri,
X509 **pcert, STACK_OF(X509) **pcerts,
int exclude_http, const char *pass, const char *desc,
return 0;
return 1;
}
+
+#define MAX_KEY_SIZE 2048 /* Hope nobody needs mac key longer than 2048 bytes */
+
+/*
+ * Implementations of mac algorithms only support getting a key via the
+ * key and hexkey parameters. This function processes additional parameters
+ * for reading a key from an environment variable or from a file or stdin
+ * and forms a key or hexkey parameter with the read key.
+ * Leaves other parameters unchanged.
+ * Allocates a string with a new parameter and returns a pointer to this
+ * string, the calling code must free this string by calling OPENSSL_clear_free.
+ * Returns NULL in case of an error.
+ */
+char *process_additional_mac_key_arguments(const char *arg)
+{
+ static BIO *keybio = NULL;
+ char *val = NULL, *inbuf = NULL, *outbuf = NULL;
+ int total_read = 0;
+ int n;
+ char dummy;
+ int too_long;
+
+ if (CHECK_AND_SKIP_PREFIX(arg, "keyenv:")) {
+ if (strlen(arg) == 0) {
+ BIO_printf(bio_err, "Empty environment variable name\n");
+ return NULL;
+ }
+ val = getenv(arg);
+ if (val == NULL) {
+ BIO_printf(bio_err, "No environment variable %s\n", arg);
+ return NULL;
+ }
+ outbuf = app_malloc(strlen("key:") + strlen(val) + 1, "MACOPT KEYENV");
+ strcpy(outbuf, "key:");
+ strcat(outbuf, val);
+ return outbuf;
+ }
+
+ if (CHECK_AND_SKIP_PREFIX(arg, "keyenvhex:")) {
+ if (strlen(arg) == 0) {
+ BIO_printf(bio_err, "Empty environment variable name\n");
+ return NULL;
+ }
+ val = getenv(arg);
+ if (val == NULL) {
+ BIO_printf(bio_err, "No environment variable %s\n", arg);
+ return NULL;
+ }
+ outbuf = app_malloc(strlen("hexkey:") + strlen(val) + 1, "MACOPT KEYENVHEX");
+ strcpy(outbuf, "hexkey:");
+ strcat(outbuf, val);
+ return outbuf;
+ }
+
+ if (CHECK_AND_SKIP_PREFIX(arg, "keyfile:")) {
+ if (strlen(arg) == 0) {
+ BIO_printf(bio_err, "Empty key file name\n");
+ return NULL;
+ }
+ keybio = BIO_new_file(arg, "rb");
+ if (keybio == NULL) {
+ BIO_printf(bio_err, "Can't open file %s\n", arg);
+ return NULL;
+ }
+ inbuf = app_malloc(MAX_KEY_SIZE, "MACOPT KEYFILE");
+ while (total_read < MAX_KEY_SIZE) {
+ n = BIO_read(keybio, inbuf + total_read, MAX_KEY_SIZE - total_read);
+ if (n < 0) {
+ BIO_printf(bio_err, "Can't read file %s\n", arg);
+ OPENSSL_clear_free(inbuf, MAX_KEY_SIZE);
+ BIO_free(keybio);
+ return NULL;
+ }
+ if (n == 0) /* EOF */
+ break;
+ total_read += n;
+ }
+ too_long = (total_read == MAX_KEY_SIZE && BIO_read(keybio, &dummy, 1) > 0);
+ BIO_free(keybio);
+ if (total_read == 0 || too_long) {
+ /* File is empty or longer than MAX_KEY_SIZE */
+ BIO_printf(bio_err, (too_long) ? "File %s is too long\n" : "File %s is empty\n", arg);
+ OPENSSL_clear_free(inbuf, MAX_KEY_SIZE);
+ return NULL;
+ }
+ outbuf = app_malloc(strlen("hexkey:") + total_read * 2 + 1, "MACOPT KEYFILE");
+ strcpy(outbuf, "hexkey:");
+ OPENSSL_buf2hexstr_ex(outbuf + strlen("hexkey:"), total_read * 2 + 1,
+ NULL, (unsigned char *)inbuf, total_read, '\0');
+ OPENSSL_clear_free(inbuf, MAX_KEY_SIZE);
+ return outbuf;
+ }
+
+ if (strcmp(arg, "keystdin") == 0) {
+ inbuf = get_str_from_file(NULL);
+ if (inbuf == NULL)
+ return NULL;
+ if (strlen(inbuf) == 0) {
+ BIO_printf(bio_err, "Empty key\n");
+ clear_free(inbuf);
+ return NULL;
+ }
+ outbuf = app_malloc(strlen("key:") + strlen(inbuf) + 1, "MACOPT KEYSTDIN");
+ strcpy(outbuf, "key:");
+ strcat(outbuf, inbuf);
+ clear_free(inbuf);
+ return outbuf;
+ }
+
+ return OPENSSL_strdup(arg);
+}
+
+/*
+ * Read one line from file.
+ * Allocates a string with the data read and returns a pointer to this
+ * string, the calling code must free this string.
+ * If filename == NULL, read from standard input.
+ * Returns NULL in case of any error.
+ */
+char *get_str_from_file(const char *filename)
+{
+ static BIO *bio = NULL;
+ int n;
+ char *buf = NULL;
+ char *tmp;
+
+ if (filename == NULL) {
+ unbuffer(stdin);
+ bio = dup_bio_in(FORMAT_TEXT);
+ if (bio == NULL) {
+ BIO_printf(bio_err, "Can't open BIO for stdin\n");
+ return NULL;
+ }
+ } else {
+ bio = BIO_new_file(filename, "r");
+ if (bio == NULL) {
+ BIO_printf(bio_err, "Can't open file %s\n", filename);
+ return NULL;
+ }
+ }
+ buf = app_malloc(MAX_KEY_SIZE, "get_str_from_file");
+ memset(buf, 0, MAX_KEY_SIZE);
+ n = BIO_gets(bio, buf, MAX_KEY_SIZE - 1);
+ BIO_free_all(bio);
+ bio = NULL;
+ if (n <= 0) {
+ BIO_printf(bio_err, "Error reading from %s\n", filename);
+ return NULL;
+ }
+ tmp = strchr(buf, '\n');
+ if (tmp != NULL)
+ *tmp = 0;
+ return buf;
+}
int inform = FORMAT_BINARY;
char *digest = NULL, *cipher = NULL;
OSSL_PARAM *params = NULL;
+ char *new_opt = NULL;
prog = opt_init(argc, argv, mac_options);
buf = app_malloc(BUFSIZE, "I/O buffer");
outfile = opt_arg();
break;
case OPT_MACOPT:
+ new_opt = process_additional_mac_key_arguments(opt_arg());
+ if (new_opt == NULL) {
+ ret = 1;
+ goto err;
+ }
if (opts == NULL)
opts = sk_OPENSSL_STRING_new_null();
- if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
+ if (opts == NULL || !sk_OPENSSL_STRING_push(opts, new_opt)) {
+ clear_free(new_opt);
goto opthelp;
+ }
break;
case OPT_CIPHER:
OPENSSL_free(cipher);
if (ret != 0)
ERR_print_errors(bio_err);
OPENSSL_clear_free(buf, BUFSIZE);
- OPENSSL_free(cipher);
- OPENSSL_free(digest);
- sk_OPENSSL_STRING_free(opts);
+ sk_OPENSSL_STRING_pop_free(opts, clear_free);
BIO_free(in);
BIO_free(out);
EVP_MAC_CTX_free(ctx);
[B<-signature> I<filename>]
[B<-sigopt> I<nm>:I<v>]
[B<-hmac> I<key>]
+[B<-hmac-env> I<var>]
+[B<-hmac-stdin>]
[B<-mac> I<alg>]
[B<-macopt> I<nm>:I<v>]
[B<-fips-fingerprint>]
Create a hashed MAC using "key".
+Cannot be used together with -mac option.
+If multiple -hmac, -hmac-env or -hmac-stdin options are specified, the last
+one is applied.
+
+The L<openssl-mac(1)> command should be preferred to using this command line
+option.
+
+=item B<-hmac-env> I<var>
+
+Create a hashed MAC using a key from the environment variable "var".
+
+Cannot be used together with -mac option.
+If multiple -hmac, -hmac-env or -hmac-stdin options are specified, the last
+one is applied.
+
+The L<openssl-mac(1)> command should be preferred to using this command line
+option.
+
+=item B<-hmac-stdin>
+
+Create a hashed MAC using a key obtained from the standard input. Only the
+first line from stdin is read, and the \0 character also terminates the key.
+
+Cannot be used together with -mac option.
+If multiple -hmac, -hmac-env or -hmac-stdin options are specified, the last
+one is applied.
+
The L<openssl-mac(1)> command should be preferred to using this command line
option.
supported by the B<gost> engine. MAC keys and other options should be set
via B<-macopt> parameter.
+Cannot be used together with -hmac, -hmac-env and -hmac-stdin.
+
The L<openssl-mac(1)> command should be preferred to using this command line
option.
Key length must conform to any restrictions of the MAC algorithm
for example exactly 32 chars for gost-mac.
+=item B<keyenv:>I<var>
+
+Read the MAC key as an alphanumeric string from the environment variable
+(use if the key contains printable characters only).
+The the key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=item B<keyenvhex:>I<var>
+
+Read the MAC key in hexadecimal form (two hex digits per byte)
+from the environment variable.
+The key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=item B<keyfile:>I<filename>
+
+Read the MAC key from the specified file. The key is read as binary data.
+The key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=item B<keystdin>
+
+Read the MAC key from the standard input. Only the first line from stdin is
+read, and the \0 character also terminates the key.
+The key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
=back
+If multiple MAC key options are specified, the last one is applied.
+
The L<openssl-mac(1)> command should be preferred to using this command line
option.
The B<-engine> and B<-engine_impl> options were deprecated in OpenSSL 3.0.
+The B<-hmac-env> and B<-hmac-stdin> options ware added in OpenSSL 3.6.
+
=head1 COPYRIGHT
Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.
=back
+Some additional options can be used only as command-line parameters.
+They are not passed to the MAC algorithm, but translated into
+key and hexkey parameters instead:
+
+=over 4
+
+=item B<keyenv:>I<var>
+
+Read the MAC key as an alphanumeric string from the environment variable
+(use if the key contains printable characters only).
+The the key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=item B<keyenvhex:>I<var>
+
+Read the MAC key in hexadecimal form (two hex digits per byte)
+from the environment variable.
+The key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=item B<keyfile:>I<filename>
+
+Read the MAC key from the specified file. The key is read as binary data.
+The key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=item B<keystdin>
+
+Read the MAC key from the standard input. Only the first line from stdin
+is read, and the \0 character also terminates the key.
+The key length must conform to any restrictions of the MAC algorithm.
+A key must be specified for every MAC algorithm.
+
+=back
+
{- $OpenSSL::safe::opt_provider_item -}
=item I<mac_name>
use File::Spec;
use File::Basename;
-use OpenSSL::Test qw/:DEFAULT with srctop_file bldtop_dir/;
+use OpenSSL::Test qw/:DEFAULT with srctop_file data_file bldtop_dir/;
use OpenSSL::Test::Utils;
setup("test_dgst");
-plan tests => 17;
+plan tests => 24;
sub tsignverify {
my $testtext = shift;
"HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
};
-subtest "HMAC generation with `dgst` CLI, key via option" => sub {
+subtest "HMAC generation with `dgst` CLI, key via environment" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ local $ENV{MYKEY} = 123456;
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac-env', 'MYKEY',
+ $testdata, $testdata]), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\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 "HMAC generation with `dgst` CLI, key via stdin" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac-stdin',
+ $testdata, $testdata], stdin => data_file("keyfile.txt")), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\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 "HMAC generation with `dgst` CLI, key via option key" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-mac', 'HMAC',
+ '-macopt', 'key:123456',
+ $testdata, $testdata]), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\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 "HMAC generation with `dgst` CLI, key via option hexkey" => sub {
plan tests => 2;
my $testdata = srctop_file('test', 'data.bin');
"HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
};
+subtest "HMAC generation with `dgst` CLI, key via option keyenv" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ local $ENV{MYKEY} = '123456';
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-mac', 'HMAC',
+ '-macopt', 'keyenv:MYKEY',
+ $testdata, $testdata]), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\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 "HMAC generation with `dgst` CLI, key via option keyenvhex" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ local $ENV{MYKEY} = 'FFFF';
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-mac', 'HMAC',
+ '-macopt', 'keyenvhex:MYKEY',
+ $testdata, $testdata]), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= 7c02d4a17d2560a5bb6763edbf33f3a34f415398f8f2e07f04b83ffd7c087dae/;
+ 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 "HMAC generation with `dgst` CLI, key via option keyfile" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-mac', 'HMAC',
+ '-macopt', 'keyfile:' . data_file("keyfile.bin"),
+ $testdata, $testdata]), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= 7c02d4a17d2560a5bb6763edbf33f3a34f415398f8f2e07f04b83ffd7c087dae/;
+ 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 "HMAC generation with `dgst` CLI, key via option keystdin" => sub {
+ plan tests => 2;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ #HMAC the data twice to check consistency
+ my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-mac', 'HMAC',
+ '-macopt', 'keystdin',
+ $testdata, $testdata], stdin => data_file("keyfile.txt")), capture => 1);
+ chomp(@hmacdata);
+ my $expected = qr/HMAC-SHA2-256\(\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;
--- /dev/null
+ÿÿ
\ No newline at end of file
--- /dev/null
+123456
\ No newline at end of file
use strict;
use warnings;
-use OpenSSL::Test;
+use OpenSSL::Test qw(:DEFAULT data_file);
use OpenSSL::Test::Utils;
use Storable qw(dclone);
input => '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7',
expected => 'D5BE731C954ED7732846BB59DBE3A8E30F83E77A4BFF4459F2F1C2B4ECEBB8CE67BA01C62E8AB8578D2D499BD1BB276768781190020A306A97DE281DCC30305D',
desc => 'KMAC256 with xof len of 64' },
+ { cmd => [qw{openssl mac -digest SHA256 -macopt keyenv:MACKEY}],
+ env => {'MACKEY' => 'ASCII_key_for_HMAC_tests' },
+ type => 'HMAC',
+ input => unpack("H*", "Sample message for additional key options"),
+ expected => '70B1E97C0EDDBD4CB4866E28FEBA45343BD35FD88437F17880B7ADAC058B161B',
+ desc => 'HMAC with keyenv' },
+ { cmd => [qw{openssl mac -digest SHA256 -macopt keyenvhex:MACKEY}],
+ env => {'MACKEY' => '41534349495F6B65795F666F725F484D41435F7465737473' },
+ type => 'HMAC',
+ input => unpack("H*", "Sample message for additional key options"),
+ expected => '70B1E97C0EDDBD4CB4866E28FEBA45343BD35FD88437F17880B7ADAC058B161B',
+ desc => 'HMAC with keyenvhex' },
+ { cmd => [qw{openssl mac -digest SHA256}, '-macopt', 'keyfile:' . data_file("keyfile.dat")],
+ type => 'HMAC',
+ input => unpack("H*", "Sample message for additional key options"),
+ expected => '70B1E97C0EDDBD4CB4866E28FEBA45343BD35FD88437F17880B7ADAC058B161B',
+ desc => 'HMAC with keyfile' },
+ { cmd => [qw{openssl mac -digest SHA256 -macopt keystdin}],
+ keyinput => data_file("keyfile.dat"),
+ type => 'HMAC',
+ input => unpack("H*", "Sample message for additional key options"),
+ expected => '70B1E97C0EDDBD4CB4866E28FEBA45343BD35FD88437F17880B7ADAC058B161B',
+ desc => 'HMAC with keystdin' },
);
my @siphash_tests = (
foreach (@mac_tests) {
$test_count++;
- ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
+ if ($_->{env}) {
+ ok( do {
+ local @ENV{keys %{$_->{env}}} = values %{$_->{env}};
+ compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err})
+ }, $_->{desc});
+ } elsif ($_->{keyinput}) {
+ ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}, $_->{keyinput}), $_->{desc});
+ } else {
+ ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
+ }
}
foreach (@mac_tests) {
$test_count++;
- ok(comparefile($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}), $_->{desc});
+ if ($_->{env}) {
+ ok( do {
+ local @ENV{keys %{$_->{env}}} = values %{$_->{env}};
+ comparefile($_->{cmd}, $_->{type}, $_->{input}, $_->{expected})
+ }, $_->{desc});
+ } elsif ($_->{keyinput}) {
+ ok(comparefile($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{keyinput}), $_->{desc});
+ } else {
+ ok(comparefile($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}), $_->{desc});
+ }
}
foreach (@mac_fail_tests) {
# then compare the stdout output matches the expected value.
sub compareline {
my $tmpfile = "input-$test_count.bin";
- my ($cmdarray_orig, $type, $input, $expect, $err) = @_;
+ my ($cmdarray_orig, $type, $input, $expect, $err, $keyinput) = @_;
my $cmdarray = dclone $cmdarray_orig;
if (defined($expect)) {
$expect = uc $expect;
my @other = ('-in', $tmpfile, $type);
push @$cmdarray, @other;
- my @lines = run(app($cmdarray), capture => 1);
+ my @lines = run(app($cmdarray, stdin => $keyinput), capture => 1);
# Not unlinking $tmpfile
if (defined($expect)) {
sub comparefile {
my $tmpfile = "input-$test_count.bin";
my $outfile = "output-$test_count.bin";
- my ($cmdarray, $type, $input, $expect) = @_;
+ my ($cmdarray, $type, $input, $expect, $keyinput) = @_;
$expect = uc $expect;
# Open a temporary input file and write $input to it
my @other = ("-binary", "-in", $tmpfile, "-out", $outfile, $type);
push @$cmdarray, @other;
- run(app($cmdarray));
+ run(app($cmdarray, stdin => $keyinput));
# Not unlinking $tmpfile
open(my $out, '<', $outfile) or die "Could not open file";
--- /dev/null
+ASCII_key_for_HMAC_tests
\ No newline at end of file