[patch 6/6] regression test updates

Lists: pgsql-patches
From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 0/6] pgcrypto update
Date: 2005-03-19 23:45:51
Message-ID: 20050319234551.726923000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Here are various updates for pgcrypto that
I've been sitting on for some time now.

They should be applied in order, but otherwise
they stand alone - code should in working state
after each one.

Next update is hopefully pgp_encrypt, which I
have already working, only some final polishing
is missing.

--
marko


From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 1/6] remove support for mhash/mcrypt
Date: 2005-03-19 23:45:52
Message-ID: 20050319234646.880944000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Remove support for libmhash/libmcrypt.

libmcrypt seems to dead, maintainer address bounces,
and cast-128 fails on 2 of the 3 test vectors from RFC2144.

So I see no reason to keep around stuff I don't trust
anymore.

Support for several crypto libraries is probably only
confusing to users, although it was good for initial
developing - it helped to find hidden assumptions and
forced me to create regression tests for all functionality.

I'll try to get libgcrypt working, although I'll submit
it only if I find a really good reason for it.

Index: pgsql/contrib/pgcrypto/Makefile
===================================================================
*** pgsql.orig/contrib/pgcrypto/Makefile
--- pgsql/contrib/pgcrypto/Makefile
***************
*** 2,8 ****
# $PostgreSQL: pgsql/contrib/pgcrypto/Makefile,v 1.12 2004/09/14 03:39:48 tgl Exp $
#

! # either 'builtin', 'mhash', 'openssl'
cryptolib = builtin

# either 'builtin', 'system'
--- 2,8 ----
# $PostgreSQL: pgsql/contrib/pgcrypto/Makefile,v 1.12 2004/09/14 03:39:48 tgl Exp $
#

! # either 'builtin', 'openssl'
cryptolib = builtin

# either 'builtin', 'system'
*************** CRYPTO_LDFLAGS = -lcrypto
*** 34,45 ****
SRCS = openssl.c
endif

- ifeq ($(cryptolib), mhash)
- CRYPTO_CFLAGS = -I/usr/local/include
- CRYPTO_LDFLAGS = -L/usr/local/lib -lmcrypt -lmhash -lltdl
- SRCS = mhash.c
- endif
-
ifeq ($(cryptsrc), builtin)
SRCS += crypt-blowfish.c crypt-des.c crypt-md5.c
else
--- 34,39 ----
Index: pgsql/contrib/pgcrypto/README.pgcrypto
===================================================================
*** pgsql.orig/contrib/pgcrypto/README.pgcrypto
--- pgsql/contrib/pgcrypto/README.pgcrypto
*************** OpenSSL (0.9.6):
*** 186,202 ****
Url: http://www.openssl.org/


- mhash (0.8.9) + mcrypt (2.4.16):
- 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
=======

--- 186,191 ----
Index: pgsql/contrib/pgcrypto/mhash.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/mhash.c
--- /dev/null
***************
*** 1,356 ****
- /*
- * mhash.c
- * Wrapper for mhash and mcrypt libraries.
- *
- * Copyright (c) 2001 Marko Kreen
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $PostgreSQL: pgsql/contrib/pgcrypto/mhash.c,v 1.10 2004/05/07 00:24:57 tgl Exp $
- */
-
- #include <postgres.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 unsigned
- digest_result_size(PX_MD * h)
- {
- MHASH mh = (MHASH) h->p.ptr;
- hashid id = mhash_get_mhash_algo(mh);
-
- return mhash_get_block_size(id);
- }
-
- static unsigned
- digest_block_size(PX_MD * h)
- {
- MHASH mh = (MHASH) h->p.ptr;
- hashid id = mhash_get_mhash_algo(mh);
-
- return mhash_get_hash_pblock(id);
- }
-
- 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);
-
- mhash_free(res);
- mh = mhash_init(id);
- h->p.ptr = mh;
- }
-
- static void
- digest_update(PX_MD * h, const uint8 *data, unsigned 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;
- unsigned 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 unsigned
- cipher_block_size(PX_Cipher * c)
- {
- MCRYPT ctx = (MCRYPT) c->ptr;
-
- return mcrypt_enc_get_block_size(ctx);
- }
-
- static unsigned
- cipher_key_size(PX_Cipher * c)
- {
- MCRYPT ctx = (MCRYPT) c->ptr;
-
- return mcrypt_enc_get_key_size(ctx);
- }
-
- static unsigned
- 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, unsigned klen, const uint8 *iv)
- {
- int err;
- MCRYPT ctx = (MCRYPT) c->ptr;
-
- err = mcrypt_generic_init(ctx, (char *) key, klen, (char *) iv);
- if (err < 0)
- ereport(ERROR,
- (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
- errmsg("mcrypt_generic_init error"),
- errdetail("%s", mcrypt_strerror(err))));
-
- c->pstat = 1;
- return 0;
- }
-
- static int
- cipher_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res)
- {
- int err;
- MCRYPT ctx = (MCRYPT) c->ptr;
-
- memcpy(res, data, dlen);
-
- err = mcrypt_generic(ctx, res, dlen);
- if (err < 0)
- ereport(ERROR,
- (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
- errmsg("mcrypt_generic error"),
- errdetail("%s", mcrypt_strerror(err))));
- return 0;
- }
-
- static int
- cipher_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res)
- {
- int err;
- MCRYPT ctx = (MCRYPT) c->ptr;
-
- memcpy(res, data, dlen);
-
- err = mdecrypt_generic(ctx, res, dlen);
- if (err < 0)
- ereport(ERROR,
- (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
- errmsg("mdecrypt_generic error"),
- errdetail("%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,
- b,
- i;
- char *mname;
-
- hnum = mhash_count();
- for (i = 0; i <= hnum; i++)
- {
- mname = mhash_get_hash_name(i);
- if (mname == NULL)
- continue;
- b = pg_strcasecmp(name, mname);
- free(mname);
- if (b == 0)
- {
- res = i;
- break;
- }
- }
-
- 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;
-
- StrNCpy(nbuf, name, sizeof(nbuf));
-
- 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;
- }
--- 0 ----

--


From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 2/6] various cleanups
Date: 2005-03-19 23:45:53
Message-ID: 20050319234647.000674000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

* construct "struct {} list [] = {}" confuses pgindent - split those.
It was a bad style to begin with, and now several loops can be clearer.
* pgcrypto.c: Fix function comments
* crypt-gensalt.c, crypt-blowfish.c: stop messing with errno
* openssl.c: use px_free instead pfree
* px.h: make redefining px_alloc/px_realloc/px_free easier

Index: pgsql/contrib/pgcrypto/openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/openssl.c
--- pgsql/contrib/pgcrypto/openssl.c
*************** gen_ossl_free(PX_Cipher * c)
*** 208,215 ****
ossldata *od = (ossldata *) c->ptr;

memset(od, 0, sizeof(*od));
! pfree(od);
! pfree(c);
}

/* Blowfish */
--- 208,215 ----
ossldata *od = (ossldata *) c->ptr;

memset(od, 0, sizeof(*od));
! px_free(od);
! px_free(c);
}

/* Blowfish */
*************** static const struct ossl_cipher ossl_cas
*** 473,509 ****
/*
* Special handlers
*/
! static const struct
{
const char *name;
const struct ossl_cipher *ciph;
! } ossl_cipher_types[] =

! {
! {
! "bf-cbc", &ossl_bf_cbc
! },
! {
! "bf-ecb", &ossl_bf_ecb
! },
! {
! "bf-cfb", &ossl_bf_cfb
! },
! {
! "des-ecb", &ossl_des_ecb
! },
! {
! "des-cbc", &ossl_des_cbc
! },
! {
! "cast5-ecb", &ossl_cast_ecb
! },
! {
! "cast5-cbc", &ossl_cast_cbc
! },
! {
! NULL
! }
};

/* PUBLIC functions */
--- 473,493 ----
/*
* Special handlers
*/
! struct ossl_cipher_lookup
{
const char *name;
const struct ossl_cipher *ciph;
! };

! static const struct ossl_cipher_lookup ossl_cipher_types[] = {
! {"bf-cbc", &ossl_bf_cbc},
! {"bf-ecb", &ossl_bf_ecb},
! {"bf-cfb", &ossl_bf_cfb},
! {"des-ecb", &ossl_des_ecb},
! {"des-cbc", &ossl_des_cbc},
! {"cast5-ecb", &ossl_cast_ecb},
! {"cast5-cbc", &ossl_cast_cbc},
! {NULL}
};

/* PUBLIC functions */
*************** static const struct
*** 511,548 ****
int
px_find_cipher(const char *name, PX_Cipher ** res)
{
! unsigned i;
! PX_Cipher *c = NULL,
! *csrc;
ossldata *od;
- const struct ossl_cipher *ossl_ciph = NULL;

name = px_resolve_alias(ossl_aliases, name);
! for (i = 0; ossl_cipher_types[i].name; i++)
! {
! if (!strcmp(ossl_cipher_types[i].name, name))
! {
! ossl_ciph = ossl_cipher_types[i].ciph;
break;
! }
! }
! if (ossl_ciph == NULL)
return -1;

od = px_alloc(sizeof(*od));
memset(od, 0, sizeof(*od));
! od->ciph = ossl_ciph;
!
! csrc = NULL;

c = px_alloc(sizeof(*c));
c->block_size = gen_ossl_block_size;
c->key_size = gen_ossl_key_size;
c->iv_size = gen_ossl_iv_size;
c->free = gen_ossl_free;
! c->init = ossl_ciph->init;
! c->encrypt = ossl_ciph->encrypt;
! c->decrypt = ossl_ciph->decrypt;
c->ptr = od;

*res = c;
--- 495,523 ----
int
px_find_cipher(const char *name, PX_Cipher ** res)
{
! const struct ossl_cipher_lookup *i;
! PX_Cipher *c = NULL;
ossldata *od;

name = px_resolve_alias(ossl_aliases, name);
! for (i = ossl_cipher_types; i->name; i++)
! if (!strcmp(i->name, name))
break;
! if (i->name == NULL)
return -1;

od = px_alloc(sizeof(*od));
memset(od, 0, sizeof(*od));
! od->ciph = i->ciph;

c = px_alloc(sizeof(*c));
c->block_size = gen_ossl_block_size;
c->key_size = gen_ossl_key_size;
c->iv_size = gen_ossl_iv_size;
c->free = gen_ossl_free;
! c->init = od->ciph->init;
! c->encrypt = od->ciph->encrypt;
! c->decrypt = od->ciph->decrypt;
c->ptr = od;

*res = c;
Index: pgsql/contrib/pgcrypto/px-crypt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.c
--- pgsql/contrib/pgcrypto/px-crypt.c
*************** run_crypt_bf(const char *psw, const char
*** 69,120 ****
return res;
}

! static struct
{
char *id;
unsigned id_len;
char *(*crypt) (const char *psw, const char *salt,
char *buf, unsigned len);
! } px_crypt_list[] =

! {
! {
! "$2a$", 4, run_crypt_bf
! },
! {
! "$2$", 3, NULL
! }, /* N/A */
! {
! "$1$", 3, run_crypt_md5
! },
! {
! "_", 1, run_crypt_des
! },
! {
! "", 0, run_crypt_des
! },
! {
! NULL, 0, NULL
! }
};

char *
px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
{
! int i;

! for (i = 0; px_crypt_list[i].id; i++)
{
! if (!px_crypt_list[i].id_len)
break;
! if (!strncmp(salt, px_crypt_list[i].id, px_crypt_list[i].id_len))
break;
}

! if (px_crypt_list[i].crypt == NULL)
return NULL;

! return px_crypt_list[i].crypt(psw, salt, buf, len);
}

#else /* PX_SYSTEM_CRYPT */
--- 69,109 ----
return res;
}

! struct px_crypt_algo
{
char *id;
unsigned id_len;
char *(*crypt) (const char *psw, const char *salt,
char *buf, unsigned len);
! };

! static const struct px_crypt_algo
! px_crypt_list[] = {
! {"$2a$", 4, run_crypt_bf},
! {"$2$", 3, NULL}, /* N/A */
! {"$1$", 3, run_crypt_md5},
! {"_", 1, run_crypt_des},
! {"", 0, run_crypt_des},
! {NULL, 0, NULL}
};

char *
px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
{
! const struct px_crypt_algo *c;

! for (c = px_crypt_list; c->id; c++)
{
! if (!c->id_len)
break;
! if (!strncmp(salt, c->id, c->id_len))
break;
}

! if (c->crypt == NULL)
return NULL;

! return c->crypt(psw, salt, buf, len);
}

#else /* PX_SYSTEM_CRYPT */
*************** static struct generator gen_list[] = {
*** 155,161 ****
{"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
{"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
{"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
! {NULL, NULL, 0, 0, 0}
};

unsigned
--- 144,150 ----
{"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
{"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
{"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
! {NULL, NULL, 0, 0, 0, 0}
};

unsigned
Index: pgsql/contrib/pgcrypto/internal.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/internal.c
--- pgsql/contrib/pgcrypto/internal.c
***************
*** 57,78 ****
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 */
--- 57,73 ----
static void init_md5(PX_MD * h);
static void init_sha1(PX_MD * h);

! struct int_digest
{
char *name;
void (*init) (PX_MD * h);
! };

! static const struct int_digest
! int_digest_list[] = {
! { "md5", init_md5 },
! { "sha1", init_sha1 },
! { NULL, NULL }
};

/* MD5 */
*************** bf_cbc_load(void)
*** 516,546 ****
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"},
--- 511,532 ----
return bf_load(MODE_CBC);
}

! struct int_cipher
{
char *name;
PX_Cipher *(*load) (void);
! };

! static const struct int_cipher
! 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 const PX_Alias int_aliases[] = {
{"bf", "bf-cbc"},
{"blowfish", "bf-cbc"},
{"aes", "aes-128-cbc"},
*************** static PX_Alias int_aliases[] = {
*** 557,563 ****
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++)
--- 543,549 ----
int
px_find_digest(const char *name, PX_MD ** res)
{
! const struct int_digest *p;
PX_MD *h;

for (p = int_digest_list; p->name; p++)
Index: pgsql/contrib/pgcrypto/pgcrypto.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgcrypto.c
--- pgsql/contrib/pgcrypto/pgcrypto.c
*************** typedef int (*PFN) (const char *name, vo
*** 46,52 ****
static void *
find_provider(text *name, PFN pf, char *desc, int silent);

! /* SQL function: hash(text, text) returns text */
PG_FUNCTION_INFO_V1(pg_digest);

Datum
--- 46,52 ----
static void *
find_provider(text *name, PFN pf, char *desc, int silent);

! /* SQL function: hash(bytea, text) returns bytea */
PG_FUNCTION_INFO_V1(pg_digest);

Datum
*************** pg_digest_exists(PG_FUNCTION_ARGS)
*** 111,117 ****
PG_RETURN_BOOL(true);
}

! /* SQL function: hmac(data:text, key:text, type:text) */
PG_FUNCTION_INFO_V1(pg_hmac);

Datum
--- 111,117 ----
PG_RETURN_BOOL(true);
}

! /* SQL function: hmac(data:bytea, key:bytea, type:text) returns bytea */
PG_FUNCTION_INFO_V1(pg_hmac);

Datum
*************** pg_crypt(PG_FUNCTION_ARGS)
*** 316,322 ****
PG_RETURN_TEXT_P(res);
}

! /* SQL function: pg_encrypt(text, text, text) returns text */
PG_FUNCTION_INFO_V1(pg_encrypt);

Datum
--- 316,322 ----
PG_RETURN_TEXT_P(res);
}

! /* SQL function: pg_encrypt(bytea, bytea, text) returns bytea */
PG_FUNCTION_INFO_V1(pg_encrypt);

Datum
*************** pg_encrypt(PG_FUNCTION_ARGS)
*** 367,373 ****
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_decrypt(text, text, text) returns text */
PG_FUNCTION_INFO_V1(pg_decrypt);

Datum
--- 367,373 ----
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_decrypt(bytea, bytea, text) returns bytea */
PG_FUNCTION_INFO_V1(pg_decrypt);

Datum
*************** pg_decrypt(PG_FUNCTION_ARGS)
*** 417,423 ****
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_encrypt(text, text, text) returns text */
PG_FUNCTION_INFO_V1(pg_encrypt_iv);

Datum
--- 417,423 ----
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_encrypt_iv(bytea, bytea, bytea, text) returns bytea */
PG_FUNCTION_INFO_V1(pg_encrypt_iv);

Datum
*************** pg_encrypt_iv(PG_FUNCTION_ARGS)
*** 473,479 ****
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_decrypt_iv(text, text, text) returns text */
PG_FUNCTION_INFO_V1(pg_decrypt_iv);

Datum
--- 473,479 ----
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_decrypt_iv(bytea, bytea, bytea, text) returns bytea */
PG_FUNCTION_INFO_V1(pg_decrypt_iv);

Datum
*************** pg_decrypt_iv(PG_FUNCTION_ARGS)
*** 529,535 ****
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_decrypt(text, text, text) returns text */
PG_FUNCTION_INFO_V1(pg_cipher_exists);

Datum
--- 529,535 ----
PG_RETURN_BYTEA_P(res);
}

! /* SQL function: pg_cipher_exists(text) returns bool */
PG_FUNCTION_INFO_V1(pg_cipher_exists);

Datum
*************** pg_cipher_exists(PG_FUNCTION_ARGS)
*** 550,556 ****
PG_RETURN_BOOL((c != NULL) ? true : false);
}

-
static void *
find_provider(text *name,
PFN provider_lookup,
--- 550,555 ----
Index: pgsql/contrib/pgcrypto/crypt-blowfish.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/crypt-blowfish.c
--- pgsql/contrib/pgcrypto/crypt-blowfish.c
***************
*** 35,46 ****
#include "px.h"
#include "px-crypt.h"

- #define __set_errno(v)
-
- #ifndef __set_errno
- #define __set_errno(val) errno = (val)
- #endif
-
#ifdef __i386__
#define BF_ASM 0 /* 1 */
#define BF_SCALE 1
--- 35,40 ----
*************** _crypt_blowfish_rn(const char *key, cons
*** 600,609 ****
int i;

if (size < 7 + 22 + 31 + 1)
- {
- __set_errno(ERANGE);
return NULL;
- }

if (setting[0] != '$' ||
setting[1] != '2' ||
--- 594,600 ----
*************** _crypt_blowfish_rn(const char *key, cons
*** 613,619 ****
setting[5] < '0' || setting[5] > '9' ||
setting[6] != '$')
{
- __set_errno(EINVAL);
return NULL;
}

--- 604,609 ----
*************** _crypt_blowfish_rn(const char *key, cons
*** 621,627 ****
if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
{
memset(data.binary.salt, 0, sizeof(data.binary.salt));
- __set_errno(EINVAL);
return NULL;
}
BF_swap(data.binary.salt, 4);
--- 611,616 ----
Index: pgsql/contrib/pgcrypto/crypt-gensalt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/crypt-gensalt.c
--- pgsql/contrib/pgcrypto/crypt-gensalt.c
***************
*** 15,25 ****
#include "px.h"
#include "px-crypt.h"

- #include <errno.h>
- #ifndef __set_errno
- #define __set_errno(val) (errno = (val))
- #endif
-
typedef unsigned int BF_word;

unsigned char _crypt_itoa64[64 + 1] =
--- 15,20 ----
*************** _crypt_gensalt_traditional_rn(unsigned l
*** 33,39 ****
{
if (output_size > 0)
output[0] = '\0';
- __set_errno((output_size < 2 + 1) ? ERANGE : EINVAL);
return NULL;
}

--- 28,33 ----
*************** _crypt_gensalt_extended_rn(unsigned long
*** 57,63 ****
{
if (output_size > 0)
output[0] = '\0';
- __set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL);
return NULL;
}

--- 51,56 ----
*************** _crypt_gensalt_md5_rn(unsigned long coun
*** 91,97 ****
{
if (output_size > 0)
output[0] = '\0';
- __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL);
return NULL;
}

--- 84,89 ----
*************** _crypt_gensalt_blowfish_rn(unsigned long
*** 173,179 ****
{
if (output_size > 0)
output[0] = '\0';
- __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
return NULL;
}

--- 165,170 ----
Index: pgsql/contrib/pgcrypto/px.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.h
--- pgsql/contrib/pgcrypto/px.h
***************
*** 43,63 ****
#endif


! #if 1

#define px_alloc(s) palloc(s)
! #define px_realloc(p, s) prealloc(p, s)
#define px_free(p) pfree(p)

#else

! void *xalloc(size_t s);
! void *xrealloc(void *p, size_t s);
! void xfree(void *p);
!
! #define px_alloc(s) xalloc(s)
! #define px_realloc(p, s) xrealloc(p, s)
! #define px_free(p) xfree(p)
#endif

/* max len of 'type' parms */
--- 43,60 ----
#endif


! #ifndef PX_OWN_ALLOC

#define px_alloc(s) palloc(s)
! #define px_realloc(p, s) repalloc(p, s)
#define px_free(p) pfree(p)

#else

! void *px_alloc(size_t s);
! void *px_realloc(void *p, size_t s);
! void px_free(void *p);
!
#endif

/* max len of 'type' parms */

--


From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 3/6] better error handling
Date: 2005-03-19 23:45:54
Message-ID: 20050319234647.126944000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

* Use error codes instead of -1
* px_strerror for new error codes
* calling convention change for px_gen_salt - return error code
* use px_strerror in pgcrypto.c

Index: pgsql/contrib/pgcrypto/px.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.c
--- pgsql/contrib/pgcrypto/px.c
***************
*** 33,38 ****
--- 33,73 ----

#include "px.h"

+ struct error_desc {
+ int err;
+ const char *desc;
+ };
+
+ static const struct error_desc px_err_list[] = {
+ {PXE_OK, "Everything ok"},
+ {PXE_ERR_GENERIC, "Some PX error (not specified)"},
+ {PXE_NO_HASH, "No such hash algorithm"},
+ {PXE_NO_CIPHER, "No such cipher algorithm"},
+ {PXE_NOTBLOCKSIZE, "Data not a multiple of block size"},
+ {PXE_BAD_OPTION, "Unknown option"},
+ {PXE_BAD_FORMAT, "Badly formatted type"},
+ {PXE_KEY_TOO_BIG, "Key was too big"},
+ {PXE_CIPHER_INIT, "Cipher cannot be initalized ?"},
+ {PXE_HASH_UNUSABLE_FOR_HMAC, "This hash algorithm is unusable for HMAC"},
+ {PXE_DEV_READ_ERROR, "Error reading from random device"},
+ {PXE_OSSL_RAND_ERROR, "OpenSSL PRNG error"},
+ {PXE_BUG, "pgcrypto bug"},
+ {PXE_ARGUMENT_ERROR, "Illegal argument to function"},
+ {PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"},
+ {PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"},
+ {PXE_MCRYPT_INTERNAL, "mcrypt internal error"},
+ {0, NULL},
+ };
+
+ const char *px_strerror(int err)
+ {
+ const struct error_desc *e;
+ for (e = px_err_list; e->desc; e++)
+ if (e->err == err)
+ return e->desc;
+ return "Bad error code";
+ }
+

const char *
px_resolve_alias(const PX_Alias * list, const char *name)
*************** combo_decrypt(PX_Combo * cx, const uint8
*** 215,224 ****

return 0;

- /* error reporting should be done in pgcrypto.c */
block_error:
! elog(WARNING, "Data not a multiple of block size");
! return -1;
}

static void
--- 250,257 ----

return 0;

block_error:
! return PXE_NOTBLOCKSIZE;
}

static void
*************** parse_cipher_name(char *full, char **cip
*** 262,271 ****
if (!strcmp(p, "pad"))
*pad = p2;
else
! return -1;
}
else
! return -1;

p = q;
}
--- 295,304 ----
if (!strcmp(p, "pad"))
*pad = p2;
else
! return PXE_BAD_OPTION;
}
else
! return PXE_BAD_FORMAT;

p = q;
}
*************** err1:
*** 332,336 ****
px_cipher_free(cx->cipher);
px_free(cx);
px_free(buf);
! return -1;
}
--- 365,369 ----
px_cipher_free(cx->cipher);
px_free(cx);
px_free(buf);
! return PXE_NO_CIPHER;
}
Index: pgsql/contrib/pgcrypto/px.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.h
--- pgsql/contrib/pgcrypto/px.h
*************** void px_free(void *p);
*** 63,68 ****
--- 63,88 ----
/* max salt returned */
#define PX_MAX_SALT_LEN 128

+ /*
+ * PX error codes
+ */
+ #define PXE_OK 0
+ #define PXE_ERR_GENERIC -1
+ #define PXE_NO_HASH -2
+ #define PXE_NO_CIPHER -3
+ #define PXE_NOTBLOCKSIZE -4
+ #define PXE_BAD_OPTION -5
+ #define PXE_BAD_FORMAT -6
+ #define PXE_KEY_TOO_BIG -7
+ #define PXE_CIPHER_INIT -8
+ #define PXE_HASH_UNUSABLE_FOR_HMAC -9
+ #define PXE_DEV_READ_ERROR -10
+ #define PXE_OSSL_RAND_ERROR -11
+ #define PXE_BUG -12
+ #define PXE_ARGUMENT_ERROR -13
+ #define PXE_UNKNOWN_SALT_ALGO -14
+ #define PXE_BAD_SALT_ROUNDS -15
+ #define PXE_MCRYPT_INTERNAL -16

typedef struct px_digest PX_MD;
typedef struct px_alias PX_Alias;
*************** int px_find_combo(const char *name, PX
*** 149,154 ****
--- 169,176 ----

int px_get_random_bytes(uint8 *dst, unsigned count);

+ const char *px_strerror(int err);
+
const char *px_resolve_alias(const PX_Alias * aliases, const char *name);

#define px_md_result_size(md) (md)->result_size(md)
Index: pgsql/contrib/pgcrypto/internal.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/internal.c
--- pgsql/contrib/pgcrypto/internal.c
*************** rj_init(PX_Cipher * c, const uint8 *key,
*** 275,281 ****
else if (klen <= 256 / 8)
cx->keylen = 256 / 8;
else
! return -1;

memcpy(&cx->keybuf, key, klen);

--- 275,281 ----
else if (klen <= 256 / 8)
cx->keylen = 256 / 8;
else
! return PXE_KEY_TOO_BIG;

memcpy(&cx->keybuf, key, klen);

*************** rj_encrypt(PX_Cipher * c, const uint8 *d
*** 300,313 ****
if (!cx->is_init)
{
if (rj_real_init(cx, 1))
! return -1;
}

if (dlen == 0)
return 0;

if (dlen & 15)
! return -1;

memcpy(res, data, dlen);

--- 300,313 ----
if (!cx->is_init)
{
if (rj_real_init(cx, 1))
! return PXE_CIPHER_INIT;
}

if (dlen == 0)
return 0;

if (dlen & 15)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);

*************** rj_decrypt(PX_Cipher * c, const uint8 *d
*** 329,341 ****

if (!cx->is_init)
if (rj_real_init(cx, 0))
! return -1;

if (dlen == 0)
return 0;

if (dlen & 15)
! return -1;

memcpy(res, data, dlen);

--- 329,341 ----

if (!cx->is_init)
if (rj_real_init(cx, 0))
! return PXE_CIPHER_INIT;

if (dlen == 0)
return 0;

if (dlen & 15)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);

*************** bf_encrypt(PX_Cipher * c, const uint8 *d
*** 422,428 ****
return 0;

if (dlen & 7)
! return -1;

memcpy(res, data, dlen);
switch (cx->mode)
--- 422,428 ----
return 0;

if (dlen & 7)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);
switch (cx->mode)
*************** bf_decrypt(PX_Cipher * c, const uint8 *d
*** 446,452 ****
return 0;

if (dlen & 7)
! return -1;

memcpy(res, data, dlen);
switch (cx->mode)
--- 446,452 ----
return 0;

if (dlen & 7)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);
switch (cx->mode)
*************** px_find_digest(const char *name, PX_MD *
*** 556,562 ****

return 0;
}
! return -1;
}

int
--- 556,562 ----

return 0;
}
! return PXE_NO_HASH;
}

int
*************** px_find_cipher(const char *name, PX_Ciph
*** 575,581 ****
}

if (c == NULL)
! return -1;

*res = c;
return 0;
--- 575,581 ----
}

if (c == NULL)
! return PXE_NO_CIPHER;

*res = c;
return 0;
Index: pgsql/contrib/pgcrypto/openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/openssl.c
--- pgsql/contrib/pgcrypto/openssl.c
*************** px_find_digest(const char *name, PX_MD *
*** 112,118 ****

md = EVP_get_digestbyname(name);
if (md == NULL)
! return -1;

ctx = px_alloc(sizeof(*ctx));
EVP_DigestInit(ctx, md);
--- 112,118 ----

md = EVP_get_digestbyname(name);
if (md == NULL)
! return PXE_NO_HASH;

ctx = px_alloc(sizeof(*ctx));
EVP_DigestInit(ctx, md);
*************** px_find_cipher(const char *name, PX_Ciph
*** 504,510 ****
if (!strcmp(i->name, name))
break;
if (i->name == NULL)
! return -1;

od = px_alloc(sizeof(*od));
memset(od, 0, sizeof(*od));
--- 504,510 ----
if (!strcmp(i->name, name))
break;
if (i->name == NULL)
! return PXE_NO_CIPHER;

od = px_alloc(sizeof(*od));
memset(od, 0, sizeof(*od));
Index: pgsql/contrib/pgcrypto/px-hmac.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-hmac.c
--- pgsql/contrib/pgcrypto/px-hmac.c
*************** px_find_hmac(const char *name, PX_HMAC *
*** 158,164 ****
if (bs < 2)
{
px_md_free(md);
! return -1;
}

h = px_alloc(sizeof(*h));
--- 158,164 ----
if (bs < 2)
{
px_md_free(md);
! return PXE_HASH_UNUSABLE_FOR_HMAC;
}

h = px_alloc(sizeof(*h));
Index: pgsql/contrib/pgcrypto/random.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/random.c
--- pgsql/contrib/pgcrypto/random.c
*************** safe_read(int fd, void *buf, size_t coun
*** 55,61 ****
{
if (errno == EINTR)
continue;
! return -1;
}
p += res;
done += res;
--- 55,61 ----
{
if (errno == EINTR)
continue;
! return PXE_DEV_READ_ERROR;
}
p += res;
done += res;
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 72,78 ****

fd = open(RAND_DEV, O_RDONLY);
if (fd == -1)
! return -1;
res = safe_read(fd, dst, count);
close(fd);
return res;
--- 72,78 ----

fd = open(RAND_DEV, O_RDONLY);
if (fd == -1)
! return PXE_DEV_READ_ERROR;
res = safe_read(fd, dst, count);
close(fd);
return res;
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 117,126 ****
*/

res = RAND_bytes(dst, count);
! if (res > 0)
return count;

! return -1;
}

#else
--- 117,126 ----
*/

res = RAND_bytes(dst, count);
! if (res == 1)
return count;

! return PXE_OSSL_RAND_ERROR;
}

#else
Index: pgsql/contrib/pgcrypto/px-crypt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.c
--- pgsql/contrib/pgcrypto/px-crypt.c
*************** static struct generator gen_list[] = {
*** 147,185 ****
{NULL, NULL, 0, 0, 0, 0}
};

! unsigned
px_gen_salt(const char *salt_type, char *buf, int rounds)
{
! int i,
! res;
struct generator *g;
char *p;
char rbuf[16];

! for (i = 0; gen_list[i].name; i++)
! {
! g = &gen_list[i];
! if (pg_strcasecmp(g->name, salt_type) != 0)
! continue;
!
! if (g->def_rounds)
! {
! if (rounds == 0)
! rounds = g->def_rounds;
!
! if (rounds < g->min_rounds || rounds > g->max_rounds)
! return 0;
! }
!
! res = px_get_random_bytes(rbuf, g->input_len);
! if (res != g->input_len)
! return 0;

! p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
! memset(rbuf, 0, sizeof(rbuf));

! return p != NULL ? strlen(p) : 0;
}

! return 0;
}
--- 147,186 ----
{NULL, NULL, 0, 0, 0, 0}
};

! int
px_gen_salt(const char *salt_type, char *buf, int rounds)
{
! int res;
struct generator *g;
char *p;
char rbuf[16];

! for (g = gen_list; g->name; g++)
! if (pg_strcasecmp(g->name, salt_type) == 0)
! break;
!
! if (g->name == NULL)
! return PXE_UNKNOWN_SALT_ALGO;

! if (g->def_rounds)
! {
! if (rounds == 0)
! rounds = g->def_rounds;

! if (rounds < g->min_rounds || rounds > g->max_rounds)
! return PXE_BAD_SALT_ROUNDS;
}

! res = px_get_random_bytes(rbuf, g->input_len);
! if (res < 0)
! return res;
!
! p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
! memset(rbuf, 0, sizeof(rbuf));
!
! if (p == NULL)
! return PXE_BAD_SALT_ROUNDS;
!
! return strlen(p);
}
+
Index: pgsql/contrib/pgcrypto/px-crypt.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.h
--- pgsql/contrib/pgcrypto/px-crypt.h
***************
*** 49,55 ****
* main interface
*/
char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen);
! unsigned px_gen_salt(const char *salt_type, char *dst, int rounds);

/*
* internal functions
--- 49,55 ----
* main interface
*/
char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen);
! int px_gen_salt(const char *salt_type, char *dst, int rounds);

