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 
get_algorithm_nid(int hash_alg)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 
sha_file(int md_alg,const char * filename,unsigned char * md)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