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

library “libcrypto”
`#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

BIO_new(3), EVP_DigestInit(3)

# 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.

June 8, 2025 | Debian