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 #include 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. Linux 6.8.7-arch1-1 April 28, 2023 Linux 6.8.7-arch1-1