20-test_mac.t 8.9 KB

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