Modify DSA and DH keys to use a shared FFC_PARAMS struct
[openssl.git] / crypto / dsa / dsa_sign.c
1 /*
2  * Copyright 1995-2018 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 #include <openssl/bn.h>
11 #include "internal/cryptlib.h"
12 #include "dsa_local.h"
13 #include "crypto/asn1_dsa.h"
14 #include "crypto/dsa.h"
15
16 DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
17 {
18     return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
19 }
20
21 #ifndef OPENSSL_NO_DEPRECATED_3_0
22 int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
23 {
24     return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
25 }
26 #endif
27
28 DSA_SIG *DSA_SIG_new(void)
29 {
30     DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
31     if (sig == NULL)
32         DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
33     return sig;
34 }
35
36 void DSA_SIG_free(DSA_SIG *sig)
37 {
38     if (sig == NULL)
39         return;
40     BN_clear_free(sig->r);
41     BN_clear_free(sig->s);
42     OPENSSL_free(sig);
43 }
44
45 DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len)
46 {
47     DSA_SIG *sig;
48
49     if (len < 0)
50         return NULL;
51     if (psig != NULL && *psig != NULL) {
52         sig = *psig;
53     } else {
54         sig = DSA_SIG_new();
55         if (sig == NULL)
56             return NULL;
57     }
58     if (sig->r == NULL)
59         sig->r = BN_new();
60     if (sig->s == NULL)
61         sig->s = BN_new();
62     if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
63         if (psig == NULL || *psig == NULL)
64             DSA_SIG_free(sig);
65         return NULL;
66     }
67     if (psig != NULL && *psig == NULL)
68         *psig = sig;
69     return sig;
70 }
71
72 int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout)
73 {
74     BUF_MEM *buf = NULL;
75     size_t encoded_len;
76     WPACKET pkt;
77
78     if (ppout == NULL) {
79         if (!WPACKET_init_null(&pkt, 0))
80             return -1;
81     } else if (*ppout == NULL) {
82         if ((buf = BUF_MEM_new()) == NULL
83                 || !WPACKET_init_len(&pkt, buf, 0)) {
84             BUF_MEM_free(buf);
85             return -1;
86         }
87     } else {
88         if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
89             return -1;
90     }
91
92     if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
93             || !WPACKET_get_total_written(&pkt, &encoded_len)
94             || !WPACKET_finish(&pkt)) {
95         BUF_MEM_free(buf);
96         WPACKET_cleanup(&pkt);
97         return -1;
98     }
99
100     if (ppout != NULL) {
101         if (*ppout == NULL) {
102             *ppout = (unsigned char *)buf->data;
103             buf->data = NULL;
104             BUF_MEM_free(buf);
105         } else {
106             *ppout += encoded_len;
107         }
108     }
109
110     return (int)encoded_len;
111 }
112
113 int DSA_size(const DSA *dsa)
114 {
115     int ret;
116     DSA_SIG sig;
117
118     sig.r = sig.s = dsa->params.q;
119     ret = i2d_DSA_SIG(&sig, NULL);
120
121     if (ret < 0)
122         ret = 0;
123     return ret;
124 }
125
126 void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
127 {
128     if (pr != NULL)
129         *pr = sig->r;
130     if (ps != NULL)
131         *ps = sig->s;
132 }
133
134 int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
135 {
136     if (r == NULL || s == NULL)
137         return 0;
138     BN_clear_free(sig->r);
139     BN_clear_free(sig->s);
140     sig->r = r;
141     sig->s = s;
142     return 1;
143 }
144
145 int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst,
146                  int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa)
147 {
148     DSA_SIG *s;
149
150     /* legacy case uses the method table */
151     if (libctx == NULL || dsa->meth != DSA_get_default_method())
152         s = DSA_do_sign(dgst, dlen, dsa);
153     else
154         s = dsa_do_sign_int(libctx, dgst, dlen, dsa);
155     if (s == NULL) {
156         *siglen = 0;
157         return 0;
158     }
159     *siglen = i2d_DSA_SIG(s, &sig);
160     DSA_SIG_free(s);
161     return 1;
162 }
163
164 int DSA_sign(int type, const unsigned char *dgst, int dlen,
165              unsigned char *sig, unsigned int *siglen, DSA *dsa)
166 {
167     return dsa_sign_int(NULL, type, dgst, dlen, sig, siglen, dsa);
168 }
169
170 /* data has already been hashed (probably with SHA or SHA-1). */
171 /*-
172  * returns
173  *      1: correct signature
174  *      0: incorrect signature
175  *     -1: error
176  */
177 int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
178                const unsigned char *sigbuf, int siglen, DSA *dsa)
179 {
180     DSA_SIG *s;
181     const unsigned char *p = sigbuf;
182     unsigned char *der = NULL;
183     int derlen = -1;
184     int ret = -1;
185
186     s = DSA_SIG_new();
187     if (s == NULL)
188         return ret;
189     if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
190         goto err;
191     /* Ensure signature uses DER and doesn't have trailing garbage */
192     derlen = i2d_DSA_SIG(s, &der);
193     if (derlen != siglen || memcmp(sigbuf, der, derlen))
194         goto err;
195     ret = DSA_do_verify(dgst, dgst_len, s, dsa);
196  err:
197     OPENSSL_clear_free(der, derlen);
198     DSA_SIG_free(s);
199     return ret;
200 }
201