2 cc -o digest getsection.c digest.c -lssl -lcrypto
8 #include <openssl/sha.h>
11 #include <linux/limits.h>
13 #include "getsection.h"
15 typedef unsigned char byte
;
17 char segment_name
[] = ".sha256_sig";
19 int sha256_file(char *path
, char outputBuffer
[65], int skip_offset
, int skip_length
)
21 FILE *file
= fopen(path
, "rb");
23 byte hash
[SHA256_DIGEST_LENGTH
];
26 const int bufSize
= 1024*1024;
27 byte
*buffer
= malloc(bufSize
);
29 if(!buffer
) return ENOMEM
;
31 int totalBytesRead
= 0;
32 if(skip_offset
<= bufSize
){
33 bytesRead
= fread(buffer
, 1, skip_offset
, file
);
34 totalBytesRead
+= bytesRead
;
35 // printf("totalBytesRead: %i\n", totalBytesRead);
36 // printf("bytesRead: %i\n", bytesRead);
37 SHA256_Update(&sha256
, buffer
, bytesRead
);
39 int stillToRead
= skip_offset
-bytesRead
;
40 // printf("Initial stillToRead: %i\n", stillToRead);
43 if(stillToRead
>bufSize
){
44 readThisTime
= bufSize
;
46 readThisTime
= stillToRead
;
48 while((bytesRead
= fread(buffer
, 1, readThisTime
, file
)))
50 totalBytesRead
+= bytesRead
;
51 // printf("totalBytesRead: %i\n", totalBytesRead);
52 // printf("readThisTime: %i\n", readThisTime);
53 // printf("bytesRead: %i\n", bytesRead);
54 SHA256_Update(&sha256
, buffer
, bytesRead
);
55 stillToRead
= skip_offset
-totalBytesRead
;
56 // printf("stillToRead: %i\n", stillToRead);
58 if(stillToRead
>bufSize
){
59 readThisTime
= bufSize
;
61 readThisTime
= stillToRead
;
66 fseek(file
, skip_offset
+skip_length
, SEEK_SET
);
68 /* Instead of the skipped area, calculate the sha256 of the same amount if 0x00s */
70 for(i
= 0; i
< skip_length
; i
++) {
71 SHA256_Update(&sha256
, "\0", 1);
75 while((bytesRead
= fread(buffer
, 1, bufSize
, file
)))
77 totalBytesRead
+= bytesRead
;
78 // printf("totalBytesRead: %i\n", totalBytesRead);
79 // printf("bytesRead: %i\n", bytesRead);
80 SHA256_Update(&sha256
, buffer
, bytesRead
);
82 SHA256_Final(hash
, &sha256
);
84 // fprintf(stderr, "totalBytesRead: %i\n", totalBytesRead);
86 for(i
= 0; i
< SHA256_DIGEST_LENGTH
; i
++)
88 sprintf(outputBuffer
+ (i
* 2), "%02x", hash
[i
]);
95 int main(int argc
,char **argv
)
100 fprintf(stderr
, "Usage: %s file offset length\n", argv
[0]);
101 fprintf(stderr
, "If no offset and length are provided, the ELF section '%s' is skipped\n\n", segment_name
);
102 fprintf(stderr
, "Calculate a sha256 of a file except a skipped area from offset to offset+length bytes\n");
103 fprintf(stderr
, "which is replaced with 0x00 during checksum calculation.\n");
104 fprintf(stderr
, "This is useful when a signature is placed in the skipped area.\n");
108 unsigned long skip_offset
= 0;
109 unsigned long skip_length
= 0;
110 char *filename
= argv
[1];
113 if (stat(filename
, &st
) < 0) {
114 fprintf(stderr
, "not existing file: %s\n", filename
);
119 get_elf_section_offset_and_lenghth(filename
, ".sha256_sig", &skip_offset
, &skip_length
);
121 fprintf(stderr
, "Skipping ELF section %s with offset %lu, length %lu\n", segment_name
, skip_offset
, skip_length
);
122 } else if(argc
== 4) {
123 skip_offset
= atoi(argv
[2]);
124 skip_length
= atoi(argv
[3]);
129 int size
= st
.st_size
;
130 if(size
< skip_offset
+skip_length
){
131 fprintf(stderr
, "offset+length cannot be less than the file size\n");
135 static char buffer
[65];
136 res
= sha256_file(filename
, buffer
, skip_offset
, skip_length
);
137 printf("%s\n", buffer
);