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