1 /*
2 * sha1sum - compute SHA1 or SHA2 digest
3 */
4 #include <u.h>
5 #include <libc.h>
6 #include <bio.h>
7 #include <libsec.h>
8
9 #pragma varargck type "M" uchar*
10
11 typedef struct Sha2 Sha2;
12 struct Sha2 {
13 int bits;
14 int dlen;
15 DigestState* (*func)(uchar *, ulong, uchar *, DigestState *);
16 };
17
18 static Sha2 sha2s[] = {
19 224, SHA2_224dlen, sha2_224,
20 256, SHA2_256dlen, sha2_256,
21 384, SHA2_384dlen, sha2_384,
22 512, SHA2_512dlen, sha2_512,
23 };
24
25 static DigestState* (*shafunc)(uchar *, ulong, uchar *, DigestState *);
26 static int shadlen;
27
28 static int
digestfmt(Fmt * fmt)29 digestfmt(Fmt *fmt)
30 {
31 char buf[SHA2_512dlen*2 + 1];
32 uchar *p;
33 int i;
34
35 p = va_arg(fmt->args, uchar*);
36 for(i = 0; i < shadlen; i++)
37 sprint(buf + 2*i, "%.2ux", p[i]);
38 return fmtstrcpy(fmt, buf);
39 }
40
41 static void
sum(int fd,char * name)42 sum(int fd, char *name)
43 {
44 int n;
45 uchar buf[8192], digest[SHA2_512dlen];
46 DigestState *s;
47
48 s = (*shafunc)(nil, 0, nil, nil);
49 while((n = read(fd, buf, sizeof buf)) > 0)
50 (*shafunc)(buf, n, nil, s);
51 if(n < 0){
52 fprint(2, "reading %s: %r\n", name? name: "stdin");
53 return;
54 }
55 (*shafunc)(nil, 0, digest, s);
56 if(name == nil)
57 print("%M\n", digest);
58 else
59 print("%M\t%s\n", digest, name);
60 }
61
62 static void
usage(void)63 usage(void)
64 {
65 fprint(2, "usage: %s [-2 bits] [file...]\n", argv0);
66 exits("usage");
67 }
68
69 void
main(int argc,char * argv[])70 main(int argc, char *argv[])
71 {
72 int i, fd, bits;
73 Sha2 *sha;
74
75 shafunc = sha1;
76 shadlen = SHA1dlen;
77 ARGBEGIN{
78 case '2':
79 bits = atoi(EARGF(usage()));
80 for (sha = sha2s; sha < sha2s + nelem(sha2s); sha++)
81 if (sha->bits == bits)
82 break;
83 if (sha >= sha2s + nelem(sha2s))
84 sysfatal("unknown number of sha2 bits: %d", bits);
85 shafunc = sha->func;
86 shadlen = sha->dlen;
87 break;
88 default:
89 usage();
90 }ARGEND
91
92 fmtinstall('M', digestfmt);
93
94 if(argc == 0)
95 sum(0, nil);
96 else
97 for(i = 0; i < argc; i++){
98 fd = open(argv[i], OREAD);
99 if(fd < 0){
100 fprint(2, "%s: can't open %s: %r\n", argv0, argv[i]);
101 continue;
102 }
103 sum(fd, argv[i]);
104 close(fd);
105 }
106 exits(nil);
107 }
108