diff --git a/contrib/Makefile b/contrib/Makefile index a1adaa048cf..c60d2f0c121 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -1,4 +1,4 @@ -# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.8 2000/09/18 20:11:34 petere Exp $ +# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.9 2000/10/31 13:11:28 petere Exp $ subdir = contrib top_builddir = .. @@ -17,6 +17,7 @@ WANTED_DIRS = array \ noupdate \ pg_dumplo \ pgbench \ + pgcrypto \ soundex \ spi \ string \ diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile new file mode 100644 index 00000000000..e3e4002da2e --- /dev/null +++ b/contrib/pgcrypto/Makefile @@ -0,0 +1,63 @@ +# +# $Header: /cvsroot/pgsql/contrib/pgcrypto/Makefile,v 1.1 2000/10/31 13:11:28 petere Exp $ +# + +subdir = contrib/pgcrypto +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global + +# either 'builtin', 'mhash', 'openssl', 'krb5' +cryptolib = builtin + +########################## + +ifeq ($(cryptolib), builtin) +SRCS= md5.c sha1.c internal.c +endif + +ifeq ($(cryptolib), openssl) +cryptoinc := -I/usr/include/openssl +cryptolib := -lcrypto +SRCS = openssl.c +endif + +ifeq ($(cryptolib), mhash) +cryptoinc= +cryptolib=-lmhash +SRCS=mhash.c +endif + +ifeq ($(cryptolib), krb5) +cryptoinc=-I/usr/include +cryptolib=-ldes +SRCS=krb.c +endif + +NAME := pgcrypto +SRCS += pgcrypto.c +OBJS := $(SRCS:.c=.o) +SO_MAJOR_VERSION = 0 +SO_MINOR_VERSION = 1 + +override CPPFLAGS += -I$(srcdir) $(cryptoinc) + +all: all-lib $(NAME).sql + +include $(top_srcdir)/src/Makefile.shlib + +$(NAME).sql: $(NAME).sql.in + sed 's,@MODULE_FILENAME@,$(libdir)/contrib/pgcrypto$(DLSUFFIX),g' $< >$@ + +install: all installdirs + $(INSTALL_SHLIB) $(shlib) $(DESTDIR)$(libdir)/contrib/pgcrypto$(DLSUFFIX) + $(INSTALL_DATA) $(NAME).sql $(DESTDIR)$(datadir)/contrib/$(NAME).sql + $(INSTALL_DATA) README.$(NAME) $(DESTDIR)$(docdir)/contrib/README.$(NAME) + +installdirs: + $(mkinstalldirs) $(libdir)/contrib $(datadir)/contrib $(docdir)/contrib + +uninstall: uninstall-lib + rm -f $(DESTDIR)$(libdir)/contrib/pgcrypto$(DLSUFFIX) $(datadir)/contrib/$(NAME).sql $(docdir)/contrib/README.$(NAME) + +clean distclean maintainer-clean: clean-lib + rm -f $(OBJS) $(NAME).sql diff --git a/contrib/pgcrypto/README.pgcrypto b/contrib/pgcrypto/README.pgcrypto new file mode 100644 index 00000000000..cfb05a75161 --- /dev/null +++ b/contrib/pgcrypto/README.pgcrypto @@ -0,0 +1,40 @@ + +DESCRIPTION + + Here is a implementation of crypto hashes for PostgreSQL. + It exports 2 functions to SQL level: + + digest(data::text, hash_name::text) + which returns hexadecimal coded hash over data by + specified algorithm. eg + + > select digest('blah', 'sha1'); + 5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 + + digest_exists(hash_name::text)::bool + which reports if particular hash type exists. + + If any of arguments are NULL they return NULL. + +HASHES + + For choosing library you must edit Makefile. + + standalone (default): + MD5, SHA1 + + (the code is from KAME project. Actually I hate code + duplication, but I also want to quarantee that MD5 and + SHA1 exist) + + mhash (0.8.1): + MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160, + HAVAL(256,224,192,160,128) + + openssl: + MD5, SHA1, RIPEMD160, MD2 + + kerberos5 (heimdal): + MD5, SHA1 + + diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c new file mode 100644 index 00000000000..b1c24b20db9 --- /dev/null +++ b/contrib/pgcrypto/internal.c @@ -0,0 +1,114 @@ +/* + * internal.c + * Wrapper for builtin functions + * + * Copyright (c) 2000 Marko Kreen + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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. + * + * $Id: internal.c,v 1.1 2000/10/31 13:11:28 petere Exp $ + */ + +#include + +#include "pgcrypto.h" + +#include "md5.h" +#include "sha1.h" + +#ifndef MD5_DIGEST_LENGTH +#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 + +static uint +pg_md5_len(pg_digest *h); +static uint8 * +pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf); + +static uint +pg_sha1_len(pg_digest *h); +static uint8 * +pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf); + +static pg_digest +int_digest_list [] = { + { "md5", pg_md5_len, pg_md5_digest, {0}}, + { "sha1", pg_sha1_len, pg_sha1_digest, {0}}, + { NULL, NULL, NULL, {0}} +}; + +static uint +pg_md5_len(pg_digest *h) { + return MD5_DIGEST_LENGTH; +} + +static uint8 * +pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf) +{ + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, src, len); + MD5Final(buf, &ctx); + + return buf; +} + +static uint +pg_sha1_len(pg_digest *h) { + return SHA1_DIGEST_LENGTH; +} + +static uint8 * +pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf) +{ + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, src, len); + SHA1Final(buf, &ctx); + + return buf; +} + + +pg_digest * +pg_find_digest(pg_digest *h, char *name) +{ + pg_digest *p; + + for (p = int_digest_list; p->name; p++) + if (!strcasecmp(p->name, name)) + return p; + return NULL; +} + + diff --git a/contrib/pgcrypto/krb.c b/contrib/pgcrypto/krb.c new file mode 100644 index 00000000000..ab67f1ced12 --- /dev/null +++ b/contrib/pgcrypto/krb.c @@ -0,0 +1,119 @@ +/* + * krb.c + * Wrapper for Kerberos5 libdes SHA1/MD5. + * + * Copyright (c) 2000 Marko Kreen + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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. + * + * + * NOTES + * It is possible that this works with other SHA1/MD5 + * implementations too. + * + * $Id: krb.c,v 1.1 2000/10/31 13:11:28 petere Exp $ + */ + +#include + +#include "pgcrypto.h" + +#include +#include + +#ifndef MD5_DIGEST_LENGTH +#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 + +static uint +pg_md5_len(pg_digest *h); +static uint8 * +pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf); + +static uint +pg_sha1_len(pg_digest *h); +static uint8 * +pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf); + +static pg_digest +int_digest_list [] = { + { "md5", pg_md5_len, pg_md5_digest, {0}}, + { "sha1", pg_sha1_len, pg_sha1_digest, {0}}, + { NULL, NULL, NULL, {0}} +}; + +static uint +pg_md5_len(pg_digest *h) { + return MD5_DIGEST_LENGTH; +} + +static uint8 * +pg_md5_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf) +{ + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, src, len); + MD5Final(buf, &ctx); + + return buf; +} + +static uint +pg_sha1_len(pg_digest *h) { + return SHA1_DIGEST_LENGTH; +} + +static uint8 * +pg_sha1_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf) +{ + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, src, len); + SHA1Final(buf, &ctx); + + return buf; +} + + +pg_digest * +pg_find_digest(pg_digest *h, char *name) +{ + pg_digest *p; + + for (p = int_digest_list; p->name; p++) + if (!strcasecmp(p->name, name)) + return p; + return NULL; +} + + diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c new file mode 100644 index 00000000000..5181a9eb651 --- /dev/null +++ b/contrib/pgcrypto/md5.c @@ -0,0 +1,306 @@ +/* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 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. + */ + +#include +#include "pgcrypto.h" + +#include "md5.h" + +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s)))) + +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z))) +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z))) +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z))) + +#define ROUND1(a, b, c, d, k, s, i) { \ + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} + +#define ROUND2(a, b, c, d, k, s, i) { \ + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} + +#define ROUND3(a, b, c, d, k, s, i) { \ + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} + +#define ROUND4(a, b, c, d, k, s, i) { \ + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} + +#define Sa 7 +#define Sb 12 +#define Sc 17 +#define Sd 22 + +#define Se 5 +#define Sf 9 +#define Sg 14 +#define Sh 20 + +#define Si 4 +#define Sj 11 +#define Sk 16 +#define Sl 23 + +#define Sm 6 +#define Sn 10 +#define So 15 +#define Sp 21 + +#define MD5_A0 0x67452301 +#define MD5_B0 0xefcdab89 +#define MD5_C0 0x98badcfe +#define MD5_D0 0x10325476 + +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */ +static const u_int32_t T[65] = { + 0, + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +static const u_int8_t md5_paddat[MD5_BUFLEN] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void md5_calc __P((u_int8_t *, md5_ctxt *)); + +void md5_init(ctxt) + md5_ctxt *ctxt; +{ + ctxt->md5_n = 0; + ctxt->md5_i = 0; + ctxt->md5_sta = MD5_A0; + ctxt->md5_stb = MD5_B0; + ctxt->md5_stc = MD5_C0; + ctxt->md5_std = MD5_D0; + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf)); +} + +void md5_loop(ctxt, input, len) + md5_ctxt *ctxt; + u_int8_t *input; + u_int len; /* number of bytes */ +{ + u_int gap, i; + + ctxt->md5_n += len * 8; /* byte to bit */ + gap = MD5_BUFLEN - ctxt->md5_i; + + if (len >= gap) { + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i), + gap); + md5_calc(ctxt->md5_buf, ctxt); + + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) { + md5_calc((u_int8_t *)(input + i), ctxt); + } + + ctxt->md5_i = len - i; + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i); + } else { + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i), + len); + ctxt->md5_i += len; + } +} + +void md5_pad(ctxt) + md5_ctxt *ctxt; +{ + u_int gap; + + /* Don't count up padding. Keep md5_n. */ + gap = MD5_BUFLEN - ctxt->md5_i; + if (gap > 8) { + bcopy((void *)md5_paddat, + (void *)(ctxt->md5_buf + ctxt->md5_i), + gap - sizeof(ctxt->md5_n)); + } else { + /* including gap == 8 */ + bcopy((void *)md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i), + gap); + md5_calc(ctxt->md5_buf, ctxt); + bcopy((void *)(md5_paddat + gap), + (void *)ctxt->md5_buf, + MD5_BUFLEN - sizeof(ctxt->md5_n)); + } + + /* 8 byte word */ +#if BYTE_ORDER == LITTLE_ENDIAN + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8); +#endif +#if BYTE_ORDER == BIG_ENDIAN + ctxt->md5_buf[56] = ctxt->md5_n8[7]; + ctxt->md5_buf[57] = ctxt->md5_n8[6]; + ctxt->md5_buf[58] = ctxt->md5_n8[5]; + ctxt->md5_buf[59] = ctxt->md5_n8[4]; + ctxt->md5_buf[60] = ctxt->md5_n8[3]; + ctxt->md5_buf[61] = ctxt->md5_n8[2]; + ctxt->md5_buf[62] = ctxt->md5_n8[1]; + ctxt->md5_buf[63] = ctxt->md5_n8[0]; +#endif + + md5_calc(ctxt->md5_buf, ctxt); +} + +void md5_result(digest, ctxt) + u_int8_t *digest; + md5_ctxt *ctxt; +{ + /* 4 byte words */ +#if BYTE_ORDER == LITTLE_ENDIAN + bcopy(&ctxt->md5_st8[0], digest, 16); +#endif +#if BYTE_ORDER == BIG_ENDIAN + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2]; + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0]; + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6]; + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4]; + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10]; + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8]; + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14]; + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12]; +#endif +} + +#if BYTE_ORDER == BIG_ENDIAN +u_int32_t X[16]; +#endif + +static void md5_calc(b64, ctxt) + u_int8_t *b64; + md5_ctxt *ctxt; +{ + u_int32_t A = ctxt->md5_sta; + u_int32_t B = ctxt->md5_stb; + u_int32_t C = ctxt->md5_stc; + u_int32_t D = ctxt->md5_std; +#if BYTE_ORDER == LITTLE_ENDIAN + u_int32_t *X = (u_int32_t *)b64; +#endif +#if BYTE_ORDER == BIG_ENDIAN + /* 4 byte words */ + /* what a brute force but fast! */ + u_int8_t *y = (u_int8_t *)X; + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0]; + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4]; + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8]; + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12]; + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16]; + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20]; + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24]; + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28]; + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32]; + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36]; + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40]; + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44]; + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48]; + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52]; + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56]; + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60]; +#endif + + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2); + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4); + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6); + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8); + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10); + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12); + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14); + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16); + + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18); + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20); + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22); + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24); + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26); + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28); + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30); + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32); + + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34); + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36); + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38); + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40); + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42); + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44); + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46); + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48); + + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50); + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52); + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54); + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56); + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58); + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60); + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62); + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64); + + ctxt->md5_sta += A; + ctxt->md5_stb += B; + ctxt->md5_stc += C; + ctxt->md5_std += D; +} diff --git a/contrib/pgcrypto/md5.h b/contrib/pgcrypto/md5.h new file mode 100644 index 00000000000..527097ddde6 --- /dev/null +++ b/contrib/pgcrypto/md5.h @@ -0,0 +1,75 @@ +/* $KAME: md5.h,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. + */ + +#ifndef _NETINET6_MD5_H_ +#define _NETINET6_MD5_H_ + +#define MD5_BUFLEN 64 + +typedef struct { + union { + u_int32_t md5_state32[4]; + u_int8_t md5_state8[16]; + } md5_st; + +#define md5_sta md5_st.md5_state32[0] +#define md5_stb md5_st.md5_state32[1] +#define md5_stc md5_st.md5_state32[2] +#define md5_std md5_st.md5_state32[3] +#define md5_st8 md5_st.md5_state8 + + union { + u_int64_t md5_count64; + u_int8_t md5_count8[8]; + } md5_count; +#define md5_n md5_count.md5_count64 +#define md5_n8 md5_count.md5_count8 + + u_int md5_i; + u_int8_t md5_buf[MD5_BUFLEN]; +} md5_ctxt; + +extern void md5_init __P((md5_ctxt *)); +extern void md5_loop __P((md5_ctxt *, u_int8_t *, u_int)); +extern void md5_pad __P((md5_ctxt *)); +extern void md5_result __P((u_int8_t *, md5_ctxt *)); + +/* compatibility */ +#define MD5_CTX md5_ctxt +#define MD5Init(x) md5_init((x)) +#define MD5Update(x, y, z) md5_loop((x), (y), (z)) +#define MD5Final(x, y) \ +do { \ + md5_pad((y)); \ + md5_result((x), (y)); \ +} while (0) + +#endif /* ! _NETINET6_MD5_H_*/ diff --git a/contrib/pgcrypto/mhash.c b/contrib/pgcrypto/mhash.c new file mode 100644 index 00000000000..ed16c124dfc --- /dev/null +++ b/contrib/pgcrypto/mhash.c @@ -0,0 +1,86 @@ +/* + * mhash.c + * Wrapper for mhash library. + * + * Copyright (c) 2000 Marko Kreen + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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. + * + * $Id: mhash.c,v 1.1 2000/10/31 13:11:28 petere Exp $ + */ + +#include +#include "pgcrypto.h" + +#include + +static uint +pg_mhash_len(pg_digest *hash); +static uint8 * +pg_mhash_digest(pg_digest *hash, uint8 *src, + uint len, uint8 *buf); + +static uint +pg_mhash_len(pg_digest *h) { + return mhash_get_block_size(h->misc.code); +} + +static uint8 * +pg_mhash_digest(pg_digest *h, uint8 *src, uint len, uint8 *dst) +{ + uint8 *res; + + MHASH mh = mhash_init(h->misc.code); + mhash(mh, src, len); + res = mhash_end(mh); + + memcpy(dst, res, mhash_get_block_size(h->misc.code)); + mhash_free(res); + + return dst; +} + +pg_digest * +pg_find_digest(pg_digest *h, char *name) +{ + size_t hnum, i, b; + char *mname; + + hnum = mhash_count(); + for (i = 0; i <= hnum; i++) { + mname = mhash_get_hash_name(i); + if (mname == NULL) + continue; + b = strcasecmp(name, mname); + free(mname); + if (!b) { + h->name = mhash_get_hash_name(i); + h->length = pg_mhash_len; + h->digest = pg_mhash_digest; + h->misc.code = i; + return h; + } + } + return NULL; +} + diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c new file mode 100644 index 00000000000..76a2a56b672 --- /dev/null +++ b/contrib/pgcrypto/openssl.c @@ -0,0 +1,84 @@ +/* + * openssl.c + * Wrapper for OpenSSL library. + * + * Copyright (c) 2000 Marko Kreen + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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. + * + * $Id: openssl.c,v 1.1 2000/10/31 13:11:28 petere Exp $ + */ + +#include +#include "pgcrypto.h" + +#include + +static uint +pg_ossl_len(pg_digest *h); +static uint8 * +pg_ossl_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf); + +static uint +pg_ossl_len(pg_digest *h) { + return EVP_MD_size((EVP_MD*)h->misc.ptr); +} + +static uint8 * +pg_ossl_digest(pg_digest *h, uint8 *src, uint len, uint8 *buf) +{ + EVP_MD *md = (EVP_MD*)h->misc.ptr; + EVP_MD_CTX ctx; + + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, src, len); + EVP_DigestFinal(&ctx, buf, NULL); + + return buf; +} + +static int pg_openssl_initialized = 0; + +pg_digest * +pg_find_digest(pg_digest *h, char *name) +{ + const EVP_MD *md; + + if (!pg_openssl_initialized) { + OpenSSL_add_all_digests(); + pg_openssl_initialized = 1; + } + + md = EVP_get_digestbyname(name); + if (md == NULL) + return NULL; + + h->name = name; + h->length = pg_ossl_len; + h->digest = pg_ossl_digest; + h->misc.ptr = (void*)md; + + return h; +} + + diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c new file mode 100644 index 00000000000..4897edb9d25 --- /dev/null +++ b/contrib/pgcrypto/pgcrypto.c @@ -0,0 +1,155 @@ +/* + * pgcrypto.c + * Cryptographic digests for PostgreSQL. + * + * Copyright (c) 2000 Marko Kreen + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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. + * + * $Id: pgcrypto.c,v 1.1 2000/10/31 13:11:28 petere Exp $ + */ + +#include +#include + +#include "pgcrypto.h" + +/* + * maximum length of digest for internal buffers + */ +#define MAX_DIGEST_LENGTH 128 + +/* + * NAMEDATALEN is used for hash names + */ +#if NAMEDATALEN < 16 +#error "NAMEDATALEN < 16: too small" +#endif + + +/* exported functions */ +Datum digest(PG_FUNCTION_ARGS); +Datum digest_exists(PG_FUNCTION_ARGS); + +/* private stuff */ +static char * +to_hex(uint8 *src, uint len, char *dst); +static pg_digest * +find_digest(pg_digest *hbuf, text *name, int silent); + + +/* SQL function: hash(text, text) returns text */ +Datum +digest(PG_FUNCTION_ARGS) +{ + text *arg; + text *name; + uint8 *p, buf[MAX_DIGEST_LENGTH]; + uint len, hlen; + pg_digest *h, _hbuf; + text *res; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) + PG_RETURN_NULL(); + + name = PG_GETARG_TEXT_P(1); + h = find_digest(&_hbuf, name, 0); /* will give error if fails */ + + hlen = h->length(h); + if (hlen > MAX_DIGEST_LENGTH) + elog(ERROR, "Hash length overflow: %d", hlen); + + res = (text *)palloc(hlen*2 + VARHDRSZ); + VARATT_SIZEP(res) = hlen*2 + VARHDRSZ; + + arg = PG_GETARG_TEXT_P(0); + len = VARSIZE(arg) - VARHDRSZ; + + p = h->digest(h, VARDATA(arg), len, buf); + to_hex(p, hlen, VARDATA(res)); + + PG_FREE_IF_COPY(arg, 0); + PG_FREE_IF_COPY(name, 0); // unnecessary i guess + + PG_RETURN_TEXT_P(res); +} + +/* check if given hash exists */ +Datum +digest_exists(PG_FUNCTION_ARGS) +{ + text *name; + pg_digest _hbuf, *res; + + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + + name = PG_GETARG_TEXT_P(0); + + res = find_digest(&_hbuf, name, 1); + + PG_FREE_IF_COPY(name, 0); // unnecessary i guess + + if (res != NULL) + PG_RETURN_BOOL(true); + PG_RETURN_BOOL(false); +} + +static pg_digest * +find_digest(pg_digest *hbuf, text *name, int silent) +{ + pg_digest *p; + char buf[NAMEDATALEN]; + uint len; + + len = VARSIZE(name) - VARHDRSZ; + if (len >= NAMEDATALEN) { + if (silent) + return NULL; + elog(ERROR, "Hash type does not exist (name too long)"); + } + + memcpy(buf, VARDATA(name), len); + buf[len] = 0; + + p = pg_find_digest(hbuf, buf); + + if (p == NULL && !silent) + elog(ERROR, "Hash type does not exist: '%s'", buf); + return p; +} + +static unsigned char *hextbl = "0123456789abcdef"; + +/* dumps binary to hex... Note that it does not null-terminate */ +static char * +to_hex(uint8 *buf, uint len, char *dst) +{ + uint i; + for (i = 0; i < len; i++) { + dst[i*2] = hextbl[(buf[i] >> 4) & 0xF]; + dst[i*2 + 1] = hextbl[buf[i] & 0xF]; + } + return dst; +} + diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h new file mode 100644 index 00000000000..9d3ec5738ae --- /dev/null +++ b/contrib/pgcrypto/pgcrypto.h @@ -0,0 +1,52 @@ +/* + * pgcrypto.h + * Header file for pgcrypto. + * + * Copyright (c) 2000 Marko Kreen + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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. + * + * $Id: pgcrypto.h,v 1.1 2000/10/31 13:11:28 petere Exp $ + */ + +#ifndef _PG_CRYPTO_H +#define _PG_CRYPTO_H + +#include + +typedef struct _pg_digest pg_digest; +struct _pg_digest { + char *name; + uint (*length)(pg_digest *h); + uint8 *(*digest)(pg_digest *h, uint8 *data, + uint dlen, uint8 *buf); + /* private */ + union { + uint code; + const void *ptr; + } misc; +}; + +extern pg_digest *pg_find_digest(pg_digest *hbuf, char *name); + +#endif diff --git a/contrib/pgcrypto/pgcrypto.sql.in b/contrib/pgcrypto/pgcrypto.sql.in new file mode 100644 index 00000000000..a30b3116e5e --- /dev/null +++ b/contrib/pgcrypto/pgcrypto.sql.in @@ -0,0 +1,12 @@ + +-- drop function digest(text, text); +-- drop function digest_exists(text); + +CREATE FUNCTION digest(text, text) RETURNS text + AS '@MODULE_FILENAME@', + 'digest' LANGUAGE 'newC'; + +CREATE FUNCTION digest_exists(text) RETURNS bool + AS '@MODULE_FILENAME@', + 'digest_exists' LANGUAGE 'newC'; + diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c new file mode 100644 index 00000000000..0ec0337f80f --- /dev/null +++ b/contrib/pgcrypto/sha1.c @@ -0,0 +1,273 @@ +/* $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. + */ +/* + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) + * based on: http://csrc.nist.gov/fips/fip180-1.txt + * implemented by Jun-ichiro itojun Itoh + */ + +#include +#include "pgcrypto.h" + +#include "sha1.h" + +/* sanity check */ +#if BYTE_ORDER != BIG_ENDIAN +# if BYTE_ORDER != LITTLE_ENDIAN +# define unsupported 1 +# endif +#endif + +#ifndef unsupported + +/* constant table */ +static u_int32_t _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) { \ + ctxt->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + ctxt->c.b64[0] += 8; \ + if (COUNT % 64 == 0) \ + sha1_step(ctxt); \ + } + +#define PUTPAD(x) { \ + ctxt->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + if (COUNT % 64 == 0) \ + sha1_step(ctxt); \ + } + +static void sha1_step __P((struct sha1_ctxt *)); + +static void +sha1_step(ctxt) + struct sha1_ctxt *ctxt; +{ + u_int32_t a, b, c, d, e; + size_t t, s; + u_int32_t tmp; + +#if BYTE_ORDER == LITTLE_ENDIAN + struct sha1_ctxt tctxt; + bcopy(&ctxt->m.b8[0], &tctxt.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; + + bzero(&ctxt->m.b8[0], 64); +} + +/*------------------------------------------------------------*/ + +void +sha1_init(ctxt) + struct sha1_ctxt *ctxt; +{ + bzero(ctxt, sizeof(struct sha1_ctxt)); + H(0) = 0x67452301; + H(1) = 0xefcdab89; + H(2) = 0x98badcfe; + H(3) = 0x10325476; + H(4) = 0xc3d2e1f0; +} + +void +sha1_pad(ctxt) + 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) { + bzero(&ctxt->m.b8[padstart], padlen); + COUNT += padlen; + COUNT %= 64; + sha1_step(ctxt); + padstart = COUNT % 64; /* should be 0 */ + padlen = 64 - padstart; /* should be 64 */ + } + bzero(&ctxt->m.b8[padstart], padlen - 8); + COUNT += (padlen - 8); + COUNT %= 64; +#if BYTE_ORDER == BIG_ENDIAN + 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(ctxt, input0, len) + struct sha1_ctxt *ctxt; + const caddr_t input0; + size_t len; +{ + const u_int8_t *input; + size_t gaplen; + size_t gapstart; + size_t off; + size_t copysiz; + + input = (const u_int8_t *)input0; + off = 0; + + while (off < len) { + gapstart = COUNT % 64; + gaplen = 64 - gapstart; + + copysiz = (gaplen < len - off) ? gaplen : len - off; + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz); + COUNT += copysiz; + COUNT %= 64; + ctxt->c.b64[0] += copysiz * 8; + if (COUNT % 64 == 0) + sha1_step(ctxt); + off += copysiz; + } +} + +void +sha1_result(ctxt, digest0) + struct sha1_ctxt *ctxt; + caddr_t digest0; +{ + u_int8_t *digest; + + digest = (u_int8_t *)digest0; + sha1_pad(ctxt); +#if BYTE_ORDER == BIG_ENDIAN + bcopy(&ctxt->h.b8[0], digest, 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 +} + +#endif /*unsupported*/ diff --git a/contrib/pgcrypto/sha1.h b/contrib/pgcrypto/sha1.h new file mode 100644 index 00000000000..e4b6453abee --- /dev/null +++ b/contrib/pgcrypto/sha1.h @@ -0,0 +1,69 @@ +/* $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://csrc.nist.gov/fips/fip180-1.txt + * implemented by Jun-ichiro itojun Itoh + */ + +#ifndef _NETINET6_SHA1_H_ +#define _NETINET6_SHA1_H_ + +struct sha1_ctxt { + union { + u_int8_t b8[20]; + u_int32_t b32[5]; + } h; + union { + u_int8_t b8[8]; + u_int64_t b64[1]; + } c; + union { + u_int8_t b8[64]; + u_int32_t b32[16]; + } m; + u_int8_t count; +}; + +extern void sha1_init __P((struct sha1_ctxt *)); +extern void sha1_pad __P((struct sha1_ctxt *)); +extern void sha1_loop __P((struct sha1_ctxt *, const caddr_t, size_t)); +extern void sha1_result __P((struct sha1_ctxt *, caddr_t)); + +/* compatibilty 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_*/