/*
* internal functions
Index: pgsql/contrib/pgcrypto/pgcrypto.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgcrypto.c
--- pgsql/contrib/pgcrypto/pgcrypto.c
*************** Datum
*** 190,196 ****
pg_gen_salt(PG_FUNCTION_ARGS)
{
text *arg0;
! unsigned len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

--- 190,196 ----
pg_gen_salt(PG_FUNCTION_ARGS)
{
text *arg0;
! int len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

*************** pg_gen_salt(PG_FUNCTION_ARGS)
*** 204,213 ****
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, 0);
! if (len == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("no such crypt algorithm")));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
--- 204,213 ----
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, 0);
! if (len < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("gen_salt: %s", px_strerror(len))));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
*************** pg_gen_salt_rounds(PG_FUNCTION_ARGS)
*** 226,232 ****
{
text *arg0;
int rounds;
! unsigned len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

--- 226,232 ----
{
text *arg0;
int rounds;
! int len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

*************** pg_gen_salt_rounds(PG_FUNCTION_ARGS)
*** 241,250 ****
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, rounds);
! if (len == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("no such crypt algorithm or bad number of rounds")));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
--- 241,250 ----
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, rounds);
! if (len < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("gen_salt: %s", px_strerror(len))));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
*************** pg_encrypt(PG_FUNCTION_ARGS)
*** 360,366 ****
pfree(res);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt error: %d", err)));
}

VARATT_SIZEP(res) = VARHDRSZ + rlen;
--- 360,366 ----
pfree(res);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt error: %s", px_strerror(err))));
}

VARATT_SIZEP(res) = VARHDRSZ + rlen;
*************** pg_decrypt(PG_FUNCTION_ARGS)
*** 406,412 ****
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt error: %d", err)));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

--- 406,412 ----
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt error: %s", px_strerror(err))));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

*************** pg_encrypt_iv(PG_FUNCTION_ARGS)
*** 461,467 ****
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt_iv error: %d", err)));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

--- 461,467 ----
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt_iv error: %s", px_strerror(err))));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

*************** pg_decrypt_iv(PG_FUNCTION_ARGS)
*** 517,523 ****
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt_iv error: %d", err)));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

--- 517,523 ----
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt_iv error: %s", px_strerror(err))));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

*************** find_provider(text *name,
*** 568,574 ****
if (err && !silent)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("%s type does not exist: \"%s\"", desc, buf)));

pfree(buf);

--- 568,574 ----
if (err && !silent)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("Cannot use \"%s\": %s", buf, px_strerror(err))));

pfree(buf);

--


From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 4/6] openssl.c: 3DES and AES support
Date: 2005-03-19 23:45:55
Message-ID: 20050319234647.244194000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

* openssl.c: Add 3des and AES support
* README.pgcrypto: list only supported ciphers for openssl

OpenSSL has pre-processor symbol OPENSSL_NO_AES, which
isn't that helpful for detecting if it _does_ exist.
Thus the hack with AES_ENCRYPT.

Index: pgsql/contrib/pgcrypto/openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/openssl.c
--- pgsql/contrib/pgcrypto/openssl.c
***************
*** 36,41 ****
--- 36,49 ----
#include <openssl/evp.h>

/*
+ * Is OpenSSL compiled with AES?
+ */
+ #undef GOT_AES
+ #ifdef AES_ENCRYPT
+ #define GOT_AES
+ #endif
+
+ /*
* Hashes
*/
static unsigned
*************** typedef struct
*** 165,171 ****
--- 173,186 ----
{
des_key_schedule key_schedule;
} des;
+ struct
+ {
+ des_key_schedule k1, k2, k3;
+ } des3;
CAST_KEY cast_key;
+ #ifdef GOT_AES
+ AES_KEY aes_key;
+ #endif
} u;
uint8 key[EVP_MAX_KEY_LENGTH];
uint8 iv[EVP_MAX_IV_LENGTH];
*************** ossl_des_cbc_decrypt(PX_Cipher * c, cons
*** 362,367 ****
--- 377,467 ----
return 0;
}

