1.\" $OpenBSD: BIO_f_md.3,v 1.15 2023/04/28 16:20:01 schwarze Exp $ 2.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100 3.\" 4.\" This file is a derived work. 5.\" The changes are covered by the following Copyright and license: 6.\" 7.\" Copyright (c) 2022, 2023 Ingo Schwarze <schwarze@openbsd.org> 8.\" 9.\" Permission to use, copy, modify, and distribute this software for any 10.\" purpose with or without fee is hereby granted, provided that the above 11.\" copyright notice and this permission notice appear in all copies. 12.\" 13.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20.\" 21.\" The original file was written by Dr. Stephen Henson <steve@openssl.org>. 22.\" Copyright (c) 2000, 2006, 2009, 2016 The OpenSSL Project. 23.\" All rights reserved. 24.\" 25.\" Redistribution and use in source and binary forms, with or without 26.\" modification, are permitted provided that the following conditions 27.\" are met: 28.\" 29.\" 1. Redistributions of source code must retain the above copyright 30.\" notice, this list of conditions and the following disclaimer. 31.\" 32.\" 2. Redistributions in binary form must reproduce the above copyright 33.\" notice, this list of conditions and the following disclaimer in 34.\" the documentation and/or other materials provided with the 35.\" distribution. 36.\" 37.\" 3. All advertising materials mentioning features or use of this 38.\" software must display the following acknowledgment: 39.\" "This product includes software developed by the OpenSSL Project 40.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 41.\" 42.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 43.\" endorse or promote products derived from this software without 44.\" prior written permission. For written permission, please contact 45.\" openssl-core@openssl.org. 46.\" 47.\" 5. Products derived from this software may not be called "OpenSSL" 48.\" nor may "OpenSSL" appear in their names without prior written 49.\" permission of the OpenSSL Project. 50.\" 51.\" 6. Redistributions of any form whatsoever must retain the following 52.\" acknowledgment: 53.\" "This product includes software developed by the OpenSSL Project 54.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" 55.\" 56.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 57.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 59.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 60.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 61.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 62.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 63.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 65.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 66.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 67.\" OF THE POSSIBILITY OF SUCH DAMAGE. 68.\" 69.Dd $Mdocdate: April 28 2023 $ 70.Dt BIO_F_MD 3 71.Os 72.Sh NAME 73.Nm BIO_f_md , 74.Nm BIO_set_md , 75.Nm BIO_get_md , 76.Nm BIO_get_md_ctx , 77.Nm BIO_set_md_ctx 78.Nd message digest BIO filter 79.Sh SYNOPSIS 80.In openssl/bio.h 81.In openssl/evp.h 82.Ft const BIO_METHOD * 83.Fo BIO_f_md 84.Fa void 85.Fc 86.Ft long 87.Fo BIO_set_md 88.Fa "BIO *b" 89.Fa "EVP_MD *md" 90.Fc 91.Ft long 92.Fo BIO_get_md 93.Fa "BIO *b" 94.Fa "EVP_MD **mdp" 95.Fc 96.Ft long 97.Fo BIO_get_md_ctx 98.Fa "BIO *b" 99.Fa "EVP_MD_CTX **mdcp" 100.Fc 101.Ft long 102.Fo BIO_set_md_ctx 103.Fa "BIO *b" 104.Fa "EVP_MD_CTX *mdc" 105.Fc 106.Sh DESCRIPTION 107.Fn BIO_f_md 108returns the message digest BIO method. 109This is a filter BIO that digests any data passed through it. 110It is a BIO wrapper for the digest routines 111.Xr EVP_DigestInit 3 , 112.Xr EVP_DigestUpdate 3 , 113and 114.Xr EVP_DigestFinal 3 . 115.Pp 116.Fn BIO_set_md 117sets the message digest of 118.Fa b 119to 120.Fa md 121and initializes it using 122.Xr EVP_DigestInit_ex 3 . 123Calling this function is required before any data is passed through 124.Fa b . 125.Pp 126.Fn BIO_get_md 127places a pointer to the digest method of 128.Fa b 129into 130.Pf * Fa mdp . 131.Pp 132Any data written or read through a digest BIO using 133.Xr BIO_read 3 134and 135.Xr BIO_write 3 136is digested. 137.Pp 138.Xr BIO_gets 3 , 139if its 140.Sy size 141parameter is large enough, 142finishes the digest calculation and returns the digest value. 143.Xr BIO_puts 3 144is 145not supported. 146If an application needs to call 147.Xr BIO_gets 3 148or 149.Xr BIO_puts 3 150through a chain containing digest BIOs, 151this can be done by prepending a buffering BIO. 152.Pp 153After the digest has been retrieved from a digest BIO, call 154.Xr BIO_reset 3 155to reinitialize it and any BIOs following it in its chain 156before passing any more data through it. 157If no subsequent BIOs require reinitialization, 158.Fn BIO_set_md 159can be used instead of 160.Xr BIO_reset 3 . 161.Pp 162.Fn BIO_get_md_ctx 163places a pointer to the digest context of 164.Fa b 165into 166.Pf * Fa mdcp 167and marks the BIO as initialized without actually initializing it. 168Unless 169.Fn BIO_set_md 170was already called on 171.Fa b , 172the caller becomes responsible for initializing the digest context with 173.Xr EVP_DigestInit_ex 3 . 174.Pp 175The context returned by 176.Fn BIO_get_md_ctx 177can be used in calls to 178.Xr EVP_DigestFinal 3 179and also in the signature routines 180.Xr EVP_SignFinal 3 181and 182.Xr EVP_VerifyFinal 3 . 183.Pp 184The context returned by 185.Fn BIO_get_md_ctx 186is an internal context structure. 187Changes made to this context will affect the digest BIO itself, and 188the context pointer will become invalid when the digest BIO is freed. 189.Pp 190.Fn BIO_set_md_ctx 191replaces the digest context of 192.Fa b 193with 194.Fa mdc . 195Calling this function is usually not necessary 196because creating a digest BIO with 197.Xr BIO_new 3 198automatically creates a digest context and stores it internally. 199Before calling 200.Fn BIO_set_md_ctx , 201the caller has to retrieve the old context using 202.Fn BIO_get_md_ctx , 203and the caller also becomes responsible for calling 204.Xr EVP_MD_CTX_free 3 205on the old context. 206Unless 207.Fa mdc 208is already initialized, the caller needs to initialize it after calling 209.Fn BIO_set_md_ctx 210using either 211.Fn BIO_set_md 212or 213.Xr EVP_DigestInit 3 . 214.Pp 215When a chain containing a message digest BIO is copied with 216.Xr BIO_dup_chain 3 , 217.Xr EVP_MD_CTX_copy_ex 3 218is called internally to automatically copy the message digest context 219from the existing BIO object to the new one, 220and the init flag that can be retrieved with 221.Xr BIO_get_init 3 222is set to 1. 223.Pp 224.Xr BIO_ctrl 3 225.Fa cmd 226arguments correspond to macros as follows: 227.Bl -column BIO_C_GET_MD_CTX "corresponding macro" -offset 3n 228.It Fa cmd No constant Ta corresponding macro 229.It Dv BIO_C_GET_MD Ta Fn BIO_get_md 230.It Dv BIO_C_GET_MD_CTX Ta Fn BIO_get_md_ctx 231.It Dv BIO_C_SET_MD Ta Fn BIO_set_md 232.It Dv BIO_C_SET_MD_CTX Ta Fn BIO_set_md_ctx 233.It Dv BIO_CTRL_RESET Ta Xr BIO_reset 3 234.El 235.Sh RETURN VALUES 236.Fn BIO_f_md 237returns the digest BIO method. 238.Pp 239When called on a message digest BIO object, 240.Xr BIO_method_type 3 241returns the constant 242.Dv BIO_TYPE_MD 243and 244.Xr BIO_method_name 3 245returns a pointer to the static string 246.Qq message digest . 247.Pp 248.Fn BIO_set_md 249returns 1 on success or 0 if 250.Xr EVP_DigestInit_ex 3 251fails. 252.Pp 253.Fn BIO_get_md 254and 255.Fn BIO_set_md_ctx 256return 1 on success or 0 if 257.Fa b 258is not initialized. 259.Pp 260.Fn BIO_get_md_ctx 261returns 1 on success or 0 on failure, 262but the current implementation cannot actually fail. 263.Sh EXAMPLES 264The following example creates a BIO chain containing a SHA-1 and MD5 265digest BIO and passes the string "Hello World" through it. 266Error checking has been omitted for clarity. 267.Bd -literal -offset 2n 268BIO *bio, *mdtmp; 269const char message[] = "Hello World"; 270bio = BIO_new(BIO_s_null()); 271mdtmp = BIO_new(BIO_f_md()); 272BIO_set_md(mdtmp, EVP_sha1()); 273/* 274 * For BIO_push() we want to append the sink BIO 275 * and keep a note of the start of the chain. 276 */ 277bio = BIO_push(mdtmp, bio); 278mdtmp = BIO_new(BIO_f_md()); 279BIO_set_md(mdtmp, EVP_md5()); 280bio = BIO_push(mdtmp, bio); 281/* Note: mdtmp can now be discarded */ 282BIO_write(bio, message, strlen(message)); 283.Ed 284.Pp 285The next example digests data by reading through a chain instead: 286.Bd -literal -offset 2n 287BIO *bio, *mdtmp; 288char buf[1024]; 289int rdlen; 290 291bio = BIO_new_file(file, "rb"); 292mdtmp = BIO_new(BIO_f_md()); 293BIO_set_md(mdtmp, EVP_sha1()); 294bio = BIO_push(mdtmp, bio); 295mdtmp = BIO_new(BIO_f_md()); 296BIO_set_md(mdtmp, EVP_md5()); 297bio = BIO_push(mdtmp, bio); 298do { 299 rdlen = BIO_read(bio, buf, sizeof(buf)); 300 /* Might want to do something with the data here */ 301} while (rdlen > 0); 302.Ed 303.Pp 304This next example retrieves the message digests from a BIO chain 305and outputs them. 306This could be used with the examples above. 307.Bd -literal -offset 2n 308BIO *mdtmp; 309unsigned char mdbuf[EVP_MAX_MD_SIZE]; 310int mdlen; 311int i; 312 313mdtmp = bio; /* Assume bio has previously been set up */ 314do { 315 EVP_MD *md; 316 mdtmp = BIO_find_type(mdtmp, BIO_TYPE_MD); 317 if (!mdtmp) 318 break; 319 BIO_get_md(mdtmp, &md); 320 printf("%s digest", OBJ_nid2sn(EVP_MD_type(md))); 321 mdlen = BIO_gets(mdtmp, mdbuf, EVP_MAX_MD_SIZE); 322 for(i = 0; i < mdlen; i++) 323 printf(":%02X", mdbuf[i]); 324 printf("\en"); 325 mdtmp = BIO_next(mdtmp); 326} while(mdtmp); 327BIO_free_all(bio); 328.Ed 329.Sh SEE ALSO 330.Xr BIO_new 3 , 331.Xr EVP_DigestInit 3 332.Sh HISTORY 333.Fn BIO_f_md , 334.Fn BIO_set_md , 335and 336.Fn BIO_get_md 337first appeared in SSLeay 0.6.0. 338.Fn BIO_get_md_ctx 339first appeared in SSLeay 0.8.1. 340These functions have been available since 341.Ox 2.4 . 342.Pp 343.Fn BIO_set_md_ctx 344first appeared in OpenSSL 0.9.7e and has been available since 345.Ox 3.8 . 346.Pp 347Before OpenSSL 1.0.0, the call to 348.Fn BIO_get_md_ctx 349would only work if the 350.Vt BIO 351had been initialized, for example by calling 352.Fn BIO_set_md . 353.Sh BUGS 354The lack of support for 355.Xr BIO_puts 3 356and the non-standard behaviour of 357.Xr BIO_gets 3 358could be regarded as anomalous. 359It could be argued that 360.Xr BIO_gets 3 361and 362.Xr BIO_puts 3 363should be passed to the next BIO in the chain and digest the data 364passed through and that digests should be retrieved using a separate 365.Xr BIO_ctrl 3 366call. 367