/*-
 * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * 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
 */

#include <string.h>
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>

/*-
 * This demonstration will show how to digest data using
 * the soliloqy from Hamlet scene 1 act 3
 * The soliloqy is split into two parts to demonstrate using EVP_DigestUpdate
 * more than once.
 */

const char * hamlet_1 =
    "To be, or not to be, that is the question,\n"
    "Whether tis nobler in the minde to suffer\n"
    "The ſlings and arrowes of outragious fortune,\n"
    "Or to take Armes again in a sea of troubles,\n"
    "And by opposing, end them, to die to sleep;\n"
    "No more, and by a sleep, to say we end\n"
    "The heart-ache, and the thousand natural shocks\n"
    "That flesh is heir to? tis a consumation\n"
    "Devoutly to be wished. To die to sleep,\n"
    "To sleepe, perchance to dreame, Aye, there's the rub,\n"
    "For in that sleep of death what dreams may come\n"
    "When we haue shuffled off this mortal coil\n"
    "Must give us pause. There's the respect\n"
    "That makes calamity of so long life:\n"
    "For who would bear the Ships and Scorns of time,\n"
    "The oppressor's wrong, the proud man's Contumely,\n"
    "The pangs of dispised love, the Law's delay,\n"
;
const char * hamlet_2 =
    "The insolence of Office, and the spurns\n"
    "That patient merit of the'unworthy takes,\n"
    "When he himself might his Quietas make\n"
    "With a bare bodkin? Who would fardels bear,\n"
    "To grunt and sweat under a weary life,\n"
    "But that the dread of something after death,\n"
    "The undiscovered country, from whose bourn\n"
    "No traveller returns, puzzles the will,\n"
    "And makes us rather bear those ills we have,\n"
    "Then fly to others we know not of?\n"
    "Thus conscience does make cowards of us all,\n"
    "And thus the native hue of Resolution\n"
    "Is sickled o'er with the pale cast of Thought,\n"
    "And enterprises of great pith and moment,\n"
    "With this regard their currents turn awry,\n"
    "And lose the name of Action. Soft you now,\n"
    "The fair Ophelia? Nymph in thy Orisons\n"
    "Be all my sins remember'd.\n"
; 

/* The known value of the SHA3-512 digest of the above soliloqy */
const unsigned char known_answer[] = {
    0xbb, 0x69, 0xf8, 0x09, 0x9c, 0x2e, 0x00, 0x3d,
    0xa4, 0x29, 0x5f, 0x59, 0x4b, 0x89, 0xe4, 0xd9,
    0xdb, 0xa2, 0xe5, 0xaf, 0xa5, 0x87, 0x73, 0x9d,
    0x83, 0x72, 0xcf, 0xea, 0x84, 0x66, 0xc1, 0xf9,
    0xc9, 0x78, 0xef, 0xba, 0x3d, 0xe9, 0xc1, 0xff,
    0xa3, 0x75, 0xc7, 0x58, 0x74, 0x8e, 0x9c, 0x1d,
    0x14, 0xd9, 0xdd, 0xd1, 0xfd, 0x24, 0x30, 0xd6,
    0x81, 0xca, 0x8f, 0x78, 0x29, 0x19, 0x9a, 0xfe,
};

int demonstrate_digest(void)
{
    OSSL_LIB_CTX *library_context;
    int result = 0;
    const char *option_properties = NULL;
    EVP_MD *message_digest = NULL;
    EVP_MD_CTX *digest_context = NULL;
    unsigned int digest_length;
    unsigned char *digest_value = NULL;
    int j;

    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.");
        goto cleanup;
    }
    /* Determine the length of the fetched digest type */
    digest_length = EVP_MD_get_size(message_digest);
    if (digest_length <= 0) {
        fprintf(stderr, "EVP_MD_get_size returned invalid size.\n");
        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");
        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");
        goto cleanup;
    }
    /* Digest parts one and two of the soliloqy */
    if (EVP_DigestUpdate(digest_context, hamlet_1, strlen(hamlet_1)) != 1) {
        fprintf(stderr, "EVP_DigestUpdate(hamlet_1) failed.\n");
        goto cleanup;
    }
    if (EVP_DigestUpdate(digest_context, hamlet_2, strlen(hamlet_2)) != 1) {
        fprintf(stderr, "EVP_DigestUpdate(hamlet_2) failed.\n");
        goto cleanup;
    }
    if (EVP_DigestFinal(digest_context, digest_value, &digest_length) != 1) {
        fprintf(stderr, "EVP_DigestFinal() failed.\n");
        goto cleanup;
    }
    for (j=0; j<digest_length; j++)  {
        fprintf(stdout, "%02x", digest_value[j]);
    }
    fprintf(stdout, "\n");
    /* Check digest_value against the known answer */
    if ((size_t)digest_length != sizeof(known_answer)) {
        fprintf(stdout, "Digest length(%d) not equal to known answer length(%lu).\n",
            digest_length, sizeof(known_answer));
    } else if (memcmp(digest_value, known_answer, digest_length) != 0) {
        for (j=0; j<sizeof(known_answer); j++) {
            fprintf(stdout, "%02x", known_answer[j] );
        }
        fprintf(stdout, "\nDigest does not match known answer\n");
    } else {
        fprintf(stdout, "Digest computed properly.\n");
        result = 1;
    }


cleanup:
    if (result != 1)
        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);
    return result;
}

int main(void)
{
    return demonstrate_digest() == 0;
}
