=pod

=head1 NAME

EVP_SignInit, EVP_SignUpdate, EVP_SignFinal - EVP signing functions

=head1 SYNOPSIS

 #include <openssl/evp.h>

 int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
 int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
 int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey);

 void EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);

 int EVP_PKEY_size(EVP_PKEY *pkey);

=head1 DESCRIPTION

The EVP signature routines are a high level interface to digital
signatures.

EVP_SignInit_ex() sets up signing context B<ctx> to use digest
B<type> from ENGINE B<impl>. B<ctx> must be initialized with
EVP_MD_CTX_init() before calling this function.

EVP_SignUpdate() hashes B<cnt> bytes of data at B<d> into the
signature context B<ctx>. This function can be called several times on the
same B<ctx> to include additional data.

EVP_SignFinal() signs the data in B<ctx> using the private key B<pkey> and
places the signature in B<sig>. The number of bytes of data written (i.e. the
length of the signature) will be written to the integer at B<s>, at most
EVP_PKEY_size(pkey) bytes will be written. 

EVP_SignInit() initializes a signing context B<ctx> to use the default
implementation of digest B<type>.

EVP_PKEY_size() returns the maximum size of a signature in bytes. The actual
signature returned by EVP_SignFinal() may be smaller.

=head1 RETURN VALUES

EVP_SignInit_ex(), EVP_SignUpdate() and EVP_SignFinal() return 1
for success and 0 for failure.

EVP_PKEY_size() returns the maximum size of a signature in bytes.

The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.

=head1 NOTES

The B<EVP> interface to digital signatures should almost always be used in
preference to the low level interfaces. This is because the code then becomes
transparent to the algorithm used and much more flexible.

Due to the link between message digests and public key algorithms the correct
digest algorithm must be used with the correct public key type. A list of
algorithms and associated public key algorithms appears in 
L<EVP_DigestInit(3)|EVP_DigestInit(3)>.

When signing with DSA private keys the random number generator must be seeded
or the operation will fail. The random number generator does not need to be
seeded for RSA signatures.

The call to EVP_SignFinal() internally finalizes a copy of the digest context.
This means that calls to EVP_SignUpdate() and EVP_SignFinal() can be called
later to digest and sign additional data.

Since only a copy of the digest context is ever finalized the context must
be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
will occur.

=head1 BUGS

Older versions of this documentation wrongly stated that calls to 
EVP_SignUpdate() could not be made after calling EVP_SignFinal().

=head1 SEE ALSO

L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>,
L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>

=head1 HISTORY

EVP_SignInit(), EVP_SignUpdate() and EVP_SignFinal() are
available in all versions of SSLeay and OpenSSL.

EVP_SignInit_ex() was added in OpenSSL 0.9.7.

=cut
