xref: /freebsd/crypto/openssl/test/dsatest.c (revision 44096ebd22ddd0081a357011714eff8963614b65)
1e0c4386eSCy Schubert /*
2*44096ebdSEnji Cooper  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
3e0c4386eSCy Schubert  *
4e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
6e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
7e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
8e0c4386eSCy Schubert  */
9e0c4386eSCy Schubert 
10e0c4386eSCy Schubert /*
11e0c4386eSCy Schubert  * DSA low level APIs are deprecated for public use, but still ok for
12e0c4386eSCy Schubert  * internal use.
13e0c4386eSCy Schubert  */
14e0c4386eSCy Schubert #include "internal/deprecated.h"
15e0c4386eSCy Schubert 
16e0c4386eSCy Schubert #include <stdio.h>
17e0c4386eSCy Schubert #include <stdlib.h>
18e0c4386eSCy Schubert #include <string.h>
19e0c4386eSCy Schubert #include <sys/types.h>
20e0c4386eSCy Schubert #include <sys/stat.h>
21e0c4386eSCy Schubert 
22e0c4386eSCy Schubert #include <openssl/crypto.h>
23e0c4386eSCy Schubert #include <openssl/rand.h>
24e0c4386eSCy Schubert #include <openssl/bn.h>
25e0c4386eSCy Schubert #include <openssl/dsa.h>
26e0c4386eSCy Schubert #include <openssl/evp.h>
27e0c4386eSCy Schubert #include <openssl/core_names.h>
28e0c4386eSCy Schubert 
29e0c4386eSCy Schubert #include "testutil.h"
30e0c4386eSCy Schubert #include "internal/nelem.h"
31e0c4386eSCy Schubert 
32e0c4386eSCy Schubert #ifndef OPENSSL_NO_DSA
33e0c4386eSCy Schubert static int dsa_cb(int p, int n, BN_GENCB *arg);
34e0c4386eSCy Schubert 
35e0c4386eSCy Schubert static unsigned char out_p[] = {
36e0c4386eSCy Schubert     0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa,
37e0c4386eSCy Schubert     0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb,
38e0c4386eSCy Schubert     0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7,
39e0c4386eSCy Schubert     0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5,
40e0c4386eSCy Schubert     0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf,
41e0c4386eSCy Schubert     0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac,
42e0c4386eSCy Schubert     0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2,
43e0c4386eSCy Schubert     0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
44e0c4386eSCy Schubert };
45e0c4386eSCy Schubert static unsigned char out_q[] = {
46e0c4386eSCy Schubert     0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee,
47e0c4386eSCy Schubert     0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e,
48e0c4386eSCy Schubert     0xda, 0xce, 0x91, 0x5f,
49e0c4386eSCy Schubert };
50e0c4386eSCy Schubert static unsigned char out_g[] = {
51e0c4386eSCy Schubert     0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13,
52e0c4386eSCy Schubert     0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00,
53e0c4386eSCy Schubert     0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb,
54e0c4386eSCy Schubert     0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e,
55e0c4386eSCy Schubert     0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf,
56e0c4386eSCy Schubert     0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c,
57e0c4386eSCy Schubert     0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c,
58e0c4386eSCy Schubert     0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
59e0c4386eSCy Schubert };
60e0c4386eSCy Schubert 
61e0c4386eSCy Schubert static int dsa_test(void)
62e0c4386eSCy Schubert {
63e0c4386eSCy Schubert     BN_GENCB *cb;
64e0c4386eSCy Schubert     DSA *dsa = NULL;
65e0c4386eSCy Schubert     int counter, ret = 0, i, j;
66e0c4386eSCy Schubert     unsigned char buf[256];
67e0c4386eSCy Schubert     unsigned long h;
68e0c4386eSCy Schubert     unsigned char sig[256];
69e0c4386eSCy Schubert     unsigned int siglen;
70e0c4386eSCy Schubert     const BIGNUM *p = NULL, *q = NULL, *g = NULL;
71e0c4386eSCy Schubert     /*
72e0c4386eSCy Schubert      * seed, out_p, out_q, out_g are taken from the updated Appendix 5 to FIPS
73e0c4386eSCy Schubert      * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1
74e0c4386eSCy Schubert      */
75e0c4386eSCy Schubert     static unsigned char seed[20] = {
76e0c4386eSCy Schubert         0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8,
77e0c4386eSCy Schubert         0xb6, 0x21, 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24,
78e0c4386eSCy Schubert         0xe0, 0x42, 0x7d, 0xd3,
79e0c4386eSCy Schubert     };
80e0c4386eSCy Schubert     static const unsigned char str1[] = "12345678901234567890";
81e0c4386eSCy Schubert 
82e0c4386eSCy Schubert     if (!TEST_ptr(cb = BN_GENCB_new()))
83e0c4386eSCy Schubert         goto end;
84e0c4386eSCy Schubert 
85e0c4386eSCy Schubert     BN_GENCB_set(cb, dsa_cb, NULL);
86e0c4386eSCy Schubert     if (!TEST_ptr(dsa = DSA_new())
87e0c4386eSCy Schubert         || !TEST_true(DSA_generate_parameters_ex(dsa, 512, seed, 20,
88e0c4386eSCy Schubert                                                 &counter, &h, cb)))
89e0c4386eSCy Schubert         goto end;
90e0c4386eSCy Schubert 
91e0c4386eSCy Schubert     if (!TEST_int_eq(counter, 105))
92e0c4386eSCy Schubert         goto end;
93e0c4386eSCy Schubert     if (!TEST_int_eq(h, 2))
94e0c4386eSCy Schubert         goto end;
95e0c4386eSCy Schubert 
96e0c4386eSCy Schubert     DSA_get0_pqg(dsa, &p, &q, &g);
97e0c4386eSCy Schubert     i = BN_bn2bin(q, buf);
98e0c4386eSCy Schubert     j = sizeof(out_q);
99e0c4386eSCy Schubert     if (!TEST_int_eq(i, j) || !TEST_mem_eq(buf, i, out_q, i))
100e0c4386eSCy Schubert         goto end;
101e0c4386eSCy Schubert 
102e0c4386eSCy Schubert     i = BN_bn2bin(p, buf);
103e0c4386eSCy Schubert     j = sizeof(out_p);
104e0c4386eSCy Schubert     if (!TEST_int_eq(i, j) || !TEST_mem_eq(buf, i, out_p, i))
105e0c4386eSCy Schubert         goto end;
106e0c4386eSCy Schubert 
107e0c4386eSCy Schubert     i = BN_bn2bin(g, buf);
108e0c4386eSCy Schubert     j = sizeof(out_g);
109e0c4386eSCy Schubert     if (!TEST_int_eq(i, j) || !TEST_mem_eq(buf, i, out_g, i))
110e0c4386eSCy Schubert         goto end;
111e0c4386eSCy Schubert 
112e0c4386eSCy Schubert     if (!TEST_true(DSA_generate_key(dsa)))
113e0c4386eSCy Schubert         goto end;
114e0c4386eSCy Schubert     if (!TEST_true(DSA_sign(0, str1, 20, sig, &siglen, dsa)))
115e0c4386eSCy Schubert         goto end;
116e0c4386eSCy Schubert     if (TEST_int_gt(DSA_verify(0, str1, 20, sig, siglen, dsa), 0))
117e0c4386eSCy Schubert         ret = 1;
118e0c4386eSCy Schubert  end:
119e0c4386eSCy Schubert     DSA_free(dsa);
120e0c4386eSCy Schubert     BN_GENCB_free(cb);
121e0c4386eSCy Schubert     return ret;
122e0c4386eSCy Schubert }
123e0c4386eSCy Schubert 
124e0c4386eSCy Schubert static int dsa_cb(int p, int n, BN_GENCB *arg)
125e0c4386eSCy Schubert {
126e0c4386eSCy Schubert     static int ok = 0, num = 0;
127e0c4386eSCy Schubert 
128e0c4386eSCy Schubert     if (p == 0)
129e0c4386eSCy Schubert         num++;
130e0c4386eSCy Schubert     if (p == 2)
131e0c4386eSCy Schubert         ok++;
132e0c4386eSCy Schubert 
133e0c4386eSCy Schubert     if (!ok && (p == 0) && (num > 1)) {
134e0c4386eSCy Schubert         TEST_error("dsa_cb error");
135e0c4386eSCy Schubert         return 0;
136e0c4386eSCy Schubert     }
137e0c4386eSCy Schubert     return 1;
138e0c4386eSCy Schubert }
139e0c4386eSCy Schubert 
140e0c4386eSCy Schubert # define P      0
141e0c4386eSCy Schubert # define Q      1
142e0c4386eSCy Schubert # define G      2
143e0c4386eSCy Schubert # define SEED   3
144e0c4386eSCy Schubert # define PCOUNT 4
145e0c4386eSCy Schubert # define GINDEX 5
146e0c4386eSCy Schubert # define HCOUNT 6
147e0c4386eSCy Schubert # define GROUP  7
148e0c4386eSCy Schubert 
149e0c4386eSCy Schubert static int dsa_keygen_test(void)
150e0c4386eSCy Schubert {
151e0c4386eSCy Schubert     int ret = 0;
152e0c4386eSCy Schubert     EVP_PKEY *param_key = NULL, *key = NULL;
153e0c4386eSCy Schubert     EVP_PKEY_CTX *pg_ctx = NULL, *kg_ctx = NULL;
154e0c4386eSCy Schubert     BIGNUM *p_in = NULL, *q_in = NULL, *g_in = NULL;
155e0c4386eSCy Schubert     BIGNUM *p_out = NULL, *q_out = NULL, *g_out = NULL;
156e0c4386eSCy Schubert     int gindex_out = 0, pcount_out = 0, hcount_out = 0;
157e0c4386eSCy Schubert     unsigned char seed_out[32];
158e0c4386eSCy Schubert     char group_out[32];
159e0c4386eSCy Schubert     size_t len = 0;
160e0c4386eSCy Schubert     const OSSL_PARAM *settables = NULL;
161e0c4386eSCy Schubert     static const unsigned char seed_data[] = {
162e0c4386eSCy Schubert         0xa6, 0xf5, 0x28, 0x8c, 0x50, 0x77, 0xa5, 0x68,
163e0c4386eSCy Schubert         0x6d, 0x3a, 0xf5, 0xf1, 0xc6, 0x4c, 0xdc, 0x35,
164e0c4386eSCy Schubert         0x95, 0x26, 0x3f, 0x03, 0xdc, 0x00, 0x3f, 0x44,
165e0c4386eSCy Schubert         0x7b, 0x2a, 0xc7, 0x29
166e0c4386eSCy Schubert     };
167e0c4386eSCy Schubert     static const unsigned char expected_p[]= {
168e0c4386eSCy Schubert         0xdb, 0x47, 0x07, 0xaf, 0xf0, 0x06, 0x49, 0x55,
169e0c4386eSCy Schubert         0xc9, 0xbb, 0x09, 0x41, 0xb8, 0xdb, 0x1f, 0xbc,
170e0c4386eSCy Schubert         0xa8, 0xed, 0x12, 0x06, 0x7f, 0x88, 0x49, 0xb8,
171e0c4386eSCy Schubert         0xc9, 0x12, 0x87, 0x21, 0xbb, 0x08, 0x6c, 0xbd,
172e0c4386eSCy Schubert         0xf1, 0x89, 0xef, 0x84, 0xd9, 0x7a, 0x93, 0xe8,
173e0c4386eSCy Schubert         0x45, 0x40, 0x81, 0xec, 0x37, 0x27, 0x1a, 0xa4,
174e0c4386eSCy Schubert         0x22, 0x51, 0x99, 0xf0, 0xde, 0x04, 0xdb, 0xea,
175e0c4386eSCy Schubert         0xa1, 0xf9, 0x37, 0x83, 0x80, 0x96, 0x36, 0x53,
176e0c4386eSCy Schubert         0xf6, 0xae, 0x14, 0x73, 0x33, 0x0f, 0xdf, 0x0b,
177e0c4386eSCy Schubert         0xf9, 0x2f, 0x08, 0x46, 0x31, 0xf9, 0x66, 0xcd,
178e0c4386eSCy Schubert         0x5a, 0xeb, 0x6c, 0xf3, 0xbb, 0x74, 0xf3, 0x88,
179e0c4386eSCy Schubert         0xf0, 0x31, 0x5c, 0xa4, 0xc8, 0x0f, 0x86, 0xf3,
180e0c4386eSCy Schubert         0x0f, 0x9f, 0xc0, 0x8c, 0x57, 0xe4, 0x7f, 0x95,
181e0c4386eSCy Schubert         0xb3, 0x62, 0xc8, 0x4e, 0xae, 0xf3, 0xd8, 0x14,
182e0c4386eSCy Schubert         0xcc, 0x47, 0xc2, 0x4b, 0x4f, 0xef, 0xaf, 0xcd,
183e0c4386eSCy Schubert         0xcf, 0xb2, 0xbb, 0xe8, 0xbe, 0x08, 0xca, 0x15,
184e0c4386eSCy Schubert         0x90, 0x59, 0x35, 0xef, 0x35, 0x1c, 0xfe, 0xeb,
185e0c4386eSCy Schubert         0x33, 0x2e, 0x25, 0x22, 0x57, 0x9c, 0x55, 0x23,
186e0c4386eSCy Schubert         0x0c, 0x6f, 0xed, 0x7c, 0xb6, 0xc7, 0x36, 0x0b,
187e0c4386eSCy Schubert         0xcb, 0x2b, 0x6a, 0x21, 0xa1, 0x1d, 0x55, 0x77,
188e0c4386eSCy Schubert         0xd9, 0x91, 0xcd, 0xc1, 0xcd, 0x3d, 0x82, 0x16,
189e0c4386eSCy Schubert         0x9c, 0xa0, 0x13, 0xa5, 0x83, 0x55, 0x3a, 0x73,
190e0c4386eSCy Schubert         0x7e, 0x2c, 0x44, 0x3e, 0x70, 0x2e, 0x50, 0x91,
191e0c4386eSCy Schubert         0x6e, 0xca, 0x3b, 0xef, 0xff, 0x85, 0x35, 0x70,
192e0c4386eSCy Schubert         0xff, 0x61, 0x0c, 0xb1, 0xb2, 0xb7, 0x94, 0x6f,
193e0c4386eSCy Schubert         0x65, 0xa4, 0x57, 0x62, 0xef, 0x21, 0x83, 0x0f,
194e0c4386eSCy Schubert         0x3e, 0x71, 0xae, 0x7d, 0xe4, 0xad, 0xfb, 0xe3,
195e0c4386eSCy Schubert         0xdd, 0xd6, 0x03, 0xda, 0x9a, 0xd8, 0x8f, 0x2d,
196e0c4386eSCy Schubert         0xbb, 0x90, 0x87, 0xf8, 0xdb, 0xdc, 0xec, 0x71,
197e0c4386eSCy Schubert         0xf2, 0xdb, 0x0b, 0x8e, 0xfc, 0x1a, 0x7e, 0x79,
198e0c4386eSCy Schubert         0xb1, 0x1b, 0x0d, 0xfc, 0x70, 0xec, 0x85, 0xc2,
199e0c4386eSCy Schubert         0xc5, 0xba, 0xb9, 0x69, 0x3f, 0x88, 0xbc, 0xcb
200e0c4386eSCy Schubert     };
201e0c4386eSCy Schubert     static const unsigned char expected_q[]= {
202e0c4386eSCy Schubert         0x99, 0xb6, 0xa0, 0xee, 0xb3, 0xa6, 0x99, 0x1a,
203e0c4386eSCy Schubert         0xb6, 0x67, 0x8d, 0xc1, 0x2b, 0x9b, 0xce, 0x2b,
204e0c4386eSCy Schubert         0x01, 0x72, 0x5a, 0x65, 0x76, 0x3d, 0x93, 0x69,
205e0c4386eSCy Schubert         0xe2, 0x56, 0xae, 0xd7
206e0c4386eSCy Schubert     };
207e0c4386eSCy Schubert     static const unsigned char expected_g[]= {
208e0c4386eSCy Schubert         0x63, 0xf8, 0xb6, 0xee, 0x2a, 0x27, 0xaf, 0x4f,
209e0c4386eSCy Schubert         0x4c, 0xf6, 0x08, 0x28, 0x87, 0x4a, 0xe7, 0x1f,
210e0c4386eSCy Schubert         0x45, 0x46, 0x27, 0x52, 0x3b, 0x7f, 0x6f, 0xd2,
211e0c4386eSCy Schubert         0x29, 0xcb, 0xe8, 0x11, 0x19, 0x25, 0x35, 0x76,
212e0c4386eSCy Schubert         0x99, 0xcb, 0x4f, 0x1b, 0xe0, 0xed, 0x32, 0x9e,
213e0c4386eSCy Schubert         0x05, 0xb5, 0xbe, 0xd7, 0xf6, 0x5a, 0xb2, 0xf6,
214e0c4386eSCy Schubert         0x0e, 0x0c, 0x7e, 0xf5, 0xe1, 0x05, 0xfe, 0xda,
215e0c4386eSCy Schubert         0xaf, 0x0f, 0x27, 0x1e, 0x40, 0x2a, 0xf7, 0xa7,
216e0c4386eSCy Schubert         0x23, 0x49, 0x2c, 0xd9, 0x1b, 0x0a, 0xbe, 0xff,
217e0c4386eSCy Schubert         0xc7, 0x7c, 0x7d, 0x60, 0xca, 0xa3, 0x19, 0xc3,
218e0c4386eSCy Schubert         0xb7, 0xe4, 0x43, 0xb0, 0xf5, 0x75, 0x44, 0x90,
219e0c4386eSCy Schubert         0x46, 0x47, 0xb1, 0xa6, 0x48, 0x0b, 0x21, 0x8e,
220e0c4386eSCy Schubert         0xee, 0x75, 0xe6, 0x3d, 0xa7, 0xd3, 0x7b, 0x31,
221e0c4386eSCy Schubert         0xd1, 0xd2, 0x9d, 0xe2, 0x8a, 0xfc, 0x57, 0xfd,
222e0c4386eSCy Schubert         0x8a, 0x10, 0x31, 0xeb, 0x87, 0x36, 0x3f, 0x65,
223e0c4386eSCy Schubert         0x72, 0x23, 0x2c, 0xd3, 0xd6, 0x17, 0xa5, 0x62,
224e0c4386eSCy Schubert         0x58, 0x65, 0x57, 0x6a, 0xd4, 0xa8, 0xfe, 0xec,
225e0c4386eSCy Schubert         0x57, 0x76, 0x0c, 0xb1, 0x4c, 0x93, 0xed, 0xb0,
226e0c4386eSCy Schubert         0xb4, 0xf9, 0x45, 0xb3, 0x3e, 0xdd, 0x47, 0xf1,
227e0c4386eSCy Schubert         0xfb, 0x7d, 0x25, 0x79, 0x3d, 0xfc, 0xa7, 0x39,
228e0c4386eSCy Schubert         0x90, 0x68, 0x6a, 0x6b, 0xae, 0xf2, 0x6e, 0x64,
229e0c4386eSCy Schubert         0x8c, 0xfb, 0xb8, 0xdd, 0x76, 0x4e, 0x4a, 0x69,
230e0c4386eSCy Schubert         0x8c, 0x97, 0x15, 0x77, 0xb2, 0x67, 0xdc, 0xeb,
231e0c4386eSCy Schubert         0x4a, 0x40, 0x6b, 0xb9, 0x47, 0x8f, 0xa6, 0xab,
232e0c4386eSCy Schubert         0x6e, 0x98, 0xc0, 0x97, 0x9a, 0x0c, 0xea, 0x00,
233e0c4386eSCy Schubert         0xfd, 0x56, 0x1a, 0x74, 0x9a, 0x32, 0x6b, 0xfe,
234e0c4386eSCy Schubert         0xbd, 0xdf, 0x6c, 0x82, 0x54, 0x53, 0x4d, 0x70,
235e0c4386eSCy Schubert         0x65, 0xe3, 0x8b, 0x37, 0xb8, 0xe4, 0x70, 0x08,
236e0c4386eSCy Schubert         0xb7, 0x3b, 0x30, 0x27, 0xaf, 0x1c, 0x77, 0xf3,
237e0c4386eSCy Schubert         0x62, 0xd4, 0x9a, 0x59, 0xba, 0xd1, 0x6e, 0x89,
238e0c4386eSCy Schubert         0x5c, 0x34, 0x9a, 0xa1, 0xb7, 0x4f, 0x7d, 0x8c,
239e0c4386eSCy Schubert         0xdc, 0xbc, 0x74, 0x25, 0x5e, 0xbf, 0x77, 0x46
240e0c4386eSCy Schubert     };
241e0c4386eSCy Schubert     int expected_c = 1316;
242e0c4386eSCy Schubert     int expected_h = 2;
243e0c4386eSCy Schubert 
244e0c4386eSCy Schubert     if (!TEST_ptr(p_in = BN_bin2bn(expected_p, sizeof(expected_p), NULL))
245e0c4386eSCy Schubert         || !TEST_ptr(q_in = BN_bin2bn(expected_q, sizeof(expected_q), NULL))
246e0c4386eSCy Schubert         || !TEST_ptr(g_in = BN_bin2bn(expected_g, sizeof(expected_g), NULL)))
247e0c4386eSCy Schubert         goto end;
248e0c4386eSCy Schubert     if (!TEST_ptr(pg_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
249e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_paramgen_init(pg_ctx), 0)
250e0c4386eSCy Schubert         || !TEST_ptr_null(EVP_PKEY_CTX_gettable_params(pg_ctx))
251e0c4386eSCy Schubert         || !TEST_ptr(settables = EVP_PKEY_CTX_settable_params(pg_ctx))
252e0c4386eSCy Schubert         || !TEST_ptr(OSSL_PARAM_locate_const(settables,
253e0c4386eSCy Schubert                                              OSSL_PKEY_PARAM_FFC_PBITS))
254e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_type(pg_ctx, "fips186_4"))
255e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(pg_ctx, 2048))
256e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(pg_ctx, 224))
257e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_seed(pg_ctx, seed_data,
258e0c4386eSCy Schubert                                                          sizeof(seed_data)))
259e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_md_props(pg_ctx, "SHA256",
260e0c4386eSCy Schubert                                                              ""))
261e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_generate(pg_ctx, &param_key), 0)
262e0c4386eSCy Schubert         || !TEST_ptr(kg_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL))
263e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_keygen_init(kg_ctx), 0)
264e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_generate(kg_ctx, &key), 0))
265e0c4386eSCy Schubert         goto end;
266e0c4386eSCy Schubert 
267e0c4386eSCy Schubert     if (!TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_P, &p_out))
268e0c4386eSCy Schubert         || !TEST_BN_eq(p_in, p_out)
269e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_Q, &q_out))
270e0c4386eSCy Schubert         || !TEST_BN_eq(q_in, q_out)
271e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_G, &g_out))
272e0c4386eSCy Schubert         || !TEST_BN_eq(g_in, g_out)
273e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_octet_string_param(
274e0c4386eSCy Schubert                           key, OSSL_PKEY_PARAM_FFC_SEED, seed_out,
275e0c4386eSCy Schubert                           sizeof(seed_out), &len))
276e0c4386eSCy Schubert         || !TEST_mem_eq(seed_out, len, seed_data, sizeof(seed_data))
277e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_int_param(key, OSSL_PKEY_PARAM_FFC_GINDEX,
278e0c4386eSCy Schubert                                              &gindex_out))
279e0c4386eSCy Schubert         || !TEST_int_eq(gindex_out, -1)
280e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_int_param(key, OSSL_PKEY_PARAM_FFC_H,
281e0c4386eSCy Schubert                                              &hcount_out))
282e0c4386eSCy Schubert         || !TEST_int_eq(hcount_out, expected_h)
283e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_int_param(key,
284e0c4386eSCy Schubert                                              OSSL_PKEY_PARAM_FFC_PCOUNTER,
285e0c4386eSCy Schubert                                              &pcount_out))
286e0c4386eSCy Schubert         || !TEST_int_eq(pcount_out, expected_c)
287e0c4386eSCy Schubert         || !TEST_false(EVP_PKEY_get_utf8_string_param(key,
288e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
289e0c4386eSCy Schubert                                                       group_out,
290e0c4386eSCy Schubert                                                       sizeof(group_out), &len)))
291e0c4386eSCy Schubert         goto end;
292e0c4386eSCy Schubert     ret = 1;
293e0c4386eSCy Schubert end:
294e0c4386eSCy Schubert     BN_free(p_in);
295e0c4386eSCy Schubert     BN_free(q_in);
296e0c4386eSCy Schubert     BN_free(g_in);
297e0c4386eSCy Schubert     BN_free(p_out);
298e0c4386eSCy Schubert     BN_free(q_out);
299e0c4386eSCy Schubert     BN_free(g_out);
300e0c4386eSCy Schubert     EVP_PKEY_free(param_key);
301e0c4386eSCy Schubert     EVP_PKEY_free(key);
302e0c4386eSCy Schubert     EVP_PKEY_CTX_free(kg_ctx);
303e0c4386eSCy Schubert     EVP_PKEY_CTX_free(pg_ctx);
304e0c4386eSCy Schubert     return ret;
305e0c4386eSCy Schubert }
306e0c4386eSCy Schubert 
307e0c4386eSCy Schubert static int test_dsa_default_paramgen_validate(int i)
308e0c4386eSCy Schubert {
309e0c4386eSCy Schubert     int ret;
310e0c4386eSCy Schubert     EVP_PKEY_CTX *gen_ctx = NULL;
311e0c4386eSCy Schubert     EVP_PKEY_CTX *check_ctx = NULL;
312e0c4386eSCy Schubert     EVP_PKEY *params = NULL;
313e0c4386eSCy Schubert 
314e0c4386eSCy Schubert     ret = TEST_ptr(gen_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
315e0c4386eSCy Schubert           && TEST_int_gt(EVP_PKEY_paramgen_init(gen_ctx), 0)
316e0c4386eSCy Schubert           && (i == 0
317e0c4386eSCy Schubert               || TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(gen_ctx, 512)))
318e0c4386eSCy Schubert           && TEST_int_gt(EVP_PKEY_generate(gen_ctx, &params), 0)
319e0c4386eSCy Schubert           && TEST_ptr(check_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, params, NULL))
320e0c4386eSCy Schubert           && TEST_int_gt(EVP_PKEY_param_check(check_ctx), 0);
321e0c4386eSCy Schubert 
322e0c4386eSCy Schubert     EVP_PKEY_free(params);
323e0c4386eSCy Schubert     EVP_PKEY_CTX_free(check_ctx);
324e0c4386eSCy Schubert     EVP_PKEY_CTX_free(gen_ctx);
325e0c4386eSCy Schubert     return ret;
326e0c4386eSCy Schubert }
327e0c4386eSCy Schubert 
328e0c4386eSCy Schubert static int test_dsa_sig_infinite_loop(void)
329e0c4386eSCy Schubert {
330e0c4386eSCy Schubert     int ret = 0;
331e0c4386eSCy Schubert     DSA *dsa = NULL;
332e0c4386eSCy Schubert     BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv = NULL, *pub = NULL, *priv2 = NULL;
333e0c4386eSCy Schubert     BIGNUM *badq = NULL, *badpriv = NULL;
334e0c4386eSCy Schubert     const unsigned char msg[] = { 0x00 };
335*44096ebdSEnji Cooper     unsigned int signature_len0;
336e0c4386eSCy Schubert     unsigned int signature_len;
337e0c4386eSCy Schubert     unsigned char signature[64];
338e0c4386eSCy Schubert 
339e0c4386eSCy Schubert     static unsigned char out_priv[] = {
340e0c4386eSCy Schubert         0x17, 0x00, 0xb2, 0x8d, 0xcb, 0x24, 0xc9, 0x98,
341e0c4386eSCy Schubert         0xd0, 0x7f, 0x1f, 0x83, 0x1a, 0xa1, 0xc4, 0xa4,
342e0c4386eSCy Schubert         0xf8, 0x0f, 0x7f, 0x12
343e0c4386eSCy Schubert     };
344e0c4386eSCy Schubert     static unsigned char out_pub[] = {
345e0c4386eSCy Schubert         0x04, 0x72, 0xee, 0x8d, 0xaa, 0x4d, 0x89, 0x60,
346e0c4386eSCy Schubert         0x0e, 0xb2, 0xd4, 0x38, 0x84, 0xa2, 0x2a, 0x60,
347e0c4386eSCy Schubert         0x5f, 0x67, 0xd7, 0x9e, 0x24, 0xdd, 0xe8, 0x50,
348e0c4386eSCy Schubert         0xf2, 0x23, 0x71, 0x55, 0x53, 0x94, 0x0d, 0x6b,
349e0c4386eSCy Schubert         0x2e, 0xcd, 0x30, 0xda, 0x6f, 0x1e, 0x2c, 0xcf,
350e0c4386eSCy Schubert         0x59, 0xbe, 0x05, 0x6c, 0x07, 0x0e, 0xc6, 0x38,
351e0c4386eSCy Schubert         0x05, 0xcb, 0x0c, 0x44, 0x0a, 0x08, 0x13, 0xb6,
352e0c4386eSCy Schubert         0x0f, 0x14, 0xde, 0x4a, 0xf6, 0xed, 0x4e, 0xc3
353e0c4386eSCy Schubert     };
354e0c4386eSCy Schubert     if (!TEST_ptr(p = BN_bin2bn(out_p, sizeof(out_p), NULL))
355e0c4386eSCy Schubert         || !TEST_ptr(q = BN_bin2bn(out_q, sizeof(out_q), NULL))
356e0c4386eSCy Schubert         || !TEST_ptr(g = BN_bin2bn(out_g, sizeof(out_g), NULL))
357e0c4386eSCy Schubert         || !TEST_ptr(pub = BN_bin2bn(out_pub, sizeof(out_pub), NULL))
358e0c4386eSCy Schubert         || !TEST_ptr(priv = BN_bin2bn(out_priv, sizeof(out_priv), NULL))
359e0c4386eSCy Schubert         || !TEST_ptr(priv2 = BN_dup(priv))
360e0c4386eSCy Schubert         || !TEST_ptr(badq = BN_new())
361e0c4386eSCy Schubert         || !TEST_true(BN_set_word(badq, 1))
362e0c4386eSCy Schubert         || !TEST_ptr(badpriv = BN_new())
363e0c4386eSCy Schubert         || !TEST_true(BN_set_word(badpriv, 0))
364e0c4386eSCy Schubert         || !TEST_ptr(dsa = DSA_new()))
365e0c4386eSCy Schubert         goto err;
366e0c4386eSCy Schubert 
367e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_pqg(dsa, p, q, g)))
368e0c4386eSCy Schubert         goto err;
369e0c4386eSCy Schubert     p = q = g = NULL;
370e0c4386eSCy Schubert 
371e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_key(dsa, pub, priv)))
372e0c4386eSCy Schubert         goto err;
373e0c4386eSCy Schubert     pub = priv = NULL;
374e0c4386eSCy Schubert 
375e0c4386eSCy Schubert     if (!TEST_int_le(DSA_size(dsa), sizeof(signature)))
376e0c4386eSCy Schubert         goto err;
377e0c4386eSCy Schubert 
378e0c4386eSCy Schubert     /* Test passing signature as NULL */
379*44096ebdSEnji Cooper     if (!TEST_true(DSA_sign(0, msg, sizeof(msg), NULL, &signature_len0, dsa))
380*44096ebdSEnji Cooper         || !TEST_int_gt(signature_len0, 0))
381e0c4386eSCy Schubert         goto err;
382e0c4386eSCy Schubert 
383*44096ebdSEnji Cooper     if (!TEST_true(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa))
384*44096ebdSEnji Cooper         || !TEST_int_gt(signature_len, 0)
385*44096ebdSEnji Cooper         || !TEST_int_le(signature_len, signature_len0))
386e0c4386eSCy Schubert         goto err;
387e0c4386eSCy Schubert 
388e0c4386eSCy Schubert     /* Test using a private key of zero fails - this causes an infinite loop without the retry test */
389e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_key(dsa, NULL, badpriv)))
390e0c4386eSCy Schubert         goto err;
391e0c4386eSCy Schubert     badpriv = NULL;
392e0c4386eSCy Schubert     if (!TEST_false(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa)))
393e0c4386eSCy Schubert         goto err;
394e0c4386eSCy Schubert 
395e0c4386eSCy Schubert     /* Restore private and set a bad q - this caused an infinite loop in the setup */
396e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_key(dsa, NULL, priv2)))
397e0c4386eSCy Schubert         goto err;
398e0c4386eSCy Schubert     priv2 = NULL;
399e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_pqg(dsa, NULL, badq, NULL)))
400e0c4386eSCy Schubert         goto err;
401e0c4386eSCy Schubert     badq = NULL;
402e0c4386eSCy Schubert     if (!TEST_false(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa)))
403e0c4386eSCy Schubert         goto err;
404e0c4386eSCy Schubert 
405e0c4386eSCy Schubert     ret = 1;
406e0c4386eSCy Schubert err:
407e0c4386eSCy Schubert     BN_free(badq);
408e0c4386eSCy Schubert     BN_free(badpriv);
409e0c4386eSCy Schubert     BN_free(pub);
410e0c4386eSCy Schubert     BN_free(priv);
411e0c4386eSCy Schubert     BN_free(priv2);
412e0c4386eSCy Schubert     BN_free(g);
413e0c4386eSCy Schubert     BN_free(q);
414e0c4386eSCy Schubert     BN_free(p);
415e0c4386eSCy Schubert     DSA_free(dsa);
416e0c4386eSCy Schubert     return ret;
417e0c4386eSCy Schubert }
418e0c4386eSCy Schubert 
419e0c4386eSCy Schubert static int test_dsa_sig_neg_param(void)
420e0c4386eSCy Schubert {
421e0c4386eSCy Schubert     int ret = 0, setpqg = 0;
422e0c4386eSCy Schubert     DSA *dsa = NULL;
423e0c4386eSCy Schubert     BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv = NULL, *pub = NULL;
424e0c4386eSCy Schubert     const unsigned char msg[] = { 0x00 };
425e0c4386eSCy Schubert     unsigned int signature_len;
426e0c4386eSCy Schubert     unsigned char signature[64];
427e0c4386eSCy Schubert 
428e0c4386eSCy Schubert     static unsigned char out_priv[] = {
429e0c4386eSCy Schubert         0x17, 0x00, 0xb2, 0x8d, 0xcb, 0x24, 0xc9, 0x98,
430e0c4386eSCy Schubert         0xd0, 0x7f, 0x1f, 0x83, 0x1a, 0xa1, 0xc4, 0xa4,
431e0c4386eSCy Schubert         0xf8, 0x0f, 0x7f, 0x12
432e0c4386eSCy Schubert     };
433e0c4386eSCy Schubert     static unsigned char out_pub[] = {
434e0c4386eSCy Schubert         0x04, 0x72, 0xee, 0x8d, 0xaa, 0x4d, 0x89, 0x60,
435e0c4386eSCy Schubert         0x0e, 0xb2, 0xd4, 0x38, 0x84, 0xa2, 0x2a, 0x60,
436e0c4386eSCy Schubert         0x5f, 0x67, 0xd7, 0x9e, 0x24, 0xdd, 0xe8, 0x50,
437e0c4386eSCy Schubert         0xf2, 0x23, 0x71, 0x55, 0x53, 0x94, 0x0d, 0x6b,
438e0c4386eSCy Schubert         0x2e, 0xcd, 0x30, 0xda, 0x6f, 0x1e, 0x2c, 0xcf,
439e0c4386eSCy Schubert         0x59, 0xbe, 0x05, 0x6c, 0x07, 0x0e, 0xc6, 0x38,
440e0c4386eSCy Schubert         0x05, 0xcb, 0x0c, 0x44, 0x0a, 0x08, 0x13, 0xb6,
441e0c4386eSCy Schubert         0x0f, 0x14, 0xde, 0x4a, 0xf6, 0xed, 0x4e, 0xc3
442e0c4386eSCy Schubert     };
443e0c4386eSCy Schubert     if (!TEST_ptr(p = BN_bin2bn(out_p, sizeof(out_p), NULL))
444e0c4386eSCy Schubert         || !TEST_ptr(q = BN_bin2bn(out_q, sizeof(out_q), NULL))
445e0c4386eSCy Schubert         || !TEST_ptr(g = BN_bin2bn(out_g, sizeof(out_g), NULL))
446e0c4386eSCy Schubert         || !TEST_ptr(pub = BN_bin2bn(out_pub, sizeof(out_pub), NULL))
447e0c4386eSCy Schubert         || !TEST_ptr(priv = BN_bin2bn(out_priv, sizeof(out_priv), NULL))
448e0c4386eSCy Schubert         || !TEST_ptr(dsa = DSA_new()))
449e0c4386eSCy Schubert         goto err;
450e0c4386eSCy Schubert 
451e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_pqg(dsa, p, q, g)))
452e0c4386eSCy Schubert         goto err;
453e0c4386eSCy Schubert     setpqg = 1;
454e0c4386eSCy Schubert 
455e0c4386eSCy Schubert     if (!TEST_true(DSA_set0_key(dsa, pub, priv)))
456e0c4386eSCy Schubert         goto err;
457e0c4386eSCy Schubert     pub = priv = NULL;
458e0c4386eSCy Schubert 
459e0c4386eSCy Schubert     BN_set_negative(p, 1);
460e0c4386eSCy Schubert     if (!TEST_false(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa)))
461e0c4386eSCy Schubert         goto err;
462e0c4386eSCy Schubert 
463e0c4386eSCy Schubert     BN_set_negative(p, 0);
464e0c4386eSCy Schubert     BN_set_negative(q, 1);
465e0c4386eSCy Schubert     if (!TEST_false(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa)))
466e0c4386eSCy Schubert         goto err;
467e0c4386eSCy Schubert 
468e0c4386eSCy Schubert     BN_set_negative(q, 0);
469e0c4386eSCy Schubert     BN_set_negative(g, 1);
470e0c4386eSCy Schubert     if (!TEST_false(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa)))
471e0c4386eSCy Schubert         goto err;
472e0c4386eSCy Schubert 
473e0c4386eSCy Schubert     BN_set_negative(p, 1);
474e0c4386eSCy Schubert     BN_set_negative(q, 1);
475e0c4386eSCy Schubert     BN_set_negative(g, 1);
476e0c4386eSCy Schubert     if (!TEST_false(DSA_sign(0, msg, sizeof(msg), signature, &signature_len, dsa)))
477e0c4386eSCy Schubert         goto err;
478e0c4386eSCy Schubert 
479e0c4386eSCy Schubert     ret = 1;
480e0c4386eSCy Schubert err:
481e0c4386eSCy Schubert     BN_free(pub);
482e0c4386eSCy Schubert     BN_free(priv);
483e0c4386eSCy Schubert 
484e0c4386eSCy Schubert     if (setpqg == 0) {
485e0c4386eSCy Schubert         BN_free(g);
486e0c4386eSCy Schubert         BN_free(q);
487e0c4386eSCy Schubert         BN_free(p);
488e0c4386eSCy Schubert     }
489e0c4386eSCy Schubert     DSA_free(dsa);
490e0c4386eSCy Schubert     return ret;
491e0c4386eSCy Schubert }
492e0c4386eSCy Schubert 
493e0c4386eSCy Schubert #endif /* OPENSSL_NO_DSA */
494e0c4386eSCy Schubert 
495e0c4386eSCy Schubert int setup_tests(void)
496e0c4386eSCy Schubert {
497e0c4386eSCy Schubert #ifndef OPENSSL_NO_DSA
498e0c4386eSCy Schubert     ADD_TEST(dsa_test);
499e0c4386eSCy Schubert     ADD_TEST(dsa_keygen_test);
500e0c4386eSCy Schubert     ADD_TEST(test_dsa_sig_infinite_loop);
501e0c4386eSCy Schubert     ADD_TEST(test_dsa_sig_neg_param);
502e0c4386eSCy Schubert     ADD_ALL_TESTS(test_dsa_default_paramgen_validate, 2);
503e0c4386eSCy Schubert #endif
504e0c4386eSCy Schubert     return 1;
505e0c4386eSCy Schubert }
506