1 /* $OpenBSD: dsa.h,v 1.30 2018/03/17 15:19:12 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as core.stdc.config.c_long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 /*
60  * The DSS routines are based on patches supplied by
61  * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
62  * work and I have just tweaked them a little to fit into my
63  * stylistic vision for SSLeay :-)
64  */
65 module libressl_d.openssl.dsa;
66 
67 
68 private static import core.stdc.config;
69 private static import libressl_d.compat.stdio;
70 private static import libressl_d.openssl.evp;
71 public import libressl_d.openssl.bio;
72 public import libressl_d.openssl.bn;
73 public import libressl_d.openssl.crypto;
74 public import libressl_d.openssl.opensslconf;
75 public import libressl_d.openssl.ossl_typ;
76 
77 version (OPENSSL_NO_DSA) {
78 	static assert(false, "DSA is disabled.");
79 }
80 
81 version (OPENSSL_NO_BIO) {
82 } else {
83 	public import libressl_d.openssl.bio;
84 }
85 
86 version (OPENSSL_NO_DEPRECATED) {
87 } else {
88 	public import libressl_d.openssl.bn;
89 
90 	version (OPENSSL_NO_DH) {
91 	} else {
92 		public import libressl_d.openssl.dh;
93 	}
94 }
95 
96 version (OPENSSL_DSA_MAX_MODULUS_BITS) {
97 } else {
98 	enum OPENSSL_DSA_MAX_MODULUS_BITS = 10000;
99 }
100 
101 enum DSA_FLAG_CACHE_MONT_P = 0x01;
102 
103 /**
104  * If this flag is set the DSA method is FIPS compliant and can be used
105  * in FIPS mode. This is set in the validated module method. If an
106  * application sets this flag in its own methods it is its reposibility
107  * to ensure the result is compliant.
108  */
109 enum DSA_FLAG_FIPS_METHOD = 0x0400;
110 
111 /**
112  * If this flag is set the operations normally disabled in FIPS mode are
113  * permitted it is then the applications responsibility to ensure that the
114  * usage is compliant.
115  */
116 enum DSA_FLAG_NON_FIPS_ALLOW = 0x0400;
117 
118 extern (C):
119 nothrow @nogc:
120 
121 /* Already defined in ossl_typ.h */
122 /* alias DSA = .dsa.dsa_st; */
123 /* alias DSA_METHOD = .dsa_method; */
124 
125 struct DSA_SIG_st
126 {
127 	libressl_d.openssl.ossl_typ.BIGNUM* r;
128 	libressl_d.openssl.ossl_typ.BIGNUM* s;
129 }
130 
131 alias DSA_SIG = .DSA_SIG_st;
132 
133 struct dsa_method
134 {
135 	const (char)* name;
136 	.DSA_SIG* function(const (ubyte)* dgst, int dlen, libressl_d.openssl.ossl_typ.DSA* dsa) dsa_do_sign;
137 	int function(libressl_d.openssl.ossl_typ.DSA* dsa, libressl_d.openssl.ossl_typ.BN_CTX* ctx_in, libressl_d.openssl.ossl_typ.BIGNUM** kinvp, libressl_d.openssl.ossl_typ.BIGNUM** rp) dsa_sign_setup;
138 	int function(const (ubyte)* dgst, int dgst_len, .DSA_SIG* sig, libressl_d.openssl.ossl_typ.DSA* dsa) dsa_do_verify;
139 	int function(libressl_d.openssl.ossl_typ.DSA* dsa, libressl_d.openssl.ossl_typ.BIGNUM* rr, libressl_d.openssl.ossl_typ.BIGNUM* a1, libressl_d.openssl.ossl_typ.BIGNUM* p1, libressl_d.openssl.ossl_typ.BIGNUM* a2, libressl_d.openssl.ossl_typ.BIGNUM* p2, libressl_d.openssl.ossl_typ.BIGNUM* m, libressl_d.openssl.ossl_typ.BN_CTX* ctx, libressl_d.openssl.ossl_typ.BN_MONT_CTX* in_mont) dsa_mod_exp;
140 
141 	/**
142 	 * Can be null
143 	 */
144 	int function(libressl_d.openssl.ossl_typ.DSA* dsa, libressl_d.openssl.ossl_typ.BIGNUM* r, libressl_d.openssl.ossl_typ.BIGNUM* a, const (libressl_d.openssl.ossl_typ.BIGNUM)* p, const (libressl_d.openssl.ossl_typ.BIGNUM)* m, libressl_d.openssl.ossl_typ.BN_CTX* ctx, libressl_d.openssl.ossl_typ.BN_MONT_CTX* m_ctx) bn_mod_exp;
145 
146 	int function(libressl_d.openssl.ossl_typ.DSA* dsa) init;
147 	int function(libressl_d.openssl.ossl_typ.DSA* dsa) finish;
148 	int flags;
149 	char* app_data;
150 
151 	/**
152 	 * If this is non-null, it is used to generate DSA parameters
153 	 */
154 	int function(libressl_d.openssl.ossl_typ.DSA* dsa, int bits, const (ubyte)* seed, int seed_len, int* counter_ret, core.stdc.config.c_ulong* h_ret, libressl_d.openssl.ossl_typ.BN_GENCB* cb) dsa_paramgen;
155 
156 	/**
157 	 * If this is non-null, it is used to generate DSA keys
158 	 */
159 	int function(libressl_d.openssl.ossl_typ.DSA* dsa) dsa_keygen;
160 }
161 
162 struct dsa_st
163 {
164 	/**
165 	 * This first variable is used to pick up errors where
166 	 * a DSA is passed instead of of a EVP_PKEY
167 	 */
168 	int pad;
169 
170 	core.stdc.config.c_long version_;
171 	int write_params;
172 	libressl_d.openssl.ossl_typ.BIGNUM* p;
173 
174 	/**
175 	 * == 20
176 	 */
177 	libressl_d.openssl.ossl_typ.BIGNUM* q;
178 
179 	libressl_d.openssl.ossl_typ.BIGNUM* g;
180 
181 	/**
182 	 * y public key
183 	 */
184 	libressl_d.openssl.ossl_typ.BIGNUM* pub_key;
185 
186 	/**
187 	 * x private key
188 	 */
189 	libressl_d.openssl.ossl_typ.BIGNUM* priv_key;
190 
191 	/**
192 	 * Signing pre-calc
193 	 */
194 	libressl_d.openssl.ossl_typ.BIGNUM* kinv;
195 
196 	/**
197 	 * Signing pre-calc
198 	 */
199 	libressl_d.openssl.ossl_typ.BIGNUM* r;
200 
201 	int flags;
202 	/* Normally used to cache montgomery values */
203 	libressl_d.openssl.ossl_typ.BN_MONT_CTX* method_mont_p;
204 	int references;
205 	libressl_d.openssl.ossl_typ.CRYPTO_EX_DATA ex_data;
206 	const (libressl_d.openssl.ossl_typ.DSA_METHOD)* meth;
207 
208 	/**
209 	 * functional reference if 'meth' is ENGINE-provided
210 	 */
211 	libressl_d.openssl.ossl_typ.ENGINE* engine;
212 }
213 
214 libressl_d.openssl.ossl_typ.DSA* d2i_DSAparams_bio(libressl_d.openssl.bio.BIO* bp, libressl_d.openssl.ossl_typ.DSA** a);
215 int i2d_DSAparams_bio(libressl_d.openssl.bio.BIO* bp, libressl_d.openssl.ossl_typ.DSA* a);
216 libressl_d.openssl.ossl_typ.DSA* d2i_DSAparams_fp(libressl_d.compat.stdio.FILE* fp, libressl_d.openssl.ossl_typ.DSA** a);
217 int i2d_DSAparams_fp(libressl_d.compat.stdio.FILE* fp, libressl_d.openssl.ossl_typ.DSA* a);
218 
219 libressl_d.openssl.ossl_typ.DSA* DSAparams_dup(libressl_d.openssl.ossl_typ.DSA* x);
220 .DSA_SIG* DSA_SIG_new();
221 void DSA_SIG_free(.DSA_SIG* a);
222 int i2d_DSA_SIG(const (.DSA_SIG)* a, ubyte** pp);
223 .DSA_SIG* d2i_DSA_SIG(.DSA_SIG** v, const (ubyte)** pp, core.stdc.config.c_long length_);
224 void DSA_SIG_get0(const (.DSA_SIG)* sig, const (libressl_d.openssl.ossl_typ.BIGNUM)** pr, const (libressl_d.openssl.ossl_typ.BIGNUM)** ps);
225 int DSA_SIG_set0(.DSA_SIG* sig, libressl_d.openssl.ossl_typ.BIGNUM* r, libressl_d.openssl.ossl_typ.BIGNUM* s);
226 
227 .DSA_SIG* DSA_do_sign(const (ubyte)* dgst, int dlen, libressl_d.openssl.ossl_typ.DSA* dsa);
228 int DSA_do_verify(const (ubyte)* dgst, int dgst_len, .DSA_SIG* sig, libressl_d.openssl.ossl_typ.DSA* dsa);
229 
230 const (libressl_d.openssl.ossl_typ.DSA_METHOD)* DSA_OpenSSL();
231 
232 void DSA_set_default_method(const (libressl_d.openssl.ossl_typ.DSA_METHOD)*);
233 const (libressl_d.openssl.ossl_typ.DSA_METHOD)* DSA_get_default_method();
234 int DSA_set_method(libressl_d.openssl.ossl_typ.DSA* dsa, const (libressl_d.openssl.ossl_typ.DSA_METHOD)*);
235 
236 libressl_d.openssl.ossl_typ.DSA* DSA_new();
237 libressl_d.openssl.ossl_typ.DSA* DSA_new_method(libressl_d.openssl.ossl_typ.ENGINE* engine);
238 void DSA_free(libressl_d.openssl.ossl_typ.DSA* r);
239 /* "up" the DSA object's reference count */
240 int DSA_up_ref(libressl_d.openssl.ossl_typ.DSA* r);
241 int DSA_size(const (libressl_d.openssl.ossl_typ.DSA)*);
242 /* next 4 return -1 on error */
243 int DSA_sign_setup(libressl_d.openssl.ossl_typ.DSA* dsa, libressl_d.openssl.ossl_typ.BN_CTX* ctx_in, libressl_d.openssl.ossl_typ.BIGNUM** kinvp, libressl_d.openssl.ossl_typ.BIGNUM** rp);
244 int DSA_sign(int type, const (ubyte)* dgst, int dlen, ubyte* sig, uint* siglen, libressl_d.openssl.ossl_typ.DSA* dsa);
245 int DSA_verify(int type, const (ubyte)* dgst, int dgst_len, const (ubyte)* sigbuf, int siglen, libressl_d.openssl.ossl_typ.DSA* dsa);
246 int DSA_get_ex_new_index(core.stdc.config.c_long argl, void* argp, libressl_d.openssl.ossl_typ.CRYPTO_EX_new* new_func, libressl_d.openssl.ossl_typ.CRYPTO_EX_dup* dup_func, libressl_d.openssl.ossl_typ.CRYPTO_EX_free* free_func);
247 int DSA_set_ex_data(libressl_d.openssl.ossl_typ.DSA* d, int idx, void* arg);
248 void* DSA_get_ex_data(libressl_d.openssl.ossl_typ.DSA* d, int idx);
249 
250 libressl_d.openssl.ossl_typ.DSA* d2i_DSAPublicKey(libressl_d.openssl.ossl_typ.DSA** a, const (ubyte)** pp, core.stdc.config.c_long length_);
251 int i2d_DSAPublicKey(const (libressl_d.openssl.ossl_typ.DSA)* a, ubyte** pp);
252 extern __gshared const libressl_d.openssl.ossl_typ.ASN1_ITEM DSAPublicKey_it;
253 
254 libressl_d.openssl.ossl_typ.DSA* d2i_DSAPrivateKey(libressl_d.openssl.ossl_typ.DSA** a, const (ubyte)** pp, core.stdc.config.c_long length_);
255 int i2d_DSAPrivateKey(const (libressl_d.openssl.ossl_typ.DSA)* a, ubyte** pp);
256 extern __gshared const libressl_d.openssl.ossl_typ.ASN1_ITEM DSAPrivateKey_it;
257 
258 libressl_d.openssl.ossl_typ.DSA* d2i_DSAparams(libressl_d.openssl.ossl_typ.DSA** a, const (ubyte)** pp, core.stdc.config.c_long length_);
259 int i2d_DSAparams(const (libressl_d.openssl.ossl_typ.DSA)* a, ubyte** pp);
260 extern __gshared const libressl_d.openssl.ossl_typ.ASN1_ITEM DSAparams_it;
261 
262 /* Deprecated version */
263 version (OPENSSL_NO_DEPRECATED) {
264 } else {
265 	libressl_d.openssl.ossl_typ.DSA* DSA_generate_parameters(int bits, ubyte* seed, int seed_len, int* counter_ret, core.stdc.config.c_ulong* h_ret, void function(int, int, void*) callback, void* cb_arg);
266 }
267 
268 /* New version */
269 int DSA_generate_parameters_ex(libressl_d.openssl.ossl_typ.DSA* dsa, int bits, const (ubyte)* seed, int seed_len, int* counter_ret, core.stdc.config.c_ulong* h_ret, libressl_d.openssl.ossl_typ.BN_GENCB* cb);
270 
271 int DSA_generate_key(libressl_d.openssl.ossl_typ.DSA* a);
272 
273 version (OPENSSL_NO_BIO) {
274 } else {
275 	int DSAparams_print(libressl_d.openssl.bio.BIO* bp, const (libressl_d.openssl.ossl_typ.DSA)* x);
276 	int DSA_print(libressl_d.openssl.bio.BIO* bp, const (libressl_d.openssl.ossl_typ.DSA)* x, int off);
277 }
278 
279 int DSAparams_print_fp(libressl_d.compat.stdio.FILE* fp, const (libressl_d.openssl.ossl_typ.DSA)* x);
280 int DSA_print_fp(libressl_d.compat.stdio.FILE* bp, const (libressl_d.openssl.ossl_typ.DSA)* x, int off);
281 
282 enum DSS_prime_checks = 50;
283 /*
284  * Primality test according to FIPS PUB 186[-1], Appendix 2.1:
285  * 50 rounds of Rabin-Miller
286  */
287 pragma(inline, true)
288 int DSA_is_prime(const (libressl_d.openssl.ossl_typ.BIGNUM)* n, void function(int, int, void*) callback, void* cb_arg)
289 
290 	do
291 	{
292 		return libressl_d.openssl.bn.BN_is_prime(n, .DSS_prime_checks, callback, null, cb_arg);
293 	}
294 
295 version (OPENSSL_NO_DH) {
296 } else {
297 	/*
298 	 * Convert DSA structure (key or just parameters) into DH structure
299 	 * (be careful to avoid small subgroup attacks when using this!)
300 	 */
301 	libressl_d.openssl.ossl_typ.DH* DSA_dup_DH(const (libressl_d.openssl.ossl_typ.DSA)* r);
302 }
303 
304 void DSA_get0_pqg(const (libressl_d.openssl.ossl_typ.DSA)* d, const (libressl_d.openssl.ossl_typ.BIGNUM)** p, const (libressl_d.openssl.ossl_typ.BIGNUM)** q, const (libressl_d.openssl.ossl_typ.BIGNUM)** g);
305 int DSA_set0_pqg(libressl_d.openssl.ossl_typ.DSA* d, libressl_d.openssl.ossl_typ.BIGNUM* p, libressl_d.openssl.ossl_typ.BIGNUM* q, libressl_d.openssl.ossl_typ.BIGNUM* g);
306 void DSA_get0_key(const (libressl_d.openssl.ossl_typ.DSA)* d, const (libressl_d.openssl.ossl_typ.BIGNUM)** pub_key, const (libressl_d.openssl.ossl_typ.BIGNUM)** priv_key);
307 int DSA_set0_key(libressl_d.openssl.ossl_typ.DSA* d, libressl_d.openssl.ossl_typ.BIGNUM* pub_key, libressl_d.openssl.ossl_typ.BIGNUM* priv_key);
308 void DSA_clear_flags(libressl_d.openssl.ossl_typ.DSA* d, int flags);
309 int DSA_test_flags(const (libressl_d.openssl.ossl_typ.DSA)* d, int flags);
310 void DSA_set_flags(libressl_d.openssl.ossl_typ.DSA* d, int flags);
311 libressl_d.openssl.ossl_typ.ENGINE* DSA_get0_engine(libressl_d.openssl.ossl_typ.DSA* d);
312 
313 libressl_d.openssl.ossl_typ.DSA_METHOD* DSA_meth_new(const (char)* name, int flags);
314 void DSA_meth_free(libressl_d.openssl.ossl_typ.DSA_METHOD* meth);
315 libressl_d.openssl.ossl_typ.DSA_METHOD* DSA_meth_dup(const (libressl_d.openssl.ossl_typ.DSA_METHOD)* meth);
316 int DSA_meth_set_sign(libressl_d.openssl.ossl_typ.DSA_METHOD* meth, DSA_SIG* function(const (ubyte)*, int, libressl_d.openssl.ossl_typ.DSA*) sign);
317 int DSA_meth_set_finish(libressl_d.openssl.ossl_typ.DSA_METHOD* meth, int function(libressl_d.openssl.ossl_typ.DSA*) finish);
318 
319 pragma(inline, true)
320 int EVP_PKEY_CTX_set_dsa_paramgen_bits(libressl_d.openssl.ossl_typ.EVP_PKEY_CTX* ctx, int nbits)
321 
322 	do
323 	{
324 		return libressl_d.openssl.evp.EVP_PKEY_CTX_ctrl(ctx, libressl_d.openssl.evp.EVP_PKEY_DSA, libressl_d.openssl.evp.EVP_PKEY_OP_PARAMGEN, .EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, null);
325 	}
326 
327 enum EVP_PKEY_CTRL_DSA_PARAMGEN_BITS = libressl_d.openssl.evp.EVP_PKEY_ALG_CTRL + 1;
328 enum EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS = libressl_d.openssl.evp.EVP_PKEY_ALG_CTRL + 2;
329 enum EVP_PKEY_CTRL_DSA_PARAMGEN_MD = libressl_d.openssl.evp.EVP_PKEY_ALG_CTRL + 3;
330 
331 /* BEGIN ERROR CODES */
332 /**
333  * The following lines are auto generated by the script mkerr.pl. Any changes
334  * made after this point may be overwritten when the script is next run.
335  */
336 void ERR_load_DSA_strings();
337 
338 /* Error codes for the DSA functions. */
339 
340 /* Function codes. */
341 enum DSA_F_D2I_DSA_SIG = 110;
342 enum DSA_F_DO_DSA_PRINT = 104;
343 enum DSA_F_DSAPARAMS_PRINT = 100;
344 enum DSA_F_DSAPARAMS_PRINT_FP = 101;
345 enum DSA_F_DSA_DO_SIGN = 112;
346 enum DSA_F_DSA_DO_VERIFY = 113;
347 enum DSA_F_DSA_GENERATE_KEY = 124;
348 enum DSA_F_DSA_GENERATE_PARAMETERS_EX = 123;
349 enum DSA_F_DSA_NEW_METHOD = 103;
350 enum DSA_F_DSA_PARAM_DECODE = 119;
351 enum DSA_F_DSA_PRINT_FP = 105;
352 enum DSA_F_DSA_PRIV_DECODE = 115;
353 enum DSA_F_DSA_PRIV_ENCODE = 116;
354 enum DSA_F_DSA_PUB_DECODE = 117;
355 enum DSA_F_DSA_PUB_ENCODE = 118;
356 enum DSA_F_DSA_SIGN = 106;
357 enum DSA_F_DSA_SIGN_SETUP = 107;
358 enum DSA_F_DSA_SIG_NEW = 109;
359 enum DSA_F_DSA_SIG_PRINT = 125;
360 enum DSA_F_DSA_VERIFY = 108;
361 enum DSA_F_I2D_DSA_SIG = 111;
362 enum DSA_F_OLD_DSA_PRIV_DECODE = 122;
363 enum DSA_F_PKEY_DSA_CTRL = 120;
364 enum DSA_F_PKEY_DSA_KEYGEN = 121;
365 enum DSA_F_SIG_CB = 114;
366 
367 /* Reason codes. */
368 enum DSA_R_BAD_Q_VALUE = 102;
369 enum DSA_R_BN_DECODE_ERROR = 108;
370 enum DSA_R_BN_ERROR = 109;
371 enum DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE = 100;
372 enum DSA_R_DECODE_ERROR = 104;
373 enum DSA_R_INVALID_DIGEST_TYPE = 106;
374 enum DSA_R_MISSING_PARAMETERS = 101;
375 enum DSA_R_MODULUS_TOO_LARGE = 103;
376 enum DSA_R_NEED_NEW_SETUP_VALUES = 110;
377 enum DSA_R_NON_FIPS_DSA_METHOD = 111;
378 enum DSA_R_NO_PARAMETERS_SET = 107;
379 enum DSA_R_PARAMETER_ENCODING_ERROR = 105;