1/* 2 * Copyright 1995-2023 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 22DSA_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 28int 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 34DSA_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 42void 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 51DSA_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 79int 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 120int 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 135void 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 143int 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 154int 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 178int 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 */ 191int 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