diff --git a/Makefile b/Makefile index db395c0..3db2c65 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,19 @@ all: - jbuilder build --dev @install + dune build --dev @install test: - jbuilder runtest + dune runtest doc: - jbuilder build @doc + dune build @doc install: - jbuilder install + dune install uninstall: - jbuilder uninstall + dune uninstall clean: - jbuilder clean + dune clean .PHONY: all test doc install uninstall clean diff --git a/bitfn.h b/bitfn.h index cebb952..d25d806 100644 --- a/bitfn.h +++ b/bitfn.h @@ -72,7 +72,7 @@ static inline uint64_t swap64(uint64_t a) #include #elif defined(__FreeBSD__) #include -#elif WIN32 +#elif _WIN32 /* nothing */ #else #include diff --git a/c_flags.ml b/c_flags.ml new file mode 100755 index 0000000..ea64a03 --- /dev/null +++ b/c_flags.ml @@ -0,0 +1,7 @@ +let flags = + match Sys.win32 with + | true -> "()" + | false -> "(-Wall -O3 -funroll-loops)" + +let () = + print_endline flags diff --git a/dune b/dune new file mode 100644 index 0000000..e073fea --- /dev/null +++ b/dune @@ -0,0 +1,13 @@ +(rule (with-stdout-to c_flags.sexp (run %{ocaml} %{dep:c_flags.ml}))) + +(library + (name sha) + (public_name sha) + (synopsis "SHA-1 and SHA-2 family implementations") + (wrapped false) + (modules sha1 sha256 sha512) + (flags -warn-error -3) + (foreign_stubs + (language c) + (flags (:include c_flags.sexp)) + (names sha1_stubs sha256_stubs sha512_stubs))) diff --git a/dune-project b/dune-project new file mode 100755 index 0000000..3298157 --- /dev/null +++ b/dune-project @@ -0,0 +1,24 @@ +(lang dune 2.0) + +(name sha) + +(source (github djs55/ocaml-sha)) + +(license ISC) + +(authors "Vincent Hanquez" + "Thomas Gazagnaire" + "Goswin von Brederlow" + "Eric Cooper" + "Florent Monnier" + "Forrest L Norvell" + "Vincent Bernadoff" + "David Scott") + +(maintainers dave@recoil.org) + +(package + (name sha) + (depends (dune (>= 2.0)) (ounit :with-test))) + +(generate_opam_files true) diff --git a/jbuild b/jbuild deleted file mode 100644 index 12711af..0000000 --- a/jbuild +++ /dev/null @@ -1,10 +0,0 @@ -(jbuild_version 1) - -(library - ((name sha) - (public_name sha) - (synopsis "SHA-1 and SHA-2 family implementations") - (wrapped false) - (modules (sha1 sha256 sha512)) - (c_flags (-Wall -O3 -funroll-loops)) ; Needs adapting for Windows - (c_names (sha1c sha1_stubs sha256c sha256_stubs sha512c sha512_stubs)))) diff --git a/sha.opam b/sha.opam index 551693f..7e42ebf 100644 --- a/sha.opam +++ b/sha.opam @@ -1,22 +1,35 @@ -opam-version: "1.2" -maintainer: "dave@recoil.org" -authors: [ -"Vincent Hanquez" "Thomas Gazagnaire" "Goswin von Brederlow" - "Eric Cooper" "Florent Monnier" "Forrest L Norvell" - "Vincent Bernadoff" "David Scott" +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +maintainer: ["dave@recoil.org"] +authors: [ + "Vincent Hanquez" + "Thomas Gazagnaire" + "Goswin von Brederlow" + "Eric Cooper" + "Florent Monnier" + "Forrest L Norvell" + "Vincent Bernadoff" + "David Scott" ] -homepage: "https://github.com/djs55/ocaml-sha" -bug-reports: "https://github.com/djs55/ocaml-sha/issues" -dev-repo: "https://github.com/djs55/ocaml-sha.git" -license: "ISC" - -build: [["jbuilder" "build" "-p" name "-j" jobs]] - -build-test: [["jbuilder" "runtest" "-p" name]] - +license: "ISC" +homepage: "https://github.com/djs55/ocaml-sha" +bug-reports: "https://github.com/djs55/ocaml-sha/issues" depends: [ - "jbuilder" {build & >= "1.0+beta13"} - "ounit" {test} + "dune" {>= "2.0"} + "ounit" {with-test} ] - -available: [ ocaml-version >= "4.02.0" ] +build: [ + ["dune" "subst"] {pinned} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/djs55/ocaml-sha.git" diff --git a/sha1.h b/sha1.h index 630477a..1ae5292 100644 --- a/sha1.h +++ b/sha1.h @@ -18,6 +18,10 @@ #ifndef SHA1_H #define SHA1_H +#include +#include +#include "bitfn.h" + struct sha1_ctx { unsigned int h[5]; @@ -27,11 +31,261 @@ struct sha1_ctx typedef struct { unsigned int digest[5]; } sha1_digest; -void sha1_init(struct sha1_ctx *ctx); -void sha1_copy(struct sha1_ctx *dst, struct sha1_ctx *src); -void sha1_update(struct sha1_ctx *ctx, unsigned char *data, int len); -void sha1_finalize(struct sha1_ctx *ctx, sha1_digest *out); -void sha1_to_bin(sha1_digest *digest, char *out); -void sha1_to_hex(sha1_digest *digest, char *out); +/** + * sha1_init - Init SHA1 context + */ +static void sha1_init(struct sha1_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + + /* initialize H */ + ctx->h[0] = 0x67452301; + ctx->h[1] = 0xEFCDAB89; + ctx->h[2] = 0x98BADCFE; + ctx->h[3] = 0x10325476; + ctx->h[4] = 0xC3D2E1F0; +} + +/** + * sha1_copy - Copy SHA1 context + */ +static void sha1_copy(struct sha1_ctx *dst, struct sha1_ctx *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + +#define f1(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define f2(x, y, z) (x ^ y ^ z) /* XOR */ +#define f3(x, y, z) ((x & y) + (z & (x ^ y))) /* majority */ +#define f4(x, y, z) f2(x, y, z) + +#define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */ +#define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */ +#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */ +#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */ + +#define R(a, b, c, d, e, f, k, w) e += rol32(a, 5) + f(b, c, d) + k + w; \ + b = rol32(b, 30) + +#define M(i) (w[i & 0x0f] = rol32(w[i & 0x0f] ^ w[(i - 14) & 0x0f] \ + ^ w[(i - 8) & 0x0f] ^ w[(i - 3) & 0x0f], 1)) + +static inline void sha1_do_chunk(unsigned char W[], unsigned int h[]) +{ + unsigned int a, b, c, d, e; + unsigned int w[80]; + + #define CPY(i) w[i] = be32_to_cpu(((unsigned int *) W)[i]) + CPY(0); CPY(1); CPY(2); CPY(3); CPY(4); CPY(5); CPY(6); CPY(7); + CPY(8); CPY(9); CPY(10); CPY(11); CPY(12); CPY(13); CPY(14); CPY(15); + #undef CPY + + a = h[0]; + b = h[1]; + c = h[2]; + d = h[3]; + e = h[4]; + + /* following unrolled from: + * for (i = 0; i < 20; i++) { + * t = f1(b, c, d) + K1 + rol32(a, 5) + e + M(i); + * e = d; d = c; c = rol32(b, 30); b = a; a = t; + * } + */ + R(a, b, c, d, e, f1, K1, w[0]); + R(e, a, b, c, d, f1, K1, w[1]); + R(d, e, a, b, c, f1, K1, w[2]); + R(c, d, e, a, b, f1, K1, w[3]); + R(b, c, d, e, a, f1, K1, w[4]); + R(a, b, c, d, e, f1, K1, w[5]); + R(e, a, b, c, d, f1, K1, w[6]); + R(d, e, a, b, c, f1, K1, w[7]); + R(c, d, e, a, b, f1, K1, w[8]); + R(b, c, d, e, a, f1, K1, w[9]); + R(a, b, c, d, e, f1, K1, w[10]); + R(e, a, b, c, d, f1, K1, w[11]); + R(d, e, a, b, c, f1, K1, w[12]); + R(c, d, e, a, b, f1, K1, w[13]); + R(b, c, d, e, a, f1, K1, w[14]); + R(a, b, c, d, e, f1, K1, w[15]); + R(e, a, b, c, d, f1, K1, M(16)); + R(d, e, a, b, c, f1, K1, M(17)); + R(c, d, e, a, b, f1, K1, M(18)); + R(b, c, d, e, a, f1, K1, M(19)); + + /* following unrolled from: + * for (i = 20; i < 40; i++) { + * t = f2(b, c, d) + K2 + rol32(a, 5) + e + M(i); + * e = d; d = c; c = rol32(b, 30); b = a; a = t; + * } + */ + + R(a, b, c, d, e, f2, K2, M(20)); + R(e, a, b, c, d, f2, K2, M(21)); + R(d, e, a, b, c, f2, K2, M(22)); + R(c, d, e, a, b, f2, K2, M(23)); + R(b, c, d, e, a, f2, K2, M(24)); + R(a, b, c, d, e, f2, K2, M(25)); + R(e, a, b, c, d, f2, K2, M(26)); + R(d, e, a, b, c, f2, K2, M(27)); + R(c, d, e, a, b, f2, K2, M(28)); + R(b, c, d, e, a, f2, K2, M(29)); + R(a, b, c, d, e, f2, K2, M(30)); + R(e, a, b, c, d, f2, K2, M(31)); + R(d, e, a, b, c, f2, K2, M(32)); + R(c, d, e, a, b, f2, K2, M(33)); + R(b, c, d, e, a, f2, K2, M(34)); + R(a, b, c, d, e, f2, K2, M(35)); + R(e, a, b, c, d, f2, K2, M(36)); + R(d, e, a, b, c, f2, K2, M(37)); + R(c, d, e, a, b, f2, K2, M(38)); + R(b, c, d, e, a, f2, K2, M(39)); + + /* following unrolled from: + * for (i = 40; i < 60; i++) { + * t = f3(b, c, d) + K3 + rol32(a, 5) + e + M(i); + * e = d; d = c; c = rol32(b, 30); b = a; a = t; + * } + */ + + R(a, b, c, d, e, f3, K3, M(40)); + R(e, a, b, c, d, f3, K3, M(41)); + R(d, e, a, b, c, f3, K3, M(42)); + R(c, d, e, a, b, f3, K3, M(43)); + R(b, c, d, e, a, f3, K3, M(44)); + R(a, b, c, d, e, f3, K3, M(45)); + R(e, a, b, c, d, f3, K3, M(46)); + R(d, e, a, b, c, f3, K3, M(47)); + R(c, d, e, a, b, f3, K3, M(48)); + R(b, c, d, e, a, f3, K3, M(49)); + R(a, b, c, d, e, f3, K3, M(50)); + R(e, a, b, c, d, f3, K3, M(51)); + R(d, e, a, b, c, f3, K3, M(52)); + R(c, d, e, a, b, f3, K3, M(53)); + R(b, c, d, e, a, f3, K3, M(54)); + R(a, b, c, d, e, f3, K3, M(55)); + R(e, a, b, c, d, f3, K3, M(56)); + R(d, e, a, b, c, f3, K3, M(57)); + R(c, d, e, a, b, f3, K3, M(58)); + R(b, c, d, e, a, f3, K3, M(59)); + + /* following unrolled from: + * for (i = 60; i < 80; i++) { + * t = f2(b, c, d) + K4 + rol32(a, 5) + e + M(i); + * e = d; d = c; c = rol32(b, 30); b = a; a = t; + * } + */ + R(a, b, c, d, e, f4, K4, M(60)); + R(e, a, b, c, d, f4, K4, M(61)); + R(d, e, a, b, c, f4, K4, M(62)); + R(c, d, e, a, b, f4, K4, M(63)); + R(b, c, d, e, a, f4, K4, M(64)); + R(a, b, c, d, e, f4, K4, M(65)); + R(e, a, b, c, d, f4, K4, M(66)); + R(d, e, a, b, c, f4, K4, M(67)); + R(c, d, e, a, b, f4, K4, M(68)); + R(b, c, d, e, a, f4, K4, M(69)); + R(a, b, c, d, e, f4, K4, M(70)); + R(e, a, b, c, d, f4, K4, M(71)); + R(d, e, a, b, c, f4, K4, M(72)); + R(c, d, e, a, b, f4, K4, M(73)); + R(b, c, d, e, a, f4, K4, M(74)); + R(a, b, c, d, e, f4, K4, M(75)); + R(e, a, b, c, d, f4, K4, M(76)); + R(d, e, a, b, c, f4, K4, M(77)); + R(c, d, e, a, b, f4, K4, M(78)); + R(b, c, d, e, a, f4, K4, M(79)); + + h[0] += a; + h[1] += b; + h[2] += c; + h[3] += d; + h[4] += e; +} + +/** + * sha1_update - Update the SHA1 context values with length bytes of data + */ +static void sha1_update(struct sha1_ctx *ctx, unsigned char *data, int len) +{ + unsigned int index, to_fill; + + index = (unsigned int) (ctx->sz & 0x3f); + to_fill = 64 - index; + + ctx->sz += len; + + /* process partial buffer if there's enough data to make a block */ + if (index && len >= to_fill) { + memcpy(ctx->buf + index, data, to_fill); + sha1_do_chunk(ctx->buf, ctx->h); + len -= to_fill; + data += to_fill; + index = 0; + } + + /* process as much 64-block as possible */ + for (; len >= 64; len -= 64, data += 64) + sha1_do_chunk(data, ctx->h); + + /* append data into buf */ + if (len) + memcpy(ctx->buf + index, data, len); +} + +/** + * sha1_finalize - Finalize the context and create the SHA1 digest + */ +static void sha1_finalize(struct sha1_ctx *ctx, sha1_digest *out) +{ + static unsigned char padding[64] = { 0x80, }; + unsigned int bits[2]; + unsigned int index, padlen; + + /* add padding and update data with it */ + bits[0] = cpu_to_be32((unsigned int) (ctx->sz >> 29)); + bits[1] = cpu_to_be32((unsigned int) (ctx->sz << 3)); + + /* pad out to 56 */ + index = (unsigned int) (ctx->sz & 0x3f); + padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); + sha1_update(ctx, padding, padlen); + + /* append length */ + sha1_update(ctx, (unsigned char *) bits, sizeof(bits)); + + /* output hash */ + out->digest[0] = cpu_to_be32(ctx->h[0]); + out->digest[1] = cpu_to_be32(ctx->h[1]); + out->digest[2] = cpu_to_be32(ctx->h[2]); + out->digest[3] = cpu_to_be32(ctx->h[3]); + out->digest[4] = cpu_to_be32(ctx->h[4]); +} + +/** + * sha1_to_bin - Transform the SHA1 digest into a binary data + */ +static void sha1_to_bin(sha1_digest *digest, char *out) +{ + uint32_t *ptr = (uint32_t *) out; + + ptr[0] = digest->digest[0]; + ptr[1] = digest->digest[1]; + ptr[2] = digest->digest[2]; + ptr[3] = digest->digest[3]; + ptr[4] = digest->digest[4]; +} + +/** + * sha1_to_hex - Transform the SHA1 digest into a readable data + */ +static void sha1_to_hex(sha1_digest *digest, char *out) +{ + + #define D(i) (cpu_to_be32(digest->digest[i])) + snprintf(out, 41, "%08x%08x%08x%08x%08x", + D(0), D(1), D(2), D(3), D(4)); + #undef D +} #endif diff --git a/sha1_stubs.c b/sha1_stubs.c index 4d48ef9..34e91f9 100644 --- a/sha1_stubs.c +++ b/sha1_stubs.c @@ -36,7 +36,7 @@ static inline int sha1_file(char *filename, sha1_digest *digest) int fd; ssize_t n; struct sha1_ctx ctx; -#ifdef WIN32 +#ifdef _WIN32 fd = open(filename, O_RDONLY); #else fd = open(filename, O_RDONLY | O_CLOEXEC); diff --git a/sha1c.c b/sha1c.c deleted file mode 100644 index df58840..0000000 --- a/sha1c.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2006-2009 Vincent Hanquez - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SHA1 implementation as describe in wikipedia. - */ - -#include -#include -#include "sha1.h" -#include "bitfn.h" - -/** - * sha1_init - Init SHA1 context - */ -void sha1_init(struct sha1_ctx *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - - /* initialize H */ - ctx->h[0] = 0x67452301; - ctx->h[1] = 0xEFCDAB89; - ctx->h[2] = 0x98BADCFE; - ctx->h[3] = 0x10325476; - ctx->h[4] = 0xC3D2E1F0; -} - -/** - * sha1_copy - Copy SHA1 context - */ -void sha1_copy(struct sha1_ctx *dst, struct sha1_ctx *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -#define f1(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ -#define f2(x, y, z) (x ^ y ^ z) /* XOR */ -#define f3(x, y, z) ((x & y) + (z & (x ^ y))) /* majority */ -#define f4(x, y, z) f2(x, y, z) - -#define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */ -#define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */ -#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */ -#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */ - -#define R(a, b, c, d, e, f, k, w) e += rol32(a, 5) + f(b, c, d) + k + w; \ - b = rol32(b, 30) - -#define M(i) (w[i & 0x0f] = rol32(w[i & 0x0f] ^ w[(i - 14) & 0x0f] \ - ^ w[(i - 8) & 0x0f] ^ w[(i - 3) & 0x0f], 1)) - -static inline void sha1_do_chunk(unsigned char W[], unsigned int h[]) -{ - unsigned int a, b, c, d, e; - unsigned int w[80]; - - #define CPY(i) w[i] = be32_to_cpu(((unsigned int *) W)[i]) - CPY(0); CPY(1); CPY(2); CPY(3); CPY(4); CPY(5); CPY(6); CPY(7); - CPY(8); CPY(9); CPY(10); CPY(11); CPY(12); CPY(13); CPY(14); CPY(15); - #undef CPY - - a = h[0]; - b = h[1]; - c = h[2]; - d = h[3]; - e = h[4]; - - /* following unrolled from: - * for (i = 0; i < 20; i++) { - * t = f1(b, c, d) + K1 + rol32(a, 5) + e + M(i); - * e = d; d = c; c = rol32(b, 30); b = a; a = t; - * } - */ - R(a, b, c, d, e, f1, K1, w[0]); - R(e, a, b, c, d, f1, K1, w[1]); - R(d, e, a, b, c, f1, K1, w[2]); - R(c, d, e, a, b, f1, K1, w[3]); - R(b, c, d, e, a, f1, K1, w[4]); - R(a, b, c, d, e, f1, K1, w[5]); - R(e, a, b, c, d, f1, K1, w[6]); - R(d, e, a, b, c, f1, K1, w[7]); - R(c, d, e, a, b, f1, K1, w[8]); - R(b, c, d, e, a, f1, K1, w[9]); - R(a, b, c, d, e, f1, K1, w[10]); - R(e, a, b, c, d, f1, K1, w[11]); - R(d, e, a, b, c, f1, K1, w[12]); - R(c, d, e, a, b, f1, K1, w[13]); - R(b, c, d, e, a, f1, K1, w[14]); - R(a, b, c, d, e, f1, K1, w[15]); - R(e, a, b, c, d, f1, K1, M(16)); - R(d, e, a, b, c, f1, K1, M(17)); - R(c, d, e, a, b, f1, K1, M(18)); - R(b, c, d, e, a, f1, K1, M(19)); - - /* following unrolled from: - * for (i = 20; i < 40; i++) { - * t = f2(b, c, d) + K2 + rol32(a, 5) + e + M(i); - * e = d; d = c; c = rol32(b, 30); b = a; a = t; - * } - */ - - R(a, b, c, d, e, f2, K2, M(20)); - R(e, a, b, c, d, f2, K2, M(21)); - R(d, e, a, b, c, f2, K2, M(22)); - R(c, d, e, a, b, f2, K2, M(23)); - R(b, c, d, e, a, f2, K2, M(24)); - R(a, b, c, d, e, f2, K2, M(25)); - R(e, a, b, c, d, f2, K2, M(26)); - R(d, e, a, b, c, f2, K2, M(27)); - R(c, d, e, a, b, f2, K2, M(28)); - R(b, c, d, e, a, f2, K2, M(29)); - R(a, b, c, d, e, f2, K2, M(30)); - R(e, a, b, c, d, f2, K2, M(31)); - R(d, e, a, b, c, f2, K2, M(32)); - R(c, d, e, a, b, f2, K2, M(33)); - R(b, c, d, e, a, f2, K2, M(34)); - R(a, b, c, d, e, f2, K2, M(35)); - R(e, a, b, c, d, f2, K2, M(36)); - R(d, e, a, b, c, f2, K2, M(37)); - R(c, d, e, a, b, f2, K2, M(38)); - R(b, c, d, e, a, f2, K2, M(39)); - - /* following unrolled from: - * for (i = 40; i < 60; i++) { - * t = f3(b, c, d) + K3 + rol32(a, 5) + e + M(i); - * e = d; d = c; c = rol32(b, 30); b = a; a = t; - * } - */ - - R(a, b, c, d, e, f3, K3, M(40)); - R(e, a, b, c, d, f3, K3, M(41)); - R(d, e, a, b, c, f3, K3, M(42)); - R(c, d, e, a, b, f3, K3, M(43)); - R(b, c, d, e, a, f3, K3, M(44)); - R(a, b, c, d, e, f3, K3, M(45)); - R(e, a, b, c, d, f3, K3, M(46)); - R(d, e, a, b, c, f3, K3, M(47)); - R(c, d, e, a, b, f3, K3, M(48)); - R(b, c, d, e, a, f3, K3, M(49)); - R(a, b, c, d, e, f3, K3, M(50)); - R(e, a, b, c, d, f3, K3, M(51)); - R(d, e, a, b, c, f3, K3, M(52)); - R(c, d, e, a, b, f3, K3, M(53)); - R(b, c, d, e, a, f3, K3, M(54)); - R(a, b, c, d, e, f3, K3, M(55)); - R(e, a, b, c, d, f3, K3, M(56)); - R(d, e, a, b, c, f3, K3, M(57)); - R(c, d, e, a, b, f3, K3, M(58)); - R(b, c, d, e, a, f3, K3, M(59)); - - /* following unrolled from: - * for (i = 60; i < 80; i++) { - * t = f2(b, c, d) + K4 + rol32(a, 5) + e + M(i); - * e = d; d = c; c = rol32(b, 30); b = a; a = t; - * } - */ - R(a, b, c, d, e, f4, K4, M(60)); - R(e, a, b, c, d, f4, K4, M(61)); - R(d, e, a, b, c, f4, K4, M(62)); - R(c, d, e, a, b, f4, K4, M(63)); - R(b, c, d, e, a, f4, K4, M(64)); - R(a, b, c, d, e, f4, K4, M(65)); - R(e, a, b, c, d, f4, K4, M(66)); - R(d, e, a, b, c, f4, K4, M(67)); - R(c, d, e, a, b, f4, K4, M(68)); - R(b, c, d, e, a, f4, K4, M(69)); - R(a, b, c, d, e, f4, K4, M(70)); - R(e, a, b, c, d, f4, K4, M(71)); - R(d, e, a, b, c, f4, K4, M(72)); - R(c, d, e, a, b, f4, K4, M(73)); - R(b, c, d, e, a, f4, K4, M(74)); - R(a, b, c, d, e, f4, K4, M(75)); - R(e, a, b, c, d, f4, K4, M(76)); - R(d, e, a, b, c, f4, K4, M(77)); - R(c, d, e, a, b, f4, K4, M(78)); - R(b, c, d, e, a, f4, K4, M(79)); - - h[0] += a; - h[1] += b; - h[2] += c; - h[3] += d; - h[4] += e; -} - -/** - * sha1_update - Update the SHA1 context values with length bytes of data - */ -void sha1_update(struct sha1_ctx *ctx, unsigned char *data, int len) -{ - unsigned int index, to_fill; - - index = (unsigned int) (ctx->sz & 0x3f); - to_fill = 64 - index; - - ctx->sz += len; - - /* process partial buffer if there's enough data to make a block */ - if (index && len >= to_fill) { - memcpy(ctx->buf + index, data, to_fill); - sha1_do_chunk(ctx->buf, ctx->h); - len -= to_fill; - data += to_fill; - index = 0; - } - - /* process as much 64-block as possible */ - for (; len >= 64; len -= 64, data += 64) - sha1_do_chunk(data, ctx->h); - - /* append data into buf */ - if (len) - memcpy(ctx->buf + index, data, len); -} - -/** - * sha1_finalize - Finalize the context and create the SHA1 digest - */ -void sha1_finalize(struct sha1_ctx *ctx, sha1_digest *out) -{ - static unsigned char padding[64] = { 0x80, }; - unsigned int bits[2]; - unsigned int index, padlen; - - /* add padding and update data with it */ - bits[0] = cpu_to_be32((unsigned int) (ctx->sz >> 29)); - bits[1] = cpu_to_be32((unsigned int) (ctx->sz << 3)); - - /* pad out to 56 */ - index = (unsigned int) (ctx->sz & 0x3f); - padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); - sha1_update(ctx, padding, padlen); - - /* append length */ - sha1_update(ctx, (unsigned char *) bits, sizeof(bits)); - - /* output hash */ - out->digest[0] = cpu_to_be32(ctx->h[0]); - out->digest[1] = cpu_to_be32(ctx->h[1]); - out->digest[2] = cpu_to_be32(ctx->h[2]); - out->digest[3] = cpu_to_be32(ctx->h[3]); - out->digest[4] = cpu_to_be32(ctx->h[4]); -} - -/** - * sha1_to_bin - Transform the SHA1 digest into a binary data - */ -void sha1_to_bin(sha1_digest *digest, char *out) -{ - uint32_t *ptr = (uint32_t *) out; - - ptr[0] = digest->digest[0]; - ptr[1] = digest->digest[1]; - ptr[2] = digest->digest[2]; - ptr[3] = digest->digest[3]; - ptr[4] = digest->digest[4]; -} - -/** - * sha1_to_hex - Transform the SHA1 digest into a readable data - */ -void sha1_to_hex(sha1_digest *digest, char *out) -{ - - #define D(i) (cpu_to_be32(digest->digest[i])) - snprintf(out, 41, "%08x%08x%08x%08x%08x", - D(0), D(1), D(2), D(3), D(4)); - #undef D -} diff --git a/sha256.h b/sha256.h index a56bd24..133f587 100644 --- a/sha256.h +++ b/sha256.h @@ -15,9 +15,14 @@ * * SHA256 implementation */ + #ifndef SHA256_H #define SHA256_H +#include +#include +#include "bitfn.h" + struct sha256_ctx { unsigned int h[8]; @@ -27,11 +32,205 @@ struct sha256_ctx typedef struct { unsigned int digest[8]; } sha256_digest; -void sha256_init(struct sha256_ctx *ctx); -void sha256_copy(struct sha256_ctx *dst, struct sha256_ctx *src); -void sha256_update(struct sha256_ctx *ctx, unsigned char *data, int len); -void sha256_finalize(struct sha256_ctx *ctx, sha256_digest *out); -void sha256_to_bin(sha256_digest *digest, char *out); -void sha256_to_hex(sha256_digest *digest, char *out); +/** + * sha256_init - Init SHA256 context + */ +static void sha256_init(struct sha256_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->h[0] = 0x6a09e667; + ctx->h[1] = 0xbb67ae85; + ctx->h[2] = 0x3c6ef372; + ctx->h[3] = 0xa54ff53a; + ctx->h[4] = 0x510e527f; + ctx->h[5] = 0x9b05688c; + ctx->h[6] = 0x1f83d9ab; + ctx->h[7] = 0x5be0cd19; +} + +/** + * sha256_copy - Copy SHA256 context + */ +static void sha256_copy(struct sha256_ctx *dst, struct sha256_ctx *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + +/* 232 times the cube root of the first 64 primes 2..311 */ +static const unsigned int k[] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + +static inline unsigned int Ch(unsigned int x, unsigned int y, unsigned int z) +{ + return z ^ (x & (y ^ z)); +} + +static inline unsigned int Maj(unsigned int x, unsigned int y, unsigned int z) +{ + return (x & y) | (z & (x | y)); +} + +#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22)) +#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25)) +#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3)) +#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10)) + +/** + * sha256_do_chunk - Process a block through SHA256 + */ +static void sha256_do_chunk(unsigned char __W[], unsigned int H[]) +{ + unsigned int a, b, c, d, e, f, g, h, t1, t2; + unsigned int W[64]; + int i; + + for (i = 0; i < 16; i++) + W[i] = be32_to_cpu(((unsigned int *) __W)[i]); + + for (i = 16; i < 64; i++) + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + +#define T(a, b, c, d, e, f, g, h, k, w) \ + do { \ + t1 = h + e1(e) + Ch(e, f, g) + k + w; \ + t2 = e0(a) + Maj(a, b, c); \ + d += t1; \ + h = t1 + t2; \ + } while (0) + +#define PASS(i) \ + do { \ + T(a, b, c, d, e, f, g, h, k[i + 0], W[i + 0]); \ + T(h, a, b, c, d, e, f, g, k[i + 1], W[i + 1]); \ + T(g, h, a, b, c, d, e, f, k[i + 2], W[i + 2]); \ + T(f, g, h, a, b, c, d, e, k[i + 3], W[i + 3]); \ + T(e, f, g, h, a, b, c, d, k[i + 4], W[i + 4]); \ + T(d, e, f, g, h, a, b, c, k[i + 5], W[i + 5]); \ + T(c, d, e, f, g, h, a, b, k[i + 6], W[i + 6]); \ + T(b, c, d, e, f, g, h, a, k[i + 7], W[i + 7]); \ + } while (0) + + PASS(0); + PASS(8); + PASS(16); + PASS(24); + PASS(32); + PASS(40); + PASS(48); + PASS(56); + +#undef T +#undef PASS + + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + H[5] += f; + H[6] += g; + H[7] += h; +} + +/** + * sha256_update - Update the SHA256 context values with length bytes of data + */ +static void sha256_update(struct sha256_ctx *ctx, unsigned char *data, int len) +{ + unsigned int index, to_fill; + + /* check for partial buffer */ + index = (unsigned int) (ctx->sz & 0x3f); + to_fill = 64 - index; + + ctx->sz += len; + + /* process partial buffer if there's enough data to make a block */ + if (index && len >= to_fill) { + memcpy(ctx->buf + index, data, to_fill); + sha256_do_chunk(ctx->buf, ctx->h); + len -= to_fill; + data += to_fill; + index = 0; + } + + /* process as much 64-block as possible */ + for (; len >= 64; len -= 64, data += 64) + sha256_do_chunk(data, ctx->h); + + /* append data into buf */ + if (len) + memcpy(ctx->buf + index, data, len); +} + +/** + * sha256_finalize - Finalize the context and create the SHA256 digest + */ +static void sha256_finalize(struct sha256_ctx *ctx, sha256_digest *out) +{ + static unsigned char padding[64] = { 0x80, }; + unsigned int bits[2]; + unsigned int i, index, padlen; + + /* cpu -> big endian */ + bits[0] = cpu_to_be32((unsigned int) (ctx->sz >> 29)); + bits[1] = cpu_to_be32((unsigned int) (ctx->sz << 3)); + + /* pad out to 56 */ + index = (unsigned int) (ctx->sz & 0x3f); + padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); + sha256_update(ctx, padding, padlen); + + /* append length */ + sha256_update(ctx, (unsigned char *) bits, sizeof(bits)); + + /* store to digest */ + for (i = 0; i < 8; i++) + out->digest[i] = cpu_to_be32(ctx->h[i]); +} + +/** + * sha256_to_bin - Transform the SHA256 digest into a binary data + */ +static void sha256_to_bin(sha256_digest *digest, char *out) +{ + uint32_t *ptr = (uint32_t *) out; + int i; + + for (i = 0; i < 8; i++) + ptr[i] = digest->digest[i]; +} + +/** + * sha256_to_hex - Transform the SHA256 digest into a readable data + */ +static void sha256_to_hex(sha256_digest *digest, char *out) +{ + char *p; + int i; + + for (p = out, i = 0; i < 8; i++, p += 8) + snprintf(p, 9, "%08x", be32_to_cpu(digest->digest[i])); +} #endif diff --git a/sha256_stubs.c b/sha256_stubs.c index f0b6411..729d018 100644 --- a/sha256_stubs.c +++ b/sha256_stubs.c @@ -36,7 +36,7 @@ static inline int sha256_file(char *filename, sha256_digest *digest) int fd; ssize_t n; struct sha256_ctx ctx; -#ifdef WIN32 +#ifdef _WIN32 fd = open(filename, O_RDONLY); #else fd = open(filename, O_RDONLY | O_CLOEXEC); diff --git a/sha256c.c b/sha256c.c deleted file mode 100644 index 5516881..0000000 --- a/sha256c.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2006-2009 Vincent Hanquez - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SHA256 implementation - */ - -#include -#include -#include "bitfn.h" -#include "sha256.h" - - -/** - * sha256_init - Init SHA256 context - */ -void sha256_init(struct sha256_ctx *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - - ctx->h[0] = 0x6a09e667; - ctx->h[1] = 0xbb67ae85; - ctx->h[2] = 0x3c6ef372; - ctx->h[3] = 0xa54ff53a; - ctx->h[4] = 0x510e527f; - ctx->h[5] = 0x9b05688c; - ctx->h[6] = 0x1f83d9ab; - ctx->h[7] = 0x5be0cd19; -} - -/** - * sha256_copy - Copy SHA256 context - */ -void sha256_copy(struct sha256_ctx *dst, struct sha256_ctx *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -/* 232 times the cube root of the first 64 primes 2..311 */ -static const unsigned int k[] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, - 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, - 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, - 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, - 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, - 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; - -static inline unsigned int Ch(unsigned int x, unsigned int y, unsigned int z) -{ - return z ^ (x & (y ^ z)); -} - -static inline unsigned int Maj(unsigned int x, unsigned int y, unsigned int z) -{ - return (x & y) | (z & (x | y)); -} - -#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22)) -#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25)) -#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3)) -#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10)) - -/** - * sha256_do_chunk - Process a block through SHA256 - */ -static void sha256_do_chunk(unsigned char __W[], unsigned int H[]) -{ - unsigned int a, b, c, d, e, f, g, h, t1, t2; - unsigned int W[64]; - int i; - - for (i = 0; i < 16; i++) - W[i] = be32_to_cpu(((unsigned int *) __W)[i]); - - for (i = 16; i < 64; i++) - W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; - - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - -#define T(a, b, c, d, e, f, g, h, k, w) \ - do { \ - t1 = h + e1(e) + Ch(e, f, g) + k + w; \ - t2 = e0(a) + Maj(a, b, c); \ - d += t1; \ - h = t1 + t2; \ - } while (0) - -#define PASS(i) \ - do { \ - T(a, b, c, d, e, f, g, h, k[i + 0], W[i + 0]); \ - T(h, a, b, c, d, e, f, g, k[i + 1], W[i + 1]); \ - T(g, h, a, b, c, d, e, f, k[i + 2], W[i + 2]); \ - T(f, g, h, a, b, c, d, e, k[i + 3], W[i + 3]); \ - T(e, f, g, h, a, b, c, d, k[i + 4], W[i + 4]); \ - T(d, e, f, g, h, a, b, c, k[i + 5], W[i + 5]); \ - T(c, d, e, f, g, h, a, b, k[i + 6], W[i + 6]); \ - T(b, c, d, e, f, g, h, a, k[i + 7], W[i + 7]); \ - } while (0) - - PASS(0); - PASS(8); - PASS(16); - PASS(24); - PASS(32); - PASS(40); - PASS(48); - PASS(56); - -#undef T -#undef PASS - - H[0] += a; - H[1] += b; - H[2] += c; - H[3] += d; - H[4] += e; - H[5] += f; - H[6] += g; - H[7] += h; -} - -/** - * sha256_update - Update the SHA256 context values with length bytes of data - */ -void sha256_update(struct sha256_ctx *ctx, unsigned char *data, int len) -{ - unsigned int index, to_fill; - - /* check for partial buffer */ - index = (unsigned int) (ctx->sz & 0x3f); - to_fill = 64 - index; - - ctx->sz += len; - - /* process partial buffer if there's enough data to make a block */ - if (index && len >= to_fill) { - memcpy(ctx->buf + index, data, to_fill); - sha256_do_chunk(ctx->buf, ctx->h); - len -= to_fill; - data += to_fill; - index = 0; - } - - /* process as much 64-block as possible */ - for (; len >= 64; len -= 64, data += 64) - sha256_do_chunk(data, ctx->h); - - /* append data into buf */ - if (len) - memcpy(ctx->buf + index, data, len); -} - -/** - * sha256_finalize - Finalize the context and create the SHA256 digest - */ -void sha256_finalize(struct sha256_ctx *ctx, sha256_digest *out) -{ - static unsigned char padding[64] = { 0x80, }; - unsigned int bits[2]; - unsigned int i, index, padlen; - - /* cpu -> big endian */ - bits[0] = cpu_to_be32((unsigned int) (ctx->sz >> 29)); - bits[1] = cpu_to_be32((unsigned int) (ctx->sz << 3)); - - /* pad out to 56 */ - index = (unsigned int) (ctx->sz & 0x3f); - padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); - sha256_update(ctx, padding, padlen); - - /* append length */ - sha256_update(ctx, (unsigned char *) bits, sizeof(bits)); - - /* store to digest */ - for (i = 0; i < 8; i++) - out->digest[i] = cpu_to_be32(ctx->h[i]); -} - -/** - * sha256_to_bin - Transform the SHA256 digest into a binary data - */ -void sha256_to_bin(sha256_digest *digest, char *out) -{ - uint32_t *ptr = (uint32_t *) out; - int i; - - for (i = 0; i < 8; i++) - ptr[i] = digest->digest[i]; -} - -/** - * sha256_to_hex - Transform the SHA256 digest into a readable data - */ -void sha256_to_hex(sha256_digest *digest, char *out) -{ - char *p; - int i; - - for (p = out, i = 0; i < 8; i++, p += 8) - snprintf(p, 9, "%08x", be32_to_cpu(digest->digest[i])); -} diff --git a/sha512.h b/sha512.h index 4f4d751..714fcb1 100644 --- a/sha512.h +++ b/sha512.h @@ -15,10 +15,14 @@ * * SHA512 implementation */ + #ifndef SHA512_H #define SHA512_H #include +#include +#include +#include "bitfn.h" struct sha512_ctx { @@ -29,11 +33,228 @@ struct sha512_ctx typedef struct { uint64_t digest[8]; } sha512_digest; -void sha512_init(struct sha512_ctx *ctx); -void sha512_copy(struct sha512_ctx *dst, struct sha512_ctx *src); -void sha512_update(struct sha512_ctx *ctx, unsigned char *data, int len); -void sha512_finalize(struct sha512_ctx *ctx, sha512_digest *out); -void sha512_to_bin(sha512_digest *digest, char *out); -void sha512_to_hex(sha512_digest *digest, char *out); +/** + * sha512_init - Init SHA512 context + */ +static void sha512_init(struct sha512_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->h[0] = 0x6a09e667f3bcc908ULL; + ctx->h[1] = 0xbb67ae8584caa73bULL; + ctx->h[2] = 0x3c6ef372fe94f82bULL; + ctx->h[3] = 0xa54ff53a5f1d36f1ULL; + ctx->h[4] = 0x510e527fade682d1ULL; + ctx->h[5] = 0x9b05688c2b3e6c1fULL; + ctx->h[6] = 0x1f83d9abfb41bd6bULL; + ctx->h[7] = 0x5be0cd19137e2179ULL; +} + +/** + * sha512_copy - Copy SHA512 context + */ +static void sha512_copy(struct sha512_ctx *dst, struct sha512_ctx *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + +/* 232 times the cube root of the first 64 primes 2..311 */ +static const uint64_t k[] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, +}; + +static inline uint64_t Ch(uint64_t x, uint64_t y, uint64_t z) +{ + return z ^ (x & (y ^ z)); +} + +static inline uint64_t Maj(uint64_t x, uint64_t y, uint64_t z) +{ + return (x & y) | (z & (x | y)); +} + +#define e0(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39)) +#define e1(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41)) +#define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) +#define s1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6)) + +/** + * sha512_do_chunk - Process a block through SHA512 + */ +static void sha512_do_chunk(unsigned char __W[], uint64_t H[]) +{ + uint64_t a, b, c, d, e, f, g, h, t1, t2; + uint64_t W[80]; + int i; + + for (i = 0; i < 16; i++) + W[i] = be64_to_cpu(((uint64_t *) __W)[i]); + + for (i = 16; i < 80; i++) + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + +#define T(a, b, c, d, e, f, g, h, k, w) \ + do { \ + t1 = h + e1(e) + Ch(e, f, g) + k + w; \ + t2 = e0(a) + Maj(a, b, c); \ + d += t1; \ + h = t1 + t2; \ + } while (0) + +#define PASS(i) \ + do { \ + T(a, b, c, d, e, f, g, h, k[i + 0], W[i + 0]); \ + T(h, a, b, c, d, e, f, g, k[i + 1], W[i + 1]); \ + T(g, h, a, b, c, d, e, f, k[i + 2], W[i + 2]); \ + T(f, g, h, a, b, c, d, e, k[i + 3], W[i + 3]); \ + T(e, f, g, h, a, b, c, d, k[i + 4], W[i + 4]); \ + T(d, e, f, g, h, a, b, c, k[i + 5], W[i + 5]); \ + T(c, d, e, f, g, h, a, b, k[i + 6], W[i + 6]); \ + T(b, c, d, e, f, g, h, a, k[i + 7], W[i + 7]); \ + } while (0) + + PASS(0); + PASS(8); + PASS(16); + PASS(24); + PASS(32); + PASS(40); + PASS(48); + PASS(56); + PASS(64); + PASS(72); + +#undef T +#undef PASS + + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + H[5] += f; + H[6] += g; + H[7] += h; +} + +/** + * sha512_update - Update the SHA512 context values with length bytes of data + */ +static void sha512_update(struct sha512_ctx *ctx, unsigned char *data, int len) +{ + unsigned int index, to_fill; + + /* check for partial buffer */ + index = (unsigned int) (ctx->sz[0] & 0x7f); + to_fill = 128 - index; + + ctx->sz[0] += len; + if (ctx->sz[0] < len) + ctx->sz[1]++; + + /* process partial buffer if there's enough data to make a block */ + if (index && len >= to_fill) { + memcpy(ctx->buf + index, data, to_fill); + sha512_do_chunk(ctx->buf, ctx->h); + len -= to_fill; + data += to_fill; + index = 0; + } + + /* process as much 128-block as possible */ + for (; len >= 128; len -= 128, data += 128) + sha512_do_chunk(data, ctx->h); + + /* append data into buf */ + if (len) + memcpy(ctx->buf + index, data, len); +} + +/** + * sha512_finalize - Finalize the context and create the SHA512 digest + */ +static void sha512_finalize(struct sha512_ctx *ctx, sha512_digest *out) +{ + static unsigned char padding[128] = { 0x80, }; + unsigned int i, index, padlen; + uint64_t bits[2]; + + /* cpu -> big endian */ + bits[0] = cpu_to_be64((ctx->sz[1] << 3 | ctx->sz[0] >> 61)); + bits[1] = cpu_to_be64((ctx->sz[0] << 3)); + + /* pad out to 56 */ + index = (unsigned int) (ctx->sz[0] & 0x7f); + padlen = (index < 112) ? (112 - index) : ((128 + 112) - index); + sha512_update(ctx, padding, padlen); + + /* append length */ + sha512_update(ctx, (unsigned char *) bits, sizeof(bits)); + + /* store to digest */ + for (i = 0; i < 8; i++) + out->digest[i] = cpu_to_be64(ctx->h[i]); +} + +/** + * sha512_to_bin - Transform the SHA512 digest into a binary data + */ +static void sha512_to_bin(sha512_digest *digest, char *out) +{ + uint64_t *ptr = (uint64_t *) out; + int i; + + for (i = 0; i < 8; i++) + ptr[i] = digest->digest[i]; +} + + +/** + * sha512_to_hex - Transform the SHA512 digest into a readable data + */ +static void sha512_to_hex(sha512_digest *digest, char *out) +{ + char *p; + int i; + + for (p = out, i = 0; i < 8; i++, p += 16) + snprintf(p, 17, "%016llx", + (unsigned long long) be64_to_cpu(digest->digest[i])); +} #endif diff --git a/sha512_stubs.c b/sha512_stubs.c index 2652e19..d4afc4e 100644 --- a/sha512_stubs.c +++ b/sha512_stubs.c @@ -36,7 +36,7 @@ static inline int sha512_file(char *filename, sha512_digest *digest) int fd; ssize_t n; struct sha512_ctx ctx; -#ifdef WIN32 +#ifdef _WIN32 fd = open(filename, O_RDONLY); #else fd = open(filename, O_RDONLY | O_CLOEXEC); diff --git a/sha512c.c b/sha512c.c deleted file mode 100644 index cc30779..0000000 --- a/sha512c.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2006-2009 Vincent Hanquez - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SHA512 implementation - */ - -#include -#include -#include "bitfn.h" -#include "sha512.h" - -/** - * sha512_init - Init SHA512 context - */ -void sha512_init(struct sha512_ctx *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - - ctx->h[0] = 0x6a09e667f3bcc908ULL; - ctx->h[1] = 0xbb67ae8584caa73bULL; - ctx->h[2] = 0x3c6ef372fe94f82bULL; - ctx->h[3] = 0xa54ff53a5f1d36f1ULL; - ctx->h[4] = 0x510e527fade682d1ULL; - ctx->h[5] = 0x9b05688c2b3e6c1fULL; - ctx->h[6] = 0x1f83d9abfb41bd6bULL; - ctx->h[7] = 0x5be0cd19137e2179ULL; -} - -/** - * sha512_copy - Copy SHA512 context - */ -void sha512_copy(struct sha512_ctx *dst, struct sha512_ctx *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -/* 232 times the cube root of the first 64 primes 2..311 */ -static const uint64_t k[] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, - 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, - 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, - 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, - 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, - 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, - 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, - 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, - 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, - 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, - 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, - 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, - 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, - 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, -}; - -static inline uint64_t Ch(uint64_t x, uint64_t y, uint64_t z) -{ - return z ^ (x & (y ^ z)); -} - -static inline uint64_t Maj(uint64_t x, uint64_t y, uint64_t z) -{ - return (x & y) | (z & (x | y)); -} - -#define e0(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39)) -#define e1(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41)) -#define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) -#define s1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6)) - -/** - * sha512_do_chunk - Process a block through SHA512 - */ -static void sha512_do_chunk(unsigned char __W[], uint64_t H[]) -{ - uint64_t a, b, c, d, e, f, g, h, t1, t2; - uint64_t W[80]; - int i; - - for (i = 0; i < 16; i++) - W[i] = be64_to_cpu(((uint64_t *) __W)[i]); - - for (i = 16; i < 80; i++) - W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; - - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - -#define T(a, b, c, d, e, f, g, h, k, w) \ - do { \ - t1 = h + e1(e) + Ch(e, f, g) + k + w; \ - t2 = e0(a) + Maj(a, b, c); \ - d += t1; \ - h = t1 + t2; \ - } while (0) - -#define PASS(i) \ - do { \ - T(a, b, c, d, e, f, g, h, k[i + 0], W[i + 0]); \ - T(h, a, b, c, d, e, f, g, k[i + 1], W[i + 1]); \ - T(g, h, a, b, c, d, e, f, k[i + 2], W[i + 2]); \ - T(f, g, h, a, b, c, d, e, k[i + 3], W[i + 3]); \ - T(e, f, g, h, a, b, c, d, k[i + 4], W[i + 4]); \ - T(d, e, f, g, h, a, b, c, k[i + 5], W[i + 5]); \ - T(c, d, e, f, g, h, a, b, k[i + 6], W[i + 6]); \ - T(b, c, d, e, f, g, h, a, k[i + 7], W[i + 7]); \ - } while (0) - - PASS(0); - PASS(8); - PASS(16); - PASS(24); - PASS(32); - PASS(40); - PASS(48); - PASS(56); - PASS(64); - PASS(72); - -#undef T -#undef PASS - - H[0] += a; - H[1] += b; - H[2] += c; - H[3] += d; - H[4] += e; - H[5] += f; - H[6] += g; - H[7] += h; -} - -/** - * sha512_update - Update the SHA512 context values with length bytes of data - */ -void sha512_update(struct sha512_ctx *ctx, unsigned char *data, int len) -{ - unsigned int index, to_fill; - - /* check for partial buffer */ - index = (unsigned int) (ctx->sz[0] & 0x7f); - to_fill = 128 - index; - - ctx->sz[0] += len; - if (ctx->sz[0] < len) - ctx->sz[1]++; - - /* process partial buffer if there's enough data to make a block */ - if (index && len >= to_fill) { - memcpy(ctx->buf + index, data, to_fill); - sha512_do_chunk(ctx->buf, ctx->h); - len -= to_fill; - data += to_fill; - index = 0; - } - - /* process as much 128-block as possible */ - for (; len >= 128; len -= 128, data += 128) - sha512_do_chunk(data, ctx->h); - - /* append data into buf */ - if (len) - memcpy(ctx->buf + index, data, len); -} - -/** - * sha512_finalize - Finalize the context and create the SHA512 digest - */ -void sha512_finalize(struct sha512_ctx *ctx, sha512_digest *out) -{ - static unsigned char padding[128] = { 0x80, }; - unsigned int i, index, padlen; - uint64_t bits[2]; - - /* cpu -> big endian */ - bits[0] = cpu_to_be64((ctx->sz[1] << 3 | ctx->sz[0] >> 61)); - bits[1] = cpu_to_be64((ctx->sz[0] << 3)); - - /* pad out to 56 */ - index = (unsigned int) (ctx->sz[0] & 0x7f); - padlen = (index < 112) ? (112 - index) : ((128 + 112) - index); - sha512_update(ctx, padding, padlen); - - /* append length */ - sha512_update(ctx, (unsigned char *) bits, sizeof(bits)); - - /* store to digest */ - for (i = 0; i < 8; i++) - out->digest[i] = cpu_to_be64(ctx->h[i]); -} - -/** - * sha512_to_bin - Transform the SHA512 digest into a binary data - */ -void sha512_to_bin(sha512_digest *digest, char *out) -{ - uint64_t *ptr = (uint64_t *) out; - int i; - - for (i = 0; i < 8; i++) - ptr[i] = digest->digest[i]; -} - - -/** - * sha512_to_hex - Transform the SHA512 digest into a readable data - */ -void sha512_to_hex(sha512_digest *digest, char *out) -{ - char *p; - int i; - - for (p = out, i = 0; i < 8; i++, p += 16) - snprintf(p, 17, "%016llx", - (unsigned long long) be64_to_cpu(digest->digest[i])); -} diff --git a/test/dune b/test/dune new file mode 100755 index 0000000..afbff97 --- /dev/null +++ b/test/dune @@ -0,0 +1,14 @@ +(executable + (name shasum) + (modules shasum) + (libraries sha)) + +(executable + (name shatest) + (modules shatest) + (libraries sha oUnit)) + +(rule + (alias runtest) + (deps sample.txt) + (action (run ./shatest.exe))) diff --git a/test/jbuild b/test/jbuild deleted file mode 100755 index 7ba4059..0000000 --- a/test/jbuild +++ /dev/null @@ -1,16 +0,0 @@ -(jbuild_version 1) - -(executable - ((name shasum) - (modules (shasum)) - (libraries (sha)))) - -(executable - ((name shatest) - (modules (shatest)) - (libraries (sha oUnit)))) - -(alias - ((name runtest) - (deps (shatest.exe sample.txt)) - (action (run ${<}))))