[patch 0/6] pgcrypto update
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
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 ----
--
* 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 */
--
* 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);
--
* 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/
--
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},
};
--
* 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');
+
--
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
Marko Kreen wrote:
Here are various updates for pgcrypto that
I've been sitting on for some time now.
Thanks, applied.
-Neil
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@postgresql.org
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Bruce Momjian <pgman@candle.pha.pa.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
On Fri, May 06, 2005 at 11:49:43AM -0400, Tom Lane wrote:
Bruce Momjian <pgman@candle.pha.pa.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
Marko Kreen wrote:
On Fri, May 06, 2005 at 11:49:43AM -0400, Tom Lane wrote:
Bruce Momjian <pgman@candle.pha.pa.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@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
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@postgresql.org
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073