1 /* 2 * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdio.h> 8 #include "debug.h" 9 #include "key.h" 10 #if USING_OPENSSL3 11 #include <openssl/evp.h> 12 #include <openssl/obj_mac.h> 13 #else 14 #include <openssl/sha.h> 15 #endif 16 17 #define BUFFER_SIZE 256 18 19 #if USING_OPENSSL3 20 static int get_algorithm_nid(int hash_alg) 21 { 22 int nids[] = {NID_sha256, NID_sha384, NID_sha512}; 23 if (hash_alg < 0 || hash_alg >= sizeof(nids) / sizeof(*nids)) { 24 return NID_undef; 25 } 26 return nids[hash_alg]; 27 } 28 #endif 29 30 int sha_file(int md_alg, const char *filename, unsigned char *md) 31 { 32 FILE *inFile; 33 int bytes; 34 unsigned char data[BUFFER_SIZE]; 35 #if USING_OPENSSL3 36 EVP_MD_CTX *mdctx; 37 const EVP_MD *md_type; 38 int alg_nid; 39 unsigned int total_bytes; 40 #else 41 SHA256_CTX shaContext; 42 SHA512_CTX sha512Context; 43 #endif 44 45 if ((filename == NULL) || (md == NULL)) { 46 ERROR("%s(): NULL argument\n", __func__); 47 return 0; 48 } 49 50 inFile = fopen(filename, "rb"); 51 if (inFile == NULL) { 52 ERROR("Cannot read %s\n", filename); 53 return 0; 54 } 55 56 #if USING_OPENSSL3 57 58 mdctx = EVP_MD_CTX_new(); 59 if (mdctx == NULL) { 60 fclose(inFile); 61 ERROR("%s(): Could not create EVP MD context\n", __func__); 62 return 0; 63 } 64 65 alg_nid = get_algorithm_nid(md_alg); 66 if (alg_nid == NID_undef) { 67 ERROR("%s(): Invalid hash algorithm\n", __func__); 68 goto err; 69 } 70 71 md_type = EVP_get_digestbynid(alg_nid); 72 if (EVP_DigestInit_ex(mdctx, md_type, NULL) == 0) { 73 ERROR("%s(): Could not initialize EVP MD digest\n", __func__); 74 goto err; 75 } 76 77 while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { 78 EVP_DigestUpdate(mdctx, data, bytes); 79 } 80 EVP_DigestFinal_ex(mdctx, md, &total_bytes); 81 82 fclose(inFile); 83 EVP_MD_CTX_free(mdctx); 84 return 1; 85 86 err: 87 fclose(inFile); 88 EVP_MD_CTX_free(mdctx); 89 return 0; 90 91 #else 92 93 if (md_alg == HASH_ALG_SHA384) { 94 SHA384_Init(&sha512Context); 95 while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { 96 SHA384_Update(&sha512Context, data, bytes); 97 } 98 SHA384_Final(md, &sha512Context); 99 } else if (md_alg == HASH_ALG_SHA512) { 100 SHA512_Init(&sha512Context); 101 while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { 102 SHA512_Update(&sha512Context, data, bytes); 103 } 104 SHA512_Final(md, &sha512Context); 105 } else { 106 SHA256_Init(&shaContext); 107 while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { 108 SHA256_Update(&shaContext, data, bytes); 109 } 110 SHA256_Final(md, &shaContext); 111 } 112 113 fclose(inFile); 114 return 1; 115 116 #endif 117 } 118 119