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