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 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 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 63 usage(void) 64 { 65 fprint(2, "usage: %s [-2 bits] [file...]\n", argv0); 66 exits("usage"); 67 } 68 69 void 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