Thread: [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
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}, }; --
* 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); --
* 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 */ --
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 ---- --
* 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'); + --
* 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/ --
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