| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  | /*-
 | 
					
						
							| 
									
										
										
										
											2024-03-29 22:05:51 +08:00
										 |  |  |  * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*-
 | 
					
						
							|  |  |  |  * Example of using EVP_MD_fetch and EVP_Digest* methods to calculate | 
					
						
							|  |  |  |  * a digest of static buffers | 
					
						
							|  |  |  |  * You can find SHA3 test vectors from NIST here: | 
					
						
							|  |  |  |  * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/sha3/sha-3bytetestvectors.zip
 | 
					
						
							|  |  |  |  * For example, contains these lines: | 
					
						
							|  |  |  |     Len = 80 | 
					
						
							|  |  |  |     Msg = 1ca984dcc913344370cf | 
					
						
							|  |  |  |     MD = 6915ea0eeffb99b9b246a0e34daf3947852684c3d618260119a22835659e4f23d4eb66a15d0affb8e93771578f5e8f25b7a5f2a55f511fb8b96325ba2cd14816 | 
					
						
							|  |  |  |  * use xxd convert the hex message string to binary input for EVP_MD_stdin: | 
					
						
							|  |  |  |  * echo "1ca984dcc913344370cf" | xxd -r -p | ./EVP_MD_stdin | 
					
						
							|  |  |  |  * and then verify the output matches MD above. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <openssl/err.h>
 | 
					
						
							|  |  |  | #include <openssl/evp.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*-
 | 
					
						
							|  |  |  |  * This demonstration will show how to digest data using | 
					
						
							|  |  |  |  * a BIO created to read from stdin | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-06 10:20:54 +08:00
										 |  |  | static int demonstrate_digest(BIO *input) | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *library_context = NULL; | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |     int ret = 0; | 
					
						
							| 
									
										
										
										
											2023-07-17 02:03:40 +08:00
										 |  |  |     const char *option_properties = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |     EVP_MD *message_digest = NULL; | 
					
						
							|  |  |  |     EVP_MD_CTX *digest_context = NULL; | 
					
						
							| 
									
										
										
										
											2024-04-06 10:20:54 +08:00
										 |  |  |     unsigned int digest_length; | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |     unsigned char *digest_value = NULL; | 
					
						
							|  |  |  |     unsigned char buffer[512]; | 
					
						
							| 
									
										
										
										
											2024-04-06 10:20:54 +08:00
										 |  |  |     unsigned int ii; | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     library_context = OSSL_LIB_CTX_new(); | 
					
						
							|  |  |  |     if (library_context == NULL) { | 
					
						
							|  |  |  |         fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n"); | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Fetch a message digest by name | 
					
						
							|  |  |  |      * The algorithm name is case insensitive.  | 
					
						
							|  |  |  |      * See providers(7) for details about algorithm fetching | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     message_digest = EVP_MD_fetch(library_context, | 
					
						
							|  |  |  |                                   "SHA3-512", option_properties); | 
					
						
							|  |  |  |     if (message_digest == NULL) { | 
					
						
							|  |  |  |         fprintf(stderr, "EVP_MD_fetch could not find SHA3-512."); | 
					
						
							|  |  |  |         ERR_print_errors_fp(stderr); | 
					
						
							|  |  |  |         OSSL_LIB_CTX_free(library_context); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* Determine the length of the fetched digest type */ | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |     digest_length = EVP_MD_get_size(message_digest); | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |     if (digest_length <= 0) { | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |         fprintf(stderr, "EVP_MD_get_size returned invalid size.\n"); | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     digest_value = OPENSSL_malloc(digest_length); | 
					
						
							|  |  |  |     if (digest_value == NULL) { | 
					
						
							|  |  |  |         fprintf(stderr, "No memory.\n"); | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Make a message digest context to hold temporary state | 
					
						
							|  |  |  |      * during digest creation | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     digest_context = EVP_MD_CTX_new(); | 
					
						
							|  |  |  |     if (digest_context == NULL) { | 
					
						
							|  |  |  |         fprintf(stderr, "EVP_MD_CTX_new failed.\n"); | 
					
						
							|  |  |  |         ERR_print_errors_fp(stderr); | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Initialize the message digest context to use the fetched  | 
					
						
							|  |  |  |      * digest provider | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (EVP_DigestInit(digest_context, message_digest) != 1) { | 
					
						
							|  |  |  |         fprintf(stderr, "EVP_DigestInit failed.\n"); | 
					
						
							|  |  |  |         ERR_print_errors_fp(stderr); | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     while ((ii = BIO_read(input, buffer, sizeof(buffer))) > 0) { | 
					
						
							|  |  |  |         if (EVP_DigestUpdate(digest_context, buffer, ii) != 1) { | 
					
						
							|  |  |  |             fprintf(stderr, "EVP_DigestUpdate() failed.\n"); | 
					
						
							|  |  |  |             goto cleanup; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (EVP_DigestFinal(digest_context, digest_value, &digest_length) != 1) { | 
					
						
							|  |  |  |         fprintf(stderr, "EVP_DigestFinal() failed.\n"); | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |     ret = 1; | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |     for (ii=0; ii<digest_length; ii++) { | 
					
						
							|  |  |  |         fprintf(stdout, "%02x", digest_value[ii]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     fprintf(stdout, "\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cleanup: | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |     if (ret != 1) | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |         ERR_print_errors_fp(stderr); | 
					
						
							|  |  |  |     /* OpenSSL free functions will ignore NULL arguments */ | 
					
						
							|  |  |  |     EVP_MD_CTX_free(digest_context); | 
					
						
							|  |  |  |     OPENSSL_free(digest_value); | 
					
						
							|  |  |  |     EVP_MD_free(message_digest); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OSSL_LIB_CTX_free(library_context); | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |     int ret = EXIT_FAILURE; | 
					
						
							| 
									
										
										
										
											2021-10-26 15:16:18 +08:00
										 |  |  |     BIO *input = BIO_new_fd(fileno(stdin), 1); | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (input != NULL) { | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |         ret = (demonstrate_digest(input) ? EXIT_SUCCESS : EXIT_FAILURE); | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  |         BIO_free(input); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-20 12:48:33 +08:00
										 |  |  |     if (ret != EXIT_SUCCESS) | 
					
						
							|  |  |  |         ERR_print_errors_fp(stderr); | 
					
						
							|  |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2021-02-11 06:49:19 +08:00
										 |  |  | } |