+ /* DES3 */
+
+ static int
+ ossl_des3_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
+ {
+ ossldata *od = c->ptr;
+ des_cblock xkey1,
+ xkey2,
+ xkey3;
+
+ memset(&xkey1, 0, sizeof(xkey1));
+ memset(&xkey2, 0, sizeof(xkey2));
+ memset(&xkey2, 0, sizeof(xkey2));
+ memcpy(&xkey1, key, klen > 8 ? 8 : klen);
+ if (klen > 8)
+ memcpy(&xkey2, key + 8, (klen - 8) > 8 ? 8 : (klen - 8));
+ if (klen > 16)
+ memcpy(&xkey3, key + 16, (klen - 16) > 8 ? 8 : (klen - 16));
+
+ DES_set_key(&xkey1, &od->u.des3.k1);
+ DES_set_key(&xkey2, &od->u.des3.k2);
+ DES_set_key(&xkey3, &od->u.des3.k3);
+ memset(&xkey1, 0, sizeof(xkey1));
+ memset(&xkey2, 0, sizeof(xkey2));
+ memset(&xkey3, 0, sizeof(xkey3));
+
+ if (iv)
+ memcpy(od->iv, iv, 8);
+ else
+ memset(od->iv, 0, 8);
+ return 0;
+ }
+
+ static int
+ ossl_des3_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ unsigned bs = gen_ossl_block_size(c);
+ unsigned i;
+ ossldata *od = c->ptr;
+
+ for (i = 0; i < dlen / bs; i++)
+ DES_ecb3_encrypt(data + i * bs, res + i * bs,
+ &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 1);
+ return 0;
+ }
+
+ static int
+ ossl_des3_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ unsigned bs = gen_ossl_block_size(c);
+ unsigned i;
+ ossldata *od = c->ptr;
+
+ for (i = 0; i < dlen / bs; i++)
+ DES_ecb3_encrypt(data + i * bs, res + i * bs,
+ &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 0);
+ return 0;
+ }
+
+ static int
+ ossl_des3_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ ossldata *od = c->ptr;
+
+ DES_ede3_cbc_encrypt(data, res, dlen,
+ &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
+ (des_cblock *) od->iv, 1);
+ return 0;
+ }
+
+ static int
+ ossl_des3_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ ossldata *od = c->ptr;
+
+ DES_ede3_cbc_encrypt(data, res, dlen,
+ &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
+ (des_cblock *) od->iv, 0);
+ return 0;
+ }
+
/* CAST5 */

