On Wed, Jul 6, 2016 at 4:18 PM, Michael Paquier <michael.paqu...@gmail.com> wrote: > OK, after hacking that for a bit I have finished with option 2 and the > set of PG-like set of routines, the use of USE_SSL in the file > containing all the SHA functions of OpenBSD has proved to be really > ugly, but with a split things are really clear to the eye. The stuff I > got builds on OSX, Linux and MSVC. pgcrypto cannot link directly to > libpgcommon.a, so I am making it compile directly with the source > files, as it is doing on HEAD.
Btw, attached is the patch I did for this part if there is any interest in it. Also, while working on the rest, I am not adding a new column to pg_auth_id to identify the password verifier type. That's just to keep the patch at a bare minimum size. Are there issues with that? -- Michael
From 6101ffb3baf12cbb13a20812b1d8d10350683ff7 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@otacoo.com> Date: Wed, 6 Jul 2016 16:09:31 +0900 Subject: [PATCH 1/3] Refactor SHA functions and move them to src/common/ This way both frontend and backends can refer to them if needed. Those functions are taken from pgcrypto, which now fetches directly the source files it needs from src/common/ when compiling its library. A new interface, which is more PG-like is designed for those SHA functions, allowing to link to either OpenSSL or the in-core stuff taken from OpenBSD as need be, which is the most flexible solution. --- contrib/pgcrypto/.gitignore | 4 + contrib/pgcrypto/Makefile | 11 +- contrib/pgcrypto/fortuna.c | 12 +- contrib/pgcrypto/internal-sha2.c | 82 +- contrib/pgcrypto/internal.c | 32 +- contrib/pgcrypto/sha1.c | 341 --------- contrib/pgcrypto/sha1.h | 75 -- contrib/pgcrypto/sha2.h | 100 --- src/common/Makefile | 6 + contrib/pgcrypto/sha2.c => src/common/sha.c | 1101 +++++++++++++++++---------- src/common/sha_openssl.c | 120 +++ src/include/common/sha.h | 95 +++ src/tools/msvc/Mkvcbuild.pm | 11 +- 13 files changed, 1012 insertions(+), 978 deletions(-) delete mode 100644 contrib/pgcrypto/sha1.c delete mode 100644 contrib/pgcrypto/sha1.h delete mode 100644 contrib/pgcrypto/sha2.h rename contrib/pgcrypto/sha2.c => src/common/sha.c (54%) create mode 100644 src/common/sha_openssl.c create mode 100644 src/include/common/sha.h diff --git a/contrib/pgcrypto/.gitignore b/contrib/pgcrypto/.gitignore index 5dcb3ff..582110e 100644 --- a/contrib/pgcrypto/.gitignore +++ b/contrib/pgcrypto/.gitignore @@ -1,3 +1,7 @@ +# Source file copied from src/common +/sha.c +/sha_openssl.c + # Generated subdirectories /log/ /results/ diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile index 805db76..492184d 100644 --- a/contrib/pgcrypto/Makefile +++ b/contrib/pgcrypto/Makefile @@ -1,6 +1,6 @@ # contrib/pgcrypto/Makefile -INT_SRCS = md5.c sha1.c sha2.c internal.c internal-sha2.c blf.c rijndael.c \ +INT_SRCS = md5.c internal.c internal-sha2.c blf.c rijndael.c \ fortuna.c random.c pgp-mpi-internal.c imath.c INT_TESTS = sha2 @@ -22,6 +22,12 @@ SRCS = pgcrypto.c px.c px-hmac.c px-crypt.c \ pgp-pubdec.c pgp-pubenc.c pgp-pubkey.c pgp-s2k.c \ pgp-pgsql.c +ifeq ($(with_openssl),yes) +SRCS += sha_openssl.c +else +SRCS += sha.c +endif + MODULE_big = pgcrypto OBJS = $(SRCS:.c=.o) $(WIN32RES) @@ -59,6 +65,9 @@ SHLIB_LINK += $(filter -leay32, $(LIBS)) SHLIB_LINK += -lws2_32 endif +sha.c sha_openssl.c: % : $(top_srcdir)/src/common/% + rm -f $@ && $(LN_S) $< . + rijndael.o: rijndael.tbl rijndael.tbl: diff --git a/contrib/pgcrypto/fortuna.c b/contrib/pgcrypto/fortuna.c index 5028203..6bc6faf 100644 --- a/contrib/pgcrypto/fortuna.c +++ b/contrib/pgcrypto/fortuna.c @@ -34,9 +34,9 @@ #include <sys/time.h> #include <time.h> +#include "common/sha.h" #include "px.h" #include "rijndael.h" -#include "sha2.h" #include "fortuna.h" @@ -112,7 +112,7 @@ #define CIPH_BLOCK 16 /* for internal wrappers */ -#define MD_CTX SHA256_CTX +#define MD_CTX pg_sha256_ctx #define CIPH_CTX rijndael_ctx struct fortuna_state @@ -154,22 +154,22 @@ ciph_encrypt(CIPH_CTX * ctx, const uint8 *in, uint8 *out) static void md_init(MD_CTX * ctx) { - SHA256_Init(ctx); + pg_sha256_init(ctx); } static void md_update(MD_CTX * ctx, const uint8 *data, int len) { - SHA256_Update(ctx, data, len); + pg_sha256_update(ctx, data, len); } static void md_result(MD_CTX * ctx, uint8 *dst) { - SHA256_CTX tmp; + pg_sha256_ctx tmp; memcpy(&tmp, ctx, sizeof(*ctx)); - SHA256_Final(dst, &tmp); + pg_sha256_final(&tmp, dst); px_memset(&tmp, 0, sizeof(tmp)); } diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c index 55ec7e1..3868fd2 100644 --- a/contrib/pgcrypto/internal-sha2.c +++ b/contrib/pgcrypto/internal-sha2.c @@ -33,8 +33,8 @@ #include <time.h> +#include "common/sha.h" #include "px.h" -#include "sha2.h" void init_sha224(PX_MD *h); void init_sha256(PX_MD *h); @@ -46,43 +46,43 @@ void init_sha512(PX_MD *h); static unsigned int_sha224_len(PX_MD *h) { - return SHA224_DIGEST_LENGTH; + return PG_SHA224_DIGEST_LENGTH; } static unsigned int_sha224_block_len(PX_MD *h) { - return SHA224_BLOCK_LENGTH; + return PG_SHA224_BLOCK_LENGTH; } static void int_sha224_update(PX_MD *h, const uint8 *data, unsigned dlen) { - SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr; + pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - SHA224_Update(ctx, data, dlen); + pg_sha224_update(ctx, data, dlen); } static void int_sha224_reset(PX_MD *h) { - SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr; + pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - SHA224_Init(ctx); + pg_sha224_init(ctx); } static void int_sha224_finish(PX_MD *h, uint8 *dst) { - SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr; + pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - SHA224_Final(dst, ctx); + pg_sha224_final(ctx, dst); } static void int_sha224_free(PX_MD *h) { - SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr; + pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; px_memset(ctx, 0, sizeof(*ctx)); px_free(ctx); @@ -94,43 +94,43 @@ int_sha224_free(PX_MD *h) static unsigned int_sha256_len(PX_MD *h) { - return SHA256_DIGEST_LENGTH; + return PG_SHA256_DIGEST_LENGTH; } static unsigned int_sha256_block_len(PX_MD *h) { - return SHA256_BLOCK_LENGTH; + return PG_SHA256_BLOCK_LENGTH; } static void int_sha256_update(PX_MD *h, const uint8 *data, unsigned dlen) { - SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr; + pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - SHA256_Update(ctx, data, dlen); + pg_sha256_update(ctx, data, dlen); } static void int_sha256_reset(PX_MD *h) { - SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr; + pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - SHA256_Init(ctx); + pg_sha256_init(ctx); } static void int_sha256_finish(PX_MD *h, uint8 *dst) { - SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr; + pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - SHA256_Final(dst, ctx); + pg_sha256_final(ctx, dst); } static void int_sha256_free(PX_MD *h) { - SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr; + pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; px_memset(ctx, 0, sizeof(*ctx)); px_free(ctx); @@ -142,43 +142,43 @@ int_sha256_free(PX_MD *h) static unsigned int_sha384_len(PX_MD *h) { - return SHA384_DIGEST_LENGTH; + return PG_SHA384_DIGEST_LENGTH; } static unsigned int_sha384_block_len(PX_MD *h) { - return SHA384_BLOCK_LENGTH; + return PG_SHA384_BLOCK_LENGTH; } static void int_sha384_update(PX_MD *h, const uint8 *data, unsigned dlen) { - SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr; + pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - SHA384_Update(ctx, data, dlen); + pg_sha384_update(ctx, data, dlen); } static void int_sha384_reset(PX_MD *h) { - SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr; + pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - SHA384_Init(ctx); + pg_sha384_init(ctx); } static void int_sha384_finish(PX_MD *h, uint8 *dst) { - SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr; + pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - SHA384_Final(dst, ctx); + pg_sha384_final(ctx, dst); } static void int_sha384_free(PX_MD *h) { - SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr; + pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; px_memset(ctx, 0, sizeof(*ctx)); px_free(ctx); @@ -190,43 +190,43 @@ int_sha384_free(PX_MD *h) static unsigned int_sha512_len(PX_MD *h) { - return SHA512_DIGEST_LENGTH; + return PG_SHA512_DIGEST_LENGTH; } static unsigned int_sha512_block_len(PX_MD *h) { - return SHA512_BLOCK_LENGTH; + return PG_SHA512_BLOCK_LENGTH; } static void int_sha512_update(PX_MD *h, const uint8 *data, unsigned dlen) { - SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr; + pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; - SHA512_Update(ctx, data, dlen); + pg_sha512_update(ctx, data, dlen); } static void int_sha512_reset(PX_MD *h) { - SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr; + pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; - SHA512_Init(ctx); + pg_sha512_init(ctx); } static void int_sha512_finish(PX_MD *h, uint8 *dst) { - SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr; + pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; - SHA512_Final(dst, ctx); + pg_sha512_final(ctx, dst); } static void int_sha512_free(PX_MD *h) { - SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr; + pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; px_memset(ctx, 0, sizeof(*ctx)); px_free(ctx); @@ -238,7 +238,7 @@ int_sha512_free(PX_MD *h) void init_sha224(PX_MD *md) { - SHA224_CTX *ctx; + pg_sha224_ctx *ctx; ctx = px_alloc(sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); @@ -258,7 +258,7 @@ init_sha224(PX_MD *md) void init_sha256(PX_MD *md) { - SHA256_CTX *ctx; + pg_sha256_ctx *ctx; ctx = px_alloc(sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); @@ -278,7 +278,7 @@ init_sha256(PX_MD *md) void init_sha384(PX_MD *md) { - SHA384_CTX *ctx; + pg_sha384_ctx *ctx; ctx = px_alloc(sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); @@ -298,7 +298,7 @@ init_sha384(PX_MD *md) void init_sha512(PX_MD *md) { - SHA512_CTX *ctx; + pg_sha512_ctx *ctx; ctx = px_alloc(sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index cb8ba26..5e3fc30 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -33,9 +33,10 @@ #include <time.h> +#include "common/sha.h" + #include "px.h" #include "md5.h" -#include "sha1.h" #include "blf.h" #include "rijndael.h" #include "fortuna.h" @@ -63,15 +64,6 @@ #define MD5_DIGEST_LENGTH 16 #endif -#ifndef SHA1_DIGEST_LENGTH -#ifdef SHA1_RESULTLEN -#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN -#else -#define SHA1_DIGEST_LENGTH 20 -#endif -#endif - -#define SHA1_BLOCK_SIZE 64 #define MD5_BLOCK_SIZE 64 static void init_md5(PX_MD *h); @@ -152,43 +144,43 @@ int_md5_free(PX_MD *h) static unsigned int_sha1_len(PX_MD *h) { - return SHA1_DIGEST_LENGTH; + return PG_SHA1_DIGEST_LENGTH; } static unsigned int_sha1_block_len(PX_MD *h) { - return SHA1_BLOCK_SIZE; + return PG_SHA1_BLOCK_LENGTH; } static void int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_sha1_ctx *ctx = (pg_sha1_ctx *) h->p.ptr; - SHA1Update(ctx, data, dlen); + pg_sha1_update(ctx, data, dlen); } static void int_sha1_reset(PX_MD *h) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_sha1_ctx *ctx = (pg_sha1_ctx *) h->p.ptr; - SHA1Init(ctx); + pg_sha1_init(ctx); } static void int_sha1_finish(PX_MD *h, uint8 *dst) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_sha1_ctx *ctx = (pg_sha1_ctx *) h->p.ptr; - SHA1Final(dst, ctx); + pg_sha1_final(ctx, dst); } static void int_sha1_free(PX_MD *h) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_sha1_ctx *ctx = (pg_sha1_ctx *) h->p.ptr; px_memset(ctx, 0, sizeof(*ctx)); px_free(ctx); @@ -220,7 +212,7 @@ init_md5(PX_MD *md) static void init_sha1(PX_MD *md) { - SHA1_CTX *ctx; + pg_sha1_ctx *ctx; ctx = px_alloc(sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c deleted file mode 100644 index 0e753ce..0000000 --- a/contrib/pgcrypto/sha1.c +++ /dev/null @@ -1,341 +0,0 @@ -/* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * contrib/pgcrypto/sha1.c - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm - * implemented by Jun-ichiro itojun Itoh <ito...@itojun.org> - */ - -#include "postgres.h" - -#include <sys/param.h> - -#include "sha1.h" - -/* constant table */ -static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; - -#define K(t) _K[(t) / 20] - -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - (n)))) - -#define H(n) (ctxt->h.b32[(n)]) -#define COUNT (ctxt->count) -#define BCOUNT (ctxt->c.b64[0] / 8) -#define W(n) (ctxt->m.b32[(n)]) - -#define PUTBYTE(x) \ -do { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - ctxt->c.b64[0] += 8; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ -} while (0) - -#define PUTPAD(x) \ -do { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ -} while (0) - -static void sha1_step(struct sha1_ctxt *); - -static void -sha1_step(struct sha1_ctxt * ctxt) -{ - uint32 a, - b, - c, - d, - e; - size_t t, - s; - uint32 tmp; - -#ifndef WORDS_BIGENDIAN - struct sha1_ctxt tctxt; - - memmove(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; - ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; - ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; - ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; - ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; - ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; - ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; - ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; - ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; - ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; - ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; - ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; - ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; - ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; - ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; - ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; - ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; - ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; - ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; - ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; - ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; - ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; - ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; - ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; - ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; - ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; - ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; - ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; - ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; - ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; - ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; - ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; - ctxt->m.b8[63] = tctxt.m.b8[60]; -#endif - - a = H(0); - b = H(1); - c = H(2); - d = H(3); - e = H(4); - - for (t = 0; t < 20; t++) - { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 20; t < 40; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 40; t < 60; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 60; t < 80; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - memset(&ctxt->m.b8[0], 0, 64); -} - -/*------------------------------------------------------------*/ - -void -sha1_init(struct sha1_ctxt * ctxt) -{ - memset(ctxt, 0, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; -} - -void -sha1_pad(struct sha1_ctxt * ctxt) -{ - size_t padlen; /* pad length in bytes */ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) - { - memset(&ctxt->m.b8[padstart], 0, padlen); - COUNT += padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - memset(&ctxt->m.b8[padstart], 0, padlen - 8); - COUNT += (padlen - 8); - COUNT %= 64; -#ifdef WORDS_BIGENDIAN - PUTPAD(ctxt->c.b8[0]); - PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[7]); -#else - PUTPAD(ctxt->c.b8[7]); - PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[0]); -#endif -} - -void -sha1_loop(struct sha1_ctxt * ctxt, const uint8 *input0, size_t len) -{ - const uint8 *input; - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - input = (const uint8 *) input0; - off = 0; - - while (off < len) - { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - memmove(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } -} - -void -sha1_result(struct sha1_ctxt * ctxt, uint8 *digest0) -{ - uint8 *digest; - - digest = (uint8 *) digest0; - sha1_pad(ctxt); -#ifdef WORDS_BIGENDIAN - memmove(digest, &ctxt->h.b8[0], 20); -#else - digest[0] = ctxt->h.b8[3]; - digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; - digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; - digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; - digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; - digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; - digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; - digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; - digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; - digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; - digest[19] = ctxt->h.b8[16]; -#endif -} diff --git a/contrib/pgcrypto/sha1.h b/contrib/pgcrypto/sha1.h deleted file mode 100644 index 2f61e45..0000000 --- a/contrib/pgcrypto/sha1.h +++ /dev/null @@ -1,75 +0,0 @@ -/* contrib/pgcrypto/sha1.h */ -/* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm - * implemented by Jun-ichiro itojun Itoh <ito...@itojun.org> - */ - -#ifndef _NETINET6_SHA1_H_ -#define _NETINET6_SHA1_H_ - -struct sha1_ctxt -{ - union - { - uint8 b8[20]; - uint32 b32[5]; - } h; - union - { - uint8 b8[8]; - uint64 b64[1]; - } c; - union - { - uint8 b8[64]; - uint32 b32[16]; - } m; - uint8 count; -}; - -extern void sha1_init(struct sha1_ctxt *); -extern void sha1_pad(struct sha1_ctxt *); -extern void sha1_loop(struct sha1_ctxt *, const uint8 *, size_t); -extern void sha1_result(struct sha1_ctxt *, uint8 *); - -/* compatibility with other SHA1 source codes */ -typedef struct sha1_ctxt SHA1_CTX; - -#define SHA1Init(x) sha1_init((x)) -#define SHA1Update(x, y, z) sha1_loop((x), (y), (z)) -#define SHA1Final(x, y) sha1_result((y), (x)) - -#define SHA1_RESULTLEN (160/8) - -#endif /* _NETINET6_SHA1_H_ */ diff --git a/contrib/pgcrypto/sha2.h b/contrib/pgcrypto/sha2.h deleted file mode 100644 index 501f0e0..0000000 --- a/contrib/pgcrypto/sha2.h +++ /dev/null @@ -1,100 +0,0 @@ -/* contrib/pgcrypto/sha2.h */ -/* $OpenBSD: sha2.h,v 1.2 2004/04/28 23:11:57 millert Exp $ */ - -/* - * FILE: sha2.h - * AUTHOR: Aaron D. Gifford <m...@aarongifford.com> - * - * Copyright (c) 2000-2001, Aaron D. Gifford - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ - */ - -#ifndef _SHA2_H -#define _SHA2_H - -/* avoid conflict with OpenSSL */ -#define SHA256_Init pg_SHA256_Init -#define SHA256_Update pg_SHA256_Update -#define SHA256_Final pg_SHA256_Final -#define SHA384_Init pg_SHA384_Init -#define SHA384_Update pg_SHA384_Update -#define SHA384_Final pg_SHA384_Final -#define SHA512_Init pg_SHA512_Init -#define SHA512_Update pg_SHA512_Update -#define SHA512_Final pg_SHA512_Final - -/*** SHA-224/256/384/512 Various Length Definitions ***********************/ -#define SHA224_BLOCK_LENGTH 64 -#define SHA224_DIGEST_LENGTH 28 -#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) -#define SHA256_BLOCK_LENGTH 64 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) -#define SHA384_BLOCK_LENGTH 128 -#define SHA384_DIGEST_LENGTH 48 -#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) - - -/*** SHA-256/384/512 Context Structures *******************************/ -typedef struct _SHA256_CTX -{ - uint32 state[8]; - uint64 bitcount; - uint8 buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX -{ - uint64 state[8]; - uint64 bitcount[2]; - uint8 buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; - -typedef SHA256_CTX SHA224_CTX; -typedef SHA512_CTX SHA384_CTX; - -void SHA224_Init(SHA224_CTX *); -void SHA224_Update(SHA224_CTX *, const uint8 *, size_t); -void SHA224_Final(uint8[SHA224_DIGEST_LENGTH], SHA224_CTX *); - -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX *, const uint8 *, size_t); -void SHA256_Final(uint8[SHA256_DIGEST_LENGTH], SHA256_CTX *); - -void SHA384_Init(SHA384_CTX *); -void SHA384_Update(SHA384_CTX *, const uint8 *, size_t); -void SHA384_Final(uint8[SHA384_DIGEST_LENGTH], SHA384_CTX *); - -void SHA512_Init(SHA512_CTX *); -void SHA512_Update(SHA512_CTX *, const uint8 *, size_t); -void SHA512_Final(uint8[SHA512_DIGEST_LENGTH], SHA512_CTX *); - -#endif /* _SHA2_H */ diff --git a/src/common/Makefile b/src/common/Makefile index 72b7369..c27e25e 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -40,6 +40,12 @@ OBJS_COMMON = config_info.o controldata_utils.o exec.o keywords.o \ pg_lzcompress.o pgfnames.o psprintf.o relpath.o rmtree.o \ string.o username.o wait_error.o +ifeq ($(with_openssl),yes) +OBJS_COMMON += sha_openssl.o +else +OBJS_COMMON += sha.o +endif + OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o restricted_token.o OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o) diff --git a/contrib/pgcrypto/sha2.c b/src/common/sha.c similarity index 54% rename from contrib/pgcrypto/sha2.c rename to src/common/sha.c index 231f9df..0809671 100644 --- a/contrib/pgcrypto/sha2.c +++ b/src/common/sha.c @@ -1,10 +1,22 @@ -/* $OpenBSD: sha2.c,v 1.6 2004/05/03 02:57:36 millert Exp $ */ +/*------------------------------------------------------------------------- + * + * sha.c + * Set of SHA functions for SHA-1, SHA-224, SHA-256, SHA-384 and + * SHA-512. + * + * This is the set of in-core functions used when there are no other + * alternative options like OpenSSL. + * + * Portions Copyright (c) 2016, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/sha.c + * + *------------------------------------------------------------------------- + */ /* - * FILE: sha2.c - * AUTHOR: Aaron D. Gifford <m...@aarongifford.com> - * - * Copyright (c) 2000-2001, Aaron D. Gifford + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -15,14 +27,14 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors + * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -31,109 +43,341 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ - * - * contrib/pgcrypto/sha2.c + * src/common/sha.c + */ + +/* + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) + * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm + * implemented by Jun-ichiro itojun Itoh <ito...@itojun.org> */ +#ifndef FRONTEND #include "postgres.h" +#else +#include "postgres_fe.h" +#endif #include <sys/param.h> -#include "px.h" -#include "sha2.h" +#include "common/sha.h" -/* - * UNROLLED TRANSFORM LOOP NOTE: - * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform - * loop version for the hash transform rounds (defined using macros - * later in this file). Either define on the command line, for example: - * - * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c - * - * or define below: - * - * #define SHA2_UNROLL_TRANSFORM - * - */ +/* constant table */ +static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; -/*** SHA-256/384/512 Various Length Definitions ***********************/ -/* NOTE: Most of these are in sha2.h */ -#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) -#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) -#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) +#define K(t) _K[(t) / 20] +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) +#define F1(b, c, d) (((b) ^ (c)) ^ (d)) +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define F3(b, c, d) (((b) ^ (c)) ^ (d)) + +#define S(n, x) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define H(n) (ctx->h.b32[(n)]) +#define COUNT (ctx->count) +#define BCOUNT (ctx->c.b64[0] / 8) +#define W(n) (ctx->m.b32[(n)]) + +#define PUTBYTE(x) \ +do { \ + ctx->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + ctx->c.b64[0] += 8; \ + if (COUNT % 64 == 0) \ + pg_sha1_step(ctx); \ +} while (0) + +#define PUTPAD(x) \ +do { \ + ctx->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + if (COUNT % 64 == 0) \ + pg_sha1_step(ctx); \ +} while (0) + +static void pg_sha1_step(pg_sha1_ctx *ctx); +static void pg_sha1_pad(pg_sha1_ctx *ctx); + +static void +pg_sha1_step(pg_sha1_ctx *ctx) +{ + uint32 a, + b, + c, + d, + e; + size_t t, + s; + uint32 tmp; -/*** ENDIAN REVERSAL MACROS *******************************************/ #ifndef WORDS_BIGENDIAN -#define REVERSE32(w,x) { \ - uint32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ + pg_sha1_ctx tctxt; + + memmove(&tctxt.m.b8[0], &ctx->m.b8[0], 64); + ctx->m.b8[0] = tctxt.m.b8[3]; + ctx->m.b8[1] = tctxt.m.b8[2]; + ctx->m.b8[2] = tctxt.m.b8[1]; + ctx->m.b8[3] = tctxt.m.b8[0]; + ctx->m.b8[4] = tctxt.m.b8[7]; + ctx->m.b8[5] = tctxt.m.b8[6]; + ctx->m.b8[6] = tctxt.m.b8[5]; + ctx->m.b8[7] = tctxt.m.b8[4]; + ctx->m.b8[8] = tctxt.m.b8[11]; + ctx->m.b8[9] = tctxt.m.b8[10]; + ctx->m.b8[10] = tctxt.m.b8[9]; + ctx->m.b8[11] = tctxt.m.b8[8]; + ctx->m.b8[12] = tctxt.m.b8[15]; + ctx->m.b8[13] = tctxt.m.b8[14]; + ctx->m.b8[14] = tctxt.m.b8[13]; + ctx->m.b8[15] = tctxt.m.b8[12]; + ctx->m.b8[16] = tctxt.m.b8[19]; + ctx->m.b8[17] = tctxt.m.b8[18]; + ctx->m.b8[18] = tctxt.m.b8[17]; + ctx->m.b8[19] = tctxt.m.b8[16]; + ctx->m.b8[20] = tctxt.m.b8[23]; + ctx->m.b8[21] = tctxt.m.b8[22]; + ctx->m.b8[22] = tctxt.m.b8[21]; + ctx->m.b8[23] = tctxt.m.b8[20]; + ctx->m.b8[24] = tctxt.m.b8[27]; + ctx->m.b8[25] = tctxt.m.b8[26]; + ctx->m.b8[26] = tctxt.m.b8[25]; + ctx->m.b8[27] = tctxt.m.b8[24]; + ctx->m.b8[28] = tctxt.m.b8[31]; + ctx->m.b8[29] = tctxt.m.b8[30]; + ctx->m.b8[30] = tctxt.m.b8[29]; + ctx->m.b8[31] = tctxt.m.b8[28]; + ctx->m.b8[32] = tctxt.m.b8[35]; + ctx->m.b8[33] = tctxt.m.b8[34]; + ctx->m.b8[34] = tctxt.m.b8[33]; + ctx->m.b8[35] = tctxt.m.b8[32]; + ctx->m.b8[36] = tctxt.m.b8[39]; + ctx->m.b8[37] = tctxt.m.b8[38]; + ctx->m.b8[38] = tctxt.m.b8[37]; + ctx->m.b8[39] = tctxt.m.b8[36]; + ctx->m.b8[40] = tctxt.m.b8[43]; + ctx->m.b8[41] = tctxt.m.b8[42]; + ctx->m.b8[42] = tctxt.m.b8[41]; + ctx->m.b8[43] = tctxt.m.b8[40]; + ctx->m.b8[44] = tctxt.m.b8[47]; + ctx->m.b8[45] = tctxt.m.b8[46]; + ctx->m.b8[46] = tctxt.m.b8[45]; + ctx->m.b8[47] = tctxt.m.b8[44]; + ctx->m.b8[48] = tctxt.m.b8[51]; + ctx->m.b8[49] = tctxt.m.b8[50]; + ctx->m.b8[50] = tctxt.m.b8[49]; + ctx->m.b8[51] = tctxt.m.b8[48]; + ctx->m.b8[52] = tctxt.m.b8[55]; + ctx->m.b8[53] = tctxt.m.b8[54]; + ctx->m.b8[54] = tctxt.m.b8[53]; + ctx->m.b8[55] = tctxt.m.b8[52]; + ctx->m.b8[56] = tctxt.m.b8[59]; + ctx->m.b8[57] = tctxt.m.b8[58]; + ctx->m.b8[58] = tctxt.m.b8[57]; + ctx->m.b8[59] = tctxt.m.b8[56]; + ctx->m.b8[60] = tctxt.m.b8[63]; + ctx->m.b8[61] = tctxt.m.b8[62]; + ctx->m.b8[62] = tctxt.m.b8[61]; + ctx->m.b8[63] = tctxt.m.b8[60]; +#endif + + a = H(0); + b = H(1); + c = H(2); + d = H(3); + e = H(4); + + for (t = 0; t < 20; t++) + { + s = t & 0x0f; + if (t >= 16) + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + for (t = 20; t < 40; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + for (t = 40; t < 60; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + for (t = 60; t < 80; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + + H(0) = H(0) + a; + H(1) = H(1) + b; + H(2) = H(2) + c; + H(3) = H(3) + d; + H(4) = H(4) + e; + + memset(&ctx->m.b8[0], 0, 64); } -#define REVERSE64(w,x) { \ - uint64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ + +static void +pg_sha1_pad(pg_sha1_ctx *ctx) +{ + size_t padlen; /* pad length in bytes */ + size_t padstart; + + PUTPAD(0x80); + + padstart = COUNT % 64; + padlen = 64 - padstart; + if (padlen < 8) + { + memset(&ctx->m.b8[padstart], 0, padlen); + COUNT += padlen; + COUNT %= 64; + pg_sha1_step(ctx); + padstart = COUNT % 64; /* should be 0 */ + padlen = 64 - padstart; /* should be 64 */ + } + memset(&ctx->m.b8[padstart], 0, padlen - 8); + COUNT += (padlen - 8); + COUNT %= 64; +#ifdef WORDS_BIGENDIAN + PUTPAD(ctx->c.b8[0]); + PUTPAD(ctx->c.b8[1]); + PUTPAD(ctx->c.b8[2]); + PUTPAD(ctx->c.b8[3]); + PUTPAD(ctx->c.b8[4]); + PUTPAD(ctx->c.b8[5]); + PUTPAD(ctx->c.b8[6]); + PUTPAD(ctx->c.b8[7]); +#else + PUTPAD(ctx->c.b8[7]); + PUTPAD(ctx->c.b8[6]); + PUTPAD(ctx->c.b8[5]); + PUTPAD(ctx->c.b8[4]); + PUTPAD(ctx->c.b8[3]); + PUTPAD(ctx->c.b8[2]); + PUTPAD(ctx->c.b8[1]); + PUTPAD(ctx->c.b8[0]); +#endif } -#endif /* not bigendian */ -/* - * Macro for incrementally adding the unsigned 64-bit integer n to the - * unsigned 128-bit integer (represented using a two-element array of - * 64-bit words): - */ -#define ADDINC128(w,n) { \ - (w)[0] += (uint64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ +/* Interface routines for SHA-1 */ +void +pg_sha1_init(pg_sha1_ctx *ctx) +{ + memset(ctx, 0, sizeof(pg_sha1_ctx)); + H(0) = 0x67452301; + H(1) = 0xefcdab89; + H(2) = 0x98badcfe; + H(3) = 0x10325476; + H(4) = 0xc3d2e1f0; } -/*** THE SIX LOGICAL FUNCTIONS ****************************************/ -/* - * Bit shifting and rotation (used by the six SHA-XYZ logical functions: - * - * NOTE: The naming of R and S appears backwards here (R is a SHIFT and - * S is a ROTATION) because the SHA-256/384/512 description document - * (see http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf) - * uses this same "backwards" definition. - */ -/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define R(b,x) ((x) >> (b)) -/* 32-bit Rotate-right (used in SHA-256): */ -#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) -/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ -#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) +void +pg_sha1_update(pg_sha1_ctx *ctx, const uint8 *input0, size_t len) +{ + const uint8 *input; + size_t gaplen; + size_t gapstart; + size_t off; + size_t copysiz; -/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ -#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + input = (const uint8 *) input0; + off = 0; -/* Four of six logical functions used in SHA-256: */ -#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) -#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) -#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) -#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + while (off < len) + { + gapstart = COUNT % 64; + gaplen = 64 - gapstart; + + copysiz = (gaplen < len - off) ? gaplen : len - off; + memmove(&ctx->m.b8[gapstart], &input[off], copysiz); + COUNT += copysiz; + COUNT %= 64; + ctx->c.b64[0] += copysiz * 8; + if (COUNT % 64 == 0) + pg_sha1_step(ctx); + off += copysiz; + } +} -/* Four of six logical functions used in SHA-384 and SHA-512: */ -#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) -#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) -#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) -#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) +void +pg_sha1_final(pg_sha1_ctx *ctx, uint8 *dest) +{ + uint8 *digest; + + digest = (uint8 *) dest; + pg_sha1_pad(ctx); +#ifdef WORDS_BIGENDIAN + memmove(digest, &ctx->h.b8[0], 20); +#else + digest[0] = ctx->h.b8[3]; + digest[1] = ctx->h.b8[2]; + digest[2] = ctx->h.b8[1]; + digest[3] = ctx->h.b8[0]; + digest[4] = ctx->h.b8[7]; + digest[5] = ctx->h.b8[6]; + digest[6] = ctx->h.b8[5]; + digest[7] = ctx->h.b8[4]; + digest[8] = ctx->h.b8[11]; + digest[9] = ctx->h.b8[10]; + digest[10] = ctx->h.b8[9]; + digest[11] = ctx->h.b8[8]; + digest[12] = ctx->h.b8[15]; + digest[13] = ctx->h.b8[14]; + digest[14] = ctx->h.b8[13]; + digest[15] = ctx->h.b8[12]; + digest[16] = ctx->h.b8[19]; + digest[17] = ctx->h.b8[18]; + digest[18] = ctx->h.b8[17]; + digest[19] = ctx->h.b8[16]; +#endif +} -/*** INTERNAL FUNCTION PROTOTYPES *************************************/ -/* NOTE: These should not be accessed directly from outside this - * library -- they are intended for private internal visibility/use - * only. +/* + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * */ -static void SHA512_Last(SHA512_CTX *); -static void SHA256_Transform(SHA256_CTX *, const uint8 *); -static void SHA512_Transform(SHA512_CTX *, const uint8 *); +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define PG_SHA256_SHORT_BLOCK_LENGTH (PG_SHA256_BLOCK_LENGTH - 8) +#define PG_SHA384_SHORT_BLOCK_LENGTH (PG_SHA384_BLOCK_LENGTH - 16) +#define PG_SHA512_SHORT_BLOCK_LENGTH (PG_SHA512_BLOCK_LENGTH - 16) /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ @@ -248,16 +492,124 @@ static const uint64 sha512_initial_hash_value[8] = { 0x5be0cd19137e2179ULL }; +/*** ENDIAN REVERSAL MACROS *******************************************/ +#ifndef WORDS_BIGENDIAN +#define REVERSE32(w,x) { \ + uint32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + uint64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* not bigendian */ -/*** SHA-256: *********************************************************/ -void -SHA256_Init(SHA256_CTX *context) +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (uint64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf) + * uses this same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +static void pg_sha512_last(pg_sha512_ctx *ctx); +static void pg_sha256_transform(pg_sha256_ctx *ctx, const uint8 *data); +static void pg_sha512_transform(pg_sha512_ctx *ctx, const uint8 *data); + +static void +pg_sha512_last(pg_sha512_ctx *ctx) { - if (context == NULL) - return; - memcpy(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - memset(context->buffer, 0, SHA256_BLOCK_LENGTH); - context->bitcount = 0; + unsigned int usedspace; + + usedspace = (ctx->bitcount[0] >> 3) % PG_SHA512_BLOCK_LENGTH; +#ifndef WORDS_BIGENDIAN + /* Convert FROM host byte order */ + REVERSE64(ctx->bitcount[0], ctx->bitcount[0]); + REVERSE64(ctx->bitcount[1], ctx->bitcount[1]); +#endif + if (usedspace > 0) + { + /* Begin padding with a 1 bit: */ + ctx->buffer[usedspace++] = 0x80; + + if (usedspace <= PG_SHA512_SHORT_BLOCK_LENGTH) + { + /* Set-up for the last transform: */ + memset(&ctx->buffer[usedspace], 0, PG_SHA512_SHORT_BLOCK_LENGTH - usedspace); + } + else + { + if (usedspace < PG_SHA512_BLOCK_LENGTH) + { + memset(&ctx->buffer[usedspace], 0, PG_SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + pg_sha512_transform(ctx, ctx->buffer); + + /* And set-up for the last transform: */ + memset(ctx->buffer, 0, PG_SHA512_BLOCK_LENGTH - 2); + } + } + else + { + /* Prepare for final transform: */ + memset(ctx->buffer, 0, PG_SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *ctx->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(uint64 *) &ctx->buffer[PG_SHA512_SHORT_BLOCK_LENGTH] = ctx->bitcount[1]; + *(uint64 *) &ctx->buffer[PG_SHA512_SHORT_BLOCK_LENGTH + 8] = ctx->bitcount[0]; + + /* Final transform: */ + pg_sha512_transform(ctx, ctx->buffer); } #ifdef SHA2_UNROLL_TRANSFORM @@ -287,7 +639,7 @@ SHA256_Init(SHA256_CTX *context) } while(0) static void -SHA256_Transform(SHA256_CTX *context, const uint8 *data) +pg_sha256_transform(pg_sha256_ctx *ctx, const uint8 *data) { uint32 a, b, @@ -303,17 +655,17 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data) *W256; int j; - W256 = (uint32 *) context->buffer; + W256 = (uint32 *) ctx->buffer; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; j = 0; do @@ -343,14 +695,14 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data) } while (j < 64); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; @@ -358,7 +710,7 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data) #else /* SHA2_UNROLL_TRANSFORM */ static void -SHA256_Transform(SHA256_CTX *context, const uint8 *data) +pg_sha256_transform(pg_sha256_ctx *ctx, const uint8 *data) { uint32 a, b, @@ -375,17 +727,17 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data) *W256; int j; - W256 = (uint32 *) context->buffer; + W256 = (uint32 *) ctx->buffer; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; j = 0; do @@ -433,159 +785,20 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data) } while (j < 64); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ -void -SHA256_Update(SHA256_CTX *context, const uint8 *data, size_t len) -{ - size_t freespace, - usedspace; - - /* Calling with no data is valid (we do nothing) */ - if (len == 0) - return; - - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - if (usedspace > 0) - { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) - { - /* Fill the buffer completely and process it */ - memcpy(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Transform(context, context->buffer); - } - else - { - /* The buffer is not yet full */ - memcpy(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) - { - /* Process as many complete blocks as we can */ - SHA256_Transform(context, data); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) - { - /* There's left-overs, so save 'em */ - memcpy(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; -} - -static void -SHA256_Last(SHA256_CTX *context) -{ - unsigned int usedspace; - - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; -#ifndef WORDS_BIGENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount, context->bitcount); -#endif - if (usedspace > 0) - { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) - { - /* Set-up for the last transform: */ - memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace); - } - else - { - if (usedspace < SHA256_BLOCK_LENGTH) - { - memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, context->buffer); - - /* And set-up for the last transform: */ - memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); - } - } - else - { - /* Set-up for the last transform: */ - memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Set the bit count: */ - *(uint64 *) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; - - /* Final transform: */ - SHA256_Transform(context, context->buffer); -} - -void -SHA256_Final(uint8 digest[], SHA256_CTX *context) -{ - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) - { - SHA256_Last(context); - -#ifndef WORDS_BIGENDIAN - { - /* Convert TO host byte order */ - int j; - - for (j = 0; j < 8; j++) - { - REVERSE32(context->state[j], context->state[j]); - } - } -#endif - memcpy(digest, context->state, SHA256_DIGEST_LENGTH); - } - - /* Clean up state data: */ - px_memset(context, 0, sizeof(*context)); -} - - -/*** SHA-512: *********************************************************/ -void -SHA512_Init(SHA512_CTX *context) -{ - if (context == NULL) - return; - memcpy(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - memset(context->buffer, 0, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ @@ -616,7 +829,7 @@ SHA512_Init(SHA512_CTX *context) } while(0) static void -SHA512_Transform(SHA512_CTX *context, const uint8 *data) +pg_sha512_transform(pg_sha512_ctx *ctx, const uint8 *data) { uint64 a, b, @@ -629,18 +842,18 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data) s0, s1; uint64 T1, - *W512 = (uint64 *) context->buffer; + *W512 = (uint64 *) ctx->buffer; int j; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; j = 0; do @@ -669,14 +882,14 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data) } while (j < 80); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; @@ -684,7 +897,7 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data) #else /* SHA2_UNROLL_TRANSFORM */ static void -SHA512_Transform(SHA512_CTX *context, const uint8 *data) +pg_sha512_transform(pg_sha512_ctx *ctx, const uint8 *data) { uint64 a, b, @@ -698,18 +911,18 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data) s1; uint64 T1, T2, - *W512 = (uint64 *) context->buffer; + *W512 = (uint64 *) ctx->buffer; int j; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; j = 0; do @@ -759,22 +972,82 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data) } while (j < 80); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ +static void +pg_sha256_last(pg_sha256_ctx *ctx) +{ + unsigned int usedspace; + + usedspace = (ctx->bitcount >> 3) % PG_SHA256_BLOCK_LENGTH; +#ifndef WORDS_BIGENDIAN + /* Convert FROM host byte order */ + REVERSE64(ctx->bitcount, ctx->bitcount); +#endif + if (usedspace > 0) + { + /* Begin padding with a 1 bit: */ + ctx->buffer[usedspace++] = 0x80; + + if (usedspace <= PG_SHA256_SHORT_BLOCK_LENGTH) + { + /* Set-up for the last transform: */ + memset(&ctx->buffer[usedspace], 0, PG_SHA256_SHORT_BLOCK_LENGTH - usedspace); + } + else + { + if (usedspace < PG_SHA256_BLOCK_LENGTH) + { + memset(&ctx->buffer[usedspace], 0, PG_SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + pg_sha256_transform(ctx, ctx->buffer); + + /* And set-up for the last transform: */ + memset(ctx->buffer, 0, PG_SHA256_SHORT_BLOCK_LENGTH); + } + } + else + { + /* Set-up for the last transform: */ + memset(ctx->buffer, 0, PG_SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *ctx->buffer = 0x80; + } + /* Set the bit count: */ + *(uint64 *) &ctx->buffer[PG_SHA256_SHORT_BLOCK_LENGTH] = ctx->bitcount; + + /* Final transform: */ + pg_sha256_transform(ctx, ctx->buffer); +} + +/* Interface routines for SHA-256 */ +void +pg_sha256_init(pg_sha256_ctx *ctx) +{ + if (ctx == NULL) + return; + memcpy(ctx->state, sha256_initial_hash_value, PG_SHA256_DIGEST_LENGTH); + memset(ctx->buffer, 0, PG_SHA256_BLOCK_LENGTH); + ctx->bitcount = 0; +} + + void -SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len) +pg_sha256_update(pg_sha256_ctx *ctx, const uint8 *data, size_t len) { size_t freespace, usedspace; @@ -783,106 +1056,148 @@ SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len) if (len == 0) return; - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (ctx->bitcount >> 3) % PG_SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; + freespace = PG_SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ - memcpy(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); + memcpy(&ctx->buffer[usedspace], data, freespace); + ctx->bitcount += freespace << 3; len -= freespace; data += freespace; - SHA512_Transform(context, context->buffer); + pg_sha256_transform(ctx, ctx->buffer); } else { /* The buffer is not yet full */ - memcpy(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); + memcpy(&ctx->buffer[usedspace], data, len); + ctx->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } - while (len >= SHA512_BLOCK_LENGTH) + while (len >= PG_SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ - SHA512_Transform(context, data); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; + pg_sha256_transform(ctx, data); + ctx->bitcount += PG_SHA256_BLOCK_LENGTH << 3; + len -= PG_SHA256_BLOCK_LENGTH; + data += PG_SHA256_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ - memcpy(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); + memcpy(ctx->buffer, data, len); + ctx->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } -static void -SHA512_Last(SHA512_CTX *context) +void +pg_sha256_final(pg_sha256_ctx *ctx, uint8 *dest) { - unsigned int usedspace; + /* If no destination buffer is passed, we don't bother doing this: */ + if (dest != NULL) + { + pg_sha256_last(ctx); - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; #ifndef WORDS_BIGENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0], context->bitcount[0]); - REVERSE64(context->bitcount[1], context->bitcount[1]); + { + /* Convert TO host byte order */ + int j; + + for (j = 0; j < 8; j++) + { + REVERSE32(ctx->state[j], ctx->state[j]); + } + } #endif + memcpy(dest, ctx->state, PG_SHA256_DIGEST_LENGTH); + } + + /* Clean up state data: */ + memset(ctx, 0, sizeof(pg_sha256_ctx)); +} + + +/* Interface routines for SHA-512 */ +void +pg_sha512_init(pg_sha512_ctx *ctx) +{ + if (ctx == NULL) + return; + memcpy(ctx->state, sha512_initial_hash_value, PG_SHA512_DIGEST_LENGTH); + memset(ctx->buffer, 0, PG_SHA512_BLOCK_LENGTH); + ctx->bitcount[0] = ctx->bitcount[1] = 0; +} + + +void +pg_sha512_update(pg_sha512_ctx *ctx, const uint8 *data, size_t len) +{ + size_t freespace, + usedspace; + + /* Calling with no data is valid (we do nothing) */ + if (len == 0) + return; + + usedspace = (ctx->bitcount[0] >> 3) % PG_SHA512_BLOCK_LENGTH; if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; + /* Calculate how much free space is available in the buffer */ + freespace = PG_SHA512_BLOCK_LENGTH - usedspace; - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) + if (len >= freespace) { - /* Set-up for the last transform: */ - memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace); + /* Fill the buffer completely and process it */ + memcpy(&ctx->buffer[usedspace], data, freespace); + ADDINC128(ctx->bitcount, freespace << 3); + len -= freespace; + data += freespace; + pg_sha512_transform(ctx, ctx->buffer); } else { - if (usedspace < SHA512_BLOCK_LENGTH) - { - memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA512_Transform(context, context->buffer); - - /* And set-up for the last transform: */ - memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); + /* The buffer is not yet full */ + memcpy(&ctx->buffer[usedspace], data, len); + ADDINC128(ctx->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; } } - else + while (len >= PG_SHA512_BLOCK_LENGTH) { - /* Prepare for final transform: */ - memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; + /* Process as many complete blocks as we can */ + pg_sha512_transform(ctx, data); + ADDINC128(ctx->bitcount, PG_SHA512_BLOCK_LENGTH << 3); + len -= PG_SHA512_BLOCK_LENGTH; + data += PG_SHA512_BLOCK_LENGTH; } - /* Store the length of input data (in bits): */ - *(uint64 *) &context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; - *(uint64 *) &context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8] = context->bitcount[0]; - - /* Final transform: */ - SHA512_Transform(context, context->buffer); + if (len > 0) + { + /* There's left-overs, so save 'em */ + memcpy(ctx->buffer, data, len); + ADDINC128(ctx->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; } void -SHA512_Final(uint8 digest[], SHA512_CTX *context) +pg_sha512_final(pg_sha512_ctx *ctx, uint8 *dest) { - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) + /* If no destination buffer is passed, we don't bother doing this: */ + if (dest != NULL) { - SHA512_Last(context); + pg_sha512_last(ctx); /* Save the hash data for output: */ #ifndef WORDS_BIGENDIAN @@ -892,42 +1207,42 @@ SHA512_Final(uint8 digest[], SHA512_CTX *context) for (j = 0; j < 8; j++) { - REVERSE64(context->state[j], context->state[j]); + REVERSE64(ctx->state[j], ctx->state[j]); } } #endif - memcpy(digest, context->state, SHA512_DIGEST_LENGTH); + memcpy(dest, ctx->state, PG_SHA512_DIGEST_LENGTH); } /* Zero out state data */ - px_memset(context, 0, sizeof(*context)); + memset(ctx, 0, sizeof(pg_sha512_ctx)); } -/*** SHA-384: *********************************************************/ +/* Interface routines for SHA-384 */ void -SHA384_Init(SHA384_CTX *context) +pg_sha384_init(pg_sha384_ctx *ctx) { - if (context == NULL) + if (ctx == NULL) return; - memcpy(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - memset(context->buffer, 0, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; + memcpy(ctx->state, sha384_initial_hash_value, PG_SHA512_DIGEST_LENGTH); + memset(ctx->buffer, 0, PG_SHA384_BLOCK_LENGTH); + ctx->bitcount[0] = ctx->bitcount[1] = 0; } void -SHA384_Update(SHA384_CTX *context, const uint8 *data, size_t len) +pg_sha384_update(pg_sha384_ctx *ctx, const uint8 *data, size_t len) { - SHA512_Update((SHA512_CTX *) context, data, len); + pg_sha512_update((pg_sha512_ctx *) ctx, data, len); } void -SHA384_Final(uint8 digest[], SHA384_CTX *context) +pg_sha384_final(pg_sha384_ctx *ctx, uint8 *dest) { - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) + /* If no destination buffer is passed, we don't bother doing this: */ + if (dest != NULL) { - SHA512_Last((SHA512_CTX *) context); + pg_sha512_last((pg_sha512_ctx *) ctx); /* Save the hash data for output: */ #ifndef WORDS_BIGENDIAN @@ -937,41 +1252,41 @@ SHA384_Final(uint8 digest[], SHA384_CTX *context) for (j = 0; j < 6; j++) { - REVERSE64(context->state[j], context->state[j]); + REVERSE64(ctx->state[j], ctx->state[j]); } } #endif - memcpy(digest, context->state, SHA384_DIGEST_LENGTH); + memcpy(dest, ctx->state, PG_SHA384_DIGEST_LENGTH); } /* Zero out state data */ - px_memset(context, 0, sizeof(*context)); + memset(ctx, 0, sizeof(pg_sha384_ctx)); } -/*** SHA-224: *********************************************************/ +/* Interface routines for SHA-224 */ void -SHA224_Init(SHA224_CTX *context) +pg_sha224_init(pg_sha224_ctx *ctx) { - if (context == NULL) + if (ctx == NULL) return; - memcpy(context->state, sha224_initial_hash_value, SHA256_DIGEST_LENGTH); - memset(context->buffer, 0, SHA256_BLOCK_LENGTH); - context->bitcount = 0; + memcpy(ctx->state, sha224_initial_hash_value, PG_SHA256_DIGEST_LENGTH); + memset(ctx->buffer, 0, PG_SHA256_BLOCK_LENGTH); + ctx->bitcount = 0; } void -SHA224_Update(SHA224_CTX *context, const uint8 *data, size_t len) +pg_sha224_update(pg_sha224_ctx *ctx, const uint8 *data, size_t len) { - SHA256_Update((SHA256_CTX *) context, data, len); + pg_sha256_update((pg_sha256_ctx *) ctx, data, len); } void -SHA224_Final(uint8 digest[], SHA224_CTX *context) +pg_sha224_final(pg_sha224_ctx *ctx, uint8 *dest) { - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != NULL) + /* If no destination buffer is passed, we don't bother doing this: */ + if (dest != NULL) { - SHA256_Last(context); + pg_sha256_last(ctx); #ifndef WORDS_BIGENDIAN { @@ -980,13 +1295,13 @@ SHA224_Final(uint8 digest[], SHA224_CTX *context) for (j = 0; j < 8; j++) { - REVERSE32(context->state[j], context->state[j]); + REVERSE32(ctx->state[j], ctx->state[j]); } } #endif - memcpy(digest, context->state, SHA224_DIGEST_LENGTH); + memcpy(dest, ctx->state, PG_SHA224_DIGEST_LENGTH); } /* Clean up state data: */ - px_memset(context, 0, sizeof(*context)); + memset(ctx, 0, sizeof(pg_sha224_ctx)); } diff --git a/src/common/sha_openssl.c b/src/common/sha_openssl.c new file mode 100644 index 0000000..c6aac90 --- /dev/null +++ b/src/common/sha_openssl.c @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------- + * + * sha_openssl.c + * Set of wrapper routines on top of OpenSSL to support SHA + * functions. + * + * This should only be used if code is compiled with OpenSSL support. + * + * Portions Copyright (c) 2016, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/sha_openssl.c + * + *------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#include <openssl/sha.h> + +#include "common/sha.h" + +/* Interface routines for SHA-1 */ +void +pg_sha1_init(pg_sha1_ctx *ctx) +{ + SHA1_Init((SHA_CTX *) ctx); +} + +void +pg_sha1_update(pg_sha1_ctx *ctx, const uint8 *input0, size_t len) +{ + SHA1_Update((SHA_CTX *) ctx, input0, len); +} + +void +pg_sha1_final(pg_sha1_ctx *ctx, uint8 *dest) +{ + SHA1_Final(dest, (SHA_CTX *) ctx); +} + +/* Interface routines for SHA-256 */ +void +pg_sha256_init(pg_sha256_ctx *ctx) +{ + SHA256_Init((SHA256_CTX *) ctx); +} + +void +pg_sha256_update(pg_sha256_ctx *ctx, const uint8 *data, size_t len) +{ + SHA256_Update((SHA256_CTX *) ctx, data, len); +} + +void +pg_sha256_final(pg_sha256_ctx *ctx, uint8 *dest) +{ + SHA256_Final(dest, (SHA256_CTX *) ctx); +} + +/* Interface routines for SHA-512 */ +void +pg_sha512_init(pg_sha512_ctx *ctx) +{ + SHA512_Init((SHA512_CTX *) ctx); +} + +void +pg_sha512_update(pg_sha512_ctx *ctx, const uint8 *data, size_t len) +{ + SHA512_Update((SHA512_CTX *) ctx, data, len); +} + +void +pg_sha512_final(pg_sha512_ctx *ctx, uint8 *dest) +{ + SHA512_Final(dest, (SHA512_CTX *) ctx); +} + +/* Interface routines for SHA-384 */ +void +pg_sha384_init(pg_sha384_ctx *ctx) +{ + SHA384_Init((SHA512_CTX *) ctx); +} + +void +pg_sha384_update(pg_sha384_ctx *ctx, const uint8 *data, size_t len) +{ + SHA384_Update((SHA512_CTX *) ctx, data, len); +} + +void +pg_sha384_final(pg_sha384_ctx *ctx, uint8 *dest) +{ + SHA384_Final(dest, (SHA512_CTX *) ctx); +} + +/* Interface routines for SHA-224 */ +void +pg_sha224_init(pg_sha224_ctx *ctx) +{ + SHA224_Init((SHA256_CTX *) ctx); +} + +void +pg_sha224_update(pg_sha224_ctx *ctx, const uint8 *data, size_t len) +{ + SHA224_Update((SHA256_CTX *) ctx, data, len); +} + +void +pg_sha224_final(pg_sha224_ctx *ctx, uint8 *dest) +{ + SHA224_Final(dest, (SHA256_CTX *) ctx); +} diff --git a/src/include/common/sha.h b/src/include/common/sha.h new file mode 100644 index 0000000..6db54b4 --- /dev/null +++ b/src/include/common/sha.h @@ -0,0 +1,95 @@ +/*------------------------------------------------------------------------- + * + * sha.h + * Generic headers for SHA functions of PostgreSQL. + * + * Portions Copyright (c) 2016, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/common/sha.h + * + *------------------------------------------------------------------------- + */ + +#ifndef _PG_SHA_H_ +#define _PG_SHA_H_ + +/*** SHA-1/224/256/384/512 Various Length Definitions ***********************/ +#define PG_SHA1_BLOCK_LENGTH 64 +#define PG_SHA1_DIGEST_LENGTH 20 +#define PG_SHA1_DIGEST_STRING_LENGTH (PG_SHA1_DIGEST_LENGTH * 2 + 1) +#define PG_SHA224_BLOCK_LENGTH 64 +#define PG_SHA224_DIGEST_LENGTH 28 +#define PG_SHA224_DIGEST_STRING_LENGTH (PG_SHA224_DIGEST_LENGTH * 2 + 1) +#define PG_SHA256_BLOCK_LENGTH 64 +#define PG_SHA256_DIGEST_LENGTH 32 +#define PG_SHA256_DIGEST_STRING_LENGTH (PG_SHA256_DIGEST_LENGTH * 2 + 1) +#define PG_SHA384_BLOCK_LENGTH 128 +#define PG_SHA384_DIGEST_LENGTH 48 +#define PG_SHA384_DIGEST_STRING_LENGTH (PG_SHA384_DIGEST_LENGTH * 2 + 1) +#define PG_SHA512_BLOCK_LENGTH 128 +#define PG_SHA512_DIGEST_LENGTH 64 +#define PG_SHA512_DIGEST_STRING_LENGTH (PG_SHA512_DIGEST_LENGTH * 2 + 1) + +/* Context Structures for SHA-1/224/256/384/512 */ +typedef struct pg_sha1_ctx +{ + union + { + uint8 b8[20]; + uint32 b32[5]; + } h; + union + { + uint8 b8[8]; + uint64 b64[1]; + } c; + union + { + uint8 b8[64]; + uint32 b32[16]; + } m; + uint8 count; +} pg_sha1_ctx; +typedef struct pg_sha256_ctx +{ + uint32 state[8]; + uint64 bitcount; + uint8 buffer[PG_SHA256_BLOCK_LENGTH]; +} pg_sha256_ctx; +typedef struct pg_sha512_ctx +{ + uint64 state[8]; + uint64 bitcount[2]; + uint8 buffer[PG_SHA512_BLOCK_LENGTH]; +} pg_sha512_ctx; +typedef struct pg_sha256_ctx pg_sha224_ctx; +typedef struct pg_sha512_ctx pg_sha384_ctx; + +/* Interface routines for SHA-1/224/256/384/512 */ +extern void pg_sha1_init(pg_sha1_ctx *ctx); +extern void pg_sha1_update(pg_sha1_ctx *ctx, + const uint8 *input0, size_t len); +extern void pg_sha1_final(pg_sha1_ctx *ctx, uint8 *dest); + +extern void pg_sha224_init(pg_sha224_ctx *ctx); +extern void pg_sha224_update(pg_sha224_ctx *ctx, + const uint8 *input0, size_t len); +extern void pg_sha224_final(pg_sha224_ctx *ctx, uint8 *dest); + +extern void pg_sha256_init(pg_sha256_ctx *ctx); +extern void pg_sha256_update(pg_sha256_ctx *ctx, + const uint8 *input0, size_t len); +extern void pg_sha256_final(pg_sha256_ctx *ctx, uint8 *dest); + +extern void pg_sha384_init(pg_sha384_ctx *ctx); +extern void pg_sha384_update(pg_sha384_ctx *ctx, + const uint8 *, size_t len); +extern void pg_sha384_final(pg_sha384_ctx *ctx, uint8 *dest); + +extern void pg_sha512_init(pg_sha512_ctx *ctx); +extern void pg_sha512_update(pg_sha512_ctx *ctx, + const uint8 *input0, size_t len); +extern void pg_sha512_final(pg_sha512_ctx *ctx, uint8 *dest); + +#endif /* _PG_SHA_H_ */ diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index fe905d3..02a3fc7 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -114,6 +114,15 @@ sub mkvcbuild pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c string.c username.c wait_error.c); + if ($solution->{options}->{openssl}) + { + push(@pgcommonallfiles, 'sha_openssl.c'); + } + else + { + push(@pgcommonallfiles, 'sha.c'); + } + our @pgcommonfrontendfiles = ( @pgcommonallfiles, qw(fe_memutils.c restricted_token.c)); @@ -443,13 +452,13 @@ sub mkvcbuild { $pgcrypto->AddFiles( 'contrib/pgcrypto', 'md5.c', - 'sha1.c', 'sha2.c', 'internal.c', 'internal-sha2.c', 'blf.c', 'rijndael.c', 'fortuna.c', 'random.c', 'pgp-mpi-internal.c', 'imath.c'); } $pgcrypto->AddReference($postgres); + $pgcrypto->AddReference($libpgcommon); $pgcrypto->AddLibrary('ws2_32.lib'); my $mf = Project::read_file('contrib/pgcrypto/Makefile'); GenerateContribSqlFiles('pgcrypto', $mf); -- 2.9.0
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers