16f971622SJuan Castillo /*
2*cf2dd17dSJuan Pablo Conde * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
36f971622SJuan Castillo *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
56f971622SJuan Castillo */
66f971622SJuan Castillo
72a4b4b71SIsla Mitchell #include <stdio.h>
86f971622SJuan Castillo #include "debug.h"
92972247cSQixiang Xu #include "key.h"
10*cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
119bc52d33SJuan Pablo Conde #include <openssl/evp.h>
129bc52d33SJuan Pablo Conde #include <openssl/obj_mac.h>
13*cf2dd17dSJuan Pablo Conde #else
14*cf2dd17dSJuan Pablo Conde #include <openssl/sha.h>
15*cf2dd17dSJuan Pablo Conde #endif
166f971622SJuan Castillo
176f971622SJuan Castillo #define BUFFER_SIZE 256
186f971622SJuan Castillo
19*cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
get_algorithm_nid(int hash_alg)209bc52d33SJuan Pablo Conde static int get_algorithm_nid(int hash_alg)
219bc52d33SJuan Pablo Conde {
229bc52d33SJuan Pablo Conde int nids[] = {NID_sha256, NID_sha384, NID_sha512};
239bc52d33SJuan Pablo Conde if (hash_alg < 0 || hash_alg >= sizeof(nids) / sizeof(*nids)) {
249bc52d33SJuan Pablo Conde return NID_undef;
259bc52d33SJuan Pablo Conde }
269bc52d33SJuan Pablo Conde return nids[hash_alg];
279bc52d33SJuan Pablo Conde }
28*cf2dd17dSJuan Pablo Conde #endif
299bc52d33SJuan Pablo Conde
sha_file(int md_alg,const char * filename,unsigned char * md)302972247cSQixiang Xu int sha_file(int md_alg, const char *filename, unsigned char *md)
316f971622SJuan Castillo {
326f971622SJuan Castillo FILE *inFile;
33*cf2dd17dSJuan Pablo Conde int bytes;
34*cf2dd17dSJuan Pablo Conde unsigned char data[BUFFER_SIZE];
35*cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
369bc52d33SJuan Pablo Conde EVP_MD_CTX *mdctx;
379bc52d33SJuan Pablo Conde const EVP_MD *md_type;
389bc52d33SJuan Pablo Conde int alg_nid;
399bc52d33SJuan Pablo Conde unsigned int total_bytes;
40*cf2dd17dSJuan Pablo Conde #else
41*cf2dd17dSJuan Pablo Conde SHA256_CTX shaContext;
42*cf2dd17dSJuan Pablo Conde SHA512_CTX sha512Context;
43*cf2dd17dSJuan Pablo Conde #endif
446f971622SJuan Castillo
456f971622SJuan Castillo if ((filename == NULL) || (md == NULL)) {
469bc52d33SJuan Pablo Conde ERROR("%s(): NULL argument\n", __func__);
476f971622SJuan Castillo return 0;
486f971622SJuan Castillo }
496f971622SJuan Castillo
506f971622SJuan Castillo inFile = fopen(filename, "rb");
516f971622SJuan Castillo if (inFile == NULL) {
526f971622SJuan Castillo ERROR("Cannot read %s\n", filename);
536f971622SJuan Castillo return 0;
546f971622SJuan Castillo }
556f971622SJuan Castillo
56*cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
57*cf2dd17dSJuan Pablo Conde
589bc52d33SJuan Pablo Conde mdctx = EVP_MD_CTX_new();
599bc52d33SJuan Pablo Conde if (mdctx == NULL) {
609bc52d33SJuan Pablo Conde fclose(inFile);
619bc52d33SJuan Pablo Conde ERROR("%s(): Could not create EVP MD context\n", __func__);
629bc52d33SJuan Pablo Conde return 0;
632972247cSQixiang Xu }
646f971622SJuan Castillo
659bc52d33SJuan Pablo Conde alg_nid = get_algorithm_nid(md_alg);
669bc52d33SJuan Pablo Conde if (alg_nid == NID_undef) {
679bc52d33SJuan Pablo Conde ERROR("%s(): Invalid hash algorithm\n", __func__);
689bc52d33SJuan Pablo Conde goto err;
696f971622SJuan Castillo }
709bc52d33SJuan Pablo Conde
719bc52d33SJuan Pablo Conde md_type = EVP_get_digestbynid(alg_nid);
729bc52d33SJuan Pablo Conde if (EVP_DigestInit_ex(mdctx, md_type, NULL) == 0) {
739bc52d33SJuan Pablo Conde ERROR("%s(): Could not initialize EVP MD digest\n", __func__);
749bc52d33SJuan Pablo Conde goto err;
759bc52d33SJuan Pablo Conde }
769bc52d33SJuan Pablo Conde
779bc52d33SJuan Pablo Conde while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
789bc52d33SJuan Pablo Conde EVP_DigestUpdate(mdctx, data, bytes);
799bc52d33SJuan Pablo Conde }
809bc52d33SJuan Pablo Conde EVP_DigestFinal_ex(mdctx, md, &total_bytes);
819bc52d33SJuan Pablo Conde
829bc52d33SJuan Pablo Conde fclose(inFile);
839bc52d33SJuan Pablo Conde EVP_MD_CTX_free(mdctx);
849bc52d33SJuan Pablo Conde return 1;
859bc52d33SJuan Pablo Conde
869bc52d33SJuan Pablo Conde err:
879bc52d33SJuan Pablo Conde fclose(inFile);
889bc52d33SJuan Pablo Conde EVP_MD_CTX_free(mdctx);
899bc52d33SJuan Pablo Conde return 0;
90*cf2dd17dSJuan Pablo Conde
91*cf2dd17dSJuan Pablo Conde #else
92*cf2dd17dSJuan Pablo Conde
93*cf2dd17dSJuan Pablo Conde if (md_alg == HASH_ALG_SHA384) {
94*cf2dd17dSJuan Pablo Conde SHA384_Init(&sha512Context);
95*cf2dd17dSJuan Pablo Conde while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
96*cf2dd17dSJuan Pablo Conde SHA384_Update(&sha512Context, data, bytes);
97*cf2dd17dSJuan Pablo Conde }
98*cf2dd17dSJuan Pablo Conde SHA384_Final(md, &sha512Context);
99*cf2dd17dSJuan Pablo Conde } else if (md_alg == HASH_ALG_SHA512) {
100*cf2dd17dSJuan Pablo Conde SHA512_Init(&sha512Context);
101*cf2dd17dSJuan Pablo Conde while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
102*cf2dd17dSJuan Pablo Conde SHA512_Update(&sha512Context, data, bytes);
103*cf2dd17dSJuan Pablo Conde }
104*cf2dd17dSJuan Pablo Conde SHA512_Final(md, &sha512Context);
105*cf2dd17dSJuan Pablo Conde } else {
106*cf2dd17dSJuan Pablo Conde SHA256_Init(&shaContext);
107*cf2dd17dSJuan Pablo Conde while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
108*cf2dd17dSJuan Pablo Conde SHA256_Update(&shaContext, data, bytes);
109*cf2dd17dSJuan Pablo Conde }
110*cf2dd17dSJuan Pablo Conde SHA256_Final(md, &shaContext);
111*cf2dd17dSJuan Pablo Conde }
112*cf2dd17dSJuan Pablo Conde
113*cf2dd17dSJuan Pablo Conde fclose(inFile);
114*cf2dd17dSJuan Pablo Conde return 1;
115*cf2dd17dSJuan Pablo Conde
116*cf2dd17dSJuan Pablo Conde #endif
1179bc52d33SJuan Pablo Conde }
1189bc52d33SJuan Pablo Conde
119