xref: /freebsd/crypto/openssl/test/recipes/20-test_dgst.t (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1*e0c4386eSCy Schubert#! /usr/bin/env perl
2*e0c4386eSCy Schubert# Copyright 2017-2022 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 File::Spec;
14*e0c4386eSCy Schubertuse File::Basename;
15*e0c4386eSCy Schubertuse OpenSSL::Test qw/:DEFAULT with srctop_file bldtop_dir/;
16*e0c4386eSCy Schubertuse OpenSSL::Test::Utils;
17*e0c4386eSCy Schubert
18*e0c4386eSCy Schubertsetup("test_dgst");
19*e0c4386eSCy Schubert
20*e0c4386eSCy Schubertplan tests => 13;
21*e0c4386eSCy Schubert
22*e0c4386eSCy Schubertsub tsignverify {
23*e0c4386eSCy Schubert    my $testtext = shift;
24*e0c4386eSCy Schubert    my $privkey = shift;
25*e0c4386eSCy Schubert    my $pubkey = shift;
26*e0c4386eSCy Schubert
27*e0c4386eSCy Schubert    my $data_to_sign = srctop_file('test', 'data.bin');
28*e0c4386eSCy Schubert    my $other_data = srctop_file('test', 'data2.bin');
29*e0c4386eSCy Schubert
30*e0c4386eSCy Schubert    my $sigfile = basename($privkey, '.pem') . '.sig';
31*e0c4386eSCy Schubert    plan tests => 4;
32*e0c4386eSCy Schubert
33*e0c4386eSCy Schubert    ok(run(app(['openssl', 'dgst', '-sign', $privkey,
34*e0c4386eSCy Schubert                '-out', $sigfile,
35*e0c4386eSCy Schubert                $data_to_sign])),
36*e0c4386eSCy Schubert       $testtext.": Generating signature");
37*e0c4386eSCy Schubert
38*e0c4386eSCy Schubert    ok(run(app(['openssl', 'dgst', '-prverify', $privkey,
39*e0c4386eSCy Schubert                '-signature', $sigfile,
40*e0c4386eSCy Schubert                $data_to_sign])),
41*e0c4386eSCy Schubert       $testtext.": Verify signature with private key");
42*e0c4386eSCy Schubert
43*e0c4386eSCy Schubert    ok(run(app(['openssl', 'dgst', '-verify', $pubkey,
44*e0c4386eSCy Schubert                '-signature', $sigfile,
45*e0c4386eSCy Schubert                $data_to_sign])),
46*e0c4386eSCy Schubert       $testtext.": Verify signature with public key");
47*e0c4386eSCy Schubert
48*e0c4386eSCy Schubert    ok(!run(app(['openssl', 'dgst', '-verify', $pubkey,
49*e0c4386eSCy Schubert                 '-signature', $sigfile,
50*e0c4386eSCy Schubert                 $other_data])),
51*e0c4386eSCy Schubert       $testtext.": Expect failure verifying mismatching data");
52*e0c4386eSCy Schubert}
53*e0c4386eSCy Schubert
54*e0c4386eSCy Schubertsub tsignverify_sha512 {
55*e0c4386eSCy Schubert    my $testtext = shift;
56*e0c4386eSCy Schubert    my $privkey = shift;
57*e0c4386eSCy Schubert    my $pubkey = shift;
58*e0c4386eSCy Schubert
59*e0c4386eSCy Schubert    my $data_to_sign = srctop_file('test', 'data.bin');
60*e0c4386eSCy Schubert    my $other_data = srctop_file('test', 'data2.bin');
61*e0c4386eSCy Schubert
62*e0c4386eSCy Schubert    my $sigfile = basename($privkey, '.pem') . '.sig';
63*e0c4386eSCy Schubert    plan tests => 5;
64*e0c4386eSCy Schubert
65*e0c4386eSCy Schubert    ok(run(app(['openssl', 'sha512', '-sign', $privkey,
66*e0c4386eSCy Schubert                '-out', $sigfile,
67*e0c4386eSCy Schubert                $data_to_sign])),
68*e0c4386eSCy Schubert       $testtext.": Generating signature using sha512 command");
69*e0c4386eSCy Schubert
70*e0c4386eSCy Schubert    ok(run(app(['openssl', 'sha512', '-verify', $pubkey,
71*e0c4386eSCy Schubert                '-signature', $sigfile,
72*e0c4386eSCy Schubert                $data_to_sign])),
73*e0c4386eSCy Schubert       $testtext.": Verify signature with public key using sha512 command");
74*e0c4386eSCy Schubert
75*e0c4386eSCy Schubert    ok(run(app(['openssl', 'dgst', '-sha512', '-prverify', $privkey,
76*e0c4386eSCy Schubert                '-signature', $sigfile,
77*e0c4386eSCy Schubert                $data_to_sign])),
78*e0c4386eSCy Schubert       $testtext.": Verify signature with private key");
79*e0c4386eSCy Schubert
80*e0c4386eSCy Schubert    ok(run(app(['openssl', 'dgst', '-sha512', '-verify', $pubkey,
81*e0c4386eSCy Schubert                '-signature', $sigfile,
82*e0c4386eSCy Schubert                $data_to_sign])),
83*e0c4386eSCy Schubert       $testtext.": Verify signature with public key");
84*e0c4386eSCy Schubert
85*e0c4386eSCy Schubert    ok(!run(app(['openssl', 'dgst', '-sha512', '-verify', $pubkey,
86*e0c4386eSCy Schubert                 '-signature', $sigfile,
87*e0c4386eSCy Schubert                 $other_data])),
88*e0c4386eSCy Schubert       $testtext.": Expect failure verifying mismatching data");
89*e0c4386eSCy Schubert}
90*e0c4386eSCy Schubert
91*e0c4386eSCy SchubertSKIP: {
92*e0c4386eSCy Schubert    skip "RSA is not supported by this OpenSSL build", 1
93*e0c4386eSCy Schubert        if disabled("rsa");
94*e0c4386eSCy Schubert
95*e0c4386eSCy Schubert    subtest "RSA signature generation and verification with `dgst` CLI" => sub {
96*e0c4386eSCy Schubert        tsignverify("RSA",
97*e0c4386eSCy Schubert                    srctop_file("test","testrsa.pem"),
98*e0c4386eSCy Schubert                    srctop_file("test","testrsapub.pem"));
99*e0c4386eSCy Schubert    };
100*e0c4386eSCy Schubert
101*e0c4386eSCy Schubert    subtest "RSA signature generation and verification with `sha512` CLI" => sub {
102*e0c4386eSCy Schubert        tsignverify_sha512("RSA",
103*e0c4386eSCy Schubert                           srctop_file("test","testrsa2048.pem"),
104*e0c4386eSCy Schubert                           srctop_file("test","testrsa2048pub.pem"));
105*e0c4386eSCy Schubert    };
106*e0c4386eSCy Schubert}
107*e0c4386eSCy Schubert
108*e0c4386eSCy SchubertSKIP: {
109*e0c4386eSCy Schubert    skip "DSA is not supported by this OpenSSL build", 1
110*e0c4386eSCy Schubert        if disabled("dsa");
111*e0c4386eSCy Schubert
112*e0c4386eSCy Schubert    subtest "DSA signature generation and verification with `dgst` CLI" => sub {
113*e0c4386eSCy Schubert        tsignverify("DSA",
114*e0c4386eSCy Schubert                    srctop_file("test","testdsa.pem"),
115*e0c4386eSCy Schubert                    srctop_file("test","testdsapub.pem"));
116*e0c4386eSCy Schubert    };
117*e0c4386eSCy Schubert}
118*e0c4386eSCy Schubert
119*e0c4386eSCy SchubertSKIP: {
120*e0c4386eSCy Schubert    skip "ECDSA is not supported by this OpenSSL build", 1
121*e0c4386eSCy Schubert        if disabled("ec");
122*e0c4386eSCy Schubert
123*e0c4386eSCy Schubert    subtest "ECDSA signature generation and verification with `dgst` CLI" => sub {
124*e0c4386eSCy Schubert        tsignverify("ECDSA",
125*e0c4386eSCy Schubert                    srctop_file("test","testec-p256.pem"),
126*e0c4386eSCy Schubert                    srctop_file("test","testecpub-p256.pem"));
127*e0c4386eSCy Schubert    };
128*e0c4386eSCy Schubert}
129*e0c4386eSCy Schubert
130*e0c4386eSCy SchubertSKIP: {
131*e0c4386eSCy Schubert    skip "EdDSA is not supported by this OpenSSL build", 2
132*e0c4386eSCy Schubert        if disabled("ec");
133*e0c4386eSCy Schubert
134*e0c4386eSCy Schubert    skip "EdDSA is not supported with `dgst` CLI", 2;
135*e0c4386eSCy Schubert
136*e0c4386eSCy Schubert    subtest "Ed25519 signature generation and verification with `dgst` CLI" => sub {
137*e0c4386eSCy Schubert        tsignverify("Ed25519",
138*e0c4386eSCy Schubert                    srctop_file("test","tested25519.pem"),
139*e0c4386eSCy Schubert                    srctop_file("test","tested25519pub.pem"));
140*e0c4386eSCy Schubert    };
141*e0c4386eSCy Schubert
142*e0c4386eSCy Schubert    subtest "Ed448 signature generation and verification with `dgst` CLI" => sub {
143*e0c4386eSCy Schubert        tsignverify("Ed448",
144*e0c4386eSCy Schubert                    srctop_file("test","tested448.pem"),
145*e0c4386eSCy Schubert                    srctop_file("test","tested448pub.pem"));
146*e0c4386eSCy Schubert    };
147*e0c4386eSCy Schubert}
148*e0c4386eSCy Schubert
149*e0c4386eSCy SchubertSKIP: {
150*e0c4386eSCy Schubert    skip "dgst with engine is not supported by this OpenSSL build", 1
151*e0c4386eSCy Schubert        if disabled("engine") || disabled("dynamic-engine");
152*e0c4386eSCy Schubert
153*e0c4386eSCy Schubert    subtest "SHA1 generation by engine with `dgst` CLI" => sub {
154*e0c4386eSCy Schubert        plan tests => 1;
155*e0c4386eSCy Schubert
156*e0c4386eSCy Schubert        my $testdata = srctop_file('test', 'data.bin');
157*e0c4386eSCy Schubert        # intentionally using -engine twice, please do not remove the duplicate line
158*e0c4386eSCy Schubert        my @macdata = run(app(['openssl', 'dgst', '-sha1',
159*e0c4386eSCy Schubert                               '-engine', "ossltest",
160*e0c4386eSCy Schubert                               '-engine', "ossltest",
161*e0c4386eSCy Schubert                               $testdata]), capture => 1);
162*e0c4386eSCy Schubert        chomp(@macdata);
163*e0c4386eSCy Schubert        my $expected = qr/SHA1\(\Q$testdata\E\)= 000102030405060708090a0b0c0d0e0f10111213/;
164*e0c4386eSCy Schubert        ok($macdata[0] =~ $expected, "SHA1: Check HASH value is as expected ($macdata[0]) vs ($expected)");
165*e0c4386eSCy Schubert    }
166*e0c4386eSCy Schubert}
167*e0c4386eSCy Schubert
168*e0c4386eSCy Schubertsubtest "HMAC generation with `dgst` CLI" => sub {
169*e0c4386eSCy Schubert    plan tests => 2;
170*e0c4386eSCy Schubert
171*e0c4386eSCy Schubert    my $testdata = srctop_file('test', 'data.bin');
172*e0c4386eSCy Schubert    #HMAC the data twice to check consistency
173*e0c4386eSCy Schubert    my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac', '123456',
174*e0c4386eSCy Schubert                            $testdata, $testdata]), capture => 1);
175*e0c4386eSCy Schubert    chomp(@hmacdata);
176*e0c4386eSCy Schubert    my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
177*e0c4386eSCy Schubert    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
178*e0c4386eSCy Schubert    ok($hmacdata[1] =~ $expected,
179*e0c4386eSCy Schubert       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
180*e0c4386eSCy Schubert};
181*e0c4386eSCy Schubert
182*e0c4386eSCy Schubertsubtest "HMAC generation with `dgst` CLI, default digest" => sub {
183*e0c4386eSCy Schubert    plan tests => 2;
184*e0c4386eSCy Schubert
185*e0c4386eSCy Schubert    my $testdata = srctop_file('test', 'data.bin');
186*e0c4386eSCy Schubert    #HMAC the data twice to check consistency
187*e0c4386eSCy Schubert    my @hmacdata = run(app(['openssl', 'dgst', '-hmac', '123456',
188*e0c4386eSCy Schubert                            $testdata, $testdata]), capture => 1);
189*e0c4386eSCy Schubert    chomp(@hmacdata);
190*e0c4386eSCy Schubert    my $expected = qr/HMAC-SHA256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
191*e0c4386eSCy Schubert    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
192*e0c4386eSCy Schubert    ok($hmacdata[1] =~ $expected,
193*e0c4386eSCy Schubert       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
194*e0c4386eSCy Schubert};
195*e0c4386eSCy Schubert
196*e0c4386eSCy Schubertsubtest "HMAC generation with `dgst` CLI, key via option" => sub {
197*e0c4386eSCy Schubert    plan tests => 2;
198*e0c4386eSCy Schubert
199*e0c4386eSCy Schubert    my $testdata = srctop_file('test', 'data.bin');
200*e0c4386eSCy Schubert    #HMAC the data twice to check consistency
201*e0c4386eSCy Schubert    my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac',
202*e0c4386eSCy Schubert                            '-macopt', 'hexkey:FFFF',
203*e0c4386eSCy Schubert                            $testdata, $testdata]), capture => 1);
204*e0c4386eSCy Schubert    chomp(@hmacdata);
205*e0c4386eSCy Schubert    my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= b6727b7bb251dfa65846e0a8223bdd57d244aa6d7e312cb906d8e21f2dee3a57/;
206*e0c4386eSCy Schubert    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
207*e0c4386eSCy Schubert    ok($hmacdata[1] =~ $expected,
208*e0c4386eSCy Schubert       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
209*e0c4386eSCy Schubert};
210*e0c4386eSCy Schubert
211*e0c4386eSCy Schubertsubtest "Custom length XOF digest generation with `dgst` CLI" => sub {
212*e0c4386eSCy Schubert    plan tests => 2;
213*e0c4386eSCy Schubert
214*e0c4386eSCy Schubert    my $testdata = srctop_file('test', 'data.bin');
215*e0c4386eSCy Schubert    #Digest the data twice to check consistency
216*e0c4386eSCy Schubert    my @xofdata = run(app(['openssl', 'dgst', '-shake128', '-xoflen', '64',
217*e0c4386eSCy Schubert                           $testdata, $testdata]), capture => 1);
218*e0c4386eSCy Schubert    chomp(@xofdata);
219*e0c4386eSCy Schubert    my $expected = qr/SHAKE-128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa64ffd0b3e2bf8cd73d5182dfba19b6a8a2eab96d2df854b647b3795ef090582abe41ba4e0717dc4df40bc4e17d88e4677/;
220*e0c4386eSCy Schubert    ok($xofdata[0] =~ $expected, "XOF: Check digest value is as expected ($xofdata[0]) vs ($expected)");
221*e0c4386eSCy Schubert    ok($xofdata[1] =~ $expected,
222*e0c4386eSCy Schubert       "XOF: Check second digest value is consistent with the first ($xofdata[1]) vs ($expected)");
223*e0c4386eSCy Schubert};
224*e0c4386eSCy Schubert
225*e0c4386eSCy Schubertsubtest "SHAKE digest generation with no xoflen set `dgst` CLI" => sub {
226*e0c4386eSCy Schubert    plan tests => 1;
227*e0c4386eSCy Schubert
228*e0c4386eSCy Schubert    my $testdata = srctop_file('test', 'data.bin');
229*e0c4386eSCy Schubert    my @xofdata = run(app(['openssl', 'dgst', '-shake128', $testdata], stderr => "outerr.txt"), capture => 1);
230*e0c4386eSCy Schubert    chomp(@xofdata);
231*e0c4386eSCy Schubert    my $expected = qr/SHAKE-128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa6/;
232*e0c4386eSCy Schubert    ok($xofdata[0] =~ $expected, "Check short digest is output");
233*e0c4386eSCy Schubert};
234*e0c4386eSCy Schubert
235*e0c4386eSCy SchubertSKIP: {
236*e0c4386eSCy Schubert    skip "ECDSA is not supported by this OpenSSL build", 1
237*e0c4386eSCy Schubert        if disabled("ec");
238*e0c4386eSCy Schubert
239*e0c4386eSCy Schubert    subtest "signing with xoflen is not supported `dgst` CLI" => sub {
240*e0c4386eSCy Schubert        plan tests => 1;
241*e0c4386eSCy Schubert        my $data_to_sign = srctop_file('test', 'data.bin');
242*e0c4386eSCy Schubert
243*e0c4386eSCy Schubert        ok(!run(app(['openssl', 'dgst', '-shake256', '-xoflen', '64',
244*e0c4386eSCy Schubert                     '-sign', srctop_file("test","testec-p256.pem"),
245*e0c4386eSCy Schubert                     '-out', 'test.sig',
246*e0c4386eSCy Schubert                     srctop_file('test', 'data.bin')])),
247*e0c4386eSCy Schubert                     "Generating signature with xoflen should fail");
248*e0c4386eSCy Schubert    }
249*e0c4386eSCy Schubert}
250