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 #include <openssl/evp.h> 11 #include <openssl/obj_mac.h> 12 13 #define BUFFER_SIZE 256 14 15 static int get_algorithm_nid(int hash_alg) 16 { 17 int nids[] = {NID_sha256, NID_sha384, NID_sha512}; 18 if (hash_alg < 0 || hash_alg >= sizeof(nids) / sizeof(*nids)) { 19 return NID_undef; 20 } 21 return nids[hash_alg]; 22 } 23 24 int sha_file(int md_alg, const char *filename, unsigned char *md) 25 { 26 FILE *inFile; 27 EVP_MD_CTX *mdctx; 28 const EVP_MD *md_type; 29 int bytes; 30 int alg_nid; 31 unsigned int total_bytes; 32 unsigned char data[BUFFER_SIZE]; 33 34 if ((filename == NULL) || (md == NULL)) { 35 ERROR("%s(): NULL argument\n", __func__); 36 return 0; 37 } 38 39 inFile = fopen(filename, "rb"); 40 if (inFile == NULL) { 41 ERROR("Cannot read %s\n", filename); 42 return 0; 43 } 44 45 mdctx = EVP_MD_CTX_new(); 46 if (mdctx == NULL) { 47 fclose(inFile); 48 ERROR("%s(): Could not create EVP MD context\n", __func__); 49 return 0; 50 } 51 52 alg_nid = get_algorithm_nid(md_alg); 53 if (alg_nid == NID_undef) { 54 ERROR("%s(): Invalid hash algorithm\n", __func__); 55 goto err; 56 } 57 58 md_type = EVP_get_digestbynid(alg_nid); 59 if (EVP_DigestInit_ex(mdctx, md_type, NULL) == 0) { 60 ERROR("%s(): Could not initialize EVP MD digest\n", __func__); 61 goto err; 62 } 63 64 while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { 65 EVP_DigestUpdate(mdctx, data, bytes); 66 } 67 EVP_DigestFinal_ex(mdctx, md, &total_bytes); 68 69 fclose(inFile); 70 EVP_MD_CTX_free(mdctx); 71 return 1; 72 73 err: 74 fclose(inFile); 75 EVP_MD_CTX_free(mdctx); 76 return 0; 77 } 78 79