added md5sum - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit d37eb1034e3bab754a24c9629fc369545f7c9b67 | |
parent 78a6c092e93295e60ed4cba344117a34b586d7da | |
Author: [email protected] <unknown> | |
Date: Thu, 27 May 2010 13:31:50 +0100 | |
added md5sum | |
Diffstat: | |
M Makefile | 2 +- | |
M lib9/Makefile | 3 +++ | |
A lib9/sec/md5.c | 147 +++++++++++++++++++++++++++++… | |
A lib9/sec/md5block.c | 267 +++++++++++++++++++++++++++++… | |
A lib9/sec/md5pickle.c | 39 +++++++++++++++++++++++++++++… | |
A md5sum/Makefile | 10 ++++++++++ | |
A md5sum/md5sum.1 | 0 | |
A md5sum/md5sum.c | 61 +++++++++++++++++++++++++++++… | |
8 files changed, 528 insertions(+), 1 deletion(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -2,7 +2,7 @@ | |
include config.mk | |
-SUBDIRS = lib9 yacc awk basename bc cal cat cleanname date dc du echo ed \ | |
+SUBDIRS = lib9 yacc awk basename bc cal cat cleanname date dc du dd echo ed \ | |
factor fortune fmt freq getflags grep hoc ls mk mkdir mtime primes \ | |
rc read sha1sum sed seq sleep sort tail tee test touch tr troff uniq | |
diff --git a/lib9/Makefile b/lib9/Makefile | |
@@ -17,6 +17,9 @@ SECFILES=\ | |
sec/sha1block.o\ | |
sec/sha1.o\ | |
sec/sha1pickle.o\ | |
+ sec/md5block.o\ | |
+ sec/md5.o\ | |
+ sec/md5pickle.o\ | |
NUM=\ | |
fmt/charstod.o\ | |
diff --git a/lib9/sec/md5.c b/lib9/sec/md5.c | |
@@ -0,0 +1,147 @@ | |
+#include "os.h" | |
+#include <libsec.h> | |
+ | |
+/* | |
+ * rfc1321 requires that I include this. The code is new. The constants | |
+ * all come from the rfc (hence the copyright). We trade a table for the | |
+ * macros in rfc. The total size is a lot less. -- presotto | |
+ * | |
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All | |
+ * rights reserved. | |
+ * | |
+ * License to copy and use this software is granted provided that it | |
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest | |
+ * Algorithm" in all material mentioning or referencing this software | |
+ * or this function. | |
+ * | |
+ * License is also granted to make and use derivative works provided | |
+ * that such works are identified as "derived from the RSA Data | |
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material | |
+ * mentioning or referencing the derived work. | |
+ * | |
+ * RSA Data Security, Inc. makes no representations concerning either | |
+ * the merchantability of this software or the suitability of this | |
+ * software forany particular purpose. It is provided "as is" | |
+ * without express or implied warranty of any kind. | |
+ * These notices must be retained in any copies of any part of this | |
+ * documentation and/or software. | |
+ */ | |
+ | |
+static void encode(uchar*, u32int*, ulong); | |
+ | |
+extern void _md5block(uchar*, ulong, u32int*); | |
+ | |
+MD5state* | |
+md5(uchar *p, ulong len, uchar *digest, MD5state *s) | |
+{ | |
+ u32int x[16]; | |
+ uchar buf[128]; | |
+ int i; | |
+ uchar *e; | |
+ | |
+ if(s == nil){ | |
+ s = malloc(sizeof(*s)); | |
+ if(s == nil) | |
+ return nil; | |
+ memset(s, 0, sizeof(*s)); | |
+ s->malloced = 1; | |
+ } | |
+ | |
+ if(s->seeded == 0){ | |
+ /* seed the state, these constants would look nicer big-endian… | |
+ s->state[0] = 0x67452301; | |
+ s->state[1] = 0xefcdab89; | |
+ s->state[2] = 0x98badcfe; | |
+ s->state[3] = 0x10325476; | |
+ s->seeded = 1; | |
+ } | |
+ | |
+ /* fill out the partial 64 byte block from previous calls */ | |
+ if(s->blen){ | |
+ i = 64 - s->blen; | |
+ if(len < i) | |
+ i = len; | |
+ memmove(s->buf + s->blen, p, i); | |
+ len -= i; | |
+ s->blen += i; | |
+ p += i; | |
+ if(s->blen == 64){ | |
+ _md5block(s->buf, s->blen, s->state); | |
+ s->len += s->blen; | |
+ s->blen = 0; | |
+ } | |
+ } | |
+ | |
+ /* do 64 byte blocks */ | |
+ i = len & ~0x3f; | |
+ if(i){ | |
+ _md5block(p, i, s->state); | |
+ s->len += i; | |
+ len -= i; | |
+ p += i; | |
+ } | |
+ | |
+ /* save the left overs if not last call */ | |
+ if(digest == 0){ | |
+ if(len){ | |
+ memmove(s->buf, p, len); | |
+ s->blen += len; | |
+ } | |
+ return s; | |
+ } | |
+ | |
+ /* | |
+ * this is the last time through, pad what's left with 0x80, | |
+ * 0's, and the input count to create a multiple of 64 bytes | |
+ */ | |
+ if(s->blen){ | |
+ p = s->buf; | |
+ len = s->blen; | |
+ } else { | |
+ memmove(buf, p, len); | |
+ p = buf; | |
+ } | |
+ s->len += len; | |
+ e = p + len; | |
+ if(len < 56) | |
+ i = 56 - len; | |
+ else | |
+ i = 120 - len; | |
+ memset(e, 0, i); | |
+ *e = 0x80; | |
+ len += i; | |
+ | |
+ /* append the count */ | |
+ x[0] = s->len<<3; | |
+ x[1] = s->len>>29; | |
+ encode(p+len, x, 8); | |
+ | |
+ /* digest the last part */ | |
+ _md5block(p, len+8, s->state); | |
+ s->len += len; | |
+ | |
+ /* return result and free state */ | |
+ encode(digest, s->state, MD5dlen); | |
+ if(s->malloced == 1) | |
+ free(s); | |
+ return nil; | |
+} | |
+ | |
+/* | |
+ * encodes input (u32int) into output (uchar). Assumes len is | |
+ * a multiple of 4. | |
+ */ | |
+static void | |
+encode(uchar *output, u32int *input, ulong len) | |
+{ | |
+ u32int x; | |
+ uchar *e; | |
+ | |
+ for(e = output + len; output < e;) { | |
+ x = *input++; | |
+ *output++ = x; | |
+ *output++ = x >> 8; | |
+ *output++ = x >> 16; | |
+ *output++ = x >> 24; | |
+ } | |
+} | |
diff --git a/lib9/sec/md5block.c b/lib9/sec/md5block.c | |
@@ -0,0 +1,267 @@ | |
+#include "os.h" | |
+#include <libsec.h> | |
+ | |
+/* | |
+ * rfc1321 requires that I include this. The code is new. The constants | |
+ * all come from the rfc (hence the copyright). We trade a table for the | |
+ * macros in rfc. The total size is a lot less. -- presotto | |
+ * | |
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All | |
+ * rights reserved. | |
+ * | |
+ * License to copy and use this software is granted provided that it | |
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest | |
+ * Algorithm" in all material mentioning or referencing this software | |
+ * or this function. | |
+ * | |
+ * License is also granted to make and use derivative works provided | |
+ * that such works are identified as "derived from the RSA Data | |
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material | |
+ * mentioning or referencing the derived work. | |
+ * | |
+ * RSA Data Security, Inc. makes no representations concerning either | |
+ * the merchantability of this software or the suitability of this | |
+ * software forany particular purpose. It is provided "as is" | |
+ * without express or implied warranty of any kind. | |
+ * These notices must be retained in any copies of any part of this | |
+ * documentation and/or software. | |
+ */ | |
+ | |
+/* | |
+ * Rotate ammounts used in the algorithm | |
+ */ | |
+enum | |
+{ | |
+ S11= 7, | |
+ S12= 12, | |
+ S13= 17, | |
+ S14= 22, | |
+ | |
+ S21= 5, | |
+ S22= 9, | |
+ S23= 14, | |
+ S24= 20, | |
+ | |
+ S31= 4, | |
+ S32= 11, | |
+ S33= 16, | |
+ S34= 23, | |
+ | |
+ S41= 6, | |
+ S42= 10, | |
+ S43= 15, | |
+ S44= 21, | |
+}; | |
+ | |
+static u32int md5tab[] = | |
+{ | |
+ /* round 1 */ | |
+/*[0]*/ 0xd76aa478, | |
+ 0xe8c7b756, | |
+ 0x242070db, | |
+ 0xc1bdceee, | |
+ 0xf57c0faf, | |
+ 0x4787c62a, | |
+ 0xa8304613, | |
+ 0xfd469501, | |
+ 0x698098d8, | |
+ 0x8b44f7af, | |
+ 0xffff5bb1, | |
+ 0x895cd7be, | |
+ 0x6b901122, | |
+ 0xfd987193, | |
+ 0xa679438e, | |
+ 0x49b40821, | |
+ | |
+ /* round 2 */ | |
+/*[16]*/0xf61e2562, | |
+ 0xc040b340, | |
+ 0x265e5a51, | |
+ 0xe9b6c7aa, | |
+ 0xd62f105d, | |
+ 0x2441453, | |
+ 0xd8a1e681, | |
+ 0xe7d3fbc8, | |
+ 0x21e1cde6, | |
+ 0xc33707d6, | |
+ 0xf4d50d87, | |
+ 0x455a14ed, | |
+ 0xa9e3e905, | |
+ 0xfcefa3f8, | |
+ 0x676f02d9, | |
+ 0x8d2a4c8a, | |
+ | |
+ /* round 3 */ | |
+/*[32]*/0xfffa3942, | |
+ 0x8771f681, | |
+ 0x6d9d6122, | |
+ 0xfde5380c, | |
+ 0xa4beea44, | |
+ 0x4bdecfa9, | |
+ 0xf6bb4b60, | |
+ 0xbebfbc70, | |
+ 0x289b7ec6, | |
+ 0xeaa127fa, | |
+ 0xd4ef3085, | |
+ 0x4881d05, | |
+ 0xd9d4d039, | |
+ 0xe6db99e5, | |
+ 0x1fa27cf8, | |
+ 0xc4ac5665, | |
+ | |
+ /* round 4 */ | |
+/*[48]*/0xf4292244, | |
+ 0x432aff97, | |
+ 0xab9423a7, | |
+ 0xfc93a039, | |
+ 0x655b59c3, | |
+ 0x8f0ccc92, | |
+ 0xffeff47d, | |
+ 0x85845dd1, | |
+ 0x6fa87e4f, | |
+ 0xfe2ce6e0, | |
+ 0xa3014314, | |
+ 0x4e0811a1, | |
+ 0xf7537e82, | |
+ 0xbd3af235, | |
+ 0x2ad7d2bb, | |
+ 0xeb86d391, | |
+}; | |
+ | |
+static void decode(u32int*, uchar*, ulong); | |
+extern void _md5block(uchar *p, ulong len, u32int *s); | |
+ | |
+void | |
+_md5block(uchar *p, ulong len, u32int *s) | |
+{ | |
+ u32int a, b, c, d, sh; | |
+ u32int *t; | |
+ uchar *end; | |
+ u32int x[16]; | |
+ | |
+ for(end = p+len; p < end; p += 64){ | |
+ a = s[0]; | |
+ b = s[1]; | |
+ c = s[2]; | |
+ d = s[3]; | |
+ | |
+ decode(x, p, 64); | |
+ | |
+ t = md5tab; | |
+ sh = 0; | |
+ for(; sh != 16; t += 4){ | |
+ a += ((c ^ d) & b) ^ d; | |
+ a += x[sh] + t[0]; | |
+ a = (a << S11) | (a >> (32 - S11)); | |
+ a += b; | |
+ | |
+ d += ((b ^ c) & a) ^ c; | |
+ d += x[sh + 1] + t[1]; | |
+ d = (d << S12) | (d >> (32 - S12)); | |
+ d += a; | |
+ | |
+ c += ((a ^ b) & d) ^ b; | |
+ c += x[sh + 2] + t[2]; | |
+ c = (c << S13) | (c >> (32 - S13)); | |
+ c += d; | |
+ | |
+ b += ((d ^ a) & c) ^ a; | |
+ b += x[sh + 3] + t[3]; | |
+ b = (b << S14) | (b >> (32 - S14)); | |
+ b += c; | |
+ | |
+ sh += 4; | |
+ } | |
+ sh = 1; | |
+ for(; sh != 1+20*4; t += 4){ | |
+ a += ((b ^ c) & d) ^ c; | |
+ a += x[sh & 0xf] + t[0]; | |
+ a = (a << S21) | (a >> (32 - S21)); | |
+ a += b; | |
+ | |
+ d += ((a ^ b) & c) ^ b; | |
+ d += x[(sh + 5) & 0xf] + t[1]; | |
+ d = (d << S22) | (d >> (32 - S22)); | |
+ d += a; | |
+ | |
+ c += ((d ^ a) & b) ^ a; | |
+ c += x[(sh + 10) & 0xf] + t[2]; | |
+ c = (c << S23) | (c >> (32 - S23)); | |
+ c += d; | |
+ | |
+ b += ((c ^ d) & a) ^ d; | |
+ b += x[(sh + 15) & 0xf] + t[3]; | |
+ b = (b << S24) | (b >> (32 - S24)); | |
+ b += c; | |
+ | |
+ sh += 20; | |
+ } | |
+ sh = 5; | |
+ for(; sh != 5+12*4; t += 4){ | |
+ a += b ^ c ^ d; | |
+ a += x[sh & 0xf] + t[0]; | |
+ a = (a << S31) | (a >> (32 - S31)); | |
+ a += b; | |
+ | |
+ d += a ^ b ^ c; | |
+ d += x[(sh + 3) & 0xf] + t[1]; | |
+ d = (d << S32) | (d >> (32 - S32)); | |
+ d += a; | |
+ | |
+ c += d ^ a ^ b; | |
+ c += x[(sh + 6) & 0xf] + t[2]; | |
+ c = (c << S33) | (c >> (32 - S33)); | |
+ c += d; | |
+ | |
+ b += c ^ d ^ a; | |
+ b += x[(sh + 9) & 0xf] + t[3]; | |
+ b = (b << S34) | (b >> (32 - S34)); | |
+ b += c; | |
+ | |
+ sh += 12; | |
+ } | |
+ sh = 0; | |
+ for(; sh != 28*4; t += 4){ | |
+ a += c ^ (b | ~d); | |
+ a += x[sh & 0xf] + t[0]; | |
+ a = (a << S41) | (a >> (32 - S41)); | |
+ a += b; | |
+ | |
+ d += b ^ (a | ~c); | |
+ d += x[(sh + 7) & 0xf] + t[1]; | |
+ d = (d << S42) | (d >> (32 - S42)); | |
+ d += a; | |
+ | |
+ c += a ^ (d | ~b); | |
+ c += x[(sh + 14) & 0xf] + t[2]; | |
+ c = (c << S43) | (c >> (32 - S43)); | |
+ c += d; | |
+ | |
+ b += d ^ (c | ~a); | |
+ b += x[(sh + 21) & 0xf] + t[3]; | |
+ b = (b << S44) | (b >> (32 - S44)); | |
+ b += c; | |
+ | |
+ sh += 28; | |
+ } | |
+ | |
+ s[0] += a; | |
+ s[1] += b; | |
+ s[2] += c; | |
+ s[3] += d; | |
+ } | |
+} | |
+ | |
+/* | |
+ * decodes input (uchar) into output (u32int). Assumes len is | |
+ * a multiple of 4. | |
+ */ | |
+static void | |
+decode(u32int *output, uchar *input, ulong len) | |
+{ | |
+ uchar *e; | |
+ | |
+ for(e = input+len; input < e; input += 4) | |
+ *output++ = input[0] | (input[1] << 8) | | |
+ (input[2] << 16) | (input[3] << 24); | |
+} | |
diff --git a/lib9/sec/md5pickle.c b/lib9/sec/md5pickle.c | |
@@ -0,0 +1,39 @@ | |
+#include "os.h" | |
+#include <libsec.h> | |
+ | |
+char* | |
+md5pickle(MD5state *s) | |
+{ | |
+ char *p; | |
+ int m, n; | |
+ | |
+ m = 17+4*9+4*((s->blen+3)/3); | |
+ p = malloc(m); | |
+ if(p == nil) | |
+ return p; | |
+ n = sprint(p, "%16.16llux %8.8ux %8.8ux %8.8ux %8.8ux ", | |
+ s->len, | |
+ s->state[0], s->state[1], s->state[2], | |
+ s->state[3]); | |
+ enc64(p+n, m-n, s->buf, s->blen); | |
+ return p; | |
+} | |
+ | |
+MD5state* | |
+md5unpickle(char *p) | |
+{ | |
+ MD5state *s; | |
+ | |
+ s = malloc(sizeof(*s)); | |
+ if(s == nil) | |
+ return nil; | |
+ s->len = strtoull(p, &p, 16); | |
+ s->state[0] = strtoul(p, &p, 16); | |
+ s->state[1] = strtoul(p, &p, 16); | |
+ s->state[2] = strtoul(p, &p, 16); | |
+ s->state[3] = strtoul(p, &p, 16); | |
+ s->blen = dec64(s->buf, sizeof(s->buf), p, strlen(p)); | |
+ s->malloced = 1; | |
+ s->seeded = 1; | |
+ return s; | |
+} | |
diff --git a/md5sum/Makefile b/md5sum/Makefile | |
@@ -0,0 +1,10 @@ | |
+# md5sum - md5sum unix port from plan9 | |
+# Depends on ../lib9 | |
+ | |
+TARG = md5sum | |
+ | |
+include ../std.mk | |
+ | |
+pre-uninstall: | |
+ | |
+post-install: | |
diff --git a/md5sum/md5sum.1 b/md5sum/md5sum.1 | |
diff --git a/md5sum/md5sum.c b/md5sum/md5sum.c | |
@@ -0,0 +1,61 @@ | |
+#include <u.h> | |
+#include <libc.h> | |
+#include <bio.h> | |
+#include <libsec.h> | |
+ | |
+static int | |
+digestfmt(Fmt *fmt) | |
+{ | |
+ char buf[MD5dlen*2+1]; | |
+ uchar *p; | |
+ int i; | |
+ | |
+ p = va_arg(fmt->args, uchar*); | |
+ for(i=0; i<MD5dlen; i++) | |
+ sprint(buf+2*i, "%.2ux", p[i]); | |
+ return fmtstrcpy(fmt, buf); | |
+} | |
+ | |
+static void | |
+sum(int fd, char *name) | |
+{ | |
+ int n; | |
+ uchar buf[8192], digest[MD5dlen]; | |
+ DigestState *s; | |
+ | |
+ s = md5(nil, 0, nil, nil); | |
+ while((n = read(fd, buf, sizeof buf)) > 0) | |
+ md5(buf, n, nil, s); | |
+ md5(nil, 0, digest, s); | |
+ if(name == nil) | |
+ print("%M\n", digest); | |
+ else | |
+ print("%M\t%s\n", digest, name); | |
+} | |
+ | |
+void | |
+main(int argc, char *argv[]) | |
+{ | |
+ int i, fd; | |
+ | |
+ ARGBEGIN{ | |
+ default: | |
+ fprint(2, "usage: md5sum [file...]\n"); | |
+ exits("usage"); | |
+ }ARGEND | |
+ | |
+ fmtinstall('M', digestfmt); | |
+ | |
+ if(argc == 0) | |
+ sum(0, nil); | |
+ else for(i = 0; i < argc; i++){ | |
+ fd = open(argv[i], OREAD); | |
+ if(fd < 0){ | |
+ fprint(2, "md5sum: can't open %s: %r\n", argv[i]); | |
+ continue; | |
+ } | |
+ sum(fd, argv[i]); | |
+ close(fd); | |
+ } | |
+ exits(nil); | |
+} |