static int
*************** ossl_cast_cbc_decrypt(PX_Cipher * c, con
*** 420,425 ****
--- 520,622 ----
return 0;
}

+ /* AES */
+
+ #ifdef GOT_AES
+
+ static int
+ ossl_aes_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
+ {
+ ossldata *od = c->ptr;
+ unsigned bs = gen_ossl_block_size(c);
+
+ if (klen <= 128/8)
+ od->klen = 128/8;
+ else if (klen <= 192/8)
+ od->klen = 192/8;
+ else if (klen <= 256/8)
+ od->klen = 256/8;
+ else
+ return PXE_KEY_TOO_BIG;
+
+ memcpy(od->key, key, klen);
+
+ if (iv)
+ memcpy(od->iv, iv, bs);
+ else
+ memset(od->iv, 0, bs);
+ return 0;
+ }
+
+ static void
+ ossl_aes_key_init(ossldata * od, int type)
+ {
+ if (type == AES_ENCRYPT)
+ AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key);
+ else
+ AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key);
+ od->init = 1;
+ }
+
+ static int
+ ossl_aes_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ unsigned bs = gen_ossl_block_size(c);
+ ossldata *od = c->ptr;
+ const uint8 *end = data + dlen - bs;
+
+ if (!od->init)
+ ossl_aes_key_init(od, AES_ENCRYPT);
+
+ for (; data <= end; data += bs, res += bs)
+ AES_ecb_encrypt(data, res, &od->u.aes_key, AES_ENCRYPT);
+ return 0;
+ }
+
+ static int
+ ossl_aes_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ unsigned bs = gen_ossl_block_size(c);
+ ossldata *od = c->ptr;
+ const uint8 *end = data + dlen - bs;
+
+ if (!od->init)
+ ossl_aes_key_init(od, AES_DECRYPT);
+
+ for (; data <= end; data += bs, res += bs)
+ AES_ecb_encrypt(data, res, &od->u.aes_key, AES_DECRYPT);
+ return 0;
+ }
+
+ static int
+ ossl_aes_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ ossldata *od = c->ptr;
+
+ if (!od->init)
+ ossl_aes_key_init(od, AES_ENCRYPT);
+
+ AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_ENCRYPT);
+ return 0;
+ }
+
+ static int
+ ossl_aes_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ uint8 *res)
+ {
+ ossldata *od = c->ptr;
+
+ if (!od->init)
+ ossl_aes_key_init(od, AES_DECRYPT);
+
+ AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT);
+ return 0;
+ }
+ #endif
+
/*
* aliases
*/
*************** static PX_Alias ossl_aliases[] = {
*** 431,437 ****
--- 628,641 ----
{"blowfish-ecb", "bf-ecb"},
{"blowfish-cfb", "bf-cfb"},
{"des", "des-cbc"},
+ {"3des", "des3-cbc"},
+ {"3des-ecb", "des3-ecb"},
+ {"3des-cbc", "des3-cbc"},
{"cast5", "cast5-cbc"},
+ {"aes", "aes-cbc"},
+ {"rijndael", "aes-cbc"},
+ {"rijndael-cbc", "aes-cbc"},
+ {"rijndael-ecb", "aes-ecb"},
{NULL}
};

*************** static const struct ossl_cipher ossl_des
*** 460,465 ****
--- 664,679 ----
64 / 8, 64 / 8, 0
};

+ static const struct ossl_cipher ossl_des3_ecb = {
+ ossl_des3_init, ossl_des3_ecb_encrypt, ossl_des3_ecb_decrypt,
+ 64 / 8, 192 / 8, 0
+ };
+
+ static const struct ossl_cipher ossl_des3_cbc = {
+ ossl_des3_init, ossl_des3_cbc_encrypt, ossl_des3_cbc_decrypt,
+ 64 / 8, 192 / 8, 0
+ };
+
static const struct ossl_cipher ossl_cast_ecb = {
ossl_cast_init, ossl_cast_ecb_encrypt, ossl_cast_ecb_decrypt,
64 / 8, 128 / 8, 0
*************** static const struct ossl_cipher ossl_cas
*** 470,475 ****
--- 684,701 ----
64 / 8, 128 / 8, 0
};

