OpenBSD manual page server

Manual Page Search Parameters

ECDSA_SIG_NEW(3) Library Functions Manual ECDSA_SIG_NEW(3)

ECDSA_SIG_new, ECDSA_SIG_free, ECDSA_SIG_get0, ECDSA_SIG_get0_r, ECDSA_SIG_get0_s, ECDSA_SIG_set0, i2d_ECDSA_SIG, d2i_ECDSA_SIG, ECDSA_size, ECDSA_sign, ECDSA_verify, ECDSA_do_sign, ECDSA_do_verifyElliptic Curve Digital Signature Algorithm

#include <openssl/ec.h>

ECDSA_SIG*
ECDSA_SIG_new(void);

void
ECDSA_SIG_free(ECDSA_SIG *sig);

void
ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **r, const BIGNUM **s);

const BIGNUM *
ECDSA_SIG_get0_r(const ECDSA_SIG *sig);

const BIGNUM *
ECDSA_SIG_get0_s(const ECDSA_SIG *sig);

int
ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);

int
i2d_ECDSA_SIG(const ECDSA_SIG *sig_in, unsigned char **der_out);

ECDSA_SIG*
d2i_ECDSA_SIG(ECDSA_SIG **sig_out, const unsigned char **der_in, long len);

int
ECDSA_size(const EC_KEY *eckey);

int
ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);

int
ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, const unsigned char *sig, int siglen, EC_KEY *eckey);

ECDSA_SIG*
ECDSA_do_sign(const unsigned char *dgst, int dgst_len, EC_KEY *eckey);

int
ECDSA_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY* eckey);

These functions provide a low level interface to ECDSA. Most applications should use the higher level EVP interface such as EVP_DigestSignInit(3) or EVP_DigestVerifyInit(3) instead. Creation of the required EC_KEY objects is described in EC_KEY_new(3).

The ECDSA_SIG structure consists of two BIGNUMs for the r and s value of an ECDSA signature (see X9.62 or FIPS 186-2).

struct {
	BIGNUM *r;
	BIGNUM *s;
} ECDSA_SIG;

() allocates a new ECDSA_SIG structure (note: this function also allocates the BIGNUMs) and initializes it.

() frees the ECDSA_SIG structure sig.

() retrieves internal pointers the r and s values contained in sig. The values r and s can also be retrieved separately by the corresponding function () and (), respectively.

() sets the r and s values in sig. Calling this function transfers the memory management of the values to sig. Therefore, the values that have been passed in should not be freed by the caller.

() creates the DER encoding of the ECDSA signature sig_in and writes the encoded signature to *der_out. () decodes the DER-encoded signature stored in the buffer *der_in which is len bytes long into *sig_out. For details about the semantics, examples, caveats, and bugs, see ASN1_item_d2i(3).

() returns the maximum length of a DER-encoded ECDSA signature created with the private EC key eckey.

() computes a digital signature of the dgstlen bytes hash value dgst using the private EC key eckey. The DER-encoded signature is stored in sig and its length is returned in siglen. Note: sig must point to ECDSA_size() bytes of memory. The parameter type is ignored.

() verifies that the signature in sig of size siglen is a valid ECDSA signature of the hash value dgst of size dgstlen using the public key eckey. The parameter type is ignored.

() computes a digital signature of the dgst_len bytes hash value dgst using the private key eckey. The signature is returned in a newly allocated ECDSA_SIG structure (or NULL on error).

() verifies that the signature sig is a valid ECDSA signature of the hash value dgst of size dgst_len using the public key eckey.

ECDSA_SIG_new() returns the new ECDSA_SIG object or NULL if an error occurs.

i2d_ECDSA_SIG() returns the number of bytes successfully encoded or a negative value if an error occurs.

d2i_ECDSA_SIG() returns a pointer to the decoded ECDSA_SIG structure or NULL if an error occurs.

ECDSA_size() returns the maximum length signature or 0 on error.

ECDSA_SIG_get0_r() and ECDSA_SIG_get0_s() return a pointer owned by the ECDSA_SIG object if it has been set or NULL otherwise.

ECDSA_SIG_set0() and ECDSA_sign() return 1 if successful or 0 on error.

ECDSA_do_sign() returns a pointer to an allocated ECDSA_SIG structure or NULL on error.

ECDSA_verify() and ECDSA_do_verify() return 1 for a valid signature, 0 for an invalid signature and -1 on error. The error codes can be obtained by ERR_get_error(3).

Creating an ECDSA signature of given SHA-384 hash value using the named curve secp384r1.

First step: create an EC_KEY object. This part is ECDSA specific.

int ret;
ECDSA_SIG *sig;
EC_KEY *eckey;

eckey = EC_KEY_new_by_curve_name(NID_secp384r1);
if (eckey == NULL) {
	/* error */
}
if (!EC_KEY_generate_key(eckey)) {
	/* error */
}

Second step: compute the ECDSA signature of a SHA-384 hash value using ECDSA_do_sign()

sig = ECDSA_do_sign(digest, SHA384_DIGEST_LENGTH, eckey);
if (sig == NULL) {
	/* error */
}

or using ECDSA_sign()

unsigned char *buffer, *pp;
int buf_len;

buf_len = ECDSA_size(eckey);
buffer  = malloc(buf_len);
pp = buffer;
if (!ECDSA_sign(0, dgst, dgstlen, pp, &buf_len, eckey) {
	/* error */
}

Third step: verify the created ECDSA signature using ECDSA_do_verify()

ret = ECDSA_do_verify(digest, SHA384_DIGEST_LENGTH, sig, eckey);

or using ECDSA_verify()

ret = ECDSA_verify(0, digest, SHA384_DIGEST_LENGTH, buffer, buf_len, eckey);

and finally evaluate the return value:

if (ret == -1) {
	/* error */
} else if (ret == 0) {
	/* incorrect signature */
} else {
	/* ret == 1 */
	/* signature ok */
}

crypto(3), d2i_ECPKParameters(3), DSA_new(3), EC_GROUP_new(3), EC_KEY_METHOD_new(3), EC_KEY_new(3), EC_KEY_set_ex_data(3), EVP_DigestSignInit(3), EVP_DigestVerifyInit(3), RSA_new(3)

ANSI X9.62, US Federal Information Processing Standard FIPS 186-5 (Digital Signature Standard, DSS)

ECDSA_SIG_new(), ECDSA_SIG_free(), i2d_ECDSA_SIG(), d2i_ECDSA_SIG(), ECDSA_size(), ECDSA_sign(), ECDSA_verify(), ECDSA_do_sign(), and ECDSA_do_verify() first appeared in OpenSSL 0.9.8 and have been available since OpenBSD 4.5.

ECDSA_SIG_get0() and ECDSA_SIG_set0() first appeared in OpenSSL 1.1.0 and have been available since OpenBSD 6.3. ECDSA_SIG_get0_r() and ECDSA_SIG_get0_s() first appeared in OpenSSL 1.1.1 and have been available since OpenBSD 7.1.

Nils Larsch for the OpenSSL project.

November 15, 2024 OpenBSD-current