Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/demos/digest/EVP_MD_demo.c
34889 views
1
/*-
2
* Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
/*
11
* Example of using EVP_MD_fetch and EVP_Digest* methods to calculate
12
* a digest of static buffers
13
*/
14
15
#include <string.h>
16
#include <stdio.h>
17
#include <openssl/err.h>
18
#include <openssl/evp.h>
19
20
/*-
21
* This demonstration will show how to digest data using
22
* the soliloqy from Hamlet scene 1 act 3
23
* The soliloqy is split into two parts to demonstrate using EVP_DigestUpdate
24
* more than once.
25
*/
26
27
static const char *hamlet_1 =
28
"To be, or not to be, that is the question,\n"
29
"Whether tis nobler in the minde to suffer\n"
30
"The ſlings and arrowes of outragious fortune,\n"
31
"Or to take Armes again in a sea of troubles,\n"
32
"And by opposing, end them, to die to sleep;\n"
33
"No more, and by a sleep, to say we end\n"
34
"The heart-ache, and the thousand natural shocks\n"
35
"That flesh is heir to? tis a consumation\n"
36
"Devoutly to be wished. To die to sleep,\n"
37
"To sleepe, perchance to dreame, Aye, there's the rub,\n"
38
"For in that sleep of death what dreams may come\n"
39
"When we haue shuffled off this mortal coil\n"
40
"Must give us pause. There's the respect\n"
41
"That makes calamity of so long life:\n"
42
"For who would bear the Ships and Scorns of time,\n"
43
"The oppressor's wrong, the proud man's Contumely,\n"
44
"The pangs of dispised love, the Law's delay,\n"
45
;
46
static const char *hamlet_2 =
47
"The insolence of Office, and the spurns\n"
48
"That patient merit of the'unworthy takes,\n"
49
"When he himself might his Quietas make\n"
50
"With a bare bodkin? Who would fardels bear,\n"
51
"To grunt and sweat under a weary life,\n"
52
"But that the dread of something after death,\n"
53
"The undiscovered country, from whose bourn\n"
54
"No traveller returns, puzzles the will,\n"
55
"And makes us rather bear those ills we have,\n"
56
"Then fly to others we know not of?\n"
57
"Thus conscience does make cowards of us all,\n"
58
"And thus the native hue of Resolution\n"
59
"Is sickled o'er with the pale cast of Thought,\n"
60
"And enterprises of great pith and moment,\n"
61
"With this regard their currents turn awry,\n"
62
"And lose the name of Action. Soft you now,\n"
63
"The fair Ophelia? Nymph in thy Orisons\n"
64
"Be all my sins remember'd.\n"
65
;
66
67
/* The known value of the SHA3-512 digest of the above soliloqy */
68
static const unsigned char known_answer[] = {
69
0xbb, 0x69, 0xf8, 0x09, 0x9c, 0x2e, 0x00, 0x3d,
70
0xa4, 0x29, 0x5f, 0x59, 0x4b, 0x89, 0xe4, 0xd9,
71
0xdb, 0xa2, 0xe5, 0xaf, 0xa5, 0x87, 0x73, 0x9d,
72
0x83, 0x72, 0xcf, 0xea, 0x84, 0x66, 0xc1, 0xf9,
73
0xc9, 0x78, 0xef, 0xba, 0x3d, 0xe9, 0xc1, 0xff,
74
0xa3, 0x75, 0xc7, 0x58, 0x74, 0x8e, 0x9c, 0x1d,
75
0x14, 0xd9, 0xdd, 0xd1, 0xfd, 0x24, 0x30, 0xd6,
76
0x81, 0xca, 0x8f, 0x78, 0x29, 0x19, 0x9a, 0xfe,
77
};
78
79
static int demonstrate_digest(void)
80
{
81
OSSL_LIB_CTX *library_context;
82
int ret = 0;
83
const char *option_properties = NULL;
84
EVP_MD *message_digest = NULL;
85
EVP_MD_CTX *digest_context = NULL;
86
unsigned int digest_length;
87
unsigned char *digest_value = NULL;
88
unsigned int j;
89
90
library_context = OSSL_LIB_CTX_new();
91
if (library_context == NULL) {
92
fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
93
goto cleanup;
94
}
95
96
/*
97
* Fetch a message digest by name
98
* The algorithm name is case insensitive.
99
* See providers(7) for details about algorithm fetching
100
*/
101
message_digest = EVP_MD_fetch(library_context,
102
"SHA3-512", option_properties);
103
if (message_digest == NULL) {
104
fprintf(stderr, "EVP_MD_fetch could not find SHA3-512.");
105
goto cleanup;
106
}
107
/* Determine the length of the fetched digest type */
108
digest_length = EVP_MD_get_size(message_digest);
109
if (digest_length <= 0) {
110
fprintf(stderr, "EVP_MD_get_size returned invalid size.\n");
111
goto cleanup;
112
}
113
114
digest_value = OPENSSL_malloc(digest_length);
115
if (digest_value == NULL) {
116
fprintf(stderr, "No memory.\n");
117
goto cleanup;
118
}
119
/*
120
* Make a message digest context to hold temporary state
121
* during digest creation
122
*/
123
digest_context = EVP_MD_CTX_new();
124
if (digest_context == NULL) {
125
fprintf(stderr, "EVP_MD_CTX_new failed.\n");
126
goto cleanup;
127
}
128
/*
129
* Initialize the message digest context to use the fetched
130
* digest provider
131
*/
132
if (EVP_DigestInit(digest_context, message_digest) != 1) {
133
fprintf(stderr, "EVP_DigestInit failed.\n");
134
goto cleanup;
135
}
136
/* Digest parts one and two of the soliloqy */
137
if (EVP_DigestUpdate(digest_context, hamlet_1, strlen(hamlet_1)) != 1) {
138
fprintf(stderr, "EVP_DigestUpdate(hamlet_1) failed.\n");
139
goto cleanup;
140
}
141
if (EVP_DigestUpdate(digest_context, hamlet_2, strlen(hamlet_2)) != 1) {
142
fprintf(stderr, "EVP_DigestUpdate(hamlet_2) failed.\n");
143
goto cleanup;
144
}
145
if (EVP_DigestFinal(digest_context, digest_value, &digest_length) != 1) {
146
fprintf(stderr, "EVP_DigestFinal() failed.\n");
147
goto cleanup;
148
}
149
for (j=0; j<digest_length; j++) {
150
fprintf(stdout, "%02x", digest_value[j]);
151
}
152
fprintf(stdout, "\n");
153
/* Check digest_value against the known answer */
154
if ((size_t)digest_length != sizeof(known_answer)) {
155
fprintf(stdout, "Digest length(%d) not equal to known answer length(%lu).\n",
156
digest_length, (unsigned long) sizeof(known_answer));
157
} else if (memcmp(digest_value, known_answer, digest_length) != 0) {
158
for (j=0; j<sizeof(known_answer); j++) {
159
fprintf(stdout, "%02x", known_answer[j] );
160
}
161
fprintf(stdout, "\nDigest does not match known answer\n");
162
} else {
163
fprintf(stdout, "Digest computed properly.\n");
164
ret = 1;
165
}
166
167
cleanup:
168
if (ret != 1)
169
ERR_print_errors_fp(stderr);
170
/* OpenSSL free functions will ignore NULL arguments */
171
EVP_MD_CTX_free(digest_context);
172
OPENSSL_free(digest_value);
173
EVP_MD_free(message_digest);
174
175
OSSL_LIB_CTX_free(library_context);
176
return ret;
177
}
178
179
int main(void)
180
{
181
return demonstrate_digest() ? EXIT_SUCCESS : EXIT_FAILURE;
182
}
183
184