+ #ifdef GOT_AES
+ static const struct ossl_cipher ossl_aes_ecb = {
+ ossl_aes_init, ossl_aes_ecb_encrypt, ossl_aes_ecb_decrypt,
+ 128 / 8, 256 / 8, 0
+ };
+
+ static const struct ossl_cipher ossl_aes_cbc = {
+ ossl_aes_init, ossl_aes_cbc_encrypt, ossl_aes_cbc_decrypt,
+ 128 / 8, 256 / 8, 0
+ };
+ #endif
+
/*
* Special handlers
*/
*************** static const struct ossl_cipher_lookup o
*** 485,492 ****
--- 711,724 ----
{"bf-cfb", &ossl_bf_cfb},
{"des-ecb", &ossl_des_ecb},
{"des-cbc", &ossl_des_cbc},
+ {"des3-ecb", &ossl_des3_ecb},
+ {"des3-cbc", &ossl_des3_cbc},
{"cast5-ecb", &ossl_cast_ecb},
{"cast5-cbc", &ossl_cast_cbc},
+ #ifdef GOT_AES
+ {"aes-ecb", &ossl_aes_ecb},
+ {"aes-cbc", &ossl_aes_cbc},
+ #endif
{NULL}
};

Index: pgsql/contrib/pgcrypto/README.pgcrypto
===================================================================
*** pgsql.orig/contrib/pgcrypto/README.pgcrypto
--- pgsql/contrib/pgcrypto/README.pgcrypto
*************** internal (default):
*** 178,187 ****
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/

--- 178,186 ----
Ciphers: Blowfish, Rijndael-128


! OpenSSL (0.9.7):
Hashes: MD5, SHA1, RIPEMD160, MD2
! Ciphers: Blowfish, AES, CAST5, DES, 3DES
License: BSD-like with strong advertisement
Url: http://www.openssl.org/

--


From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 5/6] pseudo random bytes
Date: 2005-03-19 23:45:56
Message-ID: 20050319234647.361618000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Reserve px_get_random_bytes() for strong randomness,
add new function px_get_pseudo_random_bytes() for
weak randomness and use it in gen_salt().

On openssl case, use RAND_pseudo_bytes() for
px_get_pseudo_random_bytes().

Final result is that is user has not configured random
souce but kept the 'silly' one, gen_salt() keeps
working, but pgp_encrypt() will throw error.

Index: pgsql/contrib/pgcrypto/px-crypt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.c
--- pgsql/contrib/pgcrypto/px-crypt.c
*************** px_gen_salt(const char *salt_type, char
*** 171,177 ****
return PXE_BAD_SALT_ROUNDS;
}

! res = px_get_random_bytes(rbuf, g->input_len);
if (res < 0)
return res;

--- 171,177 ----
return PXE_BAD_SALT_ROUNDS;
}

! res = px_get_pseudo_random_bytes(rbuf, g->input_len);
if (res < 0)
return res;

Index: pgsql/contrib/pgcrypto/px.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.h
--- pgsql/contrib/pgcrypto/px.h
*************** void px_free(void *p);
*** 83,88 ****
--- 83,89 ----
#define PXE_UNKNOWN_SALT_ALGO -14
#define PXE_BAD_SALT_ROUNDS -15
#define PXE_MCRYPT_INTERNAL -16
+ #define PXE_NO_RANDOM -17

typedef struct px_digest PX_MD;
typedef struct px_alias PX_Alias;
*************** int px_find_cipher(const char *name, P
*** 168,173 ****
--- 169,175 ----
int px_find_combo(const char *name, PX_Combo ** res);

int px_get_random_bytes(uint8 *dst, unsigned count);
+ int px_get_pseudo_random_bytes(uint8 *dst, unsigned count);

const char *px_strerror(int err);

Index: pgsql/contrib/pgcrypto/random.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/random.c
--- pgsql/contrib/pgcrypto/random.c
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 78,87 ****
return res;
}

#elif defined(RAND_SILLY)

int
! px_get_random_bytes(uint8 *dst, unsigned count)
{
int i;

--- 78,93 ----
return res;
}

+ int
+ px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
+ {
+ return px_get_random_bytes(dst, count);
+ }
+
#elif defined(RAND_SILLY)

int
! px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
{
int i;

*************** px_get_random_bytes(uint8 *dst, unsigned
*** 90,95 ****
--- 96,107 ----
return i;
}

+ int
+ px_get_random_bytes(uint8 *dst, unsigned count)
+ {
+ return PXE_NO_RANDOM;
+ }
+
#elif defined(RAND_OPENSSL)

#include <openssl/evp.h>
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 99,120 ****

static int openssl_random_init = 0;

int
px_get_random_bytes(uint8 *dst, unsigned count)
{
int res;

if (!openssl_random_init)
! {
! if (RAND_get_rand_method() == NULL)
! RAND_set_rand_method(RAND_SSLeay());
! openssl_random_init = 1;
! }
!
! /*
! * OpenSSL random should re-feeded occasionally. From /dev/urandom
! * preferably.
! */

res = RAND_bytes(dst, count);
if (res == 1)
--- 111,134 ----

static int openssl_random_init = 0;

+ /*
+ * OpenSSL random should re-feeded occasionally. From /dev/urandom
+ * preferably.
+ */
+ static void init_openssl()
+ {
+ if (RAND_get_rand_method() == NULL)
+ RAND_set_rand_method(RAND_SSLeay());
+ openssl_random_init = 1;
+ }
+
int
px_get_random_bytes(uint8 *dst, unsigned count)
{
int res;

if (!openssl_random_init)
! init_openssl();

res = RAND_bytes(dst, count);
if (res == 1)
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 123,128 ****
--- 137,157 ----
return PXE_OSSL_RAND_ERROR;
}

+ int
+ px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
+ {
+ int res;
+
+ if (!openssl_random_init)
+ init_openssl();
+
+ res = RAND_pseudo_bytes(dst, count);
+ if (res == 0 || res == 1)
+ return count;
+
+ return PXE_OSSL_RAND_ERROR;
+ }
+
#else
#error "Invalid random source"
#endif
Index: pgsql/contrib/pgcrypto/px.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.c
--- pgsql/contrib/pgcrypto/px.c
*************** static const struct error_desc px_err_li
*** 56,61 ****
--- 56,62 ----
{PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"},
{PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"},
{PXE_MCRYPT_INTERNAL, "mcrypt internal error"},
+ {PXE_NO_RANDOM, "No strong random source"},
{0, NULL},
};

--


From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 6/6] regression test updates
Date: 2005-03-19 23:45:57
Message-ID: 20050319234647.480556000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

* test error handling
* add tests for des, 3des, cast5
* add some tests to blowfish, rijndael
* Makefile: ability to specify different tests for different crypto
libraries, so we can skip des, 3des and cast5 for builtin.

Index: pgsql/contrib/pgcrypto/sql/blowfish.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/blowfish.sql
--- pgsql/contrib/pgcrypto/sql/blowfish.sql
*************** decode('6b77b4d63006dee605b156e274039793
*** 64,66 ****
--- 64,87 ----
decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'),
'bf-cbc'), 'hex');

+ -- blowfish-448
+ SELECT encode(encrypt(
+ decode('fedcba9876543210', 'hex'),
+ decode('f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455667704689104c2fd3b2f584023641aba61761f1f1f1f0e0e0e0effffffffffffffff', 'hex'),
+ 'bf-ecb/pad:none'), 'hex');
+ -- result: c04504012e4e1f53
+
+ -- empty data
+ select encode( encrypt('', 'foo', 'bf'), 'hex');
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', 'bf'), 'hex');
+ -- 22 bytes key
+ select encode( encrypt('foo', '0123456789012345678901', 'bf'), 'hex');
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'bf'), '0123456', 'bf');
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'bf'), 'hex');
+ select decrypt_iv(decode('95c7e89322525d59', 'hex'), '0123456', 'abcd', 'bf');
+
Index: pgsql/contrib/pgcrypto/sql/rijndael.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/rijndael.sql
--- pgsql/contrib/pgcrypto/sql/rijndael.sql
*************** decode('0011223344', 'hex'),
*** 41,43 ****
--- 41,58 ----
decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b', 'hex'),
'aes-cbc'), 'hex');

+ -- empty data
+ select encode( encrypt('', 'foo', 'aes'), 'hex');
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', 'aes'), 'hex');
+ -- 22 bytes key
+ select encode( encrypt('foo', '0123456789012345678901', 'aes'), 'hex');
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'aes'), '0123456', 'aes');
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'aes'), 'hex');
+ select decrypt_iv(decode('2c24cb7da91d6d5699801268b0f5adad', 'hex'),
+ '0123456', 'abcd', 'aes');
+
Index: pgsql/contrib/pgcrypto/Makefile
===================================================================
*** pgsql.orig/contrib/pgcrypto/Makefile
--- pgsql/contrib/pgcrypto/Makefile
*************** ifeq ($(cryptolib), builtin)
*** 26,37 ****
--- 26,39 ----
CRYPTO_CFLAGS =
CRYPTO_LDFLAGS =
SRCS = md5.c sha1.c internal.c blf.c rijndael.c
+ EXTRA_TESTS =
endif

