-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsha256.c
167 lines (122 loc) · 3.72 KB
/
sha256.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// SHA256 v1.2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <exec/types.h>
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <dos/dosextens.h>
#include <proto/exec.h>
#include <proto/dos.h>
#define _STR(x) #x
#define STR(x) _STR(x)
const char version[] = "$VER: SHA256 1.2 " __AMIGADATE__ " Robert Leffmann";
static const int BUFSIZE = 64*1024; // Must be a multiple of 64
static UBYTE* buffer;
void SHA256Acc(const void* buffer, ULONG* hash, ULONG count);
static int CalcHash(BPTR file, ULONG* hash);
static void PrintHash(const ULONG* hash);
static int ProcessFile(STRPTR name);
int main(int nargs, const char** args) {
if (nargs == 2 && strcmp(args[1], "?") == 0) {
puts("SHA256 1.2 " __DATE__ "\n"
"Usage: sha256 [files]\n"
"Wildcards are allowed in the filenames.\n"
"The standard input will be used when no files are specified.");
return RETURN_OK;
}
buffer = AllocVec(BUFSIZE+64, MEMF_ANY);
if (!buffer) {
fputs("Could not get " STR(BUFSIZE) " bytes for input buffer.", stderr);
return RETURN_ERROR;
}
// Process the standard input if no files were specified
int err;
if (nargs == 1) {
ULONG hash[8];
CalcHash(Input(), hash);
PrintHash(hash);
puts("");
err = RETURN_OK;
} else {
// Process all arguments
struct AnchorPath* ap = AllocVec(sizeof (struct AnchorPath)+500, MEMF_ANY|MEMF_CLEAR);
if (!ap) {
FreeVec(buffer);
return RETURN_ERROR;
}
struct Process* proc = (void*)FindTask(NULL);
APTR oldwinptr = proc->pr_WindowPtr;
proc->pr_WindowPtr = (APTR)-1;
err = RETURN_OK;
for (int i = 1; i < nargs; ++i) {
// Find and process all files that match the current argument
ap->ap_BreakBits = 0;
ap->ap_Strlen = 500;
int exerr = MatchFirst(args[i], ap);
while (exerr == 0) {
if (ap->ap_Info.fib_DirEntryType < 0) {
int ret = ProcessFile(ap->ap_Buf);
if (ret > err) err = ret;
}
exerr = MatchNext(ap);
}
MatchEnd(ap);
}
proc->pr_WindowPtr = oldwinptr;
FreeVec(ap);
}
FreeVec(buffer);
return err;
}
static int ProcessFile(STRPTR name) {
BPTR file = Open(name, MODE_OLDFILE);
if (!file) {
fprintf(stderr, "* could not open file: %s\n", name);
return RETURN_WARN;
}
ULONG hash[8];
if (CalcHash(file, hash) == -1) {
fprintf(stderr, "* read error: %s\n", name);
Close(file);
return RETURN_WARN;
}
PrintHash(hash);
printf(" %s\n", name);
Close(file);
return RETURN_OK;
}
static int CalcHash(BPTR file, ULONG* hash) {
hash[0] = 0x6a09e667; hash[1] = 0xbb67ae85;
hash[2] = 0x3c6ef372; hash[3] = 0xa54ff53a;
hash[4] = 0x510e527f; hash[5] = 0x9b05688c;
hash[6] = 0x1f83d9ab; hash[7] = 0x5be0cd19;
// Process the file in chunks of 'BUFSIZE' bytes at a time
ULONG lastlen, filelen = 0;
ULONG remaining = BUFSIZE;
do {
lastlen = Read(file, buffer, remaining);
if (lastlen == (ULONG)-1) return -1;
remaining -= lastlen;
filelen += lastlen;
if (remaining == 0) {
SHA256Acc(buffer, hash, BUFSIZE/64);
remaining = BUFSIZE;
}
} while (lastlen > 0);
// Append terminating 1-bit, padding, and message size
lastlen = BUFSIZE-remaining;
buffer[lastlen] = 0x80;
ULONG padlen = (64-9+BUFSIZE-lastlen)%64;
ULONG* pmsglen = (ULONG*)(buffer+lastlen+padlen+1);
memset(buffer+lastlen+1, 0, padlen);
pmsglen[0] = filelen>>29;
pmsglen[1] = filelen<<3;
SHA256Acc(buffer, hash, (lastlen+padlen+9)/64);
return 0;
}
static void PrintHash(const ULONG* hash) {
printf("%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
hash[0], hash[1], hash[2], hash[3],
hash[4], hash[5], hash[6], hash[7]);
}