#
-# $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)
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
$(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
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
-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.
* 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
* 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
#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;
}
+
+
-/* $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 $ */
/*
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;
}
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;
}
void
-md5_pad(ctxt)
-md5_ctxt *ctxt;
+md5_pad(md5_ctxt *ctxt)
{
unsigned int gap;
}
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
}
#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;
#if BYTE_ORDER == LITTLE_ENDIAN
uint32 *X = (uint32 *) b64;
-
#endif
#if BYTE_ORDER == BIG_ENDIAN
/* 4 byte words */
-/* $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 $ */
/*
} 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 *);
md5_pad((y)); \
md5_result((x), (y)); \
} while (0)
-
#endif /* ! _NETINET6_MD5_H_ */
/*
* 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
* 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();
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;
+}
+
* 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
* 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;
+}
+
/*
* 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
* 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;
}
* 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
+
--- 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';
+
-/* $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 $ */
/*
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,
/*------------------------------------------------------------*/
void
-sha1_init(ctxt)
-struct sha1_ctxt *ctxt;
+sha1_init(struct sha1_ctxt *ctxt)
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
}
void
-sha1_pad(ctxt)
-struct sha1_ctxt *ctxt;
+sha1_pad(struct sha1_ctxt *ctxt)
{
size_t padlen; /* pad length in bytes */
size_t padstart;
}
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;
}
void
-sha1_result(ctxt, digest0)
-struct sha1_ctxt *ctxt;
-caddr_t digest0;
+sha1_result(struct sha1_ctxt *ctxt, uint8 *digest0)
{
uint8 *digest;
digest[19] = ctxt->h.b8[16];
#endif
}
-
#endif /* unsupported */
-/* $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 $ */
/*
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;