xref: /freebsd-src/crypto/openssl/test/recipes/20-test_mac.t (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1*e0c4386eSCy Schubert#! /usr/bin/env perl
2*e0c4386eSCy Schubert# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
3*e0c4386eSCy Schubert#
4*e0c4386eSCy Schubert# Licensed under the Apache License 2.0 (the "License").  You may not use
5*e0c4386eSCy Schubert# this file except in compliance with the License.  You can obtain a copy
6*e0c4386eSCy Schubert# in the file LICENSE in the source distribution or at
7*e0c4386eSCy Schubert# https://www.openssl.org/source/license.html
8*e0c4386eSCy Schubert
9*e0c4386eSCy Schubert
10*e0c4386eSCy Schubertuse strict;
11*e0c4386eSCy Schubertuse warnings;
12*e0c4386eSCy Schubert
13*e0c4386eSCy Schubertuse OpenSSL::Test;
14*e0c4386eSCy Schubertuse OpenSSL::Test::Utils;
15*e0c4386eSCy Schubertuse Storable qw(dclone);
16*e0c4386eSCy Schubert
17*e0c4386eSCy Schubertsetup("test_mac");
18*e0c4386eSCy Schubert
19*e0c4386eSCy Schubertmy @mac_tests = (
20*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -digest SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}],
21*e0c4386eSCy Schubert      type => 'HMAC',
22*e0c4386eSCy Schubert      input => unpack("H*", "Sample message for keylen=blocklen"),
23*e0c4386eSCy Schubert      expected => '5FD596EE78D5553C8FF4E72D266DFD192366DA29',
24*e0c4386eSCy Schubert      desc => 'HMAC SHA1' },
25*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -macopt digest:SHA1 -macopt hexkey:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F}],
26*e0c4386eSCy Schubert      type => 'HMAC',
27*e0c4386eSCy Schubert      input => unpack("H*", "Sample message for keylen=blocklen"),
28*e0c4386eSCy Schubert      expected => '5FD596EE78D5553C8FF4E72D266DFD192366DA29',
29*e0c4386eSCy Schubert      desc => 'HMAC SHA1 via -macopt' },
30*e0c4386eSCy Schubert   { cmd => [qw{openssl mac -cipher AES-256-GCM -macopt hexkey:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 -macopt hexiv:7AE8E2CA4EC500012E58495C}],
31*e0c4386eSCy Schubert     type => 'GMAC',
32*e0c4386eSCy Schubert     input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007',
33*e0c4386eSCy Schubert     expected => '00BDA1B7E87608BCBF470F12157F4C07',
34*e0c4386eSCy Schubert     desc => 'GMAC' },
35*e0c4386eSCy Schubert   { cmd => [qw{openssl mac -macopt cipher:AES-256-GCM -macopt hexkey:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5 -macopt hexiv:7AE8E2CA4EC500012E58495C}],
36*e0c4386eSCy Schubert     type => 'GMAC',
37*e0c4386eSCy Schubert     input => '68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D0007',
38*e0c4386eSCy Schubert     expected => '00BDA1B7E87608BCBF470F12157F4C07',
39*e0c4386eSCy Schubert     desc => 'GMAC via -macopt' },
40*e0c4386eSCy Schubert   { cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt xof:0}],
41*e0c4386eSCy Schubert     type => 'KMAC128',
42*e0c4386eSCy Schubert     input => '00010203',
43*e0c4386eSCy Schubert     expected => 'E5780B0D3EA6F7D3A429C5706AA43A00FADBD7D49628839E3187243F456EE14E',
44*e0c4386eSCy Schubert     desc => 'KMAC128' },
45*e0c4386eSCy Schubert   { cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt }, 'custom:My Tagged Application'],
46*e0c4386eSCy Schubert     type => 'KMAC256',
47*e0c4386eSCy Schubert     input => '00010203',
48*e0c4386eSCy Schubert     expected => '20C570C31346F703C9AC36C61C03CB64C3970D0CFC787E9B79599D273A68D2F7F69D4CC3DE9D104A351689F27CF6F5951F0103F33F4F24871024D9C27773A8DD',
49*e0c4386eSCy Schubert     desc => 'KMAC256' },
50*e0c4386eSCy Schubert   { cmd => [qw{openssl mac -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F -macopt xof:1 -macopt}, 'custom:My Tagged Application'],
51*e0c4386eSCy Schubert     type => 'KMAC256',
52*e0c4386eSCy Schubert     input => '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7',
53*e0c4386eSCy Schubert     expected => 'D5BE731C954ED7732846BB59DBE3A8E30F83E77A4BFF4459F2F1C2B4ECEBB8CE67BA01C62E8AB8578D2D499BD1BB276768781190020A306A97DE281DCC30305D',
54*e0c4386eSCy Schubert     desc => 'KMAC256 with xof len of 64' },
55*e0c4386eSCy Schubert);
56*e0c4386eSCy Schubert
57*e0c4386eSCy Schubertmy @siphash_tests = (
58*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -macopt hexkey:000102030405060708090A0B0C0D0E0F}],
59*e0c4386eSCy Schubert      type => 'SipHash',
60*e0c4386eSCy Schubert      input => '00',
61*e0c4386eSCy Schubert      expected => 'da87c1d86b99af44347659119b22fc45',
62*e0c4386eSCy Schubert      desc => 'SipHash No input' }
63*e0c4386eSCy Schubert);
64*e0c4386eSCy Schubert
65*e0c4386eSCy Schubertmy @cmac_tests = (
66*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -cipher AES-256-CBC -macopt hexkey:0B122AC8F34ED1FE082A3625D157561454167AC145A10BBF77C6A70596D574F1}],
67*e0c4386eSCy Schubert      type => 'CMAC',
68*e0c4386eSCy Schubert      input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F',
69*e0c4386eSCy Schubert      expected => 'F62C46329B41085625669BAF51DEA66A',
70*e0c4386eSCy Schubert      desc => 'CMAC AES-256-CBC' },
71*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -macopt cipher:AES-256-CBC -macopt hexkey:0B122AC8F34ED1FE082A3625D157561454167AC145A10BBF77C6A70596D574F1}],
72*e0c4386eSCy Schubert      type => 'CMAC',
73*e0c4386eSCy Schubert      input => '498B53FDEC87EDCBF07097DCCDE93A084BAD7501A224E388DF349CE18959FE8485F8AD1537F0D896EA73BEDC7214713F',
74*e0c4386eSCy Schubert      expected => 'F62C46329B41085625669BAF51DEA66A',
75*e0c4386eSCy Schubert      desc => 'CMAC AES-256-CBC' },
76*e0c4386eSCy Schubert);
77*e0c4386eSCy Schubert
78*e0c4386eSCy Schubertmy @poly1305_tests = (
79*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -macopt hexkey:02000000000000000000000000000000ffffffffffffffffffffffffffffffff}],
80*e0c4386eSCy Schubert      type => 'Poly1305',
81*e0c4386eSCy Schubert      input => '02000000000000000000000000000000',
82*e0c4386eSCy Schubert      expected => '03000000000000000000000000000000',
83*e0c4386eSCy Schubert      desc => 'Poly1305 (wrap 2^128)' },
84*e0c4386eSCy Schubert);
85*e0c4386eSCy Schubert
86*e0c4386eSCy Schubertpush @mac_tests, @siphash_tests unless disabled("siphash");
87*e0c4386eSCy Schubertpush @mac_tests, @cmac_tests unless disabled("cmac");
88*e0c4386eSCy Schubertpush @mac_tests, @poly1305_tests unless disabled("poly1305");
89*e0c4386eSCy Schubert
90*e0c4386eSCy Schubertmy @mac_fail_tests = (
91*e0c4386eSCy Schubert    { cmd => [qw{openssl mac}],
92*e0c4386eSCy Schubert      type => 'KMAC128',
93*e0c4386eSCy Schubert      input => '00',
94*e0c4386eSCy Schubert      err => 'EVP_MAC_Init',
95*e0c4386eSCy Schubert      desc => 'KMAC128 Fail no key' },
96*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -propquery unknown -macopt hexkey:404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F}],
97*e0c4386eSCy Schubert      type => 'KMAC128',
98*e0c4386eSCy Schubert      input => '00',
99*e0c4386eSCy Schubert      err => 'Invalid MAC name KMAC128',
100*e0c4386eSCy Schubert      desc => 'KMAC128 Fail unknown property' },
101*e0c4386eSCy Schubert    { cmd => [qw{openssl mac -cipher AES-128-CBC -macopt hexkey:00}],
102*e0c4386eSCy Schubert      type => 'HMAC',
103*e0c4386eSCy Schubert      input => '00',
104*e0c4386eSCy Schubert      err => 'MAC parameter error',
105*e0c4386eSCy Schubert      desc => 'HMAC given a cipher' },
106*e0c4386eSCy Schubert);
107*e0c4386eSCy Schubert
108*e0c4386eSCy Schubertmy @siphash_fail_tests = (
109*e0c4386eSCy Schubert    { cmd => [qw{openssl mac}],
110*e0c4386eSCy Schubert      type => 'SipHash',
111*e0c4386eSCy Schubert      input => '00',
112*e0c4386eSCy Schubert      err => '',
113*e0c4386eSCy Schubert      desc => 'SipHash Fail no key' },
114*e0c4386eSCy Schubert);
115*e0c4386eSCy Schubert
116*e0c4386eSCy Schubertpush @mac_fail_tests, @siphash_fail_tests unless disabled("siphash");
117*e0c4386eSCy Schubert
118*e0c4386eSCy Schubertplan tests => (scalar @mac_tests * 2) + scalar @mac_fail_tests;
119*e0c4386eSCy Schubert
120*e0c4386eSCy Schubertmy $test_count = 0;
121*e0c4386eSCy Schubert
122*e0c4386eSCy Schubertforeach (@mac_tests) {
123*e0c4386eSCy Schubert    $test_count++;
124*e0c4386eSCy Schubert    ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
125*e0c4386eSCy Schubert}
126*e0c4386eSCy Schubertforeach (@mac_tests) {
127*e0c4386eSCy Schubert    $test_count++;
128*e0c4386eSCy Schubert    ok(comparefile($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}), $_->{desc});
129*e0c4386eSCy Schubert}
130*e0c4386eSCy Schubert
131*e0c4386eSCy Schubertforeach (@mac_fail_tests) {
132*e0c4386eSCy Schubert    $test_count++;
133*e0c4386eSCy Schubert    ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
134*e0c4386eSCy Schubert}
135*e0c4386eSCy Schubert
136*e0c4386eSCy Schubert# Create a temp input file and save the input data into it, and
137*e0c4386eSCy Schubert# then compare the stdout output matches the expected value.
138*e0c4386eSCy Schubertsub compareline {
139*e0c4386eSCy Schubert    my $tmpfile = "input-$test_count.bin";
140*e0c4386eSCy Schubert    my ($cmdarray_orig, $type, $input, $expect, $err) = @_;
141*e0c4386eSCy Schubert    my $cmdarray = dclone $cmdarray_orig;
142*e0c4386eSCy Schubert    if (defined($expect)) {
143*e0c4386eSCy Schubert        $expect = uc $expect;
144*e0c4386eSCy Schubert    }
145*e0c4386eSCy Schubert    # Open a temporary input file and write $input to it
146*e0c4386eSCy Schubert    open(my $in, '>', $tmpfile) or die "Could not open file";
147*e0c4386eSCy Schubert    binmode($in);
148*e0c4386eSCy Schubert    my $bin = pack("H*", $input);
149*e0c4386eSCy Schubert    print $in $bin;
150*e0c4386eSCy Schubert    close $in;
151*e0c4386eSCy Schubert
152*e0c4386eSCy Schubert    # The last cmd parameter is the temporary input file we just created.
153*e0c4386eSCy Schubert    my @other = ('-in', $tmpfile, $type);
154*e0c4386eSCy Schubert    push @$cmdarray, @other;
155*e0c4386eSCy Schubert
156*e0c4386eSCy Schubert    my @lines = run(app($cmdarray), capture => 1);
157*e0c4386eSCy Schubert    # Not unlinking $tmpfile
158*e0c4386eSCy Schubert
159*e0c4386eSCy Schubert    if (defined($expect)) {
160*e0c4386eSCy Schubert        if ($lines[0] =~ m|^\Q${expect}\E\R$|) {
161*e0c4386eSCy Schubert            return 1;
162*e0c4386eSCy Schubert        } else {
163*e0c4386eSCy Schubert            print "Got: $lines[0]";
164*e0c4386eSCy Schubert            print "Exp: $expect\n";
165*e0c4386eSCy Schubert            return 0;
166*e0c4386eSCy Schubert        }
167*e0c4386eSCy Schubert    }
168*e0c4386eSCy Schubert    if (defined($err)) {
169*e0c4386eSCy Schubert        if (defined($lines[0])) {
170*e0c4386eSCy Schubert            $lines[0] =~ s/\s+$//;
171*e0c4386eSCy Schubert            if ($lines[0] eq $err) {
172*e0c4386eSCy Schubert                return 1;
173*e0c4386eSCy Schubert            } else {
174*e0c4386eSCy Schubert                print "Got: $lines[0]";
175*e0c4386eSCy Schubert                print "Exp: $err\n";
176*e0c4386eSCy Schubert                return 0;
177*e0c4386eSCy Schubert            }
178*e0c4386eSCy Schubert        } else {
179*e0c4386eSCy Schubert            # expected an error
180*e0c4386eSCy Schubert            return 1;
181*e0c4386eSCy Schubert        }
182*e0c4386eSCy Schubert    }
183*e0c4386eSCy Schubert    return 0;
184*e0c4386eSCy Schubert}
185*e0c4386eSCy Schubert
186*e0c4386eSCy Schubert# Create a temp input file and save the input data into it, and
187*e0c4386eSCy Schubert# use the '-bin -out <file>' commandline options to save results out to a file.
188*e0c4386eSCy Schubert# Read this file back in and check its output matches the expected value.
189*e0c4386eSCy Schubertsub comparefile {
190*e0c4386eSCy Schubert    my $tmpfile = "input-$test_count.bin";
191*e0c4386eSCy Schubert    my $outfile = "output-$test_count.bin";
192*e0c4386eSCy Schubert    my ($cmdarray, $type, $input, $expect) = @_;
193*e0c4386eSCy Schubert    $expect = uc $expect;
194*e0c4386eSCy Schubert
195*e0c4386eSCy Schubert    # Open a temporary input file and write $input to it
196*e0c4386eSCy Schubert    open(my $in, '>', $tmpfile) or die "Could not open file";
197*e0c4386eSCy Schubert    binmode($in);
198*e0c4386eSCy Schubert    my $bin = pack("H*", $input);
199*e0c4386eSCy Schubert    print $in $bin;
200*e0c4386eSCy Schubert    close $in;
201*e0c4386eSCy Schubert
202*e0c4386eSCy Schubert    my @other = ("-binary", "-in", $tmpfile, "-out", $outfile, $type);
203*e0c4386eSCy Schubert    push @$cmdarray, @other;
204*e0c4386eSCy Schubert
205*e0c4386eSCy Schubert    run(app($cmdarray));
206*e0c4386eSCy Schubert    # Not unlinking $tmpfile
207*e0c4386eSCy Schubert
208*e0c4386eSCy Schubert    open(my $out, '<', $outfile) or die "Could not open file";
209*e0c4386eSCy Schubert    binmode($out);
210*e0c4386eSCy Schubert    my $buffer;
211*e0c4386eSCy Schubert    my $BUFSIZE = 1024;
212*e0c4386eSCy Schubert    read($out, $buffer, $BUFSIZE) or die "unable to read";
213*e0c4386eSCy Schubert    my $line = uc unpack("H*", $buffer);
214*e0c4386eSCy Schubert    close($out);
215*e0c4386eSCy Schubert    # Not unlinking $outfile
216*e0c4386eSCy Schubert
217*e0c4386eSCy Schubert    if ($line eq $expect) {
218*e0c4386eSCy Schubert        return 1;
219*e0c4386eSCy Schubert    } else {
220*e0c4386eSCy Schubert        print "Got: $line\n";
221*e0c4386eSCy Schubert        print "Exp: $expect\n";
222*e0c4386eSCy Schubert        return 0;
223*e0c4386eSCy Schubert    }
224*e0c4386eSCy Schubert}
225