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