ifeq ($(cryptolib), openssl)
CRYPTO_CFLAGS = -I/usr/include/openssl
CRYPTO_LDFLAGS = -lcrypto
SRCS = openssl.c
+ EXTRA_TESTS = des 3des cast5
endif

ifeq ($(cryptsrc), builtin)
*************** PG_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(srcdi
*** 63,68 ****
--- 65,71 ----
SHLIB_LINK = $(CRYPTO_LDFLAGS)

REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
+ $(EXTRA_TESTS) \
crypt-des crypt-md5 crypt-blowfish crypt-xdes


Index: pgsql/contrib/pgcrypto/sql/des.sql
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/sql/des.sql
***************
*** 0 ****
--- 1,24 ----
+ --
+ -- DES cipher
+ --
+
+ -- no official test vectors atm
+
+ -- from blowfish.sql
+ SELECT encode(encrypt(
+ decode('0123456789abcdef', 'hex'),
+ decode('fedcba9876543210', 'hex'),
+ 'des-ecb/pad:none'), 'hex');
+
+ -- empty data
+ select encode( encrypt('', 'foo', 'des'), 'hex');
+ -- 8 bytes key
+ select encode( encrypt('foo', '01234589', 'des'), 'hex');
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'des'), '0123456', 'des');
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'des'), 'hex');
+ select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des');
+
Index: pgsql/contrib/pgcrypto/sql/cast5.sql
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/sql/cast5.sql
***************
*** 0 ****
--- 1,42 ----
+ --
+ -- Cast5 cipher
+ --
+
+ -- test vectors from RFC2144
+
+ -- 128 bit key
+ SELECT encode(encrypt(
+ decode('01 23 45 67 89 AB CD EF', 'hex'),
+ decode('01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A', 'hex'),
+ 'cast5-ecb/pad:none'), 'hex');
+ -- result: 23 8B 4F E5 84 7E 44 B2
+
+ -- 80 bit key
+ SELECT encode(encrypt(
+ decode('01 23 45 67 89 AB CD EF', 'hex'),
+ decode('01 23 45 67 12 34 56 78 23 45', 'hex'),
+ 'cast5-ecb/pad:none'), 'hex');
+ -- result: EB 6A 71 1A 2C 02 27 1B
+
+ -- 40 bit key
+ SELECT encode(encrypt(
+ decode('01 23 45 67 89 AB CD EF', 'hex'),
+ decode('01 23 45 67 12', 'hex'),
+ 'cast5-ecb/pad:none'), 'hex');
+ -- result: 7A C8 16 D1 6E 9B 30 2E
+
+ -- cbc
+
+ -- empty data
+ select encode( encrypt('', 'foo', 'cast5'), 'hex');
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', 'cast5'), 'hex');
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'cast5'), '0123456', 'cast5');
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'cast5'), 'hex');
+ select decrypt_iv(decode('384a970695ce016a', 'hex'),
+ '0123456', 'abcd', 'cast5');
+
Index: pgsql/contrib/pgcrypto/expected/des.out
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/expected/des.out
***************
*** 0 ****
--- 1,48 ----
+ --
+ -- DES cipher
+ --
+ -- no official test vectors atm
+ -- from blowfish.sql
+ SELECT encode(encrypt(
+ decode('0123456789abcdef', 'hex'),
+ decode('fedcba9876543210', 'hex'),
+ 'des-ecb/pad:none'), 'hex');
+ encode
+ ------------------
+ ed39d950fa74bcc4
+ (1 row)
+
+ -- empty data
+ select encode( encrypt('', 'foo', 'des'), 'hex');
+ encode
+ ------------------
+ 752111e37a2d7ac3
+ (1 row)
+
+ -- 8 bytes key
+ select encode( encrypt('foo', '01234589', 'des'), 'hex');
+ encode
+ ------------------
+ dec0f9c602b647a8
+ (1 row)
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'des'), '0123456', 'des');
+ decrypt
+ ---------
+ foo
+ (1 row)
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'des'), 'hex');
+ encode
+ ------------------
+ 50735067b073bb93
+ (1 row)
+
+ select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des');
+ decrypt_iv
+ ------------
+ foo
+ (1 row)
+
Index: pgsql/contrib/pgcrypto/expected/3des.out
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/expected/3des.out
***************
*** 0 ****
--- 1,56 ----
+ --
+ -- 3DES cipher
+ --
+ -- test vector from somewhere
+ SELECT encode(encrypt(
+ decode('80 00 00 00 00 00 00 00', 'hex'),
+ decode('01 01 01 01 01 01 01 01
+ 01 01 01 01 01 01 01 01
+ 01 01 01 01 01 01 01 01', 'hex'),
+ '3des-ecb/pad:none'), 'hex');
+ encode
+ ------------------
+ 95f8a5e5dd31d900
+ (1 row)
+
+ -- val 95 F8 A5 E5 DD 31 D9 00
+ select encode( encrypt('', 'foo', '3des'), 'hex');
+ encode
+ ------------------
+ 9b641a6936249eb4
+ (1 row)
+
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', '3des'), 'hex');
+ encode
+ ------------------
+ 6f02b7076a366504
+ (1 row)
+
+ -- 22 bytes key
+ select encode( encrypt('foo', '0123456789012345678901', '3des'), 'hex');
+ encode
+ ------------------
+ a44360e699269817
+ (1 row)
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', '3des'), '0123456', '3des');
+ decrypt
+ ---------
+ foo
+ (1 row)
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', '3des'), 'hex');
+ encode
+ ------------------
+ df27c264fb24ed7a
+ (1 row)
+
+ select decrypt_iv(decode('df27c264fb24ed7a', 'hex'), '0123456', 'abcd', '3des');
+ decrypt_iv
+ ------------
+ foo
+ (1 row)
+
Index: pgsql/contrib/pgcrypto/expected/cast5.out
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/expected/cast5.out
***************
*** 0 ****
--- 1,73 ----
+ --
+ -- Cast5 cipher
+ --
+ -- test vectors from RFC2144
+ -- 128 bit key
+ SELECT encode(encrypt(
+ decode('01 23 45 67 89 AB CD EF', 'hex'),
+ decode('01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A', 'hex'),
+ 'cast5-ecb/pad:none'), 'hex');
+ encode
+ ------------------
+ 238b4fe5847e44b2
+ (1 row)
+
+ -- result: 23 8B 4F E5 84 7E 44 B2
+ -- 80 bit key
+ SELECT encode(encrypt(
+ decode('01 23 45 67 89 AB CD EF', 'hex'),
+ decode('01 23 45 67 12 34 56 78 23 45', 'hex'),
+ 'cast5-ecb/pad:none'), 'hex');
+ encode
+ ------------------
+ eb6a711a2c02271b
+ (1 row)
+
+ -- result: EB 6A 71 1A 2C 02 27 1B
+ -- 40 bit key
+ SELECT encode(encrypt(
+ decode('01 23 45 67 89 AB CD EF', 'hex'),
+ decode('01 23 45 67 12', 'hex'),
+ 'cast5-ecb/pad:none'), 'hex');
+ encode
+ ------------------
+ 7ac816d16e9b302e
+ (1 row)
+
+ -- result: 7A C8 16 D1 6E 9B 30 2E
+ -- cbc
+ -- empty data
+ select encode( encrypt('', 'foo', 'cast5'), 'hex');
+ encode
+ ------------------
+ a48bd1aabde4de10
+ (1 row)
+
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', 'cast5'), 'hex');
+ encode
+ ------------------
+ b07f19255e60cb6d
+ (1 row)
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'cast5'), '0123456', 'cast5');
+ decrypt
+ ---------
+ foo
+ (1 row)
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'cast5'), 'hex');
+ encode
+ ------------------
+ 384a970695ce016a
+ (1 row)
+
+ select decrypt_iv(decode('384a970695ce016a', 'hex'),
+ '0123456', 'abcd', 'cast5');
+ decrypt_iv
+ ------------
+ foo
+ (1 row)
+
Index: pgsql/contrib/pgcrypto/sql/3des.sql
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/sql/3des.sql
***************
*** 0 ****
--- 1,26 ----
+ --
+ -- 3DES cipher
+ --
+
+ -- test vector from somewhere
+ SELECT encode(encrypt(
+ decode('80 00 00 00 00 00 00 00', 'hex'),
+ decode('01 01 01 01 01 01 01 01
+ 01 01 01 01 01 01 01 01
+ 01 01 01 01 01 01 01 01', 'hex'),
+ '3des-ecb/pad:none'), 'hex');
+ -- val 95 F8 A5 E5 DD 31 D9 00
+
+ select encode( encrypt('', 'foo', '3des'), 'hex');
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', '3des'), 'hex');
+ -- 22 bytes key
+ select encode( encrypt('foo', '0123456789012345678901', '3des'), 'hex');
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', '3des'), '0123456', '3des');
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', '3des'), 'hex');
+ select decrypt_iv(decode('df27c264fb24ed7a', 'hex'), '0123456', 'abcd', '3des');
+
Index: pgsql/contrib/pgcrypto/expected/blowfish.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/blowfish.out
--- pgsql/contrib/pgcrypto/expected/blowfish.out
*************** decode('37363534333231204e6f772069732074
*** 106,108 ****
--- 106,160 ----
3ea6357a0ee7fad6d0c4b63464f2aafa40c2e91b4b7e1bba8114932fd92b5c8f111e7e50e7b2e541
(1 row)

+ -- blowfish-448
+ SELECT encode(encrypt(
+ decode('fedcba9876543210', 'hex'),
+ decode('f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455667704689104c2fd3b2f584023641aba61761f1f1f1f0e0e0e0effffffffffffffff', 'hex'),
+ 'bf-ecb/pad:none'), 'hex');
+ encode
+ ------------------
+ c04504012e4e1f53
+ (1 row)
+
+ -- result: c04504012e4e1f53
+ -- empty data
+ select encode( encrypt('', 'foo', 'bf'), 'hex');
+ encode
+ ------------------
+ 1871949bb2311c8e
+ (1 row)
+
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', 'bf'), 'hex');
+ encode
+ ------------------
+ 42f58af3b2c03f46
+ (1 row)
+
+ -- 22 bytes key
+ select encode( encrypt('foo', '0123456789012345678901', 'bf'), 'hex');
+ encode
+ ------------------
+ 86ab6f0bc72b5f22
+ (1 row)
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'bf'), '0123456', 'bf');
+ decrypt
+ ---------
+ foo
+ (1 row)
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'bf'), 'hex');
+ encode
+ ------------------
+ 95c7e89322525d59
+ (1 row)
+
+ select decrypt_iv(decode('95c7e89322525d59', 'hex'), '0123456', 'abcd', 'bf');
+ decrypt_iv
+ ------------
+ foo
+ (1 row)
+
Index: pgsql/contrib/pgcrypto/expected/rijndael.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/rijndael.out
--- pgsql/contrib/pgcrypto/expected/rijndael.out
*************** decode('000102030405060708090a0b0c0d0e0f
*** 67,69 ****
--- 67,111 ----
4facb6a041d53e0a5a73289170901fe7
(1 row)

+ -- empty data
+ select encode( encrypt('', 'foo', 'aes'), 'hex');
+ encode
+ ----------------------------------
+ b48cc3338a2eb293b6007ef72c360d48
+ (1 row)
+
+ -- 10 bytes key
+ select encode( encrypt('foo', '0123456789', 'aes'), 'hex');
+ encode
+ ----------------------------------
+ f397f03d2819b7172b68d0706fda4693
+ (1 row)
+
+ -- 22 bytes key
+ select encode( encrypt('foo', '0123456789012345678901', 'aes'), 'hex');
+ encode
+ ----------------------------------
+ 5c9db77af02b4678117bcd8a71ae7f53
+ (1 row)
+
+ -- decrypt
+ select decrypt(encrypt('foo', '0123456', 'aes'), '0123456', 'aes');
+ decrypt
+ ---------
+ foo
+ (1 row)
+
+ -- iv
+ select encode(encrypt_iv('foo', '0123456', 'abcd', 'aes'), 'hex');
+ encode
+ ----------------------------------
+ 2c24cb7da91d6d5699801268b0f5adad
+ (1 row)
+
+ select decrypt_iv(decode('2c24cb7da91d6d5699801268b0f5adad', 'hex'),
+ '0123456', 'abcd', 'aes');
+ decrypt_iv
+ ------------
+ foo
+ (1 row)
+
Index: pgsql/contrib/pgcrypto/expected/init.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/init.out
--- pgsql/contrib/pgcrypto/expected/init.out
*************** SELECT decode('666f6f', 'hex');
*** 15,17 ****
--- 15,26 ----
foo
(1 row)

+ -- check error handling
+ select gen_salt('foo');
+ ERROR: gen_salt: Unknown salt algorithm
+ select digest('foo', 'foo');
+ ERROR: Cannot use "foo": No such hash algorithm
+ select hmac('foo', 'foo', 'foo');
+ ERROR: Cannot use "foo": No such hash algorithm
+ select encrypt('foo', 'foo', 'foo');
+ ERROR: Cannot use "foo": No such cipher algorithm
Index: pgsql/contrib/pgcrypto/sql/init.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/init.sql
--- pgsql/contrib/pgcrypto/sql/init.sql
***************
*** 10,12 ****
--- 10,18 ----
SELECT encode('foo', 'hex');
SELECT decode('666f6f', 'hex');

+ -- check error handling
+ select gen_salt('foo');
+ select digest('foo', 'foo');
+ select hmac('foo', 'foo', 'foo');
+ select encrypt('foo', 'foo', 'foo');
+

--


From: Neil Conway <neilc(at)samurai(dot)com>
To: Marko Kreen <marko(at)l-t(dot)ee>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-03-20 23:08:59
Message-ID: 423E028B.6000400@samurai.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Marko Kreen wrote:
> Here are various updates for pgcrypto that
> I've been sitting on for some time now.

I'll apply all these later today, barring any objections.

-Neil


From: Neil Conway <neilc(at)samurai(dot)com>
To: Marko Kreen <marko(at)l-t(dot)ee>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-03-21 05:26:38
Message-ID: 423E5B0E.2030304@samurai.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Marko Kreen wrote:
> Here are various updates for pgcrypto that
> I've been sitting on for some time now.

Thanks, applied.

-Neil


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Marko Kreen <marko(at)l-t(dot)ee>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-05-06 15:34:08
Message-ID: 200505061534.j46FY8h04849@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Your patch has been added to the PostgreSQL unapplied patches list at:

http://momjian.postgresql.org/cgi-bin/pgpatches

It will be applied as soon as one of the PostgreSQL committers reviews
and approves it.

---------------------------------------------------------------------------

Marko Kreen wrote:
> Here are various updates for pgcrypto that
> I've been sitting on for some time now.
>
> They should be applied in order, but otherwise
> they stand alone - code should in working state
> after each one.
>
> Next update is hopefully pgp_encrypt, which I
> have already working, only some final polishing
> is missing.
>
> --
> marko
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo(at)postgresql(dot)org
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: Marko Kreen <marko(at)l-t(dot)ee>, pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-05-06 15:49:43
Message-ID: 15036.1115394583@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> Your patch has been added to the PostgreSQL unapplied patches list at:
> http://momjian.postgresql.org/cgi-bin/pgpatches
> It will be applied as soon as one of the PostgreSQL committers reviews
> and approves it.

Neil applied all those some time ago, no?

regards, tom lane


From: Marko Kreen <marko(at)l-t(dot)ee>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>, pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-05-06 16:20:39
Message-ID: 20050506162039.GA30796@l-t.ee
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

On Fri, May 06, 2005 at 11:49:43AM -0400, Tom Lane wrote:
> Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> > Your patch has been added to the PostgreSQL unapplied patches list at:
> > http://momjian.postgresql.org/cgi-bin/pgpatches
> > It will be applied as soon as one of the PostgreSQL committers reviews
> > and approves it.
>
> Neil applied all those some time ago, no?

Yes.

--
marko


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Marko Kreen <marko(at)l-t(dot)ee>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-05-06 17:40:05
Message-ID: 200505061740.j46He5d13794@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches

Marko Kreen wrote:
> On Fri, May 06, 2005 at 11:49:43AM -0400, Tom Lane wrote:
> > Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> > > Your patch has been added to the PostgreSQL unapplied patches list at:
> > > http://momjian.postgresql.org/cgi-bin/pgpatches
> > > It will be applied as soon as one of the PostgreSQL committers reviews
> > > and approves it.
> >
> > Neil applied all those some time ago, no?
>
> Yes.

Yes, I see now. Thanks.

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Marko Kreen <marko(at)l-t(dot)ee>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: [patch 0/6] pgcrypto update
Date: 2005-05-06 17:40:11
Message-ID: 200505061740.j46HeBW13804@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-patches


Already applied.

---------------------------------------------------------------------------

Marko Kreen wrote:
> Here are various updates for pgcrypto that
> I've been sitting on for some time now.
>
> They should be applied in order, but otherwise
> they stand alone - code should in working state
> after each one.
>
> Next update is hopefully pgp_encrypt, which I
> have already working, only some final polishing
> is missing.
>
> --
> marko
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo(at)postgresql(dot)org
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073