mirror of https://github.com/postgres/postgres
/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
This commit is contained in:
parent
5950a984a7
commit
2518e27334
|
@ -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
|
||||
|
|
|
@ -1,56 +1,184 @@
|
|||
|
||||
DESCRIPTION
|
||||
|
||||
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'.
|
||||
|
||||
decode(data, type)
|
||||
decodes the data processed by encode()
|
||||
|
||||
digest(data::text, hash_name::text)
|
||||
which returns cryptographic checksum over data by
|
||||
specified algorithm. eg
|
||||
|
||||
> select encode(digest('blah', 'sha1'), 'hex');
|
||||
5bf1fd927dfb8679496a2e6cf00cbe50c1c87145
|
||||
|
||||
digest_exists(hash_name::text)::bool
|
||||
which reports if particular hash type exists.
|
||||
|
||||
If any of arguments are NULL they return NULL.
|
||||
|
||||
HASHES
|
||||
|
||||
For choosing library you must edit Makefile.
|
||||
|
||||
standalone (default):
|
||||
MD5, SHA1
|
||||
|
||||
(the code is from KAME project. Actually I hate code
|
||||
duplication, but I also want to quarantee that MD5 and
|
||||
SHA1 exist)
|
||||
|
||||
mhash (0.8.1):
|
||||
MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160,
|
||||
HAVAL(256,224,192,160,128)
|
||||
|
||||
openssl:
|
||||
MD5, SHA1, RIPEMD160, MD2
|
||||
|
||||
kerberos5 (heimdal):
|
||||
MD5, SHA1
|
||||
|
||||
ENCRYPTION
|
||||
|
||||
There is experimental version out with encryption, HMAC
|
||||
and UN*X crypt() support in
|
||||
|
||||
http://www.l-t.ee/marko/pgsql/
|
||||
|
||||
Current latest release is pgcrypto-0.3.tar.gz.
|
||||
pgcrypto 0.4 - cryptographic functions for PostgreSQL.
|
||||
======================================================
|
||||
by Marko Kreen <marko@l-t.ee>
|
||||
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
Edit makefile, if you want to use any external library.
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
SQL FUNCTIONS
|
||||
=============
|
||||
|
||||
If any of arguments are NULL they return NULL.
|
||||
|
||||
digest(data::bytea, type::text)::bytea
|
||||
|
||||
Type is here the algorithm to use. E.g. 'md5', 'sha1', ...
|
||||
Returns binary hash.
|
||||
|
||||
digest_exists(type::text)::bool
|
||||
|
||||
Returns BOOL whether given hash exists.
|
||||
|
||||
hmac(data::bytea, key::bytea, type::text)::bytea
|
||||
|
||||
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. ]
|
||||
|
||||
hmac_exists(type::text)::bool
|
||||
Returns BOOL. It is separate function because all hashes
|
||||
cannot be used in HMAC.
|
||||
|
||||
crypt(password::text, salt::text)::text
|
||||
|
||||
Calculates UN*X crypt(3) style hash. Useful for storing
|
||||
passwords. For generating salt you should use the
|
||||
gen_salt() function. Usage:
|
||||
|
||||
New password:
|
||||
|
||||
UPDATE .. SET pswhash = crypt(new_psw, gen_salt('md5'));
|
||||
|
||||
Authentication:
|
||||
|
||||
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...
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
|
|
@ -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 void init_md5(PX_MD * h);
|
||||
static void init_sha1(PX_MD * h);
|
||||
|
||||
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 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)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, src, len);
|
||||
MD5Final(buf, &ctx);
|
||||
|
||||
return buf;
|
||||
return MD5_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
int_md5_update(PX_MD * h, const uint8 * data, uint dlen)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
int_md5_free(PX_MD * h)
|
||||
{
|
||||
MD5_CTX *ctx = (MD5_CTX *) h->p.ptr;
|
||||
|
||||
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)
|
||||
{
|
||||
SHA1_CTX ctx;
|
||||
|
||||
SHA1Init(&ctx);
|
||||
SHA1Update(&ctx, src, len);
|
||||
SHA1Final(buf, &ctx);
|
||||
|
||||
return buf;
|
||||
return SHA1_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
|
||||
pg_digest *
|
||||
pg_find_digest(pg_digest * h, char *name)
|
||||
static void
|
||||
int_sha1_update(PX_MD * h, const uint8 * data, uint dlen)
|
||||
{
|
||||
pg_digest *p;
|
||||
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()
|
||||
{
|
||||
return rj_load(MODE_CBC);
|
||||
}
|
||||
|
||||
static PX_Cipher * bf_ecb_load()
|
||||
{
|
||||
return bf_load(MODE_ECB);
|
||||
}
|
||||
|
||||
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 }
|
||||
};
|
||||
|
||||
/* PUBLIC FUNCTIONS */
|
||||
|
||||
int
|
||||
px_find_digest(const char *name, PX_MD ** res)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
/* DIGEST */
|
||||
|
||||
static uint
|
||||
pg_mhash_len(pg_digest * hash);
|
||||
static uint8 *pg_mhash_digest(pg_digest * hash, uint8 *src,
|
||||
uint len, uint8 *buf);
|
||||
|
||||
static uint
|
||||
pg_mhash_len(pg_digest * h)
|
||||
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);
|
||||
|
||||
return dst;
|
||||
mh = mhash_init(id);
|
||||
h->p.ptr = mh;
|
||||
}
|
||||
|
||||
pg_digest *
|
||||
pg_find_digest(pg_digest * h, char *name)
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 uint8 *
|
||||
pg_ossl_digest(pg_digest * h, uint8 *src, uint len, uint8 *buf)
|
||||
{
|
||||
EVP_MD *md = (EVP_MD *) h->misc.ptr;
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
EVP_DigestInit(&ctx, md);
|
||||
EVP_DigestUpdate(&ctx, src, len);
|
||||
EVP_DigestFinal(&ctx, buf, NULL);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int pg_openssl_initialized = 0;
|
||||
|
||||
pg_digest *
|
||||
pg_find_digest(pg_digest * h, char *name)
|
||||
static void
|
||||
digest_reset(PX_MD * h)
|
||||
{
|
||||
EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr;
|
||||
const EVP_MD *md;
|
||||
|
||||
if (!pg_openssl_initialized)
|
||||
md = EVP_MD_CTX_md(ctx);
|
||||
|
||||
EVP_DigestInit(ctx, md);
|
||||
}
|
||||
|
||||
static void
|
||||
digest_update(PX_MD * h, const uint8 * data, uint dlen)
|
||||
{
|
||||
EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr;
|
||||
|
||||
EVP_DigestUpdate(ctx, data, dlen);
|
||||
}
|
||||
|
||||
static void
|
||||
digest_finish(PX_MD * h, uint8 * dst)
|
||||
{
|
||||
EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr;
|
||||
|
||||
EVP_DigestFinal(ctx, dst, NULL);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 (!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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
pg_digest *p;
|
||||
char buf[NAMEDATALEN];
|
||||
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)
|
||||
{
|
||||
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 (p == NULL && !silent)
|
||||
elog(ERROR, "Hash type does not exist: '%s'", buf);
|
||||
return p;
|
||||
if (err && !silent)
|
||||
elog(ERROR, "%s type does not exist: '%s'", desc, buf);
|
||||
|
||||
return err ? NULL : res;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 encode(text, text) RETURNS text
|
||||
CREATE FUNCTION hmac(bytea, bytea, text) RETURNS bytea
|
||||
AS '@MODULE_FILENAME@',
|
||||
'encode' LANGUAGE 'C';
|
||||
'pg_hmac' LANGUAGE 'C';
|
||||
|
||||
CREATE FUNCTION decode(text, text) RETURNS text
|
||||
CREATE FUNCTION hmac_exists(text) RETURNS bool
|
||||
AS '@MODULE_FILENAME@',
|
||||
'decode' LANGUAGE 'C';
|
||||
'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 decrypt_iv(bytea, bytea, bytea, text) RETURNS bytea
|
||||
AS '@MODULE_FILENAME@',
|
||||
'pg_decrypt_iv' LANGUAGE 'C';
|
||||
|
||||
CREATE FUNCTION cipher_exists(text) RETURNS bool
|
||||
AS '@MODULE_FILENAME@',
|
||||
'pg_cipher_exists' LANGUAGE '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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue