diff --git a/apps/mac.c b/apps/mac.c index b9610f3a18..ca02a781e5 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -15,6 +15,7 @@ #include #include #include +#include #undef BUFSIZE #define BUFSIZE 1024*8 @@ -22,6 +23,7 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_MACOPT, OPT_BIN, OPT_IN, OPT_OUT, + OPT_CIPHER, OPT_DIGEST, OPT_PROV_ENUM } OPTION_CHOICE; @@ -31,6 +33,8 @@ const OPTIONS mac_options[] = { OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"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_SECTION("Input"), @@ -48,6 +52,24 @@ const OPTIONS mac_options[] = { {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 ret = 1; @@ -64,6 +86,7 @@ int mac_main(int argc, char **argv) const char *infile = NULL; int out_bin = 0; int inform = FORMAT_BINARY; + char *digest = NULL, *cipher = NULL; OSSL_PARAM *params = NULL; prog = opt_init(argc, argv, mac_options); @@ -93,6 +116,18 @@ opthelp: if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) goto opthelp; 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: if (!opt_provider(o)) goto err; @@ -193,6 +228,8 @@ err: if (ret != 0) ERR_print_errors(bio_err); OPENSSL_clear_free(buf, BUFSIZE); + OPENSSL_free(cipher); + OPENSSL_free(digest); sk_OPENSSL_STRING_free(opts); BIO_free(in); BIO_free(out); diff --git a/doc/man1/openssl-mac.pod.in b/doc/man1/openssl-mac.pod.in index 4c9cc3bc31..b158ff3b8d 100644 --- a/doc/man1/openssl-mac.pod.in +++ b/doc/man1/openssl-mac.pod.in @@ -9,6 +9,8 @@ openssl-mac - perform Message Authentication Code operations B [B<-help>] +[B<-cipher>] +[B<-digest>] [B<-macopt>] [B<-in> I] [B<-out> I] @@ -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. +=item B<-cipher> I + +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 + +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. + =item B<-macopt> I:I 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. A key must be specified for every MAC algorithm. -=item BI - -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. - -=item BI - -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 BI 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. The default is the empty string "". +=item BI + +This option is identical to the B<-digest> option. + +=item BI + +This option is identical to the B<-cipher> option. + =back {- $OpenSSL::safe::opt_provider_item -} @@ -115,7 +125,7 @@ To see the list of supported MAC's use the command C [qw{openssl mac -macopt digest:SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}], + { cmd => [qw{openssl mac -digest SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}], type => 'HMAC', input => unpack("H*", "Sample message for keylen=blocklen"), expected => '5FD596EE78D5553C8FF4E72D266DFD192366DA29', 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', input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007', expected => '00BDA1B7E87608BCBF470F12157F4C07', 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}], type => 'KMAC128', input => '00010203', @@ -53,11 +63,16 @@ my @siphash_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}], type => 'CMAC', input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F', expected => 'F62C46329B41085625669BAF51DEA66A', - desc => 'CMAC AES-256-CBC' } + desc => 'CMAC AES-256-CBC' }, ); my @poly1305_tests = ( @@ -83,6 +98,11 @@ my @mac_fail_tests = ( input => '00', err => 'Invalid MAC name KMAC128', 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 = (