feature/usage
[appimagekit/gsi.git] / digest.c
blob51f315fa8c08e66df0454716801cd2be881a68d1
1 /*
2 cc -o digest getsection.c digest.c -lssl -lcrypto
3 */
5 #include <stdio.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <openssl/sha.h>
9 #include <stdlib.h>
10 #include <sys/stat.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");
22 if(!file) return(1);
23 byte hash[SHA256_DIGEST_LENGTH];
24 SHA256_CTX sha256;
25 SHA256_Init(&sha256);
26 const int bufSize = 1024*1024;
27 byte *buffer = malloc(bufSize);
28 int bytesRead = 0;
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);
38 } else {
39 int stillToRead = skip_offset-bytesRead;
40 // printf("Initial stillToRead: %i\n", stillToRead);
41 int readThisTime;
43 if(stillToRead>bufSize){
44 readThisTime = bufSize;
45 } else {
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;
60 } else {
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 */
69 int i = 0;
70 for(i = 0; i < skip_length; i++) {
71 SHA256_Update(&sha256, "\0", 1);
72 totalBytesRead += 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]);
90 outputBuffer[64] = 0;
92 return 0;
95 int main(int argc,char **argv)
97 int res = 0;
99 if(argc < 2){
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");
105 exit(1);
108 unsigned long skip_offset = 0;
109 unsigned long skip_length = 0;
110 char *filename = argv[1];
112 struct stat st;
113 if (stat(filename, &st) < 0) {
114 fprintf(stderr, "not existing file: %s\n", filename);
115 exit(1);
118 if(argc < 4){
119 get_elf_section_offset_and_lenghth(filename, ".sha256_sig", &skip_offset, &skip_length);
120 if(skip_length > 0)
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]);
125 } else {
126 exit(1);
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");
132 exit(1);
135 static char buffer[65];
136 res = sha256_file(filename, buffer, skip_offset, skip_length);
137 printf("%s\n", buffer);
138 return res;