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