1 /*
2  * Copyright 1995-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 /*
11  * DSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 
22 #include <openssl/crypto.h>
23 #include <openssl/rand.h>
24 #include <openssl/bn.h>
25 #include <openssl/dsa.h>
26 #include <openssl/evp.h>
27 #include <openssl/core_names.h>
28 
29 #include "testutil.h"
30 #include "internal/nelem.h"
31 
32 #ifndef OPENSSL_NO_DSA
33 static int dsa_cb(int p, int n, BN_GENCB *arg);
34 
dsa_test(void)35 static int dsa_test(void)
36 {
37     BN_GENCB *cb;
38     DSA *dsa = NULL;
39     int counter, ret = 0, i, j;
40     unsigned char buf[256];
41     unsigned long h;
42     unsigned char sig[256];
43     unsigned int siglen;
44     const BIGNUM *p = NULL, *q = NULL, *g = NULL;
45     /*
46      * seed, out_p, out_q, out_g are taken from the updated Appendix 5 to FIPS
47      * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1
48      */
49     static unsigned char seed[20] = {
50         0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8,
51         0xb6, 0x21, 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24,
52         0xe0, 0x42, 0x7d, 0xd3,
53     };
54     static unsigned char out_p[] = {
55         0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa,
56         0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb,
57         0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7,
58         0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5,
59         0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf,
60         0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac,
61         0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2,
62         0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
63     };
64     static unsigned char out_q[] = {
65         0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee,
66         0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e,
67         0xda, 0xce, 0x91, 0x5f,
68     };
69     static unsigned char out_g[] = {
70         0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13,
71         0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00,
72         0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb,
73         0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e,
74         0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf,
75         0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c,
76         0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c,
77         0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
78     };
79     static const unsigned char str1[] = "12345678901234567890";
80 
81     if (!TEST_ptr(cb = BN_GENCB_new()))
82         goto end;
83 
84     BN_GENCB_set(cb, dsa_cb, NULL);
85     if (!TEST_ptr(dsa = DSA_new())
86         || !TEST_true(DSA_generate_parameters_ex(dsa, 512, seed, 20,
87                                                 &counter, &h, cb)))
88         goto end;
89 
90     if (!TEST_int_eq(counter, 105))
91         goto end;
92     if (!TEST_int_eq(h, 2))
93         goto end;
94 
95     DSA_get0_pqg(dsa, &p, &q, &g);
96     i = BN_bn2bin(q, buf);
97     j = sizeof(out_q);
98     if (!TEST_int_eq(i, j) || !TEST_mem_eq(buf, i, out_q, i))
99         goto end;
100 
101     i = BN_bn2bin(p, buf);
102     j = sizeof(out_p);
103     if (!TEST_int_eq(i, j) || !TEST_mem_eq(buf, i, out_p, i))
104         goto end;
105 
106     i = BN_bn2bin(g, buf);
107     j = sizeof(out_g);
108     if (!TEST_int_eq(i, j) || !TEST_mem_eq(buf, i, out_g, i))
109         goto end;
110 
111     if (!TEST_true(DSA_generate_key(dsa)))
112         goto end;
113     if (!TEST_true(DSA_sign(0, str1, 20, sig, &siglen, dsa)))
114         goto end;
115     if (TEST_int_gt(DSA_verify(0, str1, 20, sig, siglen, dsa), 0))
116         ret = 1;
117 
118  end:
119     DSA_free(dsa);
120     BN_GENCB_free(cb);
121     return ret;
122 }
123 
dsa_cb(int p,int n,BN_GENCB * arg)124 static int dsa_cb(int p, int n, BN_GENCB *arg)
125 {
126     static int ok = 0, num = 0;
127 
128     if (p == 0)
129         num++;
130     if (p == 2)
131         ok++;
132 
133     if (!ok && (p == 0) && (num > 1)) {
134         TEST_error("dsa_cb error");
135         return 0;
136     }
137     return 1;
138 }
139 
140 # define P      0
141 # define Q      1
142 # define G      2
143 # define SEED   3
144 # define PCOUNT 4
145 # define GINDEX 5
146 # define HCOUNT 6
147 # define GROUP  7
148 
dsa_keygen_test(void)149 static int dsa_keygen_test(void)
150 {
151     int ret = 0;
152     EVP_PKEY *param_key = NULL, *key = NULL;
153     EVP_PKEY_CTX *pg_ctx = NULL, *kg_ctx = NULL;
154     BIGNUM *p_in = NULL, *q_in = NULL, *g_in = NULL;
155     BIGNUM *p_out = NULL, *q_out = NULL, *g_out = NULL;
156     int gindex_out = 0, pcount_out = 0, hcount_out = 0;
157     unsigned char seed_out[32];
158     char group_out[32];
159     size_t len = 0;
160     const OSSL_PARAM *settables = NULL;
161     static const unsigned char seed_data[] = {
162         0xa6, 0xf5, 0x28, 0x8c, 0x50, 0x77, 0xa5, 0x68,
163         0x6d, 0x3a, 0xf5, 0xf1, 0xc6, 0x4c, 0xdc, 0x35,
164         0x95, 0x26, 0x3f, 0x03, 0xdc, 0x00, 0x3f, 0x44,
165         0x7b, 0x2a, 0xc7, 0x29
166     };
167     static const unsigned char expected_p[]= {
168         0xdb, 0x47, 0x07, 0xaf, 0xf0, 0x06, 0x49, 0x55,
169         0xc9, 0xbb, 0x09, 0x41, 0xb8, 0xdb, 0x1f, 0xbc,
170         0xa8, 0xed, 0x12, 0x06, 0x7f, 0x88, 0x49, 0xb8,
171         0xc9, 0x12, 0x87, 0x21, 0xbb, 0x08, 0x6c, 0xbd,
172         0xf1, 0x89, 0xef, 0x84, 0xd9, 0x7a, 0x93, 0xe8,
173         0x45, 0x40, 0x81, 0xec, 0x37, 0x27, 0x1a, 0xa4,
174         0x22, 0x51, 0x99, 0xf0, 0xde, 0x04, 0xdb, 0xea,
175         0xa1, 0xf9, 0x37, 0x83, 0x80, 0x96, 0x36, 0x53,
176         0xf6, 0xae, 0x14, 0x73, 0x33, 0x0f, 0xdf, 0x0b,
177         0xf9, 0x2f, 0x08, 0x46, 0x31, 0xf9, 0x66, 0xcd,
178         0x5a, 0xeb, 0x6c, 0xf3, 0xbb, 0x74, 0xf3, 0x88,
179         0xf0, 0x31, 0x5c, 0xa4, 0xc8, 0x0f, 0x86, 0xf3,
180         0x0f, 0x9f, 0xc0, 0x8c, 0x57, 0xe4, 0x7f, 0x95,
181         0xb3, 0x62, 0xc8, 0x4e, 0xae, 0xf3, 0xd8, 0x14,
182         0xcc, 0x47, 0xc2, 0x4b, 0x4f, 0xef, 0xaf, 0xcd,
183         0xcf, 0xb2, 0xbb, 0xe8, 0xbe, 0x08, 0xca, 0x15,
184         0x90, 0x59, 0x35, 0xef, 0x35, 0x1c, 0xfe, 0xeb,
185         0x33, 0x2e, 0x25, 0x22, 0x57, 0x9c, 0x55, 0x23,
186         0x0c, 0x6f, 0xed, 0x7c, 0xb6, 0xc7, 0x36, 0x0b,
187         0xcb, 0x2b, 0x6a, 0x21, 0xa1, 0x1d, 0x55, 0x77,
188         0xd9, 0x91, 0xcd, 0xc1, 0xcd, 0x3d, 0x82, 0x16,
189         0x9c, 0xa0, 0x13, 0xa5, 0x83, 0x55, 0x3a, 0x73,
190         0x7e, 0x2c, 0x44, 0x3e, 0x70, 0x2e, 0x50, 0x91,
191         0x6e, 0xca, 0x3b, 0xef, 0xff, 0x85, 0x35, 0x70,
192         0xff, 0x61, 0x0c, 0xb1, 0xb2, 0xb7, 0x94, 0x6f,
193         0x65, 0xa4, 0x57, 0x62, 0xef, 0x21, 0x83, 0x0f,
194         0x3e, 0x71, 0xae, 0x7d, 0xe4, 0xad, 0xfb, 0xe3,
195         0xdd, 0xd6, 0x03, 0xda, 0x9a, 0xd8, 0x8f, 0x2d,
196         0xbb, 0x90, 0x87, 0xf8, 0xdb, 0xdc, 0xec, 0x71,
197         0xf2, 0xdb, 0x0b, 0x8e, 0xfc, 0x1a, 0x7e, 0x79,
198         0xb1, 0x1b, 0x0d, 0xfc, 0x70, 0xec, 0x85, 0xc2,
199         0xc5, 0xba, 0xb9, 0x69, 0x3f, 0x88, 0xbc, 0xcb
200     };
201     static const unsigned char expected_q[]= {
202         0x99, 0xb6, 0xa0, 0xee, 0xb3, 0xa6, 0x99, 0x1a,
203         0xb6, 0x67, 0x8d, 0xc1, 0x2b, 0x9b, 0xce, 0x2b,
204         0x01, 0x72, 0x5a, 0x65, 0x76, 0x3d, 0x93, 0x69,
205         0xe2, 0x56, 0xae, 0xd7
206     };
207     static const unsigned char expected_g[]= {
208         0x63, 0xf8, 0xb6, 0xee, 0x2a, 0x27, 0xaf, 0x4f,
209         0x4c, 0xf6, 0x08, 0x28, 0x87, 0x4a, 0xe7, 0x1f,
210         0x45, 0x46, 0x27, 0x52, 0x3b, 0x7f, 0x6f, 0xd2,
211         0x29, 0xcb, 0xe8, 0x11, 0x19, 0x25, 0x35, 0x76,
212         0x99, 0xcb, 0x4f, 0x1b, 0xe0, 0xed, 0x32, 0x9e,
213         0x05, 0xb5, 0xbe, 0xd7, 0xf6, 0x5a, 0xb2, 0xf6,
214         0x0e, 0x0c, 0x7e, 0xf5, 0xe1, 0x05, 0xfe, 0xda,
215         0xaf, 0x0f, 0x27, 0x1e, 0x40, 0x2a, 0xf7, 0xa7,
216         0x23, 0x49, 0x2c, 0xd9, 0x1b, 0x0a, 0xbe, 0xff,
217         0xc7, 0x7c, 0x7d, 0x60, 0xca, 0xa3, 0x19, 0xc3,
218         0xb7, 0xe4, 0x43, 0xb0, 0xf5, 0x75, 0x44, 0x90,
219         0x46, 0x47, 0xb1, 0xa6, 0x48, 0x0b, 0x21, 0x8e,
220         0xee, 0x75, 0xe6, 0x3d, 0xa7, 0xd3, 0x7b, 0x31,
221         0xd1, 0xd2, 0x9d, 0xe2, 0x8a, 0xfc, 0x57, 0xfd,
222         0x8a, 0x10, 0x31, 0xeb, 0x87, 0x36, 0x3f, 0x65,
223         0x72, 0x23, 0x2c, 0xd3, 0xd6, 0x17, 0xa5, 0x62,
224         0x58, 0x65, 0x57, 0x6a, 0xd4, 0xa8, 0xfe, 0xec,
225         0x57, 0x76, 0x0c, 0xb1, 0x4c, 0x93, 0xed, 0xb0,
226         0xb4, 0xf9, 0x45, 0xb3, 0x3e, 0xdd, 0x47, 0xf1,
227         0xfb, 0x7d, 0x25, 0x79, 0x3d, 0xfc, 0xa7, 0x39,
228         0x90, 0x68, 0x6a, 0x6b, 0xae, 0xf2, 0x6e, 0x64,
229         0x8c, 0xfb, 0xb8, 0xdd, 0x76, 0x4e, 0x4a, 0x69,
230         0x8c, 0x97, 0x15, 0x77, 0xb2, 0x67, 0xdc, 0xeb,
231         0x4a, 0x40, 0x6b, 0xb9, 0x47, 0x8f, 0xa6, 0xab,
232         0x6e, 0x98, 0xc0, 0x97, 0x9a, 0x0c, 0xea, 0x00,
233         0xfd, 0x56, 0x1a, 0x74, 0x9a, 0x32, 0x6b, 0xfe,
234         0xbd, 0xdf, 0x6c, 0x82, 0x54, 0x53, 0x4d, 0x70,
235         0x65, 0xe3, 0x8b, 0x37, 0xb8, 0xe4, 0x70, 0x08,
236         0xb7, 0x3b, 0x30, 0x27, 0xaf, 0x1c, 0x77, 0xf3,
237         0x62, 0xd4, 0x9a, 0x59, 0xba, 0xd1, 0x6e, 0x89,
238         0x5c, 0x34, 0x9a, 0xa1, 0xb7, 0x4f, 0x7d, 0x8c,
239         0xdc, 0xbc, 0x74, 0x25, 0x5e, 0xbf, 0x77, 0x46
240     };
241     int expected_c = 1316;
242     int expected_h = 2;
243 
244     if (!TEST_ptr(p_in = BN_bin2bn(expected_p, sizeof(expected_p), NULL))
245         || !TEST_ptr(q_in = BN_bin2bn(expected_q, sizeof(expected_q), NULL))
246         || !TEST_ptr(g_in = BN_bin2bn(expected_g, sizeof(expected_g), NULL)))
247         goto end;
248     if (!TEST_ptr(pg_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
249         || !TEST_int_gt(EVP_PKEY_paramgen_init(pg_ctx), 0)
250         || !TEST_ptr_null(EVP_PKEY_CTX_gettable_params(pg_ctx))
251         || !TEST_ptr(settables = EVP_PKEY_CTX_settable_params(pg_ctx))
252         || !TEST_ptr(OSSL_PARAM_locate_const(settables,
253                                              OSSL_PKEY_PARAM_FFC_PBITS))
254         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_type(pg_ctx, "fips186_4"))
255         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(pg_ctx, 2048))
256         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(pg_ctx, 224))
257         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_seed(pg_ctx, seed_data,
258                                                          sizeof(seed_data)))
259         || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_md_props(pg_ctx, "SHA256",
260                                                              ""))
261         || !TEST_int_gt(EVP_PKEY_generate(pg_ctx, &param_key), 0)
262         || !TEST_ptr(kg_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL))
263         || !TEST_int_gt(EVP_PKEY_keygen_init(kg_ctx), 0)
264         || !TEST_int_gt(EVP_PKEY_generate(kg_ctx, &key), 0))
265         goto end;
266 
267     if (!TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_P, &p_out))
268         || !TEST_BN_eq(p_in, p_out)
269         || !TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_Q, &q_out))
270         || !TEST_BN_eq(q_in, q_out)
271         || !TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_G, &g_out))
272         || !TEST_BN_eq(g_in, g_out)
273         || !TEST_true(EVP_PKEY_get_octet_string_param(
274                           key, OSSL_PKEY_PARAM_FFC_SEED, seed_out,
275                           sizeof(seed_out), &len))
276         || !TEST_mem_eq(seed_out, len, seed_data, sizeof(seed_data))
277         || !TEST_true(EVP_PKEY_get_int_param(key, OSSL_PKEY_PARAM_FFC_GINDEX,
278                                              &gindex_out))
279         || !TEST_int_eq(gindex_out, -1)
280         || !TEST_true(EVP_PKEY_get_int_param(key, OSSL_PKEY_PARAM_FFC_H,
281                                              &hcount_out))
282         || !TEST_int_eq(hcount_out, expected_h)
283         || !TEST_true(EVP_PKEY_get_int_param(key,
284                                              OSSL_PKEY_PARAM_FFC_PCOUNTER,
285                                              &pcount_out))
286         || !TEST_int_eq(pcount_out, expected_c)
287         || !TEST_false(EVP_PKEY_get_utf8_string_param(key,
288                                                       OSSL_PKEY_PARAM_GROUP_NAME,
289                                                       group_out,
290                                                       sizeof(group_out), &len)))
291         goto end;
292     ret = 1;
293 end:
294     BN_free(p_in);
295     BN_free(q_in);
296     BN_free(g_in);
297     BN_free(p_out);
298     BN_free(q_out);
299     BN_free(g_out);
300     EVP_PKEY_free(param_key);
301     EVP_PKEY_free(key);
302     EVP_PKEY_CTX_free(kg_ctx);
303     EVP_PKEY_CTX_free(pg_ctx);
304     return ret;
305 }
306 
test_dsa_default_paramgen_validate(int i)307 static int test_dsa_default_paramgen_validate(int i)
308 {
309     int ret;
310     EVP_PKEY_CTX *gen_ctx = NULL;
311     EVP_PKEY_CTX *check_ctx = NULL;
312     EVP_PKEY *params = NULL;
313 
314     ret = TEST_ptr(gen_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
315           && TEST_int_gt(EVP_PKEY_paramgen_init(gen_ctx), 0)
316           && (i == 0
317               || TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(gen_ctx, 512)))
318           && TEST_int_gt(EVP_PKEY_generate(gen_ctx, &params), 0)
319           && TEST_ptr(check_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, params, NULL))
320           && TEST_int_gt(EVP_PKEY_param_check(check_ctx), 0);
321 
322     EVP_PKEY_free(params);
323     EVP_PKEY_CTX_free(check_ctx);
324     EVP_PKEY_CTX_free(gen_ctx);
325     return ret;
326 }
327 
328 #endif /* OPENSSL_NO_DSA */
329 
setup_tests(void)330 int setup_tests(void)
331 {
332 #ifndef OPENSSL_NO_DSA
333     ADD_TEST(dsa_test);
334     ADD_TEST(dsa_keygen_test);
335     ADD_ALL_TESTS(test_dsa_default_paramgen_validate, 2);
336 #endif
337     return 1;
338 }
339