BIO_F_MD(3)
okay so welcome to BIO_F_MD(3) from the Library Functions Manual, bestie π
this is the message digest BIO filter and itβs literally giving main character energy.
β¨ 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. Itβs a filter BIO that digests any data passed through it. Lowkey itβs a BIO wrapper for the digest routines EVP_DigestInit(3), EVP_DigestUpdate(3), and EVP_DigestFinal(3). β¨
BIO_set_md()β sets the message digest ofbtomdand initializes it usingEVP_DigestInit_ex(3). Calling this function is required before any data is passed throughb, no cap.BIO_get_md()β places a pointer to the digest method ofbinto*mdp.
Any data written or read through a digest BIO using BIO_read(3) and BIO_write(3) is digested. Thatβs the whole vibe check. π«Ά
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). periodt.
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).
π okay important bestie: 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. iconic behavior honestly. π
BIO_ctrl(3) cmd arguments correspond to macros as follows:
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 constantBIO_TYPE_MDandBIO_method_name(3)returns a pointer to the static string"message digest". BIO_set_md()returns1on success or0ifEVP_DigestInit_ex(3)fails.BIO_get_md()andBIO_set_md_ctx()return1on success or0ifbis not initialized.BIO_get_md_ctx()returns1on success or0on failure, but the current implementation cannot actually fail. π
π EXAMPLES π
okay so this first 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(), andBIO_get_md()first appeared in SSLeay0.6.0.BIO_get_md_ctx()first appeared in SSLeay0.8.1. These functions have been available since OpenBSD2.4.BIO_set_md_ctx()first appeared in OpenSSL0.9.7eand has been available since OpenBSD3.8.- Before OpenSSL
1.0.0, the call toBIO_get_md_ctx()would only work if the BIO had been initialized, for example by callingBIO_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. π
π«Ά thatβs the whole page bestie β from Debian, dated April 28, 2023, and the manual is BIO_F_MD(3). slay π
π¦ where this page comes from
- opensuse-leap 16.0: libressl-devel-doc 4.1.0-bp160.1.1 Β· OpenSSL
- Copyright (c) 2022, 2023 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2000, 2006, 2009, 2016 The OpenSSL Project
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms