apps/mac: Add digest and cipher command line options

Add -cipher and -digest as short forms of -macopt cipher: and -macopt digest:
respectively.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15189)
This commit is contained in:
Pauli 2021-05-07 15:48:27 +10:00
parent 29f5727b83
commit 0f4fb64785
3 changed files with 87 additions and 20 deletions

View File

@ -15,6 +15,7 @@
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/params.h> #include <openssl/params.h>
#include <openssl/core_names.h>
#undef BUFSIZE #undef BUFSIZE
#define BUFSIZE 1024*8 #define BUFSIZE 1024*8
@ -22,6 +23,7 @@
typedef enum OPTION_choice { typedef enum OPTION_choice {
OPT_COMMON, OPT_COMMON,
OPT_MACOPT, OPT_BIN, OPT_IN, OPT_OUT, OPT_MACOPT, OPT_BIN, OPT_IN, OPT_OUT,
OPT_CIPHER, OPT_DIGEST,
OPT_PROV_ENUM OPT_PROV_ENUM
} OPTION_CHOICE; } OPTION_CHOICE;
@ -31,6 +33,8 @@ const OPTIONS mac_options[] = {
OPT_SECTION("General"), OPT_SECTION("General"),
{"help", OPT_HELP, '-', "Display this summary"}, {"help", OPT_HELP, '-', "Display this summary"},
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form"}, {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form"},
{"cipher", OPT_CIPHER, 's', "Cipher"},
{"digest", OPT_DIGEST, 's', "Digest"},
{OPT_MORE_STR, 1, '-', "See 'PARAMETER NAMES' in the EVP_MAC_ docs"}, {OPT_MORE_STR, 1, '-', "See 'PARAMETER NAMES' in the EVP_MAC_ docs"},
OPT_SECTION("Input"), OPT_SECTION("Input"),
@ -48,6 +52,24 @@ const OPTIONS mac_options[] = {
{NULL} {NULL}
}; };
static char *alloc_mac_algorithm_name(STACK_OF(OPENSSL_STRING) **optp,
const char *name, const char *arg)
{
size_t len = strlen(name) + strlen(arg) + 2;
char *res = app_malloc(len, "algorithm name");
if (*optp == NULL)
*optp = sk_OPENSSL_STRING_new_null();
if (*optp == NULL)
return NULL;
BIO_snprintf(res, len, "%s:%s", name, arg);
if (sk_OPENSSL_STRING_push(*optp, res))
return res;
OPENSSL_free(res);
return NULL;
}
int mac_main(int argc, char **argv) int mac_main(int argc, char **argv)
{ {
int ret = 1; int ret = 1;
@ -64,6 +86,7 @@ int mac_main(int argc, char **argv)
const char *infile = NULL; const char *infile = NULL;
int out_bin = 0; int out_bin = 0;
int inform = FORMAT_BINARY; int inform = FORMAT_BINARY;
char *digest = NULL, *cipher = NULL;
OSSL_PARAM *params = NULL; OSSL_PARAM *params = NULL;
prog = opt_init(argc, argv, mac_options); prog = opt_init(argc, argv, mac_options);
@ -93,6 +116,18 @@ opthelp:
if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
goto opthelp; goto opthelp;
break; break;
case OPT_CIPHER:
OPENSSL_free(cipher);
cipher = alloc_mac_algorithm_name(&opts, "cipher", opt_arg());
if (cipher == NULL)
goto opthelp;
break;
case OPT_DIGEST:
OPENSSL_free(digest);
digest = alloc_mac_algorithm_name(&opts, "digest", opt_arg());
if (digest == NULL)
goto opthelp;
break;
case OPT_PROV_CASES: case OPT_PROV_CASES:
if (!opt_provider(o)) if (!opt_provider(o))
goto err; goto err;
@ -193,6 +228,8 @@ err:
if (ret != 0) if (ret != 0)
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
OPENSSL_clear_free(buf, BUFSIZE); OPENSSL_clear_free(buf, BUFSIZE);
OPENSSL_free(cipher);
OPENSSL_free(digest);
sk_OPENSSL_STRING_free(opts); sk_OPENSSL_STRING_free(opts);
BIO_free(in); BIO_free(in);
BIO_free(out); BIO_free(out);

View File

@ -9,6 +9,8 @@ openssl-mac - perform Message Authentication Code operations
B<openssl mac> B<openssl mac>
[B<-help>] [B<-help>]
[B<-cipher>]
[B<-digest>]
[B<-macopt>] [B<-macopt>]
[B<-in> I<filename>] [B<-in> I<filename>]
[B<-out> I<filename>] [B<-out> I<filename>]
@ -44,6 +46,20 @@ Filename to output to, or standard output by default.
Output the MAC in binary form. Uses hexadecimal text format if not specified. Output the MAC in binary form. Uses hexadecimal text format if not specified.
=item B<-cipher> I<name>
Used by CMAC and GMAC to specify the cipher algorithm.
For CMAC it must be one of AES-128-CBC, AES-192-CBC, AES-256-CBC or
DES-EDE3-CBC.
For GMAC it should be a GCM mode cipher e.g. AES-128-GCM.
=item B<-digest> I<name>
Used by HMAC as an alphanumeric string (use if the key contains printable
characters only).
The string length must conform to any restrictions of the MAC algorithm.
To see the list of supported digests, use C<openssl list -digest-commands>.
=item B<-macopt> I<nm>:I<v> =item B<-macopt> I<nm>:I<v>
Passes options to the MAC algorithm. Passes options to the MAC algorithm.
@ -66,20 +82,6 @@ Specifies the MAC key in hexadecimal form (two hex digits per byte).
The key length must conform to any restrictions of the MAC algorithm. The key length must conform to any restrictions of the MAC algorithm.
A key must be specified for every MAC algorithm. A key must be specified for every MAC algorithm.
=item B<digest:>I<string>
Used by HMAC as an alphanumeric string (use if the key contains printable
characters only).
The string length must conform to any restrictions of the MAC algorithm.
To see the list of supported digests, use C<openssl list -digest-commands>.
=item B<cipher:>I<string>
Used by CMAC and GMAC to specify the cipher algorithm.
For CMAC it must be one of AES-128-CBC, AES-192-CBC, AES-256-CBC or
DES-EDE3-CBC.
For GMAC it should be a GCM mode cipher e.g. AES-128-GCM.
=item B<iv:>I<string> =item B<iv:>I<string>
Used by GMAC to specify an IV as an alphanumeric string (use if the IV contains Used by GMAC to specify an IV as an alphanumeric string (use if the IV contains
@ -99,6 +101,14 @@ The default sizes are 32 or 64 bytes respectively.
Used by KMAC128 or KMAC256 to specify a customization string. Used by KMAC128 or KMAC256 to specify a customization string.
The default is the empty string "". The default is the empty string "".
=item B<digest:>I<string>
This option is identical to the B<-digest> option.
=item B<cipher:>I<string>
This option is identical to the B<-cipher> option.
=back =back
{- $OpenSSL::safe::opt_provider_item -} {- $OpenSSL::safe::opt_provider_item -}
@ -115,7 +125,7 @@ To see the list of supported MAC's use the command C<opensssl list
=head1 EXAMPLES =head1 EXAMPLES
To create a hex-encoded HMAC-SHA1 MAC of a file and write to stdout: \ To create a hex-encoded HMAC-SHA1 MAC of a file and write to stdout: \
openssl mac -macopt digest:SHA1 \ openssl mac -digest SHA1 \
-macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 \ -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 \
-in msg.bin HMAC -in msg.bin HMAC
@ -124,7 +134,7 @@ To create a SipHash MAC from a file with a binary file output: \
-in msg.bin -out out.bin -binary SipHash -in msg.bin -out out.bin -binary SipHash
To create a hex-encoded CMAC-AES-128-CBC MAC from a file:\ To create a hex-encoded CMAC-AES-128-CBC MAC from a file:\
openssl mac -macopt cipher:AES-128-CBC \ openssl mac -cipher AES-128-CBC \
-macopt hexkey:77A77FAF290C1FA30C683DF16BA7A77B \ -macopt hexkey:77A77FAF290C1FA30C683DF16BA7A77B \
-in msg.bin CMAC -in msg.bin CMAC
@ -134,7 +144,7 @@ To create a hex-encoded KMAC128 MAC from a file with a Customisation String
-macopt size:16 -in msg.bin KMAC128 -macopt size:16 -in msg.bin KMAC128
To create a hex-encoded GMAC-AES-128-GCM with a IV from a file: \ To create a hex-encoded GMAC-AES-128-GCM with a IV from a file: \
openssl mac -macopt cipher:AES-128-GCM -macopt hexiv:E0E00F19FED7BA0136A797F3 \ openssl mac -cipher AES-128-GCM -macopt hexiv:E0E00F19FED7BA0136A797F3 \
-macopt hexkey:77A77FAF290C1FA30C683DF16BA7A77B -in msg.bin GMAC -macopt hexkey:77A77FAF290C1FA30C683DF16BA7A77B -in msg.bin GMAC
=head1 NOTES =head1 NOTES

View File

@ -17,16 +17,26 @@ use Storable qw(dclone);
setup("test_mac"); setup("test_mac");
my @mac_tests = ( my @mac_tests = (
{ cmd => [qw{openssl mac -macopt digest:SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}], { cmd => [qw{openssl mac -digest SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}],
type => 'HMAC', type => 'HMAC',
input => unpack("H*", "Sample message for keylen=blocklen"), input => unpack("H*", "Sample message for keylen=blocklen"),
expected => '5FD596EE78D5553C8FF4E72D266DFD192366DA29', expected => '5FD596EE78D5553C8FF4E72D266DFD192366DA29',
desc => 'HMAC SHA1' }, desc => 'HMAC SHA1' },
{ cmd => [qw{openssl mac -macopt cipher:AES-256-GCM -macopt hexkey:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 -macopt hexiv:7AE8E2CA4EC500012E58495C}], { cmd => [qw{openssl mac -macopt digest:SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}],
type => 'HMAC',
input => unpack("H*", "Sample message for keylen=blocklen"),
expected => '5FD596EE78D5553C8FF4E72D266DFD192366DA29',
desc => 'HMAC SHA1 via -macopt' },
{ cmd => [qw{openssl mac -cipher AES-256-GCM -macopt hexkey:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 -macopt hexiv:7AE8E2CA4EC500012E58495C}],
type => 'GMAC', type => 'GMAC',
input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007', input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007',
expected => '00BDA1B7E87608BCBF470F12157F4C07', expected => '00BDA1B7E87608BCBF470F12157F4C07',
desc => 'GMAC' }, desc => 'GMAC' },
{ cmd => [qw{openssl mac -macopt cipher:AES-256-GCM -macopt hexkey:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 -macopt hexiv:7AE8E2CA4EC500012E58495C}],
type => 'GMAC',
input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007',
expected => '00BDA1B7E87608BCBF470F12157F4C07',
desc => 'GMAC via -macopt' },
{ cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt xof:0}], { cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt xof:0}],
type => 'KMAC128', type => 'KMAC128',
input => '00010203', input => '00010203',
@ -53,11 +63,16 @@ my @siphash_tests = (
); );
my @cmac_tests = ( my @cmac_tests = (
{ cmd => [qw{openssl mac -cipher AES-256-CBC -macopt hexkey:0B122AC8F34ED1FE082A3625D157561454167AC145A10BBF77C6A70596D574F1}],
type => 'CMAC',
input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F',
expected => 'F62C46329B41085625669BAF51DEA66A',
desc => 'CMAC AES-256-CBC' },
{ cmd => [qw{openssl mac -macopt cipher:AES-256-CBC -macopt hexkey:0B122AC8F34ED1FE082A3625D157561454167AC145A10BBF77C6A70596D574F1}], { cmd => [qw{openssl mac -macopt cipher:AES-256-CBC -macopt hexkey:0B122AC8F34ED1FE082A3625D157561454167AC145A10BBF77C6A70596D574F1}],
type => 'CMAC', type => 'CMAC',
input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F', input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F',
expected => 'F62C46329B41085625669BAF51DEA66A', expected => 'F62C46329B41085625669BAF51DEA66A',
desc => 'CMAC AES-256-CBC' } desc => 'CMAC AES-256-CBC' },
); );
my @poly1305_tests = ( my @poly1305_tests = (
@ -83,6 +98,11 @@ my @mac_fail_tests = (
input => '00', input => '00',
err => 'Invalid MAC name KMAC128', err => 'Invalid MAC name KMAC128',
desc => 'KMAC128 Fail unknown property' }, desc => 'KMAC128 Fail unknown property' },
{ cmd => [qw{openssl mac -cipher AES-128-CBC -macopt hexkey:00}],
type => 'HMAC',
input => '00',
err => 'MAC parameter error',
desc => 'HMAC given a cipher' },
); );
my @siphash_fail_tests = ( my @siphash_fail_tests = (