From 2518e273340406033e65816cff6380e20860af0e Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Tue, 21 Aug 2001 00:42:41 +0000 Subject: [PATCH] /contrib/pgcrypto: * remove support for encode() as it is in main tree now * remove krb5.c * new 'PX library' architecture * remove BSD license from my code to let the general PostgreSQL one to apply * md5, sha1: ANSIfy, use const where appropriate * various other formatting and clarity changes * hmac() * UN*X-like crypt() - system or internal crypt * Internal crypt: DES, Extended DES, MD5, Blowfish crypt-des.c, crypt-md5.c from FreeBSD crypt-blowfish.c from Solar Designer * gen_salt() for crypt() - Blowfish, MD5, DES, Extended DES * encrypt(), decrypt(), encrypt_iv(), decrypt_iv() * Cipher support in mhash.c, openssl.c * internal: Blowfish, Rijndael-128 ciphers * blf.[ch], rijndael.[ch] from OpenBSD * there will be generated file rijndael-tbl.inc. Marko Kreen --- contrib/pgcrypto/Makefile | 29 +- contrib/pgcrypto/README.pgcrypto | 198 +++++++++--- contrib/pgcrypto/internal.c | 510 ++++++++++++++++++++++++++++--- contrib/pgcrypto/md5.c | 25 +- contrib/pgcrypto/md5.h | 5 +- contrib/pgcrypto/mhash.c | 309 +++++++++++++++++-- contrib/pgcrypto/openssl.c | 388 +++++++++++++++++++++-- contrib/pgcrypto/pgcrypto.c | 470 +++++++++++++++++++++++++--- contrib/pgcrypto/pgcrypto.h | 31 +- contrib/pgcrypto/pgcrypto.sql.in | 56 +++- contrib/pgcrypto/sha1.c | 21 +- contrib/pgcrypto/sha1.h | 6 +- 12 files changed, 1791 insertions(+), 257 deletions(-) diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile index 408e1c85f60..ef9a30eb63f 100644 --- a/contrib/pgcrypto/Makefile +++ b/contrib/pgcrypto/Makefile @@ -1,20 +1,23 @@ # -# $Header: /cvsroot/pgsql/contrib/pgcrypto/Makefile,v 1.4 2001/06/18 21:38:02 momjian Exp $ +# $Header: /cvsroot/pgsql/contrib/pgcrypto/Makefile,v 1.5 2001/08/21 00:42:41 momjian Exp $ # subdir = contrib/pgcrypto top_builddir = ../.. include $(top_builddir)/src/Makefile.global -# either 'builtin', 'mhash', 'openssl', 'krb5' +# either 'builtin', 'mhash', 'openssl' cryptolib = builtin +# either 'builtin', 'system' +cryptsrc = builtin + ########################## ifeq ($(cryptolib), builtin) CRYPTO_CFLAGS = CRYPTO_LDFLAGS = -SRCS = md5.c sha1.c internal.c +SRCS = md5.c sha1.c internal.c blf.c rijndael.c endif ifeq ($(cryptolib), openssl) @@ -25,18 +28,18 @@ endif ifeq ($(cryptolib), mhash) CRYPTO_CFLAGS = -I/usr/local/include -CRYPTO_LDFLAGS = -L/usr/local/lib -lmhash +CRYPTO_LDFLAGS = -L/usr/local/lib -lmcrypt -lmhash -lltdl SRCS = mhash.c endif -ifeq ($(cryptolib), krb5) -CRYPTO_CFLAGS = -I/usr/include -CRYPTO_LDFLAGS = -ldes -SRCS = krb.c +ifeq ($(cryptsrc), builtin) +SRCS += crypt-blowfish.c crypt-des.c crypt-md5.c +else +CRYPTO_CFLAGS += -DPX_SYSTEM_CRYPT endif NAME := pgcrypto -SRCS += pgcrypto.c encode.c +SRCS += pgcrypto.c px.c px-hmac.c px-crypt.c misc.c OBJS := $(SRCS:.c=.o) SHLIB_LINK := $(CRYPTO_LDFLAGS) SO_MAJOR_VERSION = 0 @@ -52,6 +55,12 @@ include $(top_srcdir)/src/Makefile.shlib $(NAME).sql: $(NAME).sql.in sed 's,@MODULE_FILENAME@,$(libdir)/contrib/pgcrypto$(DLSUFFIX),g' $< >$@ +rijndael.o: rijndael.tbl + +rijndael.tbl: + $(CC) $(CPPFLAGS) $(CFLAGS) -DPRINT_TABS rijndael.c -o gen-rtab + ./gen-rtab > rijndael.tbl + install: all installdirs $(INSTALL_SHLIB) $(shlib) $(DESTDIR)$(libdir)/contrib/pgcrypto$(DLSUFFIX) $(INSTALL_DATA) $(NAME).sql $(DESTDIR)$(datadir)/contrib/$(NAME).sql @@ -64,4 +73,4 @@ 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 + rm -f $(OBJS) $(NAME).sql gen-rtab diff --git a/contrib/pgcrypto/README.pgcrypto b/contrib/pgcrypto/README.pgcrypto index 1a4c90d0b5b..7173710bc3f 100644 --- a/contrib/pgcrypto/README.pgcrypto +++ b/contrib/pgcrypto/README.pgcrypto @@ -1,56 +1,184 @@ -DESCRIPTION +pgcrypto 0.4 - cryptographic functions for PostgreSQL. +====================================================== +by Marko Kreen <marko@l-t.ee> - Here are various cryptographic and otherwise useful - functions for PostgreSQL. - encode(data, type) - encodes binary data into ASCII-only representation. - Types supported are 'hex' and 'base64'. +INSTALLATION +============ - decode(data, type) - decodes the data processed by encode() +Edit makefile, if you want to use any external library. - digest(data::text, hash_name::text) - which returns cryptographic checksum over data by - specified algorithm. eg +make +make install - > select encode(digest('blah', 'sha1'), 'hex'); - 5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 +SQL FUNCTIONS +============= - digest_exists(hash_name::text)::bool - which reports if particular hash type exists. + If any of arguments are NULL they return NULL. - If any of arguments are NULL they return NULL. +digest(data::bytea, type::text)::bytea -HASHES + Type is here the algorithm to use. E.g. 'md5', 'sha1', ... + Returns binary hash. - For choosing library you must edit Makefile. +digest_exists(type::text)::bool - standalone (default): - MD5, SHA1 + Returns BOOL whether given hash exists. - (the code is from KAME project. Actually I hate code - duplication, but I also want to quarantee that MD5 and - SHA1 exist) +hmac(data::bytea, key::bytea, type::text)::bytea - mhash (0.8.1): - MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160, - HAVAL(256,224,192,160,128) + Calculates Hashed MAC over data. type is the same as + in digest(). Returns binary hash. Similar to digest() + but noone can alter data and re-calculate hash without + knowing key. If the key is larger than hash blocksize + it will first hashed and the hash will be used as key. + + [ HMAC is described in RFC2104. ] - openssl: - MD5, SHA1, RIPEMD160, MD2 +hmac_exists(type::text)::bool + Returns BOOL. It is separate function because all hashes + cannot be used in HMAC. - kerberos5 (heimdal): - MD5, SHA1 +crypt(password::text, salt::text)::text -ENCRYPTION + Calculates UN*X crypt(3) style hash. Useful for storing + passwords. For generating salt you should use the + gen_salt() function. Usage: - There is experimental version out with encryption, HMAC - and UN*X crypt() support in + New password: + + UPDATE .. SET pswhash = crypt(new_psw, gen_salt('md5')); + + Authentication: - http://www.l-t.ee/marko/pgsql/ + SELECT pswhash = crypt(given_psw, pswhash) WHERE .. ; + + returns BOOL whether the given_psw is correct. DES crypt + has max key of 8 bytes, MD5 has max key at least 2^32-1 + bytes but may be larger on some platforms... - Current latest release is pgcrypto-0.3.tar.gz. + Builtin crypt() supports DES, Extended DES, MD5 and Blowfish + (variant 2a) algorithms. + +gen_salt(type::text)::text + + Generates a new random salt for usage in crypt(). Type + + 'des' - Old UNIX, not recommended + 'md5' - md5-based crypt() + 'xdes' - 'Extended DES' + 'bf' - Blowfish-based, variant 2a + + When you use --enable-system-crypt then note that system + libcrypt may not support them all. + +encrypt(data::bytea, key::bytea, type::text)::bytea +decrypt(data::bytea, key::bytea, type::text)::bytea +encrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea +decrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea + + Encrypt/decrypt data with cipher, padding data if needed. + + Pseudo-noteup: + + algo ['-' mode] ['/pad:' padding] + + Supported algorithms: + + bf - Blowfish + aes, rijndael - Rijndael-128 + + Others depend on library and are not tested enough, so + play on your own risk. + + Modes: 'cbc' (default), 'ecb'. Again, library may support + more. + + Padding is 'pkcs' (default), 'none'. 'none' is mostly for + testing ciphers, you should not need it. + + So, example: + + encrypt(data, 'fooz', 'bf') + + is equal to + + encrypt(data, 'fooz', 'bf-cbc/pad:pkcs') + + IV is initial value for mode, defaults to all zeroes. + It is ignored for ECB. It is clipped or padded with zeroes + if not exactly block size. + + +ALGORITHMS +========== + +The standard functionality at the moment consist of + +Hashes: md5, sha1 +Ciphers: bf, aes +Modes: cbc, ecb + +TODO: write stardard names for optional ciphers too. + +LIBRARIES +========= + +* crypt() + + internal: des, xdes, md5, bf + + -lcrypt: ??? (whatever you have) + +* other: + +[ This only list of stuff libraries claim to support. So + pgcrypto may work with all of them. But ATM tested aree only the + standard ciphers. On others pgcrypto and library may mess something + up. You have been warned. ] + +internal (default): + Hashes: MD5, SHA1 + Ciphers: Blowfish, Rijndael-128 + + +OpenSSL (0.9.6): + Hashes: MD5, SHA1, RIPEMD160, MD2 + Ciphers: DES, DESX, DES3, RC5, RC4, RC2, IDEA, + Blowfish, CAST5 + License: BSD-like with strong advertisement + Url: http://www.openssl.org/ + + +mhash (0.8.9) + mcrypt (2.4.11): + Hashes: MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160, + HAVAL(256,224,192,160,128) + Ciphers: DES, DES3, CAST-128(CAST5), CAST-256, xTEA, 3-way, + SKIPJACK, Blowfish, Twofish, LOKI97, RC2, RC4, RC6, + Rijndael-128/192/256, MARS, PANAMA, WAKE, Serpent, IDEA, GOST, + SAFER, SAFER+, Enigma + License: LGPL + Url: http://mcrypt.sourceforge.org/ + Url: http://mhash.sourceforge.org/ + +CREDITS +======= + +I have used code from following sources: + +DES crypt() by David Burren and others FreeBSD libcrypt +MD5 crypt() by Poul-Henning Kamp FreeBSD libcrypt +Blowfish crypt() by Solar Designer www.openwall.com +Blowfish cipher by Niels Provos OpenBSD sys/crypto +Rijndael cipher by Brian Gladman OpenBSD sys/crypto +MD5 and SHA1 by WIDE Project KAME kame/sys/crypto + +LEGALESE +======== + +* I owe a beer to Poul-Henning. + +* This product includes software developed by Niels Provos. diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index 2d4a52717e0..1debd2b3884 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -2,7 +2,7 @@ * internal.c * Wrapper for builtin functions * - * Copyright (c) 2000 Marko Kreen + * Copyright (c) 2001 Marko Kreen * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,15 +26,18 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: internal.c,v 1.3 2001/03/22 03:59:10 momjian Exp $ + * $Id: internal.c,v 1.4 2001/08/21 00:42:41 momjian Exp $ */ -#include "postgres.h" -#include "pgcrypto.h" +#include <postgres.h> + +#include "px.h" #include "md5.h" #include "sha1.h" +#include "blf.h" +#include "rijndael.h" #ifndef MD5_DIGEST_LENGTH #define MD5_DIGEST_LENGTH 16 @@ -48,67 +51,496 @@ #endif #endif -static uint - pg_md5_len(pg_digest * h); -static uint8 * - pg_md5_digest(pg_digest * h, uint8 *src, uint len, uint8 *buf); +#define SHA1_BLOCK_SIZE 64 +#define MD5_BLOCK_SIZE 64 -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 void init_md5(PX_MD * h); +static void init_sha1(PX_MD * h); + +static struct int_digest +{ + char *name; + void (*init) (PX_MD * h); +} int_digest_list[] = +{ + { "md5", init_md5 }, + { "sha1", init_sha1 }, + { NULL, NULL } }; +/* MD5 */ + static uint -pg_md5_len(pg_digest * h) +int_md5_len(PX_MD * h) { return MD5_DIGEST_LENGTH; } -static uint8 * -pg_md5_digest(pg_digest * h, uint8 *src, uint len, uint8 *buf) +static uint +int_md5_block_len(PX_MD * h) +{ + return MD5_BLOCK_SIZE; +} + +static void +int_md5_update(PX_MD * h, const uint8 * data, uint dlen) { - MD5_CTX ctx; + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + MD5Update(ctx, data, dlen); +} + +static void +int_md5_reset(PX_MD * h) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + MD5Init(ctx); +} + +static void +int_md5_finish(PX_MD * h, uint8 * dst) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + MD5Final(dst, ctx); +} - MD5Init(&ctx); - MD5Update(&ctx, src, len); - MD5Final(buf, &ctx); +static void +int_md5_free(PX_MD * h) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; - return buf; + px_free(ctx); + px_free(h); } +/* SHA1 */ + static uint -pg_sha1_len(pg_digest * h) +int_sha1_len(PX_MD * h) { return SHA1_DIGEST_LENGTH; } -static uint8 * -pg_sha1_digest(pg_digest * h, uint8 *src, uint len, uint8 *buf) +static uint +int_sha1_block_len(PX_MD * h) +{ + return SHA1_BLOCK_SIZE; +} + +static void +int_sha1_update(PX_MD * h, const uint8 * data, uint dlen) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + SHA1Update(ctx, (const char *)data, dlen); +} + +static void +int_sha1_reset(PX_MD * h) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + SHA1Init(ctx); +} + +static void +int_sha1_finish(PX_MD * h, uint8 * dst) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + SHA1Final(dst, ctx); +} + +static void +int_sha1_free(PX_MD * h) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + px_free(ctx); + px_free(h); +} + +/* init functions */ + +static void +init_md5(PX_MD * md) +{ + MD5_CTX *ctx; + + ctx = px_alloc(sizeof(*ctx)); + + md->p.ptr = ctx; + + md->result_size = int_md5_len; + md->block_size = int_md5_block_len; + md->reset = int_md5_reset; + md->update = int_md5_update; + md->finish = int_md5_finish; + md->free = int_md5_free; + + md->reset(md); +} + +static void +init_sha1(PX_MD * md) +{ + SHA1_CTX *ctx; + + ctx = px_alloc(sizeof(*ctx)); + + md->p.ptr = ctx; + + md->result_size = int_sha1_len; + md->block_size = int_sha1_block_len; + md->reset = int_sha1_reset; + md->update = int_sha1_update; + md->finish = int_sha1_finish; + md->free = int_sha1_free; + + md->reset(md); +} + +/* + * ciphers generally + */ + +#define INT_MAX_KEY (512/8) +#define INT_MAX_IV (128/8) + +struct int_ctx { + uint8 keybuf[INT_MAX_KEY]; + uint8 iv[INT_MAX_IV]; + union { + blf_ctx bf; + rijndael_ctx rj; + } ctx; + uint keylen; + int is_init; + int mode; +}; + +static void intctx_free(PX_Cipher *c) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + if (cx) { + memset(cx, 0, sizeof *cx); + px_free(cx); + } + px_free(c); +} + +/* + * AES/rijndael + */ + +#define MODE_ECB 0 +#define MODE_CBC 1 + +static uint rj_block_size(PX_Cipher *c) +{ + return 128/8; +} + +static uint rj_key_size(PX_Cipher *c) +{ + return 256/8; +} + +static uint rj_iv_size(PX_Cipher *c) +{ + return 128/8; +} + +static int rj_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + + if (klen <= 128/8) + cx->keylen = 128/8; + else if (klen <= 192/8) + cx->keylen = 192/8; + else if (klen <= 256/8) + cx->keylen = 256/8; + else + return -1; + + memcpy(&cx->keybuf, key, klen); + + if (iv) + memcpy(cx->iv, iv, 128/8); + + return 0; +} + +static int rj_real_init(struct int_ctx *cx, int dir) +{ + aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen*8, dir); + return 0; +} + +static int rj_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + + if (!cx->is_init) { + if (rj_real_init(cx, 1)) + return -1; + } + + if (dlen == 0) + return 0; + + if ((dlen & 15) || (((unsigned)res) & 3)) + return -1; + + memcpy(res, data, dlen); + + if (cx->mode == MODE_CBC) { + aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen); + memcpy(cx->iv, res + dlen - 16, 16); + } else + aes_ecb_encrypt(&cx->ctx.rj, res, dlen); + + return 0; +} + +static int rj_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + + if (!cx->is_init) + if (rj_real_init(cx, 0)) + return -1; + + if (dlen == 0) + return 0; + + if ((dlen & 15) || (((unsigned)res) & 3)) + return -1; + + memcpy(res, data, dlen); + + if (cx->mode == MODE_CBC) { + aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen); + memcpy(cx->iv, data + dlen - 16, 16); + } else + aes_ecb_decrypt(&cx->ctx.rj, res, dlen); + + return 0; +} + +/* + * initializers + */ + +static PX_Cipher * rj_load(int mode) +{ + PX_Cipher *c; + struct int_ctx *cx; + + c = px_alloc(sizeof *c); + memset(c, 0, sizeof *c); + + c->block_size = rj_block_size; + c->key_size = rj_key_size; + c->iv_size = rj_iv_size; + c->init = rj_init; + c->encrypt = rj_encrypt; + c->decrypt = rj_decrypt; + c->free = intctx_free; + + cx = px_alloc(sizeof *cx); + memset(cx, 0, sizeof *cx); + cx->mode = mode; + + c->ptr = cx; + return c; +} + +/* + * blowfish + */ + +static uint bf_block_size(PX_Cipher *c) +{ + return 8; +} + +static uint bf_key_size(PX_Cipher *c) +{ + return BLF_MAXKEYLEN; +} + +static uint bf_iv_size(PX_Cipher *c) +{ + return 8; +} + +static int bf_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + + blf_key(&cx->ctx.bf, key, klen); + if (iv) + memcpy(cx->iv, iv, 8); + + return 0; +} + +static int bf_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + + if (dlen == 0) + return 0; + + if ((dlen & 7) || (((unsigned)res) & 3)) + return -1; + + memcpy(res, data, dlen); + switch (cx->mode) { + case MODE_ECB: + blf_ecb_encrypt(&cx->ctx.bf, res, dlen); + break; + case MODE_CBC: + blf_cbc_encrypt(&cx->ctx.bf, cx->iv, res, dlen); + memcpy(cx->iv, res + dlen - 8, 8); + } + return 0; +} + +static int bf_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *)c->ptr; + + if (dlen == 0) + return 0; + + if ((dlen & 7) || (((unsigned)res) & 3)) + return -1; + + memcpy(res, data, dlen); + switch (cx->mode) { + case MODE_ECB: + blf_ecb_decrypt(&cx->ctx.bf, res, dlen); + break; + case MODE_CBC: + blf_cbc_decrypt(&cx->ctx.bf, cx->iv, res, dlen); + memcpy(cx->iv, data + dlen - 8, 8); + } + return 0; +} + +static PX_Cipher * bf_load(int mode) +{ + PX_Cipher *c; + struct int_ctx *cx; + + c = px_alloc(sizeof *c); + memset(c, 0, sizeof *c); + + c->block_size = bf_block_size; + c->key_size = bf_key_size; + c->iv_size = bf_iv_size; + c->init = bf_init; + c->encrypt = bf_encrypt; + c->decrypt = bf_decrypt; + c->free = intctx_free; + + cx = px_alloc(sizeof *cx); + memset(cx, 0, sizeof *cx); + cx->mode = mode; + c->ptr = cx; + return c; +} + +/* ciphers */ + +static PX_Cipher * rj_128_ecb() +{ + return rj_load(MODE_ECB); +} + +static PX_Cipher * rj_128_cbc() { - SHA1_CTX ctx; + return rj_load(MODE_CBC); +} - SHA1Init(&ctx); - SHA1Update(&ctx, src, len); - SHA1Final(buf, &ctx); +static PX_Cipher * bf_ecb_load() +{ + return bf_load(MODE_ECB); +} - return buf; +static PX_Cipher * bf_cbc_load() +{ + return bf_load(MODE_CBC); } +static struct { + char *name; + PX_Cipher *(*load)(void); +} int_ciphers [] = { + { "bf-cbc", bf_cbc_load }, + { "bf-ecb", bf_ecb_load }, + { "aes-128-cbc", rj_128_cbc }, + { "aes-128-ecb", rj_128_ecb }, + { NULL, NULL } +}; + +static PX_Alias int_aliases [] = { + { "bf", "bf-cbc" }, + { "blowfish", "bf-cbc" }, + { "aes", "aes-128-cbc" }, + { "aes-ecb", "aes-128-ecb" }, + { "aes-cbc", "aes-128-cbc" }, + { "aes-128", "aes-128-cbc" }, + { "rijndael", "aes-128-cbc" }, + { "rijndael-128", "aes-128-cbc" }, + { NULL, NULL } +}; -pg_digest * -pg_find_digest(pg_digest * h, char *name) +/* PUBLIC FUNCTIONS */ + +int +px_find_digest(const char *name, PX_MD ** res) { - pg_digest *p; + struct int_digest *p; + PX_MD *h; for (p = int_digest_list; p->name; p++) if (!strcasecmp(p->name, name)) - return p; - return NULL; + { + h = px_alloc(sizeof(*h)); + p->init(h); + + *res = h; + + return 0; + } + return -1; +} + +int +px_find_cipher(const char *name, PX_Cipher **res) +{ + int i; + PX_Cipher *c = NULL; + + name = px_resolve_alias(int_aliases, name); + + for (i = 0; int_ciphers[i].name; i++) + if (!strcmp(int_ciphers[i].name, name)) { + c = int_ciphers[i].load(); + break; + } + + if (c == NULL) + return -1; + + *res = c; + return 0; } + + diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c index a5cfae34970..3ae9d099824 100644 --- a/contrib/pgcrypto/md5.c +++ b/contrib/pgcrypto/md5.c @@ -1,4 +1,4 @@ -/* $Id: md5.c,v 1.5 2001/03/22 03:59:10 momjian Exp $ */ +/* $Id: md5.c,v 1.6 2001/08/21 00:42:41 momjian Exp $ */ /* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */ /* @@ -128,8 +128,7 @@ static const uint8 md5_paddat[MD5_BUFLEN] = { static void md5_calc(uint8 *, md5_ctxt *); void -md5_init(ctxt) -md5_ctxt *ctxt; +md5_init(md5_ctxt *ctxt) { ctxt->md5_n = 0; ctxt->md5_i = 0; @@ -141,10 +140,7 @@ md5_ctxt *ctxt; } void -md5_loop(ctxt, input, len) -md5_ctxt *ctxt; -uint8 *input; -unsigned int len; /* number of bytes */ +md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len) { unsigned int gap, i; @@ -173,8 +169,7 @@ unsigned int len; /* number of bytes */ } void -md5_pad(ctxt) -md5_ctxt *ctxt; +md5_pad(md5_ctxt *ctxt) { unsigned int gap; @@ -216,9 +211,7 @@ md5_ctxt *ctxt; } void -md5_result(digest, ctxt) -uint8 *digest; -md5_ctxt *ctxt; +md5_result(uint8 *digest, md5_ctxt *ctxt) { /* 4 byte words */ #if BYTE_ORDER == LITTLE_ENDIAN @@ -245,14 +238,11 @@ md5_ctxt *ctxt; } #if BYTE_ORDER == BIG_ENDIAN -uint32 X[16]; - +static uint32 X[16]; #endif static void -md5_calc(b64, ctxt) -uint8 *b64; -md5_ctxt *ctxt; +md5_calc(uint8 *b64, md5_ctxt *ctxt) { uint32 A = ctxt->md5_sta; uint32 B = ctxt->md5_stb; @@ -261,7 +251,6 @@ md5_ctxt *ctxt; #if BYTE_ORDER == LITTLE_ENDIAN uint32 *X = (uint32 *) b64; - #endif #if BYTE_ORDER == BIG_ENDIAN /* 4 byte words */ diff --git a/contrib/pgcrypto/md5.h b/contrib/pgcrypto/md5.h index 54ca2558dff..868f8a233a0 100644 --- a/contrib/pgcrypto/md5.h +++ b/contrib/pgcrypto/md5.h @@ -1,4 +1,4 @@ -/* $Id: md5.h,v 1.4 2001/03/22 03:59:10 momjian Exp $ */ +/* $Id: md5.h,v 1.5 2001/08/21 00:42:41 momjian Exp $ */ /* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ /* @@ -62,7 +62,7 @@ typedef struct } md5_ctxt; extern void md5_init(md5_ctxt *); -extern void md5_loop(md5_ctxt *, uint8 *, unsigned int); +extern void md5_loop(md5_ctxt *, const uint8 *, unsigned int); extern void md5_pad(md5_ctxt *); extern void md5_result(uint8 *, md5_ctxt *); @@ -75,5 +75,4 @@ 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 index d6ada96d149..36d70471a99 100644 --- a/contrib/pgcrypto/mhash.c +++ b/contrib/pgcrypto/mhash.c @@ -1,8 +1,8 @@ /* * mhash.c - * Wrapper for mhash library. + * Wrapper for mhash and mcrypt libraries. * - * Copyright (c) 2000 Marko Kreen + * Copyright (c) 2001 Marko Kreen * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,48 +26,177 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mhash.c,v 1.3 2001/03/22 03:59:10 momjian Exp $ + * $Id: mhash.c,v 1.4 2001/08/21 00:42:41 momjian Exp $ */ -#include "postgres.h" +#include <postgres.h> -#include "pgcrypto.h" +#include "px.h" #include <mhash.h> +#include <mcrypt.h> + +#define MAX_KEY_LENGTH 512 +#define MAX_IV_LENGTH 128 + +#define DEF_KEY_LEN 16 -static uint - pg_mhash_len(pg_digest * hash); -static uint8 *pg_mhash_digest(pg_digest * hash, uint8 *src, - uint len, uint8 *buf); + +/* DIGEST */ static uint -pg_mhash_len(pg_digest * h) +digest_result_size(PX_MD * h) { - return mhash_get_block_size(h->misc.code); + MHASH mh = (MHASH) h->p.ptr; + hashid id = mhash_get_mhash_algo(mh); + + return mhash_get_block_size(id); } -static uint8 * -pg_mhash_digest(pg_digest * h, uint8 *src, uint len, uint8 *dst) +static uint +digest_block_size(PX_MD * h) { - uint8 *res; + MHASH mh = (MHASH) h->p.ptr; + hashid id = mhash_get_mhash_algo(mh); - MHASH mh = mhash_init(h->misc.code); + return mhash_get_hash_pblock(id); +} - mhash(mh, src, len); - res = mhash_end(mh); +static void +digest_reset(PX_MD * h) +{ + MHASH mh = (MHASH) h->p.ptr; + hashid id = mhash_get_mhash_algo(mh); + uint8 *res = mhash_end(mh); - memcpy(dst, res, mhash_get_block_size(h->misc.code)); mhash_free(res); + mh = mhash_init(id); + h->p.ptr = mh; +} + +static void +digest_update(PX_MD * h, const uint8 * data, uint dlen) +{ + MHASH mh = (MHASH) h->p.ptr; + + mhash(mh, data, dlen); +} + +static void +digest_finish(PX_MD * h, uint8 * dst) +{ + MHASH mh = (MHASH) h->p.ptr; + uint hlen = digest_result_size(h); + hashid id = mhash_get_mhash_algo(mh); + uint8 *buf = mhash_end(mh); + + memcpy(dst, buf, hlen); + mhash_free(buf); + + mh = mhash_init(id); + h->p.ptr = mh; +} + +static void +digest_free(PX_MD * h) +{ + MHASH mh = (MHASH) h->p.ptr; + uint8 *buf = mhash_end(mh); + + mhash_free(buf); + + px_free(h); +} + +/* ENCRYPT / DECRYPT */ + +static uint +cipher_block_size(PX_Cipher *c) +{ + MCRYPT ctx = (MCRYPT)c->ptr; + return mcrypt_enc_get_block_size(ctx); +} + +static uint +cipher_key_size(PX_Cipher *c) +{ + MCRYPT ctx = (MCRYPT)c->ptr; + return mcrypt_enc_get_key_size(ctx); +} + +static uint +cipher_iv_size(PX_Cipher *c) +{ + MCRYPT ctx = (MCRYPT)c->ptr; + return mcrypt_enc_mode_has_iv(ctx) + ? mcrypt_enc_get_iv_size(ctx) : 0; +} + +static int +cipher_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) +{ + int err; + MCRYPT ctx = (MCRYPT)c->ptr; + + err = mcrypt_generic_init(ctx, (char *)key, klen, (char*)iv); + if (err < 0) + elog(ERROR, "mcrypt_generic_init error: %s", mcrypt_strerror(err)); + + c->pstat = 1; + return 0; +} + +static int +cipher_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + int err; + MCRYPT ctx = (MCRYPT)c->ptr; - return dst; + memcpy(res, data, dlen); + + err = mcrypt_generic(ctx, res, dlen); + if (err < 0) + elog(ERROR, "mcrypt_generic error: %s", mcrypt_strerror(err)); + return 0; +} + +static int +cipher_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + int err; + MCRYPT ctx = (MCRYPT)c->ptr; + + memcpy(res, data, dlen); + + err = mdecrypt_generic(ctx, res, dlen); + if (err < 0) + elog(ERROR, "mdecrypt_generic error: %s", mcrypt_strerror(err)); + return 0; +} + + +static void +cipher_free(PX_Cipher *c) +{ + MCRYPT ctx = (MCRYPT)c->ptr; + + if (c->pstat) + mcrypt_generic_end(ctx); + else + mcrypt_module_close(ctx); + + px_free(c); } -pg_digest * -pg_find_digest(pg_digest * h, char *name) +/* Helper functions */ + +static int +find_hashid(const char *name) { + int res = -1; size_t hnum, - i, - b; + b, + i; char *mname; hnum = mhash_count(); @@ -80,12 +209,134 @@ pg_find_digest(pg_digest * h, char *name) 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; + res = i; + break; } } - return NULL; + + return res; } + +static char *modes[] = { + "ecb", "cbc", "cfb", "ofb", "nofb", "stream", + "ofb64", "cfb64", NULL +}; + +static PX_Alias aliases[] = { + {"bf", "blowfish" }, + {"3des", "tripledes" }, + {"des3", "tripledes" }, + {"aes", "rijndael-128" }, + {"rijndael", "rijndael-128" }, + {"aes-128", "rijndael-128" }, + {"aes-192", "rijndael-192" }, + {"aes-256", "rijndael-256" }, + { NULL, NULL } +}; + +static PX_Alias mode_aliases[] = { +#if 0 /* N/A */ + { "cfb", "ncfb" }, + { "ofb", "nofb" }, + { "cfb64", "ncfb" }, +#endif + /* { "ofb64", "nofb" }, not sure it works */ + { "cfb8", "cfb" }, + { "ofb8", "ofb" }, + { NULL, NULL } +}; + +static int is_mode(char *s) +{ + char **p; + + if (*s >= '0' && *s <= '9') + return 0; + + for (p = modes; *p; p++) + if (!strcmp(s, *p)) + return 1; + + return 0; +} + +/* PUBLIC FUNCTIONS */ + +int +px_find_digest(const char *name, PX_MD **res) +{ + PX_MD *h; + MHASH mh; + int i; + + i = find_hashid(name); + if (i < 0) + return -1; + + mh = mhash_init(i); + h = px_alloc(sizeof(*h)); + h->p.ptr = (void *) mh; + + h->result_size = digest_result_size; + h->block_size = digest_block_size; + h->reset = digest_reset; + h->update = digest_update; + h->finish = digest_finish; + h->free = digest_free; + + *res = h; + return 0; +} + + +int +px_find_cipher(const char *name, PX_Cipher **res) +{ + char nbuf[PX_MAX_NAMELEN + 1]; + const char *mode = NULL; + char *p; + MCRYPT ctx; + + PX_Cipher *c; + + strcpy(nbuf, name); + + if ((p = strrchr(nbuf, '-')) != NULL) { + if (is_mode(p + 1)) { + mode = p + 1; + *p = 0; + } + } + + name = px_resolve_alias(aliases, nbuf); + + if (!mode) { + mode = "cbc"; + /* + if (mcrypt_module_is_block_algorithm(name, NULL)) + mode = "cbc"; + else + mode = "stream"; + */ + } + mode = px_resolve_alias(mode_aliases, mode); + + ctx = mcrypt_module_open((char*)name, NULL, (char*)mode, NULL); + if (ctx == (void*)MCRYPT_FAILED) + return -1; + + c = palloc(sizeof *c); + c->iv_size = cipher_iv_size; + c->key_size = cipher_key_size; + c->block_size = cipher_block_size; + c->init = cipher_init; + c->encrypt = cipher_encrypt; + c->decrypt = cipher_decrypt; + c->free = cipher_free; + c->ptr = ctx; + c->pstat = 0; + + *res = c; + return 0; +} + diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index 866d26f0ffc..b4d1a0a5e9b 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -2,7 +2,7 @@ * openssl.c * Wrapper for OpenSSL library. * - * Copyright (c) 2000 Marko Kreen + * Copyright (c) 2001 Marko Kreen * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,60 +26,388 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openssl.c,v 1.3 2001/03/22 03:59:10 momjian Exp $ + * $Id: openssl.c,v 1.4 2001/08/21 00:42:41 momjian Exp $ */ -#include "postgres.h" +#include <postgres.h> -#include "pgcrypto.h" +#include "px.h" -#include <evp.h> +#include <openssl/evp.h> +#include <openssl/blowfish.h> +/*#include <openssl/crypto.h>*/ static uint - pg_ossl_len(pg_digest * h); -static uint8 * - pg_ossl_digest(pg_digest * h, uint8 *src, uint len, uint8 *buf); +digest_result_size(PX_MD * h) +{ + return EVP_MD_CTX_size((EVP_MD_CTX *) h->p.ptr); +} static uint -pg_ossl_len(pg_digest * h) +digest_block_size(PX_MD * h) { - return EVP_MD_size((EVP_MD *) h->misc.ptr); + return EVP_MD_CTX_block_size((EVP_MD_CTX *) h->p.ptr); +} + +static void +digest_reset(PX_MD * h) +{ + EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; + const EVP_MD *md; + + md = EVP_MD_CTX_md(ctx); + + EVP_DigestInit(ctx, md); } -static uint8 * -pg_ossl_digest(pg_digest * h, uint8 *src, uint len, uint8 *buf) +static void +digest_update(PX_MD * h, const uint8 * data, uint dlen) { - EVP_MD *md = (EVP_MD *) h->misc.ptr; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; + + EVP_DigestUpdate(ctx, data, dlen); +} - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, src, len); - EVP_DigestFinal(&ctx, buf, NULL); +static void +digest_finish(PX_MD * h, uint8 * dst) +{ + EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; - return buf; + EVP_DigestFinal(ctx, dst, NULL); } -static int pg_openssl_initialized = 0; +static void +digest_free(PX_MD * h) +{ + EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; + + px_free(ctx); + px_free(h); +} + +/* CIPHERS */ + +/* + * The problem with OpenSSL is that the EVP* family + * of functions does not allow enough flexibility + * and forces some of the parameters (keylen, + * padding) to SSL defaults. + */ + + +typedef struct { + union { + struct { + BF_KEY key; + int num; + } bf; + EVP_CIPHER_CTX evp_ctx; + } u; + const EVP_CIPHER *evp_ciph; + uint8 key[EVP_MAX_KEY_LENGTH]; + uint8 iv[EVP_MAX_IV_LENGTH]; + uint klen; + uint init; +} ossldata; + +/* generic EVP */ + +static uint +gen_evp_block_size(PX_Cipher *c) +{ + ossldata *od = (ossldata *)c->ptr; + return EVP_CIPHER_block_size(od->evp_ciph); +} + +static uint +gen_evp_key_size(PX_Cipher *c) +{ + ossldata *od = (ossldata *)c->ptr; + return EVP_CIPHER_key_length(od->evp_ciph); +} + +static uint +gen_evp_iv_size(PX_Cipher *c) +{ + uint ivlen; + ossldata *od = (ossldata *)c->ptr; + ivlen = EVP_CIPHER_iv_length(od->evp_ciph); + return ivlen; +} + +static void +gen_evp_free(PX_Cipher *c) +{ + ossldata *od = (ossldata*)c->ptr; + memset(od, 0, sizeof(*od)); + pfree(od); + pfree(c); +} + +/* fun */ + +static int +gen_evp_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) +{ + ossldata *od = (ossldata*)c->ptr; + uint bs = gen_evp_block_size(c); + if (iv) { + memcpy(od->iv, iv, bs); + } else + memset(od->iv, 0, bs); + memcpy(od->key, key, klen); + od->klen = klen; + od->init = 0; + return 0; +} + +static void +_gen_init(PX_Cipher *c, int enc) +{ + ossldata *od = c->ptr; + + od->evp_ciph->init(&od->u.evp_ctx, od->key, od->iv, enc); + od->init = 1; + od->u.evp_ctx.encrypt = enc; +} + +static int +gen_evp_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + if (!od->init) + _gen_init(c, 1); + od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen); + return 0; +} + +static int +gen_evp_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + if (!od->init) + _gen_init(c, 0); + od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen); + return 0; +} + +/* Blowfish */ + +static int +bf_init(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv) +{ + ossldata *od = c->ptr; + BF_set_key(&od->u.bf.key, klen, key); + if (iv) { + memcpy(od->iv, iv, BF_BLOCK); + } else + memset(od->iv, 0, BF_BLOCK); + od->u.bf.num = 0; + return 0; +} -pg_digest * -pg_find_digest(pg_digest * h, char *name) +static int +bf_ecb_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + uint bs = gen_evp_block_size(c), i; + ossldata *od = c->ptr; + for (i = 0; i < dlen / bs; i++) + BF_ecb_encrypt(data+i*bs, res+i*bs, &od->u.bf.key, BF_ENCRYPT); + return 0; +} + +static int +bf_ecb_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + uint bs = gen_evp_block_size(c), i; + ossldata *od = c->ptr; + for (i = 0; i < dlen / bs; i++) + BF_ecb_encrypt(data+i*bs, res+i*bs, &od->u.bf.key, BF_DECRYPT); + return 0; +} + +static int +bf_cbc_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT); + return 0; +} + +static int +bf_cbc_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT); + return 0; +} + +static int +bf_cfb64_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, + &od->u.bf.num, BF_ENCRYPT); + return 0; +} + +static int +bf_cfb64_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, + &od->u.bf.num, BF_DECRYPT); + return 0; +} + +static int +bf_ofb64_encrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num); + return 0; +} + +static int +bf_ofb64_decrypt(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res) +{ + ossldata *od = c->ptr; + BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num); + return 0; +} + +/* + * aliases + */ + +static PX_Alias ossl_aliases [] = { + { "bf", "bf-cbc" }, + { "blowfish", "bf-cbc" }, + { "blowfish-cbc", "bf-cbc" }, + { "blowfish-ecb", "bf-ecb" }, + { "blowfish-cfb", "bf-cfb" }, + { "blowfish-ofb", "bf-ofb" }, + { NULL } +}; + +/* +static PX_Alias ossl_mode_aliases [] = { + { "cfb64", "cfb" }, + { "ofb64", "ofb" }, + { NULL } +};*/ + +/* + * Special handlers + */ +struct { + char *name; + PX_Cipher cf; +} spec_types [] = { + { "bf-cbc", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, + bf_init, bf_cbc_encrypt, bf_cbc_decrypt, gen_evp_free}}, + { "bf-ecb", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, + bf_init, bf_ecb_encrypt, bf_ecb_decrypt, gen_evp_free}}, + { "bf-cfb", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, + bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt, gen_evp_free}}, + { "bf-ofb", { gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, + bf_init, bf_ofb64_encrypt, bf_ofb64_decrypt, gen_evp_free}}, + { NULL } +}; + +/* + * Generic EVP_* functions handler + */ +static PX_Cipher gen_evp_handler = { + gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, + gen_evp_init, gen_evp_encrypt, gen_evp_decrypt, gen_evp_free +}; + +static int px_openssl_initialized = 0; + +/* ATM not needed +static void *o_alloc(uint s) { return px_alloc(s); } +static void *o_realloc(void *p) { return px_realloc(p); } +static void o_free(void *p) { px_free(p); } +*/ + +/* PUBLIC functions */ + +int +px_find_digest(const char *name, PX_MD **res) { const EVP_MD *md; + EVP_MD_CTX *ctx; + PX_MD *h; - if (!pg_openssl_initialized) + if (!px_openssl_initialized) { - OpenSSL_add_all_digests(); - pg_openssl_initialized = 1; + px_openssl_initialized = 1; + /*CRYPTO_set_mem_functions(o_alloc, o_realloc, o_free);*/ + OpenSSL_add_all_algorithms(); } md = EVP_get_digestbyname(name); if (md == NULL) - return NULL; + return -1; - h->name = name; - h->length = pg_ossl_len; - h->digest = pg_ossl_digest; - h->misc.ptr = (void *) md; + ctx = px_alloc(sizeof(*ctx)); + EVP_DigestInit(ctx, md); - return h; + h = px_alloc(sizeof(*h)); + h->result_size = digest_result_size; + h->block_size = digest_block_size; + h->reset = digest_reset; + h->update = digest_update; + h->finish = digest_finish; + h->free = digest_free; + h->p.ptr = (void *) ctx; + + *res = h; + return 0; } + + +int +px_find_cipher(const char *name, PX_Cipher **res) +{ + uint i; + PX_Cipher *c = NULL, *csrc; + ossldata *od; + + const EVP_CIPHER *evp_c; + + if (!px_openssl_initialized) { + px_openssl_initialized = 1; + /*CRYPTO_set_mem_functions(o_alloc, o_realloc, o_free);*/ + OpenSSL_add_all_algorithms(); + } + + name = px_resolve_alias(ossl_aliases, name); + evp_c = EVP_get_cipherbyname(name); + if (evp_c == NULL) + return -1; + + od = px_alloc(sizeof(*od)); + memset(od, 0, sizeof(*od)); + od->evp_ciph = evp_c; + + csrc = NULL; + + for (i = 0; spec_types[i].name; i++) + if (!strcmp(name, spec_types[i].name)) { + csrc = &spec_types[i].cf; + break; + } + + if (csrc == NULL) + csrc = &gen_evp_handler; + + c = px_alloc(sizeof(*c)); + memcpy(c, csrc, sizeof(*c)); + c->ptr = od; + + *res = c; + return 0; +} + diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c index 31e5a845bd6..4a2f37d95be 100644 --- a/contrib/pgcrypto/pgcrypto.c +++ b/contrib/pgcrypto/pgcrypto.c @@ -1,8 +1,8 @@ /* * pgcrypto.c - * Cryptographic digests for PostgreSQL. + * Various cryptographic stuff for PostgreSQL. * - * Copyright (c) 2000 Marko Kreen + * Copyright (c) 2001 Marko Kreen * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,113 +26,487 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pgcrypto.c,v 1.7 2001/03/22 03:59:10 momjian Exp $ + * $Id: pgcrypto.c,v 1.8 2001/08/21 00:42:41 momjian Exp $ */ -#include "postgres.h" - -#include "utils/builtins.h" +#include <postgres.h> +#include <fmgr.h> +#include <ctype.h> +#include "px.h" +#include "px-crypt.h" #include "pgcrypto.h" -/* - * 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 pg_digest * - find_digest(pg_digest * hbuf, text *name, int silent); +typedef int (*PFN) (const char *name, void **res); +static void * + find_provider(text * name, PFN pf, char *desc, int silent); /* SQL function: hash(text, text) returns text */ -PG_FUNCTION_INFO_V1(digest); +PG_FUNCTION_INFO_V1(pg_digest); Datum -digest(PG_FUNCTION_ARGS) +pg_digest(PG_FUNCTION_ARGS) { - text *arg; + bytea *arg; text *name; uint len, hlen; - pg_digest *h, - _hbuf; - text *res; + PX_MD *md; + bytea *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); + /* will give error if fails */ + md = find_provider(name, (PFN) px_find_digest, "Digest", 0); + + hlen = px_md_result_size(md); res = (text *) palloc(hlen + VARHDRSZ); VARATT_SIZEP(res) = hlen + VARHDRSZ; - arg = PG_GETARG_TEXT_P(0); + arg = PG_GETARG_BYTEA_P(0); len = VARSIZE(arg) - VARHDRSZ; - h->digest(h, VARDATA(arg), len, VARDATA(res)); + px_md_update(md, VARDATA(arg), len); + px_md_finish(md, VARDATA(res)); + px_md_free(md); PG_FREE_IF_COPY(arg, 0); PG_FREE_IF_COPY(name, 1); - PG_RETURN_TEXT_P(res); + PG_RETURN_BYTEA_P(res); } /* check if given hash exists */ -PG_FUNCTION_INFO_V1(digest_exists); +PG_FUNCTION_INFO_V1(pg_digest_exists); Datum -digest_exists(PG_FUNCTION_ARGS) +pg_digest_exists(PG_FUNCTION_ARGS) { text *name; - pg_digest _hbuf, - *res; + PX_MD *res; if (PG_ARGISNULL(0)) PG_RETURN_NULL(); name = PG_GETARG_TEXT_P(0); - res = find_digest(&_hbuf, name, 1); + res = find_provider(name, (PFN) px_find_digest, "Digest", 1); PG_FREE_IF_COPY(name, 0); - if (res != NULL) + if (res == NULL) + PG_RETURN_BOOL(false); + + res->free(res); + + PG_RETURN_BOOL(true); +} + +/* SQL function: hmac(data:text, key:text, type:text) */ +PG_FUNCTION_INFO_V1(pg_hmac); + +Datum +pg_hmac(PG_FUNCTION_ARGS) +{ + bytea *arg; + bytea *key; + text *name; + uint len, + hlen, + klen; + PX_HMAC *h; + bytea *res; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) + PG_RETURN_NULL(); + + name = PG_GETARG_TEXT_P(2); + + /* will give error if fails */ + h = find_provider(name, (PFN) px_find_hmac, "HMAC", 0); + + hlen = px_hmac_result_size(h); + + res = (text *) palloc(hlen + VARHDRSZ); + VARATT_SIZEP(res) = hlen + VARHDRSZ; + + arg = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + len = VARSIZE(arg) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + + px_hmac_init(h, VARDATA(key), klen); + px_hmac_update(h, VARDATA(arg), len); + px_hmac_finish(h, VARDATA(res)); + px_hmac_free(h); + + PG_FREE_IF_COPY(arg, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(name, 2); + + PG_RETURN_BYTEA_P(res); +} + +/* check if given hmac type exists */ +PG_FUNCTION_INFO_V1(pg_hmac_exists); + +Datum +pg_hmac_exists(PG_FUNCTION_ARGS) +{ + text *name; + PX_HMAC *h; + + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + + name = PG_GETARG_TEXT_P(0); + + h = find_provider(name, (PFN) px_find_hmac, "HMAC", 1); + + PG_FREE_IF_COPY(name, 0); + + if (h != NULL) + { + px_hmac_free(h); PG_RETURN_BOOL(true); + } PG_RETURN_BOOL(false); } -static pg_digest * -find_digest(pg_digest * hbuf, text *name, int silent) + +/* SQL function: pg_gen_salt(text) returns text */ +PG_FUNCTION_INFO_V1(pg_gen_salt); + +Datum +pg_gen_salt(PG_FUNCTION_ARGS) +{ + text *arg0; + uint len; + text *res; + char buf[PX_MAX_SALT_LEN + 1]; + + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + + arg0 = PG_GETARG_TEXT_P(0); + + len = VARSIZE(arg0) - VARHDRSZ; + len = len > PX_MAX_SALT_LEN ? PX_MAX_SALT_LEN : len; + memcpy(buf, VARDATA(arg0), len); + buf[len] = 0; + len = px_gen_salt(buf, buf); + if (len == 0) + elog(ERROR, "No such crypt algorithm"); + + res = (text *) palloc(len + VARHDRSZ); + VARATT_SIZEP(res) = len + VARHDRSZ; + memcpy(VARDATA(res), buf, len); + + PG_FREE_IF_COPY(arg0, 0); + + PG_RETURN_TEXT_P(res); +} + +/* SQL function: pg_crypt(psw:text, salt:text) returns text */ +PG_FUNCTION_INFO_V1(pg_crypt); + +Datum +pg_crypt(PG_FUNCTION_ARGS) +{ + text *arg0; + text *arg1; + uint len0, + len1, + clen; + char *buf0, + *buf1, + *cres, + *resbuf; + text *res; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) + PG_RETURN_NULL(); + + arg0 = PG_GETARG_TEXT_P(0); + arg1 = PG_GETARG_TEXT_P(1); + len0 = VARSIZE(arg0) - VARHDRSZ; + len1 = VARSIZE(arg1) - VARHDRSZ; + + buf0 = palloc(len0 + 1); + buf1 = palloc(len1 + 1); + + memcpy(buf0, VARDATA(arg0), len0); + memcpy(buf1, VARDATA(arg1), len1); + + buf0[len0] = '\0'; + buf1[len1] = '\0'; + + resbuf = palloc(PX_MAX_CRYPT); + + memset(resbuf, 0, PX_MAX_CRYPT); + + cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT); + + pfree(buf0); + pfree(buf1); + + if (cres == NULL) + elog(ERROR, "crypt(3) returned NULL"); + + clen = strlen(cres); + + res = (text *) palloc(clen + VARHDRSZ); + VARATT_SIZEP(res) = clen + VARHDRSZ; + memcpy(VARDATA(res), cres, clen); + pfree(resbuf); + + PG_FREE_IF_COPY(arg0, 0); + PG_FREE_IF_COPY(arg1, 1); + + PG_RETURN_TEXT_P(res); +} + +/* SQL function: pg_encrypt(text, text, text) returns text */ +PG_FUNCTION_INFO_V1(pg_encrypt); + +Datum +pg_encrypt(PG_FUNCTION_ARGS) +{ + int err; + bytea *data, *key, *res; + text *type; + PX_Combo *c; + uint dlen, klen, rlen; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) + PG_RETURN_NULL(); + + type = PG_GETARG_TEXT_P(2); + c = find_provider(type, (PFN)px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + + rlen = px_combo_encrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, VARDATA(key), klen, NULL, 0); + if (!err) + err = px_combo_encrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); + px_combo_free(c); + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(type, 2); + + if (err) { + pfree(res); + elog(ERROR, "encrypt error: %d", err); + } + + VARATT_SIZEP(res) = VARHDRSZ + rlen; + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_decrypt(text, text, text) returns text */ +PG_FUNCTION_INFO_V1(pg_decrypt); + +Datum +pg_decrypt(PG_FUNCTION_ARGS) +{ + int err; + bytea *data, *key, *res; + text *type; + PX_Combo *c; + uint dlen, klen, rlen; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) + PG_RETURN_NULL(); + + type = PG_GETARG_TEXT_P(2); + c = find_provider(type, (PFN)px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + + rlen = px_combo_decrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, VARDATA(key), klen, NULL, 0); + if (!err) + err = px_combo_decrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); + + px_combo_free(c); + + if (err) + elog(ERROR, "decrypt error: %d", err); + + VARATT_SIZEP(res) = VARHDRSZ + rlen; + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(type, 2); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_encrypt(text, text, text) returns text */ +PG_FUNCTION_INFO_V1(pg_encrypt_iv); + +Datum +pg_encrypt_iv(PG_FUNCTION_ARGS) { - pg_digest *p; - char buf[NAMEDATALEN]; + int err; + bytea *data, *key, *iv, *res; + text *type; + PX_Combo *c; + uint dlen, klen, ivlen, rlen; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1) + || PG_ARGISNULL(2) || PG_ARGISNULL(3)) + PG_RETURN_NULL(); + + type = PG_GETARG_TEXT_P(3); + c = find_provider(type, (PFN)px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + iv = PG_GETARG_BYTEA_P(2); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + ivlen = VARSIZE(iv) - VARHDRSZ; + + rlen = px_combo_encrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, VARDATA(key), klen, VARDATA(iv), ivlen); + if (!err) + px_combo_encrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); + + px_combo_free(c); + + if (err) + elog(ERROR, "encrypt_iv error: %d", err); + + VARATT_SIZEP(res) = VARHDRSZ + rlen; + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(iv, 2); + PG_FREE_IF_COPY(type, 3); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_decrypt_iv(text, text, text) returns text */ +PG_FUNCTION_INFO_V1(pg_decrypt_iv); + +Datum +pg_decrypt_iv(PG_FUNCTION_ARGS) +{ + int err; + bytea *data, *key, *iv, *res; + text *type; + PX_Combo *c; + uint dlen, klen, rlen, ivlen; + + if (PG_ARGISNULL(0) || PG_ARGISNULL(1) + || PG_ARGISNULL(2) || PG_ARGISNULL(3)) + PG_RETURN_NULL(); + + type = PG_GETARG_TEXT_P(3); + c = find_provider(type, (PFN)px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + iv = PG_GETARG_BYTEA_P(2); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + ivlen = VARSIZE(iv) - VARHDRSZ; + + rlen = px_combo_decrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, VARDATA(key), klen, VARDATA(iv), ivlen); + if (!err) + px_combo_decrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); + + px_combo_free(c); + + if (err) + elog(ERROR, "decrypt_iv error: %d", err); + + VARATT_SIZEP(res) = VARHDRSZ + rlen; + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(iv, 2); + PG_FREE_IF_COPY(type, 3); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_decrypt(text, text, text) returns text */ +PG_FUNCTION_INFO_V1(pg_cipher_exists); + +Datum +pg_cipher_exists(PG_FUNCTION_ARGS) +{ + text *arg; + PX_Combo *c; + + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + + arg = PG_GETARG_TEXT_P(0); + + c = find_provider(arg, (PFN)px_find_combo, "Cipher", 1); + if (c != NULL) + px_combo_free(c); + + PG_RETURN_BOOL((c != NULL) ? true : false); +} + + +static void * +find_provider(text * name, + PFN provider_lookup, + char *desc, int silent) +{ + void *res; + char buf[PX_MAX_NAMELEN + 1], + *p; uint len; + uint i; + int err; len = VARSIZE(name) - VARHDRSZ; - if (len >= NAMEDATALEN) + if (len > PX_MAX_NAMELEN) { if (silent) return NULL; - elog(ERROR, "Hash type does not exist (name too long)"); + elog(ERROR, "%s type does not exist (name too long)", desc); } - memcpy(buf, VARDATA(name), len); + p = VARDATA(name); + for (i = 0; i < len; i++) + buf[i] = tolower(p[i]); buf[len] = 0; - p = pg_find_digest(hbuf, buf); + err = provider_lookup(buf, &res); + + if (err && !silent) + elog(ERROR, "%s type does not exist: '%s'", desc, buf); - if (p == NULL && !silent) - elog(ERROR, "Hash type does not exist: '%s'", buf); - return p; + return err ? NULL : res; } diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h index 1700b89b158..4c400243042 100644 --- a/contrib/pgcrypto/pgcrypto.h +++ b/contrib/pgcrypto/pgcrypto.h @@ -26,27 +26,24 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pgcrypto.h,v 1.3 2001/03/22 03:59:10 momjian Exp $ + * $Id: pgcrypto.h,v 1.4 2001/08/21 00:42:41 momjian Exp $ */ #ifndef _PG_CRYPTO_H #define _PG_CRYPTO_H -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); +/* exported functions */ +Datum pg_digest(PG_FUNCTION_ARGS); +Datum pg_digest_exists(PG_FUNCTION_ARGS); +Datum pg_hmac(PG_FUNCTION_ARGS); +Datum pg_hmac_exists(PG_FUNCTION_ARGS); +Datum pg_gen_salt(PG_FUNCTION_ARGS); +Datum pg_crypt(PG_FUNCTION_ARGS); +Datum pg_encrypt(PG_FUNCTION_ARGS); +Datum pg_decrypt(PG_FUNCTION_ARGS); +Datum pg_encrypt_iv(PG_FUNCTION_ARGS); +Datum pg_decrypt_iv(PG_FUNCTION_ARGS); +Datum pg_cipher_exists(PG_FUNCTION_ARGS); #endif + diff --git a/contrib/pgcrypto/pgcrypto.sql.in b/contrib/pgcrypto/pgcrypto.sql.in index 222b2769fa1..bed50c6946e 100644 --- a/contrib/pgcrypto/pgcrypto.sql.in +++ b/contrib/pgcrypto/pgcrypto.sql.in @@ -1,23 +1,59 @@ --- drop function digest(text, text); +-- drop function digest(bytea, text); -- drop function digest_exists(text); --- drop function encode(text, text); --- drop function decode(text, text); +-- drop function hmac(bytea, bytea, text); +-- drop function hmac_exists(text); +-- drop function crypt(text, text); +-- drop function gen_salt(text); +-- drop function encrypt(bytea, bytea, text); +-- drop function decrypt(bytea, bytea, text); +-- drop function encrypt_iv(bytea, bytea, bytea, text); +-- drop function decrypt_iv(bytea, bytea, bytea, text); -CREATE FUNCTION digest(text, text) RETURNS text + +CREATE FUNCTION digest(bytea, text) RETURNS bytea AS '@MODULE_FILENAME@', - 'digest' LANGUAGE 'C'; + 'pg_digest' LANGUAGE 'C'; CREATE FUNCTION digest_exists(text) RETURNS bool AS '@MODULE_FILENAME@', - 'digest_exists' LANGUAGE 'C'; + 'pg_digest_exists' LANGUAGE 'C'; + +CREATE FUNCTION hmac(bytea, bytea, text) RETURNS bytea + AS '@MODULE_FILENAME@', + 'pg_hmac' LANGUAGE 'C'; + +CREATE FUNCTION hmac_exists(text) RETURNS bool + AS '@MODULE_FILENAME@', + 'pg_hmac_exists' LANGUAGE 'C'; + +CREATE FUNCTION crypt(text, text) RETURNS text + AS '@MODULE_FILENAME@', + 'pg_crypt' LANGUAGE 'C'; + +CREATE FUNCTION gen_salt(text) RETURNS text + AS '@MODULE_FILENAME@', + 'pg_gen_salt' LANGUAGE 'C'; + +CREATE FUNCTION encrypt(bytea, bytea, text) RETURNS bytea + AS '@MODULE_FILENAME@', + 'pg_encrypt' LANGUAGE 'C'; + +CREATE FUNCTION decrypt(bytea, bytea, text) RETURNS bytea + AS '@MODULE_FILENAME@', + 'pg_decrypt' LANGUAGE 'C'; + +CREATE FUNCTION encrypt_iv(bytea, bytea, bytea, text) RETURNS bytea + AS '@MODULE_FILENAME@', + 'pg_encrypt_iv' LANGUAGE 'C'; -CREATE FUNCTION encode(text, text) RETURNS text +CREATE FUNCTION decrypt_iv(bytea, bytea, bytea, text) RETURNS bytea AS '@MODULE_FILENAME@', - 'encode' LANGUAGE 'C'; + 'pg_decrypt_iv' LANGUAGE 'C'; -CREATE FUNCTION decode(text, text) RETURNS text +CREATE FUNCTION cipher_exists(text) RETURNS bool AS '@MODULE_FILENAME@', - 'decode' LANGUAGE 'C'; + 'pg_cipher_exists' LANGUAGE 'C'; + diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c index db9f1a17c60..98ad552182f 100644 --- a/contrib/pgcrypto/sha1.c +++ b/contrib/pgcrypto/sha1.c @@ -1,4 +1,4 @@ -/* $Id: sha1.c,v 1.5 2001/03/22 03:59:10 momjian Exp $ */ +/* $Id: sha1.c,v 1.6 2001/08/21 00:42:41 momjian Exp $ */ /* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ /* @@ -85,8 +85,7 @@ static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; static void sha1_step(struct sha1_ctxt *); static void -sha1_step(ctxt) -struct sha1_ctxt *ctxt; +sha1_step(struct sha1_ctxt *ctxt) { uint32 a, b, @@ -231,8 +230,7 @@ struct sha1_ctxt *ctxt; /*------------------------------------------------------------*/ void -sha1_init(ctxt) -struct sha1_ctxt *ctxt; +sha1_init(struct sha1_ctxt *ctxt) { bzero(ctxt, sizeof(struct sha1_ctxt)); H(0) = 0x67452301; @@ -243,8 +241,7 @@ struct sha1_ctxt *ctxt; } void -sha1_pad(ctxt) -struct sha1_ctxt *ctxt; +sha1_pad(struct sha1_ctxt *ctxt) { size_t padlen; /* pad length in bytes */ size_t padstart; @@ -287,10 +284,7 @@ struct sha1_ctxt *ctxt; } void -sha1_loop(ctxt, input0, len) -struct sha1_ctxt *ctxt; -const caddr_t input0; -size_t len; +sha1_loop(struct sha1_ctxt *ctxt, const uint8 *input0, size_t len) { const uint8 *input; size_t gaplen; @@ -318,9 +312,7 @@ size_t len; } void -sha1_result(ctxt, digest0) -struct sha1_ctxt *ctxt; -caddr_t digest0; +sha1_result(struct sha1_ctxt *ctxt, uint8 *digest0) { uint8 *digest; @@ -351,5 +343,4 @@ caddr_t digest0; digest[19] = ctxt->h.b8[16]; #endif } - #endif /* unsupported */ diff --git a/contrib/pgcrypto/sha1.h b/contrib/pgcrypto/sha1.h index cddc8651e4f..c83bd7191a5 100644 --- a/contrib/pgcrypto/sha1.h +++ b/contrib/pgcrypto/sha1.h @@ -1,4 +1,4 @@ -/* $Id: sha1.h,v 1.4 2001/03/22 03:59:10 momjian Exp $ */ +/* $Id: sha1.h,v 1.5 2001/08/21 00:42:41 momjian Exp $ */ /* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */ /* @@ -60,8 +60,8 @@ struct sha1_ctxt extern void sha1_init(struct sha1_ctxt *); extern void sha1_pad(struct sha1_ctxt *); -extern void sha1_loop(struct sha1_ctxt *, const caddr_t, size_t); -extern void sha1_result(struct sha1_ctxt *, caddr_t); +extern void sha1_loop(struct sha1_ctxt *, const uint8 *, size_t); +extern void sha1_result(struct sha1_ctxt *, uint8 *); /* compatibilty with other SHA1 source codes */ typedef struct sha1_ctxt SHA1_CTX; -- GitLab