openssl app for macs that uses the new EVP_MAC interface (the code inside dgst uses EVP_PKEY)
Reviewed-by: Paul Yang <yang.yang@baishancloud.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/7661)
This commit is contained in:
parent
1b1ff9b94d
commit
4d768e966f
5 changed files with 555 additions and 10 deletions
|
@ -2,10 +2,10 @@
|
|||
qw(openssl.c
|
||||
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c
|
||||
dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c
|
||||
genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c
|
||||
pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c
|
||||
s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c
|
||||
srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c);
|
||||
genpkey.c genrsa.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c
|
||||
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c
|
||||
rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c
|
||||
spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c);
|
||||
our @apps_lib_src =
|
||||
( qw(apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c
|
||||
bf_prefix.c),
|
||||
|
|
200
apps/mac.c
Normal file
200
apps/mac.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#undef BUFSIZE
|
||||
#define BUFSIZE 1024*8
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_MACOPT, OPT_BIN, OPT_IN, OPT_OUT
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS mac_options[] = {
|
||||
{OPT_HELP_STR, 1, '-', "Usage: %s [options] mac_name\n"},
|
||||
{OPT_HELP_STR, 1, '-', "mac_name\t\t MAC algorithm (See list "
|
||||
"-mac-algorithms)"},
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"macopt", OPT_MACOPT, 's', "MAC algorithm control parameters in n:v form. "
|
||||
"See 'Supported Controls' in the EVP_MAC_ docs"},
|
||||
{"in", OPT_IN, '<', "Input file to MAC (default is stdin)"},
|
||||
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
|
||||
{"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal "
|
||||
"output)"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static int mac_ctrl_string(EVP_MAC_CTX *ctx, const char *value)
|
||||
{
|
||||
int rv;
|
||||
char *stmp, *vtmp = NULL;
|
||||
|
||||
stmp = OPENSSL_strdup(value);
|
||||
if (stmp == NULL)
|
||||
return -1;
|
||||
vtmp = strchr(stmp, ':');
|
||||
if (vtmp != NULL) {
|
||||
*vtmp = 0;
|
||||
vtmp++;
|
||||
}
|
||||
rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp);
|
||||
OPENSSL_free(stmp);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int mac_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog;
|
||||
const EVP_MAC *mac = NULL;
|
||||
OPTION_CHOICE o;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *opts = NULL;
|
||||
unsigned char *buf = NULL;
|
||||
size_t len;
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
const char *outfile = NULL;
|
||||
const char *infile = NULL;
|
||||
int out_bin = 0;
|
||||
int inform = FORMAT_BINARY;
|
||||
|
||||
prog = opt_init(argc, argv, mac_options);
|
||||
buf = app_malloc(BUFSIZE, "I/O buffer");
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
case OPT_EOF:
|
||||
case OPT_ERR:
|
||||
opthelp:
|
||||
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
||||
goto err;
|
||||
case OPT_HELP:
|
||||
opt_help(mac_options);
|
||||
ret = 0;
|
||||
goto err;
|
||||
case OPT_BIN:
|
||||
out_bin = 1;
|
||||
break;
|
||||
case OPT_IN:
|
||||
infile = opt_arg();
|
||||
break;
|
||||
case OPT_OUT:
|
||||
outfile = opt_arg();
|
||||
break;
|
||||
case OPT_MACOPT:
|
||||
if (opts == NULL)
|
||||
opts = sk_OPENSSL_STRING_new_null();
|
||||
if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
argv = opt_rest();
|
||||
|
||||
if (argc != 1) {
|
||||
BIO_printf(bio_err, "Invalid number of extra arguments\n");
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
mac = EVP_get_macbyname(argv[0]);
|
||||
if (mac == NULL) {
|
||||
BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]);
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
if (opts != NULL) {
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
|
||||
char *opt = sk_OPENSSL_STRING_value(opts, i);
|
||||
if (mac_ctrl_string(ctx, opt) <= 0) {
|
||||
BIO_printf(bio_err, "MAC parameter error '%s'\n", opt);
|
||||
ERR_print_errors(bio_err);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Use text mode for stdin */
|
||||
if (infile == NULL || strcmp(infile, "-") == 0)
|
||||
inform = FORMAT_TEXT;
|
||||
in = bio_open_default(infile, 'r', inform);
|
||||
if (in == NULL)
|
||||
goto err;
|
||||
|
||||
out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
|
||||
if (out == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EVP_MAC_init(ctx)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_Init failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
i = BIO_read(in, (char *)buf, BUFSIZE);
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "Read Error in '%s'\n", infile);
|
||||
goto err;
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
if (!EVP_MAC_update(ctx, buf, i)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_update failed\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EVP_MAC_final(ctx, NULL, &len)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_final failed\n");
|
||||
goto err;
|
||||
}
|
||||
if (len > BUFSIZE) {
|
||||
BIO_printf(bio_err, "output len is too large\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_final(ctx, buf, &len)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_final failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (out_bin) {
|
||||
BIO_write(out, buf, len);
|
||||
} else {
|
||||
if (outfile == NULL)
|
||||
BIO_printf(out,"\n");
|
||||
for (i = 0; i < (int)len; ++i)
|
||||
BIO_printf(out, "%02X", buf[i]);
|
||||
if (outfile == NULL)
|
||||
BIO_printf(out,"\n");
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
err:
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
OPENSSL_clear_free(buf, BUFSIZE);
|
||||
sk_OPENSSL_STRING_free(opts);
|
||||
BIO_free(in);
|
||||
BIO_free(out);
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
163
doc/man1/mac.pod
Normal file
163
doc/man1/mac.pod
Normal file
|
@ -0,0 +1,163 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
openssl-mac,
|
||||
mac - perform Message Authentication Code operations
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<openssl mac>
|
||||
[B<-help>]
|
||||
[B<-macopt>]
|
||||
[B<-in filename>]
|
||||
[B<-out filename>]
|
||||
[B<-binary>]
|
||||
B<mac_name>
|
||||
|
||||
B<openssl> I<mac> [B<...>] B<mac_name>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The message authentication code functions output the MAC of a supplied input
|
||||
file.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-help>
|
||||
|
||||
Print a usage message.
|
||||
|
||||
=item B<-in filename>
|
||||
|
||||
Input filename to calculate a MAC for, or standard input by default.
|
||||
Standard input is used if the filename is '-'.
|
||||
Files are expected to be in binary format, standard input uses hexadecimal text
|
||||
format.
|
||||
|
||||
=item B<-out filename>
|
||||
|
||||
Filename to output to, or standard output by default.
|
||||
|
||||
=item B<-binary>
|
||||
|
||||
Output the MAC in binary form. Uses hexadecimal text format if not specified.
|
||||
|
||||
=item B<-macopt nm:v>
|
||||
|
||||
Passes options to the MAC algorithm.
|
||||
A comprehensive list of controls can be found in the EVP_MAC implementation
|
||||
documentation.
|
||||
Common control strings used by EVP_MAC_ctrl_str() are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<key:string>
|
||||
|
||||
Specifies the MAC key as an alphanumeric string (use if the key contains
|
||||
printable characters only).
|
||||
The string length must conform to any restrictions of the MAC algorithm.
|
||||
A key must be specified for every MAC algorithm.
|
||||
|
||||
=item B<hexkey:string>
|
||||
|
||||
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 B<digest: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 the command I<list -digest-commands>.
|
||||
|
||||
=item B<cipher:string>
|
||||
|
||||
Used by CMAC and GMAC to specifiy 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:string>
|
||||
|
||||
Used by GMAC to specify an IV as an alphanumeric string (use if the IV contains
|
||||
printable characters only).
|
||||
|
||||
=item B<hexiv:string>
|
||||
|
||||
Used by GMAC to specify an IV in hexadecimal form (two hex digits per byte).
|
||||
|
||||
=item B<outlen:int>
|
||||
|
||||
Used by KMAC128 or KMAC256 to specify an output length.
|
||||
The default sizes are 32 or 64 bytes respectively.
|
||||
|
||||
=item B<custom:string>
|
||||
|
||||
Used by KMAC128 or KMAC256 to specify a customization string.
|
||||
The default is the empty string "".
|
||||
|
||||
=back
|
||||
|
||||
=item B<mac_name>
|
||||
|
||||
Specifies the name of a supported MAC algorithm which will be used.
|
||||
To see the list of supported MAC's use the command I<list -mac-algorithms>.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
To create a hex-encoded HMAC-SHA1 MAC of a file and write to stdout: \
|
||||
openssl mac -macopt digest:SHA1 \
|
||||
-macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 \
|
||||
-in msg.bin HMAC
|
||||
|
||||
To create a SipHash MAC from a file with a binary file output: \
|
||||
openssl mac -macopt hexkey:000102030405060708090A0B0C0D0E0F \
|
||||
-in msg.bin -out out.bin -binary SipHash
|
||||
|
||||
To create a hex-encoded CMAC-AES-128-CBC MAC from a file:\
|
||||
openssl mac -macopt cipher:AES-128-CBC \
|
||||
-macopt hexkey:77A77FAF290C1FA30C683DF16BA7A77B \
|
||||
-in msg.bin CMAC
|
||||
|
||||
To create a hex-encoded KMAC128 MAC from a file with a Customisation String
|
||||
'Tag' and output length of 16: \
|
||||
openssl mac -macopt custom:Tag -macopt hexkey:40414243444546 \
|
||||
-macopt outlen:16 -in msg.bin KMAC128
|
||||
|
||||
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 \
|
||||
-macopt hexkey:77A77FAF290C1FA30C683DF16BA7A77B -in msg.bin GMAC
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The MAC mechanisms that are available will depend on the options
|
||||
used when building OpenSSL.
|
||||
The B<list -mac-algorithms> command can be used to list them.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<EVP_MAC(3)>,
|
||||
L<EVP_MAC_CMAC(7)>,
|
||||
L<EVP_MAC_GMAC(7)>,
|
||||
L<EVP_MAC_HMAC(7)>,
|
||||
L<EVP_MAC_KMAC(7)>,
|
||||
L<EVP_MAC_SIPHASH(7)>,
|
||||
L<EVP_MAC_POLY1305(7)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the OpenSSL license (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
in the file LICENSE in the source distribution or at
|
||||
L<https://www.openssl.org/source/license.html>.
|
||||
|
||||
=cut
|
|
@ -11,7 +11,7 @@ I<command>
|
|||
[ I<command_opts> ]
|
||||
[ I<command_args> ]
|
||||
|
||||
B<openssl> B<list> [ B<standard-commands> | B<digest-commands> | B<cipher-commands> | B<cipher-algorithms> | B<digest-algorithms> | B<public-key-algorithms>]
|
||||
B<openssl> B<list> [ B<standard-commands> | B<digest-commands> | B<cipher-commands> | B<cipher-algorithms> | B<digest-algorithms> | B<mac-algorithms> | B<public-key-algorithms>]
|
||||
|
||||
B<openssl> B<no->I<XXX> [ I<arbitrary options> ]
|
||||
|
||||
|
@ -28,7 +28,7 @@ It can be used for
|
|||
o Creation and management of private keys, public keys and parameters
|
||||
o Public key cryptographic operations
|
||||
o Creation of X.509 certificates, CSRs and CRLs
|
||||
o Calculation of Message Digests
|
||||
o Calculation of Message Digests and Message Authentication Codes
|
||||
o Encryption and Decryption with Ciphers
|
||||
o SSL/TLS Client and Server Tests
|
||||
o Handling of S/MIME signed or encrypted mail
|
||||
|
@ -57,8 +57,9 @@ and B<cipher-commands> output a list (one entry per line) of the names
|
|||
of all standard commands, message digest commands, or cipher commands,
|
||||
respectively, that are available in the present B<openssl> utility.
|
||||
|
||||
The list parameters B<cipher-algorithms> and
|
||||
B<digest-algorithms> list all cipher and message digest names, one entry per line. Aliases are listed as:
|
||||
The list parameters B<cipher-algorithms>, B<digest-algorithms>,
|
||||
and B<mac-algorithms> list all cipher, message digest, and message
|
||||
authentication code names, one entry per line. Aliases are listed as:
|
||||
|
||||
from => to
|
||||
|
||||
|
@ -106,7 +107,8 @@ CRL to PKCS#7 Conversion.
|
|||
|
||||
=item B<dgst>
|
||||
|
||||
Message Digest Calculation.
|
||||
Message Digest calculation. MAC calculations are superseded by
|
||||
L<mac(1)>.
|
||||
|
||||
=item B<dh>
|
||||
|
||||
|
@ -165,6 +167,10 @@ Generation of Private Key or Parameters.
|
|||
|
||||
Generation of RSA Private Key. Superseded by L<genpkey(1)>.
|
||||
|
||||
=item B<mac>
|
||||
|
||||
Message Authentication Code Calculation.
|
||||
|
||||
=item B<nseq>
|
||||
|
||||
Create or examine a Netscape certificate sequence.
|
||||
|
@ -606,7 +612,7 @@ L<crl(1)>, L<crl2pkcs7(1)>, L<dgst(1)>,
|
|||
L<dhparam(1)>, L<dsa(1)>, L<dsaparam(1)>,
|
||||
L<ec(1)>, L<ecparam(1)>,
|
||||
L<enc(1)>, L<engine(1)>, L<errstr(1)>, L<gendsa(1)>, L<genpkey(1)>,
|
||||
L<genrsa(1)>, L<nseq(1)>, L<ocsp(1)>,
|
||||
L<genrsa(1)>, L<mac(1)>, L<nseq(1)>, L<ocsp(1)>,
|
||||
L<passwd(1)>,
|
||||
L<pkcs12(1)>, L<pkcs7(1)>, L<pkcs8(1)>,
|
||||
L<pkey(1)>, L<pkeyparam(1)>, L<pkeyutl(1)>, L<prime(1)>,
|
||||
|
|
176
test/recipes/20-test_mac.t
Normal file
176
test/recipes/20-test_mac.t
Normal file
|
@ -0,0 +1,176 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use OpenSSL::Test;
|
||||
use OpenSSL::Test::Utils;
|
||||
use Storable qw(dclone);
|
||||
|
||||
setup("test_mac");
|
||||
|
||||
my @mac_tests = (
|
||||
{ cmd => [qw{openssl mac -macopt hexkey:000102030405060708090A0B0C0D0E0F}],
|
||||
type => 'SipHash',
|
||||
input => '00',
|
||||
expected => 'da87c1d86b99af44347659119b22fc45',
|
||||
desc => 'SipHash No input' },
|
||||
{ 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' },
|
||||
{ cmd => [qw{openssl mac -macopt cipher:AES-256-CBC -macopt hexkey:0B122AC8F34ED1FE082A3625D157561454167AC145A10BBF77C6A70596D574F1}],
|
||||
type => 'CMAC',
|
||||
input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F',
|
||||
expected => 'F62C46329B41085625669BAF51DEA66A',
|
||||
desc => 'CMAC AES-256-CBC' },
|
||||
{ cmd => [qw{openssl mac -macopt hexkey:02000000000000000000000000000000ffffffffffffffffffffffffffffffff}],
|
||||
type => 'Poly1305',
|
||||
input => '02000000000000000000000000000000',
|
||||
expected => '03000000000000000000000000000000',
|
||||
desc => 'Poly1305 (wrap 2^128)' },
|
||||
{ cmd => [qw{openssl mac -macopt cipher:AES-256-GCM -macopt hexkey:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 -macopt hexiv:7AE8E2CA4EC500012E58495C}],
|
||||
type => 'GMAC',
|
||||
input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007',
|
||||
expected => '00BDA1B7E87608BCBF470F12157F4C07',
|
||||
desc => 'GMAC' },
|
||||
{ cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt xof:0}],
|
||||
type => 'KMAC128',
|
||||
input => '00010203',
|
||||
expected => 'E5780B0D3EA6F7D3A429C5706AA43A00FADBD7D49628839E3187243F456EE14E',
|
||||
desc => 'KMAC128' },
|
||||
{ cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt }, 'custom:My Tagged Application'],
|
||||
type => 'KMAC256',
|
||||
input => '00010203',
|
||||
expected => '20C570C31346F703C9AC36C61C03CB64C3970D0CFC787E9B79599D273A68D2F7F69D4CC3DE9D104A351689F27CF6F5951F0103F33F4F24871024D9C27773A8DD',
|
||||
desc => 'KMAC256' },
|
||||
{ cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt xof:1 -macopt}, 'custom:My Tagged Application'],
|
||||
type => 'KMAC256',
|
||||
input => '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7',
|
||||
expected => 'D5BE731C954ED7732846BB59DBE3A8E30F83E77A4BFF4459F2F1C2B4ECEBB8CE67BA01C62E8AB8578D2D499BD1BB276768781190020A306A97DE281DCC30305D',
|
||||
desc => 'KMAC256 with xof len of 64' },
|
||||
);
|
||||
|
||||
my @mac_fail_tests = (
|
||||
{ cmd => [qw{openssl mac}],
|
||||
type => 'SipHash',
|
||||
input => '00',
|
||||
err => '',
|
||||
desc => 'SipHash Fail no key' },
|
||||
{ cmd => [qw{openssl mac}],
|
||||
type => 'KMAC128',
|
||||
input => '00',
|
||||
err => 'EVP_MAC_Init',
|
||||
desc => 'KMAC128 Fail no key' },
|
||||
);
|
||||
|
||||
plan tests => (scalar @mac_tests * 2) + scalar @mac_fail_tests;
|
||||
|
||||
foreach (@mac_tests) {
|
||||
ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
|
||||
}
|
||||
foreach (@mac_tests) {
|
||||
ok(comparefile($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}), $_->{desc});
|
||||
}
|
||||
|
||||
foreach (@mac_fail_tests) {
|
||||
ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
|
||||
}
|
||||
|
||||
# Create a temp input file and save the input data into it, and
|
||||
# then compare the stdout output matches the expected value.
|
||||
sub compareline {
|
||||
my $tmpfile = 'tmp.bin';
|
||||
my ($cmdarray_orig, $type, $input, $expect, $err) = @_;
|
||||
my $cmdarray = dclone $cmdarray_orig;
|
||||
if (defined($expect)) {
|
||||
$expect = uc $expect;
|
||||
}
|
||||
# Open a temporary input file and write $input to it
|
||||
open(my $in, '>', $tmpfile) or die "Could not open file";
|
||||
binmode($in);
|
||||
my $bin = pack("H*", $input);
|
||||
print $in $bin;
|
||||
close $in;
|
||||
|
||||
# The last cmd parameter is the temporary input file we just created.
|
||||
my @other = ('-in', $tmpfile, $type);
|
||||
push @$cmdarray, @other;
|
||||
|
||||
my @lines = run(app($cmdarray), capture => 1);
|
||||
unlink $tmpfile;
|
||||
|
||||
if (defined($expect)) {
|
||||
if ($lines[1] =~ m|^\Q${expect}\E\R$|) {
|
||||
return 1;
|
||||
} else {
|
||||
print "Got: $lines[1]";
|
||||
print "Exp: $expect\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (defined($err)) {
|
||||
if (defined($lines[0])) {
|
||||
$lines[0] =~ s/\s+$//;
|
||||
if ($lines[0] eq $err) {
|
||||
return 1;
|
||||
} else {
|
||||
print "Got: $lines[0]";
|
||||
print "Exp: $err\n";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
# expected an error
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Create a temp input file and save the input data into it, and
|
||||
# use the '-bin -out <file>' commandline options to save results out to a file.
|
||||
# Read this file back in and check its output matches the expected value.
|
||||
sub comparefile {
|
||||
my $tmpfile = 'tmp.bin';
|
||||
my $outfile = 'out.bin';
|
||||
my ($cmdarray, $type, $input, $expect) = @_;
|
||||
$expect = uc $expect;
|
||||
|
||||
# Open a temporary input file and write $input to it
|
||||
open(my $in, '>', $tmpfile) or die "Could not open file";
|
||||
binmode($in);
|
||||
my $bin = pack("H*", $input);
|
||||
print $in $bin;
|
||||
close $in;
|
||||
|
||||
my @other = ("-binary", "-in", $tmpfile, "-out", $outfile, $type);
|
||||
push @$cmdarray, @other;
|
||||
|
||||
run(app($cmdarray));
|
||||
unlink $tmpfile;
|
||||
open(my $out, '<', $outfile) or die "Could not open file";
|
||||
binmode($out);
|
||||
my $buffer;
|
||||
my $BUFSIZE = 1024;
|
||||
read($out, $buffer, $BUFSIZE) or die "unable to read";
|
||||
|
||||
my $line = uc unpack("H*", $buffer);
|
||||
close($out);
|
||||
unlink $outfile;
|
||||
|
||||
if ($line eq $expect) {
|
||||
return 1;
|
||||
} else {
|
||||
print "Got: $line\n";
|
||||
print "Exp: $expect\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue