Sortix nightly manual
This manual documents Sortix nightly, a development build that has not been officially released. You can instead view this document in the latest official manual.
| BIO_F_MD(3) | Library Functions Manual | BIO_F_MD(3) | 
NAME
BIO_f_md,
    BIO_set_md, BIO_get_md,
    BIO_get_md_ctx,
    BIO_set_md_ctx — message
    digest BIO filter
SYNOPSIS
#include
    <openssl/bio.h>
  
  #include <openssl/evp.h>
const BIO_METHOD *
  
  BIO_f_md(void);
long
  
  BIO_set_md(BIO *b,
    EVP_MD *md);
long
  
  BIO_get_md(BIO *b,
    EVP_MD **mdp);
long
  
  BIO_get_md_ctx(BIO *b,
    EVP_MD_CTX **mdcp);
long
  
  BIO_set_md_ctx(BIO *b,
    EVP_MD_CTX *mdc);
DESCRIPTION
BIO_f_md()
    returns the message digest BIO method. This is a filter BIO that digests any
    data passed through it. It is a BIO wrapper for the digest routines
    EVP_DigestInit(3),
    EVP_DigestUpdate(3),
    and
    EVP_DigestFinal(3).
BIO_set_md()
    sets the message digest of b to
    md and initializes it using
    EVP_DigestInit_ex(3).
    Calling this function is required before any data is passed through
    b.
BIO_get_md()
    places a pointer to the digest method of b into
    *mdp.
Any data written or read through a digest BIO using BIO_read(3) and BIO_write(3) is digested.
BIO_gets(3), if its size parameter is large enough, finishes the digest calculation and returns the digest value. BIO_puts(3) is not supported. If an application needs to call BIO_gets(3) or BIO_puts(3) through a chain containing digest BIOs, this can be done by prepending a buffering BIO.
After the digest has been retrieved from a
    digest BIO, call
    BIO_reset(3) to
    reinitialize it and any BIOs following it in its chain before passing any
    more data through it. If no subsequent BIOs require reinitialization,
    BIO_set_md()
    can be used instead of
    BIO_reset(3).
BIO_get_md_ctx()
    places a pointer to the digest context of b into
    *mdcp and marks the BIO as initialized without
    actually initializing it. Unless BIO_set_md() was
    already called on b, the caller becomes responsible
    for initializing the digest context with
    EVP_DigestInit_ex(3).
The context returned by
    BIO_get_md_ctx()
    can be used in calls to
    EVP_DigestFinal(3)
    and also in the signature routines
    EVP_SignFinal(3) and
    EVP_VerifyFinal(3).
The context returned by
    BIO_get_md_ctx()
    is an internal context structure. Changes made to this context will affect
    the digest BIO itself, and the context pointer will become invalid when the
    digest BIO is freed.
BIO_set_md_ctx()
    replaces the digest context of b with
    mdc. Calling this function is usually not necessary
    because creating a digest BIO with
    BIO_new(3) automatically
    creates a digest context and stores it internally. Before calling
    BIO_set_md_ctx(), the caller has to retrieve the old
    context using BIO_get_md_ctx(), and the caller also
    becomes responsible for calling
    EVP_MD_CTX_free(3)
    on the old context. Unless mdc is already initialized,
    the caller needs to initialize it after calling
    BIO_set_md_ctx() using either
    BIO_set_md() or
    EVP_DigestInit(3).
When a chain containing a message digest BIO is copied with BIO_dup_chain(3), EVP_MD_CTX_copy_ex(3) is called internally to automatically copy the message digest context from the existing BIO object to the new one, and the init flag that can be retrieved with BIO_get_init(3) is set to 1.
BIO_ctrl(3) cmd arguments correspond to macros as follows:
| cmd constant | corresponding macro | 
| BIO_C_GET_MD | BIO_get_md() | 
| BIO_C_GET_MD_CTX | BIO_get_md_ctx() | 
| BIO_C_SET_MD | BIO_set_md() | 
| BIO_C_SET_MD_CTX | BIO_set_md_ctx() | 
| BIO_CTRL_RESET | BIO_reset(3) | 
RETURN VALUES
BIO_f_md() returns the digest BIO
  method.
When called on a message digest BIO object,
    BIO_method_type(3)
    returns the constant BIO_TYPE_MD and
    BIO_method_name(3)
    returns a pointer to the static string "message digest".
BIO_set_md() returns 1 on success or 0 if
    EVP_DigestInit_ex(3)
    fails.
BIO_get_md() and
    BIO_set_md_ctx() return 1 on success or 0 if
    b is not initialized.
BIO_get_md_ctx() returns 1 on success or 0
    on failure, but the current implementation cannot actually fail.
EXAMPLES
The following example creates a BIO chain containing a SHA-1 and MD5 digest BIO and passes the string "Hello World" through it. Error checking has been omitted for clarity.
BIO *bio, *mdtmp; const char message[] = "Hello World"; bio = BIO_new(BIO_s_null()); mdtmp = BIO_new(BIO_f_md()); BIO_set_md(mdtmp, EVP_sha1()); /* * For BIO_push() we want to append the sink BIO * and keep a note of the start of the chain. */ bio = BIO_push(mdtmp, bio); mdtmp = BIO_new(BIO_f_md()); BIO_set_md(mdtmp, EVP_md5()); bio = BIO_push(mdtmp, bio); /* Note: mdtmp can now be discarded */ BIO_write(bio, message, strlen(message));
The next example digests data by reading through a chain instead:
BIO *bio, *mdtmp;
char buf[1024];
int rdlen;
bio = BIO_new_file(file, "rb");
mdtmp = BIO_new(BIO_f_md());
BIO_set_md(mdtmp, EVP_sha1());
bio = BIO_push(mdtmp, bio);
mdtmp = BIO_new(BIO_f_md());
BIO_set_md(mdtmp, EVP_md5());
bio = BIO_push(mdtmp, bio);
do {
	rdlen = BIO_read(bio, buf, sizeof(buf));
	/* Might want to do something with the data here */
} while (rdlen > 0);
This next example retrieves the message digests from a BIO chain and outputs them. This could be used with the examples above.
BIO *mdtmp;
unsigned char mdbuf[EVP_MAX_MD_SIZE];
int mdlen;
int i;
mdtmp = bio;	/* Assume bio has previously been set up */
do {
	EVP_MD *md;
	mdtmp = BIO_find_type(mdtmp, BIO_TYPE_MD);
	if (!mdtmp)
		break;
	BIO_get_md(mdtmp, &md);
	printf("%s digest", OBJ_nid2sn(EVP_MD_type(md)));
	mdlen = BIO_gets(mdtmp, mdbuf, EVP_MAX_MD_SIZE);
	for(i = 0; i < mdlen; i++)
		printf(":%02X", mdbuf[i]);
	printf("\n");
	mdtmp = BIO_next(mdtmp);
} while(mdtmp);
BIO_free_all(bio);
SEE ALSO
HISTORY
BIO_f_md(),
    BIO_set_md(), and
    BIO_get_md() first appeared in SSLeay 0.6.0.
    BIO_get_md_ctx() first appeared in SSLeay 0.8.1.
    These functions have been available since OpenBSD
    2.4.
BIO_set_md_ctx() first appeared in OpenSSL
    0.9.7e and has been available since OpenBSD 3.8.
Before OpenSSL 1.0.0, the call to
    BIO_get_md_ctx() would only work if the
    BIO had been initialized, for example by calling
    BIO_set_md().
BUGS
The lack of support for BIO_puts(3) and the non-standard behaviour of BIO_gets(3) could be regarded as anomalous. It could be argued that BIO_gets(3) and BIO_puts(3) should be passed to the next BIO in the chain and digest the data passed through and that digests should be retrieved using a separate BIO_ctrl(3) call.
| April 28, 2023 | Sortix 1.1.0-dev | 
