1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci#
4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ciuse strict;
11e1051a39Sopenharmony_ciuse warnings;
12e1051a39Sopenharmony_ci
13e1051a39Sopenharmony_ciuse File::Spec;
14e1051a39Sopenharmony_ciuse OpenSSL::Test qw/:DEFAULT srctop_file/;
15e1051a39Sopenharmony_ciuse OpenSSL::Test::Utils;
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci# 'supported' and 'unsupported' reflect the current state of things.  In
18e1051a39Sopenharmony_ci# Test::More terms, 'supported' works exactly like ok(run(whatever)), while
19e1051a39Sopenharmony_ci# 'unsupported' wraps that in a TODO: { } block.
20e1051a39Sopenharmony_ci#
21e1051a39Sopenharmony_ci# The first argument is the test name (this becomes the last argument to
22e1051a39Sopenharmony_ci# 'ok')
23e1051a39Sopenharmony_ci# The remaining argument are passed unchecked to 'run'.
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci# 1:    the result of app() or similar, i.e. something you can pass to
26e1051a39Sopenharmony_cisub supported_pass {
27e1051a39Sopenharmony_ci    my $str = shift;
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci    ok(run(@_), $str);
30e1051a39Sopenharmony_ci}
31e1051a39Sopenharmony_ci
32e1051a39Sopenharmony_cisub supported_fail {
33e1051a39Sopenharmony_ci    my $str = shift;
34e1051a39Sopenharmony_ci
35e1051a39Sopenharmony_ci    ok(!run(@_), $str);
36e1051a39Sopenharmony_ci}
37e1051a39Sopenharmony_ci
38e1051a39Sopenharmony_cisetup("test_genec");
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_ciplan skip_all => "This test is unsupported in a no-ec build"
41e1051a39Sopenharmony_ci    if disabled("ec");
42e1051a39Sopenharmony_ci
43e1051a39Sopenharmony_cimy @prime_curves = qw(
44e1051a39Sopenharmony_ci    secp112r1
45e1051a39Sopenharmony_ci    secp112r2
46e1051a39Sopenharmony_ci    secp128r1
47e1051a39Sopenharmony_ci    secp128r2
48e1051a39Sopenharmony_ci    secp160k1
49e1051a39Sopenharmony_ci    secp160r1
50e1051a39Sopenharmony_ci    secp160r2
51e1051a39Sopenharmony_ci    secp192k1
52e1051a39Sopenharmony_ci    secp224k1
53e1051a39Sopenharmony_ci    secp224r1
54e1051a39Sopenharmony_ci    secp256k1
55e1051a39Sopenharmony_ci    secp384r1
56e1051a39Sopenharmony_ci    secp521r1
57e1051a39Sopenharmony_ci    prime192v1
58e1051a39Sopenharmony_ci    prime192v2
59e1051a39Sopenharmony_ci    prime192v3
60e1051a39Sopenharmony_ci    prime239v1
61e1051a39Sopenharmony_ci    prime239v2
62e1051a39Sopenharmony_ci    prime239v3
63e1051a39Sopenharmony_ci    prime256v1
64e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls6
65e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls7
66e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls8
67e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls9
68e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls12
69e1051a39Sopenharmony_ci    brainpoolP160r1
70e1051a39Sopenharmony_ci    brainpoolP160t1
71e1051a39Sopenharmony_ci    brainpoolP192r1
72e1051a39Sopenharmony_ci    brainpoolP192t1
73e1051a39Sopenharmony_ci    brainpoolP224r1
74e1051a39Sopenharmony_ci    brainpoolP224t1
75e1051a39Sopenharmony_ci    brainpoolP256r1
76e1051a39Sopenharmony_ci    brainpoolP256t1
77e1051a39Sopenharmony_ci    brainpoolP320r1
78e1051a39Sopenharmony_ci    brainpoolP320t1
79e1051a39Sopenharmony_ci    brainpoolP384r1
80e1051a39Sopenharmony_ci    brainpoolP384t1
81e1051a39Sopenharmony_ci    brainpoolP512r1
82e1051a39Sopenharmony_ci    brainpoolP512t1
83e1051a39Sopenharmony_ci);
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_cimy @binary_curves = qw(
86e1051a39Sopenharmony_ci    sect113r1
87e1051a39Sopenharmony_ci    sect113r2
88e1051a39Sopenharmony_ci    sect131r1
89e1051a39Sopenharmony_ci    sect131r2
90e1051a39Sopenharmony_ci    sect163k1
91e1051a39Sopenharmony_ci    sect163r1
92e1051a39Sopenharmony_ci    sect163r2
93e1051a39Sopenharmony_ci    sect193r1
94e1051a39Sopenharmony_ci    sect193r2
95e1051a39Sopenharmony_ci    sect233k1
96e1051a39Sopenharmony_ci    sect233r1
97e1051a39Sopenharmony_ci    sect239k1
98e1051a39Sopenharmony_ci    sect283k1
99e1051a39Sopenharmony_ci    sect283r1
100e1051a39Sopenharmony_ci    sect409k1
101e1051a39Sopenharmony_ci    sect409r1
102e1051a39Sopenharmony_ci    sect571k1
103e1051a39Sopenharmony_ci    sect571r1
104e1051a39Sopenharmony_ci    c2pnb163v1
105e1051a39Sopenharmony_ci    c2pnb163v2
106e1051a39Sopenharmony_ci    c2pnb163v3
107e1051a39Sopenharmony_ci    c2pnb176v1
108e1051a39Sopenharmony_ci    c2tnb191v1
109e1051a39Sopenharmony_ci    c2tnb191v2
110e1051a39Sopenharmony_ci    c2tnb191v3
111e1051a39Sopenharmony_ci    c2pnb208w1
112e1051a39Sopenharmony_ci    c2tnb239v1
113e1051a39Sopenharmony_ci    c2tnb239v2
114e1051a39Sopenharmony_ci    c2tnb239v3
115e1051a39Sopenharmony_ci    c2pnb272w1
116e1051a39Sopenharmony_ci    c2pnb304w1
117e1051a39Sopenharmony_ci    c2tnb359v1
118e1051a39Sopenharmony_ci    c2pnb368w1
119e1051a39Sopenharmony_ci    c2tnb431r1
120e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls1
121e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls3
122e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls4
123e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls5
124e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls10
125e1051a39Sopenharmony_ci    wap-wsg-idm-ecid-wtls11
126e1051a39Sopenharmony_ci);
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_cimy @explicit_only_curves = ();
129e1051a39Sopenharmony_cipush(@explicit_only_curves, qw(
130e1051a39Sopenharmony_ci        Oakley-EC2N-3
131e1051a39Sopenharmony_ci        Oakley-EC2N-4
132e1051a39Sopenharmony_ci    )) if !disabled("ec2m");
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_cimy @other_curves = ();
135e1051a39Sopenharmony_cipush(@other_curves, 'SM2')
136e1051a39Sopenharmony_ci    if !disabled("sm2");
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_cimy @curve_aliases = qw(
139e1051a39Sopenharmony_ci    P-192
140e1051a39Sopenharmony_ci    P-224
141e1051a39Sopenharmony_ci    P-256
142e1051a39Sopenharmony_ci    P-384
143e1051a39Sopenharmony_ci    P-521
144e1051a39Sopenharmony_ci);
145e1051a39Sopenharmony_cipush(@curve_aliases, qw(
146e1051a39Sopenharmony_ci    B-163
147e1051a39Sopenharmony_ci    B-233
148e1051a39Sopenharmony_ci    B-283
149e1051a39Sopenharmony_ci    B-409
150e1051a39Sopenharmony_ci    B-571
151e1051a39Sopenharmony_ci    K-163
152e1051a39Sopenharmony_ci    K-233
153e1051a39Sopenharmony_ci    K-283
154e1051a39Sopenharmony_ci    K-409
155e1051a39Sopenharmony_ci    K-571
156e1051a39Sopenharmony_ci)) if !disabled("ec2m");
157e1051a39Sopenharmony_ci
158e1051a39Sopenharmony_cimy @curve_list = ();
159e1051a39Sopenharmony_cipush(@curve_list, @prime_curves);
160e1051a39Sopenharmony_cipush(@curve_list, @binary_curves)
161e1051a39Sopenharmony_ci    if !disabled("ec2m");
162e1051a39Sopenharmony_cipush(@curve_list, @other_curves);
163e1051a39Sopenharmony_cipush(@curve_list, @curve_aliases);
164e1051a39Sopenharmony_ci
165e1051a39Sopenharmony_cimy %params_encodings =
166e1051a39Sopenharmony_ci    (
167e1051a39Sopenharmony_ci     'named_curve'      => \&supported_pass,
168e1051a39Sopenharmony_ci     'explicit'         => \&supported_pass
169e1051a39Sopenharmony_ci    );
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_cimy @output_formats = ('PEM', 'DER');
172e1051a39Sopenharmony_ci
173e1051a39Sopenharmony_ciplan tests => scalar(@curve_list) * scalar(keys %params_encodings)
174e1051a39Sopenharmony_ci    * (1 + scalar(@output_formats)) # Try listed @output_formats and text output
175e1051a39Sopenharmony_ci    * 2                             # Test generating parameters and keys
176e1051a39Sopenharmony_ci    + 1                             # Checking that with no curve it fails
177e1051a39Sopenharmony_ci    + 1                             # Checking that with unknown curve it fails
178e1051a39Sopenharmony_ci    + 1                             # Subtest for explicit only curves
179e1051a39Sopenharmony_ci    + 1                             # base serializer test
180e1051a39Sopenharmony_ci    ;
181e1051a39Sopenharmony_ci
182e1051a39Sopenharmony_ciok(!run(app([ 'openssl', 'genpkey',
183e1051a39Sopenharmony_ci              '-algorithm', 'EC'])),
184e1051a39Sopenharmony_ci   "genpkey EC with no params should fail");
185e1051a39Sopenharmony_ci
186e1051a39Sopenharmony_ciok(!run(app([ 'openssl', 'genpkey',
187e1051a39Sopenharmony_ci              '-algorithm', 'EC',
188e1051a39Sopenharmony_ci              '-pkeyopt', 'ec_paramgen_curve:bogus_foobar_curve'])),
189e1051a39Sopenharmony_ci   "genpkey EC with unknown curve name should fail");
190e1051a39Sopenharmony_ci
191e1051a39Sopenharmony_ciok(run(app([ 'openssl', 'genpkey',
192e1051a39Sopenharmony_ci             '-provider-path', 'providers',
193e1051a39Sopenharmony_ci             '-provider', 'base',
194e1051a39Sopenharmony_ci             '-config', srctop_file("test", "default.cnf"),
195e1051a39Sopenharmony_ci             '-algorithm', 'EC',
196e1051a39Sopenharmony_ci             '-pkeyopt', 'ec_paramgen_curve:prime256v1',
197e1051a39Sopenharmony_ci             '-text'])),
198e1051a39Sopenharmony_ci    "generate a private key and serialize it using the base provider");
199e1051a39Sopenharmony_ci
200e1051a39Sopenharmony_ciforeach my $curvename (@curve_list) {
201e1051a39Sopenharmony_ci    foreach my $paramenc (sort keys %params_encodings) {
202e1051a39Sopenharmony_ci        my $fn = $params_encodings{$paramenc};
203e1051a39Sopenharmony_ci
204e1051a39Sopenharmony_ci        # --- Test generating parameters ---
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_ci        $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)",
207e1051a39Sopenharmony_ci              app([ 'openssl', 'genpkey', '-genparam',
208e1051a39Sopenharmony_ci                    '-algorithm', 'EC',
209e1051a39Sopenharmony_ci                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
210e1051a39Sopenharmony_ci                    '-pkeyopt', 'ec_param_enc:'.$paramenc,
211e1051a39Sopenharmony_ci                    '-text']));
212e1051a39Sopenharmony_ci
213e1051a39Sopenharmony_ci        foreach my $outform (@output_formats) {
214e1051a39Sopenharmony_ci            my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
215e1051a39Sopenharmony_ci            $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
216e1051a39Sopenharmony_ci                  app([ 'openssl', 'genpkey', '-genparam',
217e1051a39Sopenharmony_ci                        '-algorithm', 'EC',
218e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
219e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
220e1051a39Sopenharmony_ci                        '-outform', $outform,
221e1051a39Sopenharmony_ci                        '-out', $outfile]));
222e1051a39Sopenharmony_ci        }
223e1051a39Sopenharmony_ci
224e1051a39Sopenharmony_ci        # --- Test generating actual keys ---
225e1051a39Sopenharmony_ci
226e1051a39Sopenharmony_ci        $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)",
227e1051a39Sopenharmony_ci              app([ 'openssl', 'genpkey',
228e1051a39Sopenharmony_ci                    '-algorithm', 'EC',
229e1051a39Sopenharmony_ci                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
230e1051a39Sopenharmony_ci                    '-pkeyopt', 'ec_param_enc:'.$paramenc,
231e1051a39Sopenharmony_ci                    '-text']));
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci        foreach my $outform (@output_formats) {
234e1051a39Sopenharmony_ci            my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
235e1051a39Sopenharmony_ci            $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
236e1051a39Sopenharmony_ci                  app([ 'openssl', 'genpkey',
237e1051a39Sopenharmony_ci                        '-algorithm', 'EC',
238e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
239e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
240e1051a39Sopenharmony_ci                        '-outform', $outform,
241e1051a39Sopenharmony_ci                        '-out', $outfile]));
242e1051a39Sopenharmony_ci        }
243e1051a39Sopenharmony_ci    }
244e1051a39Sopenharmony_ci}
245e1051a39Sopenharmony_ci
246e1051a39Sopenharmony_cisubtest "test curves that only support explicit parameters encoding" => sub {
247e1051a39Sopenharmony_ci    plan skip_all => "This test is unsupported under current configuration"
248e1051a39Sopenharmony_ci            if scalar(@explicit_only_curves) <= 0;
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ci    plan tests => scalar(@explicit_only_curves) * scalar(keys %params_encodings)
251e1051a39Sopenharmony_ci        * (1 + scalar(@output_formats)) # Try listed @output_formats and text output
252e1051a39Sopenharmony_ci        * 2                             # Test generating parameters and keys
253e1051a39Sopenharmony_ci        ;
254e1051a39Sopenharmony_ci
255e1051a39Sopenharmony_ci    my %params_encodings =
256e1051a39Sopenharmony_ci        (
257e1051a39Sopenharmony_ci         'named_curve'      => \&supported_fail,
258e1051a39Sopenharmony_ci         'explicit'         => \&supported_pass
259e1051a39Sopenharmony_ci        );
260e1051a39Sopenharmony_ci
261e1051a39Sopenharmony_ci    foreach my $curvename (@explicit_only_curves) {
262e1051a39Sopenharmony_ci        foreach my $paramenc (sort keys %params_encodings) {
263e1051a39Sopenharmony_ci            my $fn = $params_encodings{$paramenc};
264e1051a39Sopenharmony_ci
265e1051a39Sopenharmony_ci            # --- Test generating parameters ---
266e1051a39Sopenharmony_ci
267e1051a39Sopenharmony_ci            $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)",
268e1051a39Sopenharmony_ci                  app([ 'openssl', 'genpkey', '-genparam',
269e1051a39Sopenharmony_ci                        '-algorithm', 'EC',
270e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
271e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
272e1051a39Sopenharmony_ci                        '-text']));
273e1051a39Sopenharmony_ci
274e1051a39Sopenharmony_ci            foreach my $outform (@output_formats) {
275e1051a39Sopenharmony_ci                my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
276e1051a39Sopenharmony_ci                $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
277e1051a39Sopenharmony_ci                      app([ 'openssl', 'genpkey', '-genparam',
278e1051a39Sopenharmony_ci                            '-algorithm', 'EC',
279e1051a39Sopenharmony_ci                            '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
280e1051a39Sopenharmony_ci                            '-pkeyopt', 'ec_param_enc:'.$paramenc,
281e1051a39Sopenharmony_ci                            '-outform', $outform,
282e1051a39Sopenharmony_ci                            '-out', $outfile]));
283e1051a39Sopenharmony_ci            }
284e1051a39Sopenharmony_ci
285e1051a39Sopenharmony_ci            # --- Test generating actual keys ---
286e1051a39Sopenharmony_ci
287e1051a39Sopenharmony_ci            $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)",
288e1051a39Sopenharmony_ci                  app([ 'openssl', 'genpkey',
289e1051a39Sopenharmony_ci                        '-algorithm', 'EC',
290e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
291e1051a39Sopenharmony_ci                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
292e1051a39Sopenharmony_ci                        '-text']));
293e1051a39Sopenharmony_ci
294e1051a39Sopenharmony_ci            foreach my $outform (@output_formats) {
295e1051a39Sopenharmony_ci                my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
296e1051a39Sopenharmony_ci                $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
297e1051a39Sopenharmony_ci                      app([ 'openssl', 'genpkey',
298e1051a39Sopenharmony_ci                            '-algorithm', 'EC',
299e1051a39Sopenharmony_ci                            '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
300e1051a39Sopenharmony_ci                            '-pkeyopt', 'ec_param_enc:'.$paramenc,
301e1051a39Sopenharmony_ci                            '-outform', $outform,
302e1051a39Sopenharmony_ci                            '-out', $outfile]));
303e1051a39Sopenharmony_ci            }
304e1051a39Sopenharmony_ci        }
305e1051a39Sopenharmony_ci    }
306e1051a39Sopenharmony_ci};
307