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