1*7a31e386Stb /* $OpenBSD: dsa_ossl.c,v 1.56 2024/05/11 06:43:50 tb Exp $ */
2ba5406e9Sbeck /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3ba5406e9Sbeck * All rights reserved.
4ba5406e9Sbeck *
5ba5406e9Sbeck * This package is an SSL implementation written
6ba5406e9Sbeck * by Eric Young (eay@cryptsoft.com).
7ba5406e9Sbeck * The implementation was written so as to conform with Netscapes SSL.
8ba5406e9Sbeck *
9ba5406e9Sbeck * This library is free for commercial and non-commercial use as long as
10ba5406e9Sbeck * the following conditions are aheared to. The following conditions
11ba5406e9Sbeck * apply to all code found in this distribution, be it the RC4, RSA,
12ba5406e9Sbeck * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13ba5406e9Sbeck * included with this distribution is covered by the same copyright terms
14ba5406e9Sbeck * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15ba5406e9Sbeck *
16ba5406e9Sbeck * Copyright remains Eric Young's, and as such any Copyright notices in
17ba5406e9Sbeck * the code are not to be removed.
18ba5406e9Sbeck * If this package is used in a product, Eric Young should be given attribution
19ba5406e9Sbeck * as the author of the parts of the library used.
20ba5406e9Sbeck * This can be in the form of a textual message at program startup or
21ba5406e9Sbeck * in documentation (online or textual) provided with the package.
22ba5406e9Sbeck *
23ba5406e9Sbeck * Redistribution and use in source and binary forms, with or without
24ba5406e9Sbeck * modification, are permitted provided that the following conditions
25ba5406e9Sbeck * are met:
26ba5406e9Sbeck * 1. Redistributions of source code must retain the copyright
27ba5406e9Sbeck * notice, this list of conditions and the following disclaimer.
28ba5406e9Sbeck * 2. Redistributions in binary form must reproduce the above copyright
29ba5406e9Sbeck * notice, this list of conditions and the following disclaimer in the
30ba5406e9Sbeck * documentation and/or other materials provided with the distribution.
31ba5406e9Sbeck * 3. All advertising materials mentioning features or use of this software
32ba5406e9Sbeck * must display the following acknowledgement:
33ba5406e9Sbeck * "This product includes cryptographic software written by
34ba5406e9Sbeck * Eric Young (eay@cryptsoft.com)"
35ba5406e9Sbeck * The word 'cryptographic' can be left out if the rouines from the library
36ba5406e9Sbeck * being used are not cryptographic related :-).
37ba5406e9Sbeck * 4. If you include any Windows specific code (or a derivative thereof) from
38ba5406e9Sbeck * the apps directory (application code) you must include an acknowledgement:
39ba5406e9Sbeck * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40ba5406e9Sbeck *
41ba5406e9Sbeck * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42ba5406e9Sbeck * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43ba5406e9Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44ba5406e9Sbeck * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45ba5406e9Sbeck * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46ba5406e9Sbeck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47ba5406e9Sbeck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48ba5406e9Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49ba5406e9Sbeck * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50ba5406e9Sbeck * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51ba5406e9Sbeck * SUCH DAMAGE.
52ba5406e9Sbeck *
53ba5406e9Sbeck * The licence and distribution terms for any publically available version or
54ba5406e9Sbeck * derivative of this code cannot be changed. i.e. this code cannot simply be
55ba5406e9Sbeck * copied and put under another distribution licence
56ba5406e9Sbeck * [including the GNU Public Licence.]
57ba5406e9Sbeck */
58ba5406e9Sbeck
59ba5406e9Sbeck /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60ba5406e9Sbeck
61ba5406e9Sbeck #include <stdio.h>
62b6ab114eSjsing
63ba5406e9Sbeck #include <openssl/asn1.h>
64b6ab114eSjsing #include <openssl/bn.h>
65b6ab114eSjsing #include <openssl/dsa.h>
66b6ab114eSjsing #include <openssl/err.h>
67b6ab114eSjsing #include <openssl/sha.h>
68ba5406e9Sbeck
69c9675a23Stb #include "bn_local.h"
70c9675a23Stb #include "dsa_local.h"
713a88f7afSbeck
720d37be08Stb /*
730d37be08Stb * Since DSA parameters are entirely arbitrary and checking them to be
740d37be08Stb * consistent is very expensive, we cannot do so on every sign operation.
750d37be08Stb * Instead, cap the number of retries so we do not loop indefinitely if
760d37be08Stb * the generator of the multiplicative group happens to be nilpotent.
770d37be08Stb * The probability of needing a retry with valid parameters is negligible,
780d37be08Stb * so trying 32 times is amply enough.
790d37be08Stb */
800d37be08Stb #define DSA_MAX_SIGN_ITERATIONS 32
810d37be08Stb
82e85b1b81Smiod static DSA_SIG *
dsa_do_sign(const unsigned char * dgst,int dlen,DSA * dsa)83e85b1b81Smiod dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
84ba5406e9Sbeck {
8570901374Sjsing BIGNUM *b = NULL, *bm = NULL, *bxr = NULL, *binv = NULL, *m = NULL;
8670901374Sjsing BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
87ba5406e9Sbeck BN_CTX *ctx = NULL;
880a5d6edeSdjm int reason = ERR_R_BN_LIB;
89ba5406e9Sbeck DSA_SIG *ret = NULL;
900d37be08Stb int attempts = 0;
915cdd308eSdjm int noredo = 0;
92ba5406e9Sbeck
9383f09c76Stb if (!dsa_check_key(dsa)) {
9483f09c76Stb reason = DSA_R_INVALID_PARAMETERS;
95200c0290Sbeck goto err;
96200c0290Sbeck }
97767fe2ffSmarkus
9870901374Sjsing if ((s = BN_new()) == NULL)
99e85b1b81Smiod goto err;
10070901374Sjsing
10170901374Sjsing if ((ctx = BN_CTX_new()) == NULL)
10270901374Sjsing goto err;
10370901374Sjsing
10470901374Sjsing BN_CTX_start(ctx);
10570901374Sjsing
10670901374Sjsing if ((b = BN_CTX_get(ctx)) == NULL)
10770901374Sjsing goto err;
10870901374Sjsing if ((binv = BN_CTX_get(ctx)) == NULL)
10970901374Sjsing goto err;
11070901374Sjsing if ((bm = BN_CTX_get(ctx)) == NULL)
11170901374Sjsing goto err;
11270901374Sjsing if ((bxr = BN_CTX_get(ctx)) == NULL)
11370901374Sjsing goto err;
11470901374Sjsing if ((m = BN_CTX_get(ctx)) == NULL)
115e85b1b81Smiod goto err;
116c6a150b7Sjsing
1172a4f1d4fSjsing /*
118cca0da51Sjsing * If the digest length is greater than N (the bit length of q), the
119cca0da51Sjsing * leftmost N bits of the digest shall be used, see FIPS 186-3, 4.2.
120cca0da51Sjsing * In this case the digest length is given in bytes.
1212a4f1d4fSjsing */
1222a4f1d4fSjsing if (dlen > BN_num_bytes(dsa->q))
1232a4f1d4fSjsing dlen = BN_num_bytes(dsa->q);
12470901374Sjsing if (BN_bin2bn(dgst, dlen, m) == NULL)
1252a4f1d4fSjsing goto err;
1262a4f1d4fSjsing
1275cdd308eSdjm redo:
128e85b1b81Smiod if (dsa->kinv == NULL || dsa->r == NULL) {
129e85b1b81Smiod if (!DSA_sign_setup(dsa, ctx, &kinv, &r))
130e85b1b81Smiod goto err;
131e85b1b81Smiod } else {
132ba5406e9Sbeck kinv = dsa->kinv;
133ba5406e9Sbeck dsa->kinv = NULL;
134ba5406e9Sbeck r = dsa->r;
135ba5406e9Sbeck dsa->r = NULL;
1365cdd308eSdjm noredo = 1;
137ba5406e9Sbeck }
138ba5406e9Sbeck
139e1190f3dSjsing /*
140e1190f3dSjsing * Compute:
141e1190f3dSjsing *
142e1190f3dSjsing * s = inv(k)(m + xr) mod q
143e1190f3dSjsing *
144e1190f3dSjsing * In order to reduce the possibility of a side-channel attack, the
145e1190f3dSjsing * following is calculated using a blinding value:
146e1190f3dSjsing *
147c462c7b3Stb * s = inv(b)(bm + bxr)inv(k) mod q
148e1190f3dSjsing *
1498a144a0fStb * Where b is a random value in the range [1, q).
150e1190f3dSjsing */
15112347e81Stb if (!bn_rand_interval(b, 1, dsa->q))
152e1190f3dSjsing goto err;
15370901374Sjsing if (BN_mod_inverse_ct(binv, b, dsa->q, ctx) == NULL)
154e1190f3dSjsing goto err;
155e1190f3dSjsing
15670901374Sjsing if (!BN_mod_mul(bxr, b, dsa->priv_key, dsa->q, ctx)) /* bx */
157e1190f3dSjsing goto err;
15870901374Sjsing if (!BN_mod_mul(bxr, bxr, r, dsa->q, ctx)) /* bxr */
159e1190f3dSjsing goto err;
16070901374Sjsing if (!BN_mod_mul(bm, b, m, dsa->q, ctx)) /* bm */
161e1190f3dSjsing goto err;
16270901374Sjsing if (!BN_mod_add(s, bxr, bm, dsa->q, ctx)) /* s = bm + bxr */
163e1190f3dSjsing goto err;
16439378f3cStb if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) /* s = b(m + xr)k^-1 */
165e85b1b81Smiod goto err;
16670901374Sjsing if (!BN_mod_mul(s, s, binv, dsa->q, ctx)) /* s = (m + xr)k^-1 */
167e85b1b81Smiod goto err;
168ba5406e9Sbeck
169e85b1b81Smiod /*
170c6a150b7Sjsing * Redo if r or s is zero as required by FIPS 186-3: this is very
171c6a150b7Sjsing * unlikely.
1725cdd308eSdjm */
173e85b1b81Smiod if (BN_is_zero(r) || BN_is_zero(s)) {
174e85b1b81Smiod if (noredo) {
1755cdd308eSdjm reason = DSA_R_NEED_NEW_SETUP_VALUES;
1765cdd308eSdjm goto err;
1775cdd308eSdjm }
1780d37be08Stb if (++attempts > DSA_MAX_SIGN_ITERATIONS) {
1790d37be08Stb reason = DSA_R_INVALID_PARAMETERS;
1800d37be08Stb goto err;
1810d37be08Stb }
1825cdd308eSdjm goto redo;
1835cdd308eSdjm }
184011d7b9eSjsing
185011d7b9eSjsing if ((ret = DSA_SIG_new()) == NULL) {
186011d7b9eSjsing reason = ERR_R_MALLOC_FAILURE;
187011d7b9eSjsing goto err;
188011d7b9eSjsing }
189ba5406e9Sbeck ret->r = r;
190ba5406e9Sbeck ret->s = s;
191ba5406e9Sbeck
192ba5406e9Sbeck err:
193e85b1b81Smiod if (!ret) {
1945067ae9fSbeck DSAerror(reason);
195ba5406e9Sbeck BN_free(r);
196ba5406e9Sbeck BN_free(s);
197ba5406e9Sbeck }
19870901374Sjsing BN_CTX_end(ctx);
199e85b1b81Smiod BN_CTX_free(ctx);
20070901374Sjsing BN_free(kinv);
201c6a150b7Sjsing
202e85b1b81Smiod return ret;
203ba5406e9Sbeck }
204ba5406e9Sbeck
205e85b1b81Smiod static int
dsa_sign_setup(DSA * dsa,BN_CTX * ctx_in,BIGNUM ** kinvp,BIGNUM ** rp)206e85b1b81Smiod dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
207ba5406e9Sbeck {
20870901374Sjsing BIGNUM *k = NULL, *l = NULL, *m = NULL, *kinv = NULL, *r = NULL;
20970901374Sjsing BN_CTX *ctx = NULL;
21070901374Sjsing int q_bits;
21170901374Sjsing int ret = 0;
212ba5406e9Sbeck
21383f09c76Stb if (!dsa_check_key(dsa))
21483f09c76Stb goto err;
215767fe2ffSmarkus
216e85b1b81Smiod if ((r = BN_new()) == NULL)
217e85b1b81Smiod goto err;
218ba5406e9Sbeck
21970901374Sjsing if ((ctx = ctx_in) == NULL)
22070901374Sjsing ctx = BN_CTX_new();
22170901374Sjsing if (ctx == NULL)
22270901374Sjsing goto err;
22370901374Sjsing
22470901374Sjsing BN_CTX_start(ctx);
22570901374Sjsing
22670901374Sjsing if ((k = BN_CTX_get(ctx)) == NULL)
22770901374Sjsing goto err;
22870901374Sjsing if ((l = BN_CTX_get(ctx)) == NULL)
22970901374Sjsing goto err;
23070901374Sjsing if ((m = BN_CTX_get(ctx)) == NULL)
23170901374Sjsing goto err;
23270901374Sjsing
233edf1f588Stb /* Preallocate space */
234edf1f588Stb q_bits = BN_num_bits(dsa->q);
23570901374Sjsing if (!BN_set_bit(k, q_bits) ||
23670901374Sjsing !BN_set_bit(l, q_bits) ||
23770901374Sjsing !BN_set_bit(m, q_bits))
238edf1f588Stb goto err;
239edf1f588Stb
24012347e81Stb if (!bn_rand_interval(k, 1, dsa->q))
241e85b1b81Smiod goto err;
2426d388760Sdjm
24370901374Sjsing BN_set_flags(k, BN_FLG_CONSTTIME);
24455cda256Sbcook
245e85b1b81Smiod if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
2464fcf65c5Sdjm if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
247e85b1b81Smiod CRYPTO_LOCK_DSA, dsa->p, ctx))
2486d388760Sdjm goto err;
249ba5406e9Sbeck }
250ba5406e9Sbeck
251ba5406e9Sbeck /* Compute r = (g^k mod p) mod q */
2526d388760Sdjm
253e85b1b81Smiod /*
254e85b1b81Smiod * We do not want timing information to leak the length of k,
255edf1f588Stb * so we compute G^k using an equivalent exponent of fixed
256edf1f588Stb * bit-length.
2576d388760Sdjm *
258edf1f588Stb * We unconditionally perform both of these additions to prevent a
259edf1f588Stb * small timing information leakage. We then choose the sum that is
260edf1f588Stb * one bit longer than the modulus.
261edf1f588Stb *
262cef8f41dStb * TODO: revisit the bn_copy aiming for a memory access agnostic
263edf1f588Stb * conditional copy.
264e85b1b81Smiod */
2656d388760Sdjm
26670901374Sjsing if (!BN_add(l, k, dsa->q) ||
26770901374Sjsing !BN_add(m, l, dsa->q) ||
268cef8f41dStb !bn_copy(k, BN_num_bits(l) > q_bits ? l : m))
269e85b1b81Smiod goto err;
2706d388760Sdjm
271*7a31e386Stb if (!BN_mod_exp_mont_ct(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p))
27255cda256Sbcook goto err;
273b274ec66Sbeck
27444adc1eaSbeck if (!BN_mod_ct(r, r, dsa->q, ctx))
275e85b1b81Smiod goto err;
276ba5406e9Sbeck
277ba5406e9Sbeck /* Compute part of 's = inv(k) (m + xr) mod q' */
27870901374Sjsing if ((kinv = BN_mod_inverse_ct(NULL, k, dsa->q, ctx)) == NULL)
279e85b1b81Smiod goto err;
280ba5406e9Sbeck
28170901374Sjsing BN_free(*kinvp);
282ba5406e9Sbeck *kinvp = kinv;
283ba5406e9Sbeck kinv = NULL;
28470901374Sjsing
28570901374Sjsing BN_free(*rp);
286ba5406e9Sbeck *rp = r;
287c6a150b7Sjsing
288ba5406e9Sbeck ret = 1;
289c6a150b7Sjsing
290ba5406e9Sbeck err:
291e85b1b81Smiod if (!ret) {
2925067ae9fSbeck DSAerror(ERR_R_BN_LIB);
29370901374Sjsing BN_free(r);
294ba5406e9Sbeck }
29570901374Sjsing BN_CTX_end(ctx);
29670901374Sjsing if (ctx != ctx_in)
297e85b1b81Smiod BN_CTX_free(ctx);
298c6a150b7Sjsing
299e85b1b81Smiod return ret;
300ba5406e9Sbeck }
301ba5406e9Sbeck
302e85b1b81Smiod static int
dsa_do_verify(const unsigned char * dgst,int dgst_len,DSA_SIG * sig,DSA * dsa)303e85b1b81Smiod dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa)
304ba5406e9Sbeck {
30570901374Sjsing BIGNUM *u1 = NULL, *u2 = NULL, *t1 = NULL;
30670901374Sjsing BN_CTX *ctx = NULL;
307ba5406e9Sbeck BN_MONT_CTX *mont = NULL;
30841651db1Stb int qbits;
30941651db1Stb int ret = -1;
310e85b1b81Smiod
31183f09c76Stb if (!dsa_check_key(dsa))
31283f09c76Stb goto err;
31341651db1Stb
314e85b1b81Smiod if ((ctx = BN_CTX_new()) == NULL)
315e85b1b81Smiod goto err;
316767fe2ffSmarkus
31770901374Sjsing BN_CTX_start(ctx);
31870901374Sjsing
31970901374Sjsing if ((u1 = BN_CTX_get(ctx)) == NULL)
32070901374Sjsing goto err;
32170901374Sjsing if ((u2 = BN_CTX_get(ctx)) == NULL)
32270901374Sjsing goto err;
32370901374Sjsing if ((t1 = BN_CTX_get(ctx)) == NULL)
32470901374Sjsing goto err;
32570901374Sjsing
3264fcf65c5Sdjm if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
327e85b1b81Smiod BN_ucmp(sig->r, dsa->q) >= 0) {
328200c0290Sbeck ret = 0;
329200c0290Sbeck goto err;
330200c0290Sbeck }
3314fcf65c5Sdjm if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
332e85b1b81Smiod BN_ucmp(sig->s, dsa->q) >= 0) {
333200c0290Sbeck ret = 0;
334200c0290Sbeck goto err;
335200c0290Sbeck }
336200c0290Sbeck
337c6a150b7Sjsing /* Calculate w = inv(s) mod q, saving w in u2. */
33870901374Sjsing if ((BN_mod_inverse_ct(u2, sig->s, dsa->q, ctx)) == NULL)
339e85b1b81Smiod goto err;
340ba5406e9Sbeck
341e85b1b81Smiod /*
342e85b1b81Smiod * If the digest length is greater than the size of q use the
34383f09c76Stb * BN_num_bits(dsa->q) leftmost bits of the digest, see FIPS 186-4, 4.2.
344e85b1b81Smiod */
34583f09c76Stb qbits = BN_num_bits(dsa->q);
34641651db1Stb if (dgst_len > (qbits >> 3))
34741651db1Stb dgst_len = (qbits >> 3);
348c6a150b7Sjsing
349c6a150b7Sjsing /* Save m in u1. */
35070901374Sjsing if (BN_bin2bn(dgst, dgst_len, u1) == NULL)
351e85b1b81Smiod goto err;
352ba5406e9Sbeck
353c6a150b7Sjsing /* u1 = m * w mod q */
35470901374Sjsing if (!BN_mod_mul(u1, u1, u2, dsa->q, ctx))
355e85b1b81Smiod goto err;
356ba5406e9Sbeck
357ba5406e9Sbeck /* u2 = r * w mod q */
35870901374Sjsing if (!BN_mod_mul(u2, sig->r, u2, dsa->q, ctx))
359e85b1b81Smiod goto err;
360ba5406e9Sbeck
361e85b1b81Smiod if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
3624fcf65c5Sdjm mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
3636d388760Sdjm CRYPTO_LOCK_DSA, dsa->p, ctx);
3646d388760Sdjm if (!mont)
3656d388760Sdjm goto err;
366ba5406e9Sbeck }
367ba5406e9Sbeck
368*7a31e386Stb if (!BN_mod_exp2_mont(t1, dsa->g, u1, dsa->pub_key, u2, dsa->p,
369*7a31e386Stb ctx, mont))
37055cda256Sbcook goto err;
37155cda256Sbcook
372ba5406e9Sbeck /* let u1 = u1 mod q */
37370901374Sjsing if (!BN_mod_ct(u1, t1, dsa->q, ctx))
374e85b1b81Smiod goto err;
3754fcf65c5Sdjm
376c6a150b7Sjsing /* v is in u1 - if the signature is correct, it will be equal to r. */
37770901374Sjsing ret = BN_ucmp(u1, sig->r) == 0;
378ba5406e9Sbeck
379ba5406e9Sbeck err:
380ba04b2cdSbcook if (ret < 0)
3815067ae9fSbeck DSAerror(ERR_R_BN_LIB);
38270901374Sjsing BN_CTX_end(ctx);
383e85b1b81Smiod BN_CTX_free(ctx);
384c6a150b7Sjsing
385e85b1b81Smiod return ret;
386ba5406e9Sbeck }
387ba5406e9Sbeck
388e85b1b81Smiod static int
dsa_init(DSA * dsa)389e85b1b81Smiod dsa_init(DSA *dsa)
390ba5406e9Sbeck {
391ba5406e9Sbeck dsa->flags |= DSA_FLAG_CACHE_MONT_P;
392e85b1b81Smiod return 1;
393ba5406e9Sbeck }
394ba5406e9Sbeck
395e85b1b81Smiod static int
dsa_finish(DSA * dsa)396e85b1b81Smiod dsa_finish(DSA *dsa)
397ba5406e9Sbeck {
3984fcf65c5Sdjm BN_MONT_CTX_free(dsa->method_mont_p);
399e85b1b81Smiod return 1;
400ba5406e9Sbeck }
401c2cf2d55Stb
4023d9fb52eStb static const DSA_METHOD openssl_dsa_meth = {
40389625feaStb .name = "OpenSSL DSA method",
40489625feaStb .dsa_do_sign = dsa_do_sign,
40589625feaStb .dsa_sign_setup = dsa_sign_setup,
40689625feaStb .dsa_do_verify = dsa_do_verify,
40789625feaStb .init = dsa_init,
40889625feaStb .finish = dsa_finish,
40989625feaStb };
41089625feaStb
41189625feaStb const DSA_METHOD *
DSA_OpenSSL(void)41289625feaStb DSA_OpenSSL(void)
41389625feaStb {
41489625feaStb return &openssl_dsa_meth;
41589625feaStb }
41689625feaStb LCRYPTO_ALIAS(DSA_OpenSSL);
41789625feaStb
418c2cf2d55Stb DSA_SIG *
DSA_SIG_new(void)419c2cf2d55Stb DSA_SIG_new(void)
420c2cf2d55Stb {
421c2cf2d55Stb return calloc(1, sizeof(DSA_SIG));
422c2cf2d55Stb }
42381dbdadeSbeck LCRYPTO_ALIAS(DSA_SIG_new);
424c2cf2d55Stb
425c2cf2d55Stb void
DSA_SIG_free(DSA_SIG * sig)426c2cf2d55Stb DSA_SIG_free(DSA_SIG *sig)
427c2cf2d55Stb {
428c2cf2d55Stb if (sig == NULL)
429c2cf2d55Stb return;
430c2cf2d55Stb
431c2cf2d55Stb BN_free(sig->r);
432c2cf2d55Stb BN_free(sig->s);
433c2cf2d55Stb free(sig);
434c2cf2d55Stb }
43581dbdadeSbeck LCRYPTO_ALIAS(DSA_SIG_free);
436c2cf2d55Stb
437c2cf2d55Stb int
DSA_sign_setup(DSA * dsa,BN_CTX * ctx_in,BIGNUM ** kinvp,BIGNUM ** rp)438c2cf2d55Stb DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
439c2cf2d55Stb {
440c2cf2d55Stb return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
441c2cf2d55Stb }
44281dbdadeSbeck LCRYPTO_ALIAS(DSA_sign_setup);
443c2cf2d55Stb
444c2cf2d55Stb DSA_SIG *
DSA_do_sign(const unsigned char * dgst,int dlen,DSA * dsa)445c2cf2d55Stb DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
446c2cf2d55Stb {
447c2cf2d55Stb return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
448c2cf2d55Stb }
44981dbdadeSbeck LCRYPTO_ALIAS(DSA_do_sign);
450c2cf2d55Stb
451c2cf2d55Stb int
DSA_do_verify(const unsigned char * dgst,int dgst_len,DSA_SIG * sig,DSA * dsa)452c2cf2d55Stb DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa)
453c2cf2d55Stb {
454c2cf2d55Stb return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
455c2cf2d55Stb }
45681dbdadeSbeck LCRYPTO_ALIAS(DSA_do_verify);
457