Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 92427200B88 for ; Thu, 8 Sep 2016 04:08:46 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 90D26160AC1; Thu, 8 Sep 2016 02:08:46 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 38A06160ACF for ; Thu, 8 Sep 2016 04:08:44 +0200 (CEST) Received: (qmail 57411 invoked by uid 500); 8 Sep 2016 02:08:43 -0000 Mailing-List: contact commits-help@hawq.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hawq.incubator.apache.org Delivered-To: mailing list commits@hawq.incubator.apache.org Received: (qmail 57397 invoked by uid 99); 8 Sep 2016 02:08:43 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Sep 2016 02:08:43 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id C470CC701E for ; Thu, 8 Sep 2016 02:08:42 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.344 X-Spam-Level: X-Spam-Status: No, score=-4.344 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.124] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id NKTbQDHfJ-vW for ; Thu, 8 Sep 2016 02:08:27 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with SMTP id B4E3F61231 for ; Thu, 8 Sep 2016 02:07:38 +0000 (UTC) Received: (qmail 50728 invoked by uid 99); 8 Sep 2016 02:07:36 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Sep 2016 02:07:36 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 6709FDF9AD; Thu, 8 Sep 2016 02:07:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mli@apache.org To: commits@hawq.incubator.apache.org Date: Thu, 08 Sep 2016 02:08:32 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [59/70] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq archived-at: Thu, 08 Sep 2016 02:08:46 -0000 http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/internal.c ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c new file mode 100644 index 0000000..a02c943 --- /dev/null +++ b/contrib/pgcrypto/internal.c @@ -0,0 +1,688 @@ +/* + * internal.c + * Wrapper for builtin functions + * + * 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. + * + * contrib/pgcrypto/internal.c + */ + +#include "postgres.h" + +#include + +#include "px.h" +#include "md5.h" +#include "sha1.h" +#include "blf.h" +#include "rijndael.h" +#include "fortuna.h" + +/* + * System reseeds should be separated at least this much. + */ +#define SYSTEM_RESEED_MIN (20*60) /* 20 min */ +/* + * How often to roll dice. + */ +#define SYSTEM_RESEED_CHECK_TIME (10*60) /* 10 min */ +/* + * The chance is x/256 that the reseed happens. + */ +#define SYSTEM_RESEED_CHANCE (4) /* 256/4 * 10min ~ 10h */ + +/* + * If this much time has passed, force reseed. + */ +#define SYSTEM_RESEED_MAX (12*60*60) /* 12h */ + + +#ifndef MD5_DIGEST_LENGTH +#define MD5_DIGEST_LENGTH 16 +#endif + +#ifndef SHA1_DIGEST_LENGTH +#ifdef SHA1_RESULTLEN +#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN +#else +#define SHA1_DIGEST_LENGTH 20 +#endif +#endif + +#define SHA1_BLOCK_SIZE 64 +#define MD5_BLOCK_SIZE 64 + +static void init_md5(PX_MD *h); +static void init_sha1(PX_MD *h); + +void init_sha224(PX_MD *h); +void init_sha256(PX_MD *h); +void init_sha384(PX_MD *h); +void init_sha512(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}, + {"sha224", init_sha224}, + {"sha256", init_sha256}, + {"sha384", init_sha384}, + {"sha512", init_sha512}, + {NULL, NULL} +}; + +/* MD5 */ + +static unsigned +int_md5_len(PX_MD *h) +{ + return MD5_DIGEST_LENGTH; +} + +static unsigned +int_md5_block_len(PX_MD *h) +{ + return MD5_BLOCK_SIZE; +} + +static void +int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + MD5Update(ctx, data, dlen); +} + +static void +int_md5_reset(PX_MD *h) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + MD5Init(ctx); +} + +static void +int_md5_finish(PX_MD *h, uint8 *dst) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + MD5Final(dst, ctx); +} + +static void +int_md5_free(PX_MD *h) +{ + MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + + memset(ctx, 0, sizeof(*ctx)); + px_free(ctx); + px_free(h); +} + +/* SHA1 */ + +static unsigned +int_sha1_len(PX_MD *h) +{ + return SHA1_DIGEST_LENGTH; +} + +static unsigned +int_sha1_block_len(PX_MD *h) +{ + return SHA1_BLOCK_SIZE; +} + +static void +int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + SHA1Update(ctx, data, dlen); +} + +static void +int_sha1_reset(PX_MD *h) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + SHA1Init(ctx); +} + +static void +int_sha1_finish(PX_MD *h, uint8 *dst) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + SHA1Final(dst, ctx); +} + +static void +int_sha1_free(PX_MD *h) +{ + SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + + memset(ctx, 0, sizeof(*ctx)); + px_free(ctx); + px_free(h); +} + +/* init functions */ + +static void +init_md5(PX_MD *md) +{ + MD5_CTX *ctx; + + ctx = px_alloc(sizeof(*ctx)); + memset(ctx, 0, sizeof(*ctx)); + + md->p.ptr = ctx; + + md->result_size = int_md5_len; + md->block_size = int_md5_block_len; + md->reset = int_md5_reset; + md->update = int_md5_update; + md->finish = int_md5_finish; + md->free = int_md5_free; + + md->reset(md); +} + +static void +init_sha1(PX_MD *md) +{ + SHA1_CTX *ctx; + + ctx = px_alloc(sizeof(*ctx)); + memset(ctx, 0, sizeof(*ctx)); + + md->p.ptr = ctx; + + md->result_size = int_sha1_len; + md->block_size = int_sha1_block_len; + md->reset = int_sha1_reset; + md->update = int_sha1_update; + md->finish = int_sha1_finish; + md->free = int_sha1_free; + + md->reset(md); +} + +/* + * ciphers generally + */ + +#define INT_MAX_KEY (512/8) +#define INT_MAX_IV (128/8) + +struct int_ctx +{ + uint8 keybuf[INT_MAX_KEY]; + uint8 iv[INT_MAX_IV]; + union + { + BlowfishContext bf; + rijndael_ctx rj; + } ctx; + unsigned keylen; + int is_init; + int mode; +}; + +static void +intctx_free(PX_Cipher *c) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + + if (cx) + { + memset(cx, 0, sizeof *cx); + px_free(cx); + } + px_free(c); +} + +/* + * AES/rijndael + */ + +#define MODE_ECB 0 +#define MODE_CBC 1 + +static unsigned +rj_block_size(PX_Cipher *c) +{ + return 128 / 8; +} + +static unsigned +rj_key_size(PX_Cipher *c) +{ + return 256 / 8; +} + +static unsigned +rj_iv_size(PX_Cipher *c) +{ + return 128 / 8; +} + +static int +rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + + if (klen <= 128 / 8) + cx->keylen = 128 / 8; + else if (klen <= 192 / 8) + cx->keylen = 192 / 8; + else if (klen <= 256 / 8) + cx->keylen = 256 / 8; + else + return PXE_KEY_TOO_BIG; + + memcpy(&cx->keybuf, key, klen); + + if (iv) + memcpy(cx->iv, iv, 128 / 8); + + return 0; +} + +static int +rj_real_init(struct int_ctx * cx, int dir) +{ + aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir); + return 0; +} + +static int +rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + + 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); + + if (cx->mode == MODE_CBC) + { + aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen); + memcpy(cx->iv, res + dlen - 16, 16); + } + else + aes_ecb_encrypt(&cx->ctx.rj, res, dlen); + + return 0; +} + +static int +rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + + 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); + + if (cx->mode == MODE_CBC) + { + aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen); + memcpy(cx->iv, data + dlen - 16, 16); + } + else + aes_ecb_decrypt(&cx->ctx.rj, res, dlen); + + return 0; +} + +/* + * initializers + */ + +static PX_Cipher * +rj_load(int mode) +{ + PX_Cipher *c; + struct int_ctx *cx; + + c = px_alloc(sizeof *c); + memset(c, 0, sizeof *c); + + c->block_size = rj_block_size; + c->key_size = rj_key_size; + c->iv_size = rj_iv_size; + c->init = rj_init; + c->encrypt = rj_encrypt; + c->decrypt = rj_decrypt; + c->free = intctx_free; + + cx = px_alloc(sizeof *cx); + memset(cx, 0, sizeof *cx); + cx->mode = mode; + + c->ptr = cx; + return c; +} + +/* + * blowfish + */ + +static unsigned +bf_block_size(PX_Cipher *c) +{ + return 8; +} + +static unsigned +bf_key_size(PX_Cipher *c) +{ + return 448 / 8; +} + +static unsigned +bf_iv_size(PX_Cipher *c) +{ + return 8; +} + +static int +bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + + blowfish_setkey(&cx->ctx.bf, key, klen); + if (iv) + blowfish_setiv(&cx->ctx.bf, iv); + + return 0; +} + +static int +bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + BlowfishContext *bfctx = &cx->ctx.bf; + + if (dlen == 0) + return 0; + + if (dlen & 7) + return PXE_NOTBLOCKSIZE; + + memcpy(res, data, dlen); + switch (cx->mode) + { + case MODE_ECB: + blowfish_encrypt_ecb(res, dlen, bfctx); + break; + case MODE_CBC: + blowfish_encrypt_cbc(res, dlen, bfctx); + break; + } + return 0; +} + +static int +bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + struct int_ctx *cx = (struct int_ctx *) c->ptr; + BlowfishContext *bfctx = &cx->ctx.bf; + + if (dlen == 0) + return 0; + + if (dlen & 7) + return PXE_NOTBLOCKSIZE; + + memcpy(res, data, dlen); + switch (cx->mode) + { + case MODE_ECB: + blowfish_decrypt_ecb(res, dlen, bfctx); + break; + case MODE_CBC: + blowfish_decrypt_cbc(res, dlen, bfctx); + break; + } + return 0; +} + +static PX_Cipher * +bf_load(int mode) +{ + PX_Cipher *c; + struct int_ctx *cx; + + c = px_alloc(sizeof *c); + memset(c, 0, sizeof *c); + + c->block_size = bf_block_size; + c->key_size = bf_key_size; + c->iv_size = bf_iv_size; + c->init = bf_init; + c->encrypt = bf_encrypt; + c->decrypt = bf_decrypt; + c->free = intctx_free; + + cx = px_alloc(sizeof *cx); + memset(cx, 0, sizeof *cx); + cx->mode = mode; + c->ptr = cx; + return c; +} + +/* ciphers */ + +static PX_Cipher * +rj_128_ecb(void) +{ + return rj_load(MODE_ECB); +} + +static PX_Cipher * +rj_128_cbc(void) +{ + return rj_load(MODE_CBC); +} + +static PX_Cipher * +bf_ecb_load(void) +{ + return bf_load(MODE_ECB); +} + +static PX_Cipher * +bf_cbc_load(void) +{ + 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"}, + {"aes-ecb", "aes-128-ecb"}, + {"aes-cbc", "aes-128-cbc"}, + {"aes-128", "aes-128-cbc"}, + {"rijndael", "aes-128-cbc"}, + {"rijndael-128", "aes-128-cbc"}, + {NULL, NULL} +}; + +/* PUBLIC FUNCTIONS */ + +int +px_find_digest(const char *name, PX_MD **res) +{ + const struct int_digest *p; + PX_MD *h; + + for (p = int_digest_list; p->name; p++) + if (pg_strcasecmp(p->name, name) == 0) + { + h = px_alloc(sizeof(*h)); + p->init(h); + + *res = h; + + return 0; + } + return PXE_NO_HASH; +} + +int +px_find_cipher(const char *name, PX_Cipher **res) +{ + int i; + PX_Cipher *c = NULL; + + name = px_resolve_alias(int_aliases, name); + + for (i = 0; int_ciphers[i].name; i++) + if (strcmp(int_ciphers[i].name, name) == 0) + { + c = int_ciphers[i].load(); + break; + } + + if (c == NULL) + return PXE_NO_CIPHER; + + *res = c; + return 0; +} + +/* + * Randomness provider + */ + +/* + * Use always strong randomness. + */ +int +px_get_pseudo_random_bytes(uint8 *dst, unsigned count) +{ + return px_get_random_bytes(dst, count); +} + +static time_t seed_time = 0; +static time_t check_time = 0; + +static void +system_reseed(void) +{ + uint8 buf[1024]; + int n; + time_t t; + int skip = 1; + + t = time(NULL); + + if (seed_time == 0) + skip = 0; + else if ((t - seed_time) < SYSTEM_RESEED_MIN) + skip = 1; + else if ((t - seed_time) > SYSTEM_RESEED_MAX) + skip = 0; + else if (check_time == 0 || + (t - check_time) > SYSTEM_RESEED_CHECK_TIME) + { + check_time = t; + + /* roll dice */ + px_get_random_bytes(buf, 1); + skip = buf[0] >= SYSTEM_RESEED_CHANCE; + } + /* clear 1 byte */ + memset(buf, 0, sizeof(buf)); + + if (skip) + return; + + n = px_acquire_system_randomness(buf); + if (n > 0) + fortuna_add_entropy(buf, n); + + seed_time = t; + memset(buf, 0, sizeof(buf)); +} + +int +px_get_random_bytes(uint8 *dst, unsigned count) +{ + system_reseed(); + fortuna_get_bytes(count, dst); + return 0; +} + +int +px_add_entropy(const uint8 *data, unsigned count) +{ + system_reseed(); + fortuna_add_entropy(data, count); + return 0; +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/mbuf.c ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/mbuf.c b/contrib/pgcrypto/mbuf.c new file mode 100644 index 0000000..a2c5293 --- /dev/null +++ b/contrib/pgcrypto/mbuf.c @@ -0,0 +1,563 @@ +/* + * mbuf.c + * Memory buffer operations. + * + * Copyright (c) 2005 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. + * + * contrib/pgcrypto/mbuf.c + */ + +#include "postgres.h" + +#include "px.h" +#include "mbuf.h" + +#define STEP (16*1024) + +struct MBuf +{ + uint8 *data; + uint8 *data_end; + uint8 *read_pos; + uint8 *buf_end; + bool no_write; + bool own_data; +}; + +int +mbuf_avail(MBuf *mbuf) +{ + return mbuf->data_end - mbuf->read_pos; +} + +int +mbuf_size(MBuf *mbuf) +{ + return mbuf->data_end - mbuf->data; +} + +int +mbuf_tell(MBuf *mbuf) +{ + return mbuf->read_pos - mbuf->data; +} + +int +mbuf_free(MBuf *mbuf) +{ + if (mbuf->own_data) + { + memset(mbuf->data, 0, mbuf->buf_end - mbuf->data); + px_free(mbuf->data); + } + px_free(mbuf); + return 0; +} + +static void +prepare_room(MBuf *mbuf, int block_len) +{ + uint8 *newbuf; + unsigned newlen; + + if (mbuf->data_end + block_len <= mbuf->buf_end) + return; + + newlen = (mbuf->buf_end - mbuf->data) + + ((block_len + STEP + STEP - 1) & -STEP); + + newbuf = px_realloc(mbuf->data, newlen); + + mbuf->buf_end = newbuf + newlen; + mbuf->data_end = newbuf + (mbuf->data_end - mbuf->data); + mbuf->read_pos = newbuf + (mbuf->read_pos - mbuf->data); + mbuf->data = newbuf; + + return; +} + +int +mbuf_append(MBuf *dst, const uint8 *buf, int len) +{ + if (dst->no_write) + { + px_debug("mbuf_append: no_write"); + return PXE_BUG; + } + + prepare_room(dst, len); + + memcpy(dst->data_end, buf, len); + dst->data_end += len; + + return 0; +} + +MBuf * +mbuf_create(int len) +{ + MBuf *mbuf; + + if (!len) + len = 8192; + + mbuf = px_alloc(sizeof *mbuf); + mbuf->data = px_alloc(len); + mbuf->buf_end = mbuf->data + len; + mbuf->data_end = mbuf->data; + mbuf->read_pos = mbuf->data; + + mbuf->no_write = false; + mbuf->own_data = true; + + return mbuf; +} + +MBuf * +mbuf_create_from_data(uint8 *data, int len) +{ + MBuf *mbuf; + + mbuf = px_alloc(sizeof *mbuf); + mbuf->data = (uint8 *) data; + mbuf->buf_end = mbuf->data + len; + mbuf->data_end = mbuf->data + len; + mbuf->read_pos = mbuf->data; + + mbuf->no_write = true; + mbuf->own_data = false; + + return mbuf; +} + + +int +mbuf_grab(MBuf *mbuf, int len, uint8 **data_p) +{ + if (len > mbuf_avail(mbuf)) + len = mbuf_avail(mbuf); + + mbuf->no_write = true; + + *data_p = mbuf->read_pos; + mbuf->read_pos += len; + return len; +} + +int +mbuf_rewind(MBuf *mbuf) +{ + mbuf->read_pos = mbuf->data; + return 0; +} + +int +mbuf_steal_data(MBuf *mbuf, uint8 **data_p) +{ + int len = mbuf_size(mbuf); + + mbuf->no_write = true; + mbuf->own_data = false; + + *data_p = mbuf->data; + + mbuf->data = mbuf->data_end = mbuf->read_pos = mbuf->buf_end = NULL; + + return len; +} + +/* + * PullFilter + */ + +struct PullFilter +{ + PullFilter *src; + const PullFilterOps *op; + int buflen; + uint8 *buf; + int pos; + void *priv; +}; + +int +pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src) +{ + PullFilter *pf; + void *priv; + int res; + + if (op->init != NULL) + { + res = op->init(&priv, init_arg, src); + if (res < 0) + return res; + } + else + { + priv = init_arg; + res = 0; + } + + pf = px_alloc(sizeof(*pf)); + memset(pf, 0, sizeof(*pf)); + pf->buflen = res; + pf->op = op; + pf->priv = priv; + pf->src = src; + if (pf->buflen > 0) + { + pf->buf = px_alloc(pf->buflen); + pf->pos = 0; + } + else + { + pf->buf = NULL; + pf->pos = 0; + } + *pf_p = pf; + return 0; +} + +void +pullf_free(PullFilter *pf) +{ + if (pf->op->free) + pf->op->free(pf->priv); + + if (pf->buf) + { + memset(pf->buf, 0, pf->buflen); + px_free(pf->buf); + } + + memset(pf, 0, sizeof(*pf)); + px_free(pf); +} + +/* may return less data than asked, 0 means eof */ +int +pullf_read(PullFilter *pf, int len, uint8 **data_p) +{ + int res; + + if (pf->op->pull) + { + if (pf->buflen && len > pf->buflen) + len = pf->buflen; + res = pf->op->pull(pf->priv, pf->src, len, data_p, + pf->buf, pf->buflen); + } + else + res = pullf_read(pf->src, len, data_p); + return res; +} + +int +pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf) +{ + int res, + total; + uint8 *tmp; + + res = pullf_read(pf, len, data_p); + if (res <= 0 || res == len) + return res; + + /* read was shorter, use tmpbuf */ + memcpy(tmpbuf, *data_p, res); + *data_p = tmpbuf; + len -= res; + total = res; + + while (len > 0) + { + res = pullf_read(pf, len, &tmp); + if (res < 0) + { + /* so the caller must clear only on success */ + memset(tmpbuf, 0, total); + return res; + } + if (res == 0) + break; + memcpy(tmpbuf + total, tmp, res); + total += res; + } + return total; +} + +/* + * caller wants exatly len bytes and dont bother with references + */ +int +pullf_read_fixed(PullFilter *src, int len, uint8 *dst) +{ + int res; + uint8 *p; + + res = pullf_read_max(src, len, &p, dst); + if (res < 0) + return res; + if (res != len) + { + px_debug("pullf_read_fixed: need=%d got=%d", len, res); + return PXE_MBUF_SHORT_READ; + } + if (p != dst) + memcpy(dst, p, len); + return 0; +} + +/* + * read from MBuf + */ +static int +pull_from_mbuf(void *arg, PullFilter *src, int len, + uint8 **data_p, uint8 *buf, int buflen) +{ + MBuf *mbuf = arg; + + return mbuf_grab(mbuf, len, data_p); +} + +static const struct PullFilterOps mbuf_reader = { + NULL, pull_from_mbuf, NULL +}; + +int +pullf_create_mbuf_reader(PullFilter **mp_p, MBuf *src) +{ + return pullf_create(mp_p, &mbuf_reader, src, NULL); +} + + +/* + * PushFilter + */ + +struct PushFilter +{ + PushFilter *next; + const PushFilterOps *op; + int block_size; + uint8 *buf; + int pos; + void *priv; +}; + +int +pushf_create(PushFilter **mp_p, const PushFilterOps *op, void *init_arg, PushFilter *next) +{ + PushFilter *mp; + void *priv; + int res; + + if (op->init != NULL) + { + res = op->init(next, init_arg, &priv); + if (res < 0) + return res; + } + else + { + priv = init_arg; + res = 0; + } + + mp = px_alloc(sizeof(*mp)); + memset(mp, 0, sizeof(*mp)); + mp->block_size = res; + mp->op = op; + mp->priv = priv; + mp->next = next; + if (mp->block_size > 0) + { + mp->buf = px_alloc(mp->block_size); + mp->pos = 0; + } + else + { + mp->buf = NULL; + mp->pos = 0; + } + *mp_p = mp; + return 0; +} + +void +pushf_free(PushFilter *mp) +{ + if (mp->op->free) + mp->op->free(mp->priv); + + if (mp->buf) + { + memset(mp->buf, 0, mp->block_size); + px_free(mp->buf); + } + + memset(mp, 0, sizeof(*mp)); + px_free(mp); +} + +void +pushf_free_all(PushFilter *mp) +{ + PushFilter *tmp; + + while (mp) + { + tmp = mp->next; + pushf_free(mp); + mp = tmp; + } +} + +static int +wrap_process(PushFilter *mp, const uint8 *data, int len) +{ + int res; + + if (mp->op->push != NULL) + res = mp->op->push(mp->next, mp->priv, data, len); + else + res = pushf_write(mp->next, data, len); + if (res > 0) + return PXE_BUG; + return res; +} + +/* consumes all data, returns len on success */ +int +pushf_write(PushFilter *mp, const uint8 *data, int len) +{ + int need, + res; + + /* + * no buffering + */ + if (mp->block_size <= 0) + return wrap_process(mp, data, len); + + /* + * try to empty buffer + */ + need = mp->block_size - mp->pos; + if (need > 0) + { + if (len < need) + { + memcpy(mp->buf + mp->pos, data, len); + mp->pos += len; + return 0; + } + memcpy(mp->buf + mp->pos, data, need); + len -= need; + data += need; + } + + /* + * buffer full, process + */ + res = wrap_process(mp, mp->buf, mp->block_size); + if (res < 0) + return res; + mp->pos = 0; + + /* + * now process directly from data + */ + while (len > 0) + { + if (len > mp->block_size) + { + res = wrap_process(mp, data, mp->block_size); + if (res < 0) + return res; + data += mp->block_size; + len -= mp->block_size; + } + else + { + memcpy(mp->buf, data, len); + mp->pos += len; + break; + } + } + return 0; +} + +int +pushf_flush(PushFilter *mp) +{ + int res; + + while (mp) + { + if (mp->block_size > 0) + { + res = wrap_process(mp, mp->buf, mp->pos); + if (res < 0) + return res; + } + + if (mp->op->flush) + { + res = mp->op->flush(mp->next, mp->priv); + if (res < 0) + return res; + } + + mp = mp->next; + } + return 0; +} + + +/* + * write to MBuf + */ +static int +push_into_mbuf(PushFilter *next, void *arg, const uint8 *data, int len) +{ + int res = 0; + MBuf *mbuf = arg; + + if (len > 0) + res = mbuf_append(mbuf, data, len); + return res < 0 ? res : 0; +} + +static const struct PushFilterOps mbuf_filter = { + NULL, push_into_mbuf, NULL, NULL +}; + +int +pushf_create_mbuf_writer(PushFilter **res, MBuf *dst) +{ + return pushf_create(res, &mbuf_filter, dst, NULL); +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/mbuf.h ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/mbuf.h b/contrib/pgcrypto/mbuf.h new file mode 100644 index 0000000..da016c0 --- /dev/null +++ b/contrib/pgcrypto/mbuf.h @@ -0,0 +1,124 @@ +/* + * mbuf.h + * Memory buffer operations. + * + * Copyright (c) 2005 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. + * + * contrib/pgcrypto/mbuf.h + */ + +#ifndef __PX_MBUF_H +#define __PX_MBUF_H + +typedef struct MBuf MBuf; +typedef struct PushFilter PushFilter; +typedef struct PullFilter PullFilter; +typedef struct PushFilterOps PushFilterOps; +typedef struct PullFilterOps PullFilterOps; + +struct PushFilterOps +{ + /* + * should return needed buffer size, 0- no buffering, <0 on error if NULL, + * no buffering, and priv=init_arg + */ + int (*init) (PushFilter *next, void *init_arg, void **priv_p); + + /* + * send data to next. should consume all? if null, it will be simply + * copied (in-place) returns 0 on error + */ + int (*push) (PushFilter *next, void *priv, + const uint8 *src, int len); + int (*flush) (PushFilter *next, void *priv); + void (*free) (void *priv); +}; + +struct PullFilterOps +{ + /* + * should return needed buffer size, 0- no buffering, <0 on error if NULL, + * no buffering, and priv=init_arg + */ + int (*init) (void **priv_p, void *init_arg, PullFilter *src); + + /* + * request data from src, put result ptr to data_p can use ptr from src or + * use buf as work area if NULL in-place copy + */ + int (*pull) (void *priv, PullFilter *src, int len, + uint8 **data_p, uint8 *buf, int buflen); + void (*free) (void *priv); +}; + +/* + * Memory buffer + */ +MBuf *mbuf_create(int len); +MBuf *mbuf_create_from_data(uint8 *data, int len); +int mbuf_tell(MBuf *mbuf); +int mbuf_avail(MBuf *mbuf); +int mbuf_size(MBuf *mbuf); +int mbuf_grab(MBuf *mbuf, int len, uint8 **data_p); +int mbuf_steal_data(MBuf *mbuf, uint8 **data_p); +int mbuf_append(MBuf *dst, const uint8 *buf, int cnt); +int mbuf_rewind(MBuf *mbuf); +int mbuf_free(MBuf *mbuf); + +/* + * Push filter + */ +int pushf_create(PushFilter **res, const PushFilterOps *ops, void *init_arg, + PushFilter *next); +int pushf_write(PushFilter *mp, const uint8 *data, int len); +void pushf_free_all(PushFilter *mp); +void pushf_free(PushFilter *mp); +int pushf_flush(PushFilter *mp); + +int pushf_create_mbuf_writer(PushFilter **mp_p, MBuf *mbuf); + +/* + * Pull filter + */ +int pullf_create(PullFilter **res, const PullFilterOps *ops, + void *init_arg, PullFilter *src); +int pullf_read(PullFilter *mp, int len, uint8 **data_p); +int pullf_read_max(PullFilter *mp, int len, + uint8 **data_p, uint8 *tmpbuf); +void pullf_free(PullFilter *mp); +int pullf_read_fixed(PullFilter *src, int len, uint8 *dst); + +int pullf_create_mbuf_reader(PullFilter **pf_p, MBuf *mbuf); + +#define GETBYTE(pf, dst) \ + do { \ + uint8 __b; \ + int __res = pullf_read_fixed(pf, 1, &__b); \ + if (__res < 0) \ + return __res; \ + (dst) = __b; \ + } while (0) + +#endif /* __PX_MBUF_H */ http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/md5.c ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c new file mode 100644 index 0000000..08227a8 --- /dev/null +++ b/contrib/pgcrypto/md5.c @@ -0,0 +1,397 @@ +/* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. + * + * contrib/pgcrypto/md5.c + */ + +#include "postgres.h" + +#include + +#include "md5.h" + +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s)))) + +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z))) +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z))) +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z))) + +#define ROUND1(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define ROUND2(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define ROUND3(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define ROUND4(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define Sa 7 +#define Sb 12 +#define Sc 17 +#define Sd 22 + +#define Se 5 +#define Sf 9 +#define Sg 14 +#define Sh 20 + +#define Si 4 +#define Sj 11 +#define Sk 16 +#define Sl 23 + +#define Sm 6 +#define Sn 10 +#define So 15 +#define Sp 21 + +#define MD5_A0 0x67452301 +#define MD5_B0 0xefcdab89 +#define MD5_C0 0x98badcfe +#define MD5_D0 0x10325476 + +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */ +static const uint32 T[65] = { + 0, + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +static const uint8 md5_paddat[MD5_BUFLEN] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void md5_calc(uint8 *, md5_ctxt *); + +void +md5_init(md5_ctxt *ctxt) +{ + ctxt->md5_n = 0; + ctxt->md5_i = 0; + ctxt->md5_sta = MD5_A0; + ctxt->md5_stb = MD5_B0; + ctxt->md5_stc = MD5_C0; + ctxt->md5_std = MD5_D0; + memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf)); +} + +void +md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len) +{ + unsigned int gap, + i; + + ctxt->md5_n += len * 8; /* byte to bit */ + gap = MD5_BUFLEN - ctxt->md5_i; + + if (len >= gap) + { + memmove(ctxt->md5_buf + ctxt->md5_i, input, gap); + md5_calc(ctxt->md5_buf, ctxt); + + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) + md5_calc((uint8 *) (input + i), ctxt); + + ctxt->md5_i = len - i; + memmove(ctxt->md5_buf, input + i, ctxt->md5_i); + } + else + { + memmove(ctxt->md5_buf + ctxt->md5_i, input, len); + ctxt->md5_i += len; + } +} + +void +md5_pad(md5_ctxt *ctxt) +{ + unsigned int gap; + + /* Don't count up padding. Keep md5_n. */ + gap = MD5_BUFLEN - ctxt->md5_i; + if (gap > 8) + { + memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, + gap - sizeof(ctxt->md5_n)); + } + else + { + /* including gap == 8 */ + memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap); + md5_calc(ctxt->md5_buf, ctxt); + memmove(ctxt->md5_buf, md5_paddat + gap, + MD5_BUFLEN - sizeof(ctxt->md5_n)); + } + + /* 8 byte word */ +#ifndef WORDS_BIGENDIAN + memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8); +#else + ctxt->md5_buf[56] = ctxt->md5_n8[7]; + ctxt->md5_buf[57] = ctxt->md5_n8[6]; + ctxt->md5_buf[58] = ctxt->md5_n8[5]; + ctxt->md5_buf[59] = ctxt->md5_n8[4]; + ctxt->md5_buf[60] = ctxt->md5_n8[3]; + ctxt->md5_buf[61] = ctxt->md5_n8[2]; + ctxt->md5_buf[62] = ctxt->md5_n8[1]; + ctxt->md5_buf[63] = ctxt->md5_n8[0]; +#endif + + md5_calc(ctxt->md5_buf, ctxt); +} + +void +md5_result(uint8 *digest, md5_ctxt *ctxt) +{ + /* 4 byte words */ +#ifndef WORDS_BIGENDIAN + memmove(digest, &ctxt->md5_st8[0], 16); +#else + digest[0] = ctxt->md5_st8[3]; + digest[1] = ctxt->md5_st8[2]; + digest[2] = ctxt->md5_st8[1]; + digest[3] = ctxt->md5_st8[0]; + digest[4] = ctxt->md5_st8[7]; + digest[5] = ctxt->md5_st8[6]; + digest[6] = ctxt->md5_st8[5]; + digest[7] = ctxt->md5_st8[4]; + digest[8] = ctxt->md5_st8[11]; + digest[9] = ctxt->md5_st8[10]; + digest[10] = ctxt->md5_st8[9]; + digest[11] = ctxt->md5_st8[8]; + digest[12] = ctxt->md5_st8[15]; + digest[13] = ctxt->md5_st8[14]; + digest[14] = ctxt->md5_st8[13]; + digest[15] = ctxt->md5_st8[12]; +#endif +} + +#ifdef WORDS_BIGENDIAN +static uint32 X[16]; +#endif + +static void +md5_calc(uint8 *b64, md5_ctxt *ctxt) +{ + uint32 A = ctxt->md5_sta; + uint32 B = ctxt->md5_stb; + uint32 C = ctxt->md5_stc; + uint32 D = ctxt->md5_std; + +#ifndef WORDS_BIGENDIAN + uint32 *X = (uint32 *) b64; +#else + /* 4 byte words */ + /* what a brute force but fast! */ + uint8 *y = (uint8 *) X; + + y[0] = b64[3]; + y[1] = b64[2]; + y[2] = b64[1]; + y[3] = b64[0]; + y[4] = b64[7]; + y[5] = b64[6]; + y[6] = b64[5]; + y[7] = b64[4]; + y[8] = b64[11]; + y[9] = b64[10]; + y[10] = b64[9]; + y[11] = b64[8]; + y[12] = b64[15]; + y[13] = b64[14]; + y[14] = b64[13]; + y[15] = b64[12]; + y[16] = b64[19]; + y[17] = b64[18]; + y[18] = b64[17]; + y[19] = b64[16]; + y[20] = b64[23]; + y[21] = b64[22]; + y[22] = b64[21]; + y[23] = b64[20]; + y[24] = b64[27]; + y[25] = b64[26]; + y[26] = b64[25]; + y[27] = b64[24]; + y[28] = b64[31]; + y[29] = b64[30]; + y[30] = b64[29]; + y[31] = b64[28]; + y[32] = b64[35]; + y[33] = b64[34]; + y[34] = b64[33]; + y[35] = b64[32]; + y[36] = b64[39]; + y[37] = b64[38]; + y[38] = b64[37]; + y[39] = b64[36]; + y[40] = b64[43]; + y[41] = b64[42]; + y[42] = b64[41]; + y[43] = b64[40]; + y[44] = b64[47]; + y[45] = b64[46]; + y[46] = b64[45]; + y[47] = b64[44]; + y[48] = b64[51]; + y[49] = b64[50]; + y[50] = b64[49]; + y[51] = b64[48]; + y[52] = b64[55]; + y[53] = b64[54]; + y[54] = b64[53]; + y[55] = b64[52]; + y[56] = b64[59]; + y[57] = b64[58]; + y[58] = b64[57]; + y[59] = b64[56]; + y[60] = b64[63]; + y[61] = b64[62]; + y[62] = b64[61]; + y[63] = b64[60]; +#endif + + ROUND1(A, B, C, D, 0, Sa, 1); + ROUND1(D, A, B, C, 1, Sb, 2); + ROUND1(C, D, A, B, 2, Sc, 3); + ROUND1(B, C, D, A, 3, Sd, 4); + ROUND1(A, B, C, D, 4, Sa, 5); + ROUND1(D, A, B, C, 5, Sb, 6); + ROUND1(C, D, A, B, 6, Sc, 7); + ROUND1(B, C, D, A, 7, Sd, 8); + ROUND1(A, B, C, D, 8, Sa, 9); + ROUND1(D, A, B, C, 9, Sb, 10); + ROUND1(C, D, A, B, 10, Sc, 11); + ROUND1(B, C, D, A, 11, Sd, 12); + ROUND1(A, B, C, D, 12, Sa, 13); + ROUND1(D, A, B, C, 13, Sb, 14); + ROUND1(C, D, A, B, 14, Sc, 15); + ROUND1(B, C, D, A, 15, Sd, 16); + + ROUND2(A, B, C, D, 1, Se, 17); + ROUND2(D, A, B, C, 6, Sf, 18); + ROUND2(C, D, A, B, 11, Sg, 19); + ROUND2(B, C, D, A, 0, Sh, 20); + ROUND2(A, B, C, D, 5, Se, 21); + ROUND2(D, A, B, C, 10, Sf, 22); + ROUND2(C, D, A, B, 15, Sg, 23); + ROUND2(B, C, D, A, 4, Sh, 24); + ROUND2(A, B, C, D, 9, Se, 25); + ROUND2(D, A, B, C, 14, Sf, 26); + ROUND2(C, D, A, B, 3, Sg, 27); + ROUND2(B, C, D, A, 8, Sh, 28); + ROUND2(A, B, C, D, 13, Se, 29); + ROUND2(D, A, B, C, 2, Sf, 30); + ROUND2(C, D, A, B, 7, Sg, 31); + ROUND2(B, C, D, A, 12, Sh, 32); + + ROUND3(A, B, C, D, 5, Si, 33); + ROUND3(D, A, B, C, 8, Sj, 34); + ROUND3(C, D, A, B, 11, Sk, 35); + ROUND3(B, C, D, A, 14, Sl, 36); + ROUND3(A, B, C, D, 1, Si, 37); + ROUND3(D, A, B, C, 4, Sj, 38); + ROUND3(C, D, A, B, 7, Sk, 39); + ROUND3(B, C, D, A, 10, Sl, 40); + ROUND3(A, B, C, D, 13, Si, 41); + ROUND3(D, A, B, C, 0, Sj, 42); + ROUND3(C, D, A, B, 3, Sk, 43); + ROUND3(B, C, D, A, 6, Sl, 44); + ROUND3(A, B, C, D, 9, Si, 45); + ROUND3(D, A, B, C, 12, Sj, 46); + ROUND3(C, D, A, B, 15, Sk, 47); + ROUND3(B, C, D, A, 2, Sl, 48); + + ROUND4(A, B, C, D, 0, Sm, 49); + ROUND4(D, A, B, C, 7, Sn, 50); + ROUND4(C, D, A, B, 14, So, 51); + ROUND4(B, C, D, A, 5, Sp, 52); + ROUND4(A, B, C, D, 12, Sm, 53); + ROUND4(D, A, B, C, 3, Sn, 54); + ROUND4(C, D, A, B, 10, So, 55); + ROUND4(B, C, D, A, 1, Sp, 56); + ROUND4(A, B, C, D, 8, Sm, 57); + ROUND4(D, A, B, C, 15, Sn, 58); + ROUND4(C, D, A, B, 6, So, 59); + ROUND4(B, C, D, A, 13, Sp, 60); + ROUND4(A, B, C, D, 4, Sm, 61); + ROUND4(D, A, B, C, 11, Sn, 62); + ROUND4(C, D, A, B, 2, So, 63); + ROUND4(B, C, D, A, 9, Sp, 64); + + ctxt->md5_sta += A; + ctxt->md5_stb += B; + ctxt->md5_stc += C; + ctxt->md5_std += D; +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/md5.h ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/md5.h b/contrib/pgcrypto/md5.h new file mode 100644 index 0000000..03b9ab5 --- /dev/null +++ b/contrib/pgcrypto/md5.h @@ -0,0 +1,79 @@ +/* contrib/pgcrypto/md5.h */ +/* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. + */ + +#ifndef _NETINET6_MD5_H_ +#define _NETINET6_MD5_H_ + +#define MD5_BUFLEN 64 + +typedef struct +{ + union + { + uint32 md5_state32[4]; + uint8 md5_state8[16]; + } md5_st; + +#define md5_sta md5_st.md5_state32[0] +#define md5_stb md5_st.md5_state32[1] +#define md5_stc md5_st.md5_state32[2] +#define md5_std md5_st.md5_state32[3] +#define md5_st8 md5_st.md5_state8 + + union + { + uint64 md5_count64; + uint8 md5_count8[8]; + } md5_count; +#define md5_n md5_count.md5_count64 +#define md5_n8 md5_count.md5_count8 + + unsigned int md5_i; + uint8 md5_buf[MD5_BUFLEN]; +} md5_ctxt; + +extern void md5_init(md5_ctxt *); +extern void md5_loop(md5_ctxt *, const uint8 *, unsigned int); +extern void md5_pad(md5_ctxt *); +extern void md5_result(uint8 *, md5_ctxt *); + +/* compatibility */ +#define MD5_CTX md5_ctxt +#define MD5Init(x) md5_init((x)) +#define MD5Update(x, y, z) md5_loop((x), (y), (z)) +#define MD5Final(x, y) \ +do { \ + md5_pad((y)); \ + md5_result((x), (y)); \ +} while (0) + +#endif /* ! _NETINET6_MD5_H_ */ http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/openssl.c ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c new file mode 100644 index 0000000..ad7fb9e --- /dev/null +++ b/contrib/pgcrypto/openssl.c @@ -0,0 +1,1032 @@ +/* + * openssl.c + * Wrapper for OpenSSL library. + * + * 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. + * + * contrib/pgcrypto/openssl.c + */ + +#include "postgres.h" + +#include "px.h" + +#include +#include +#include +#include +#include +#include + +/* + * Max lengths we might want to handle. + */ +#define MAX_KEY (512/8) +#define MAX_IV (128/8) + +/* + * Compatibility with OpenSSL 0.9.6 + * + * It needs AES and newer DES and digest API. + */ +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + +/* + * Nothing needed for OpenSSL 0.9.7+ + */ + +#include +#else /* old OPENSSL */ + +/* + * Emulate OpenSSL AES. + */ + +#include "rijndael.c" + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 +#define AES_KEY rijndael_ctx + +static int +AES_set_encrypt_key(const uint8 *key, int kbits, AES_KEY *ctx) +{ + aes_set_key(ctx, key, kbits, 1); + return 0; +} + +static int +AES_set_decrypt_key(const uint8 *key, int kbits, AES_KEY *ctx) +{ + aes_set_key(ctx, key, kbits, 0); + return 0; +} + +static void +AES_ecb_encrypt(const uint8 *src, uint8 *dst, AES_KEY *ctx, int enc) +{ + memcpy(dst, src, 16); + if (enc) + aes_ecb_encrypt(ctx, dst, 16); + else + aes_ecb_decrypt(ctx, dst, 16); +} + +static void +AES_cbc_encrypt(const uint8 *src, uint8 *dst, int len, AES_KEY *ctx, uint8 *iv, int enc) +{ + memcpy(dst, src, len); + if (enc) + { + aes_cbc_encrypt(ctx, iv, dst, len); + memcpy(iv, dst + len - 16, 16); + } + else + { + aes_cbc_decrypt(ctx, iv, dst, len); + memcpy(iv, src + len - 16, 16); + } +} + +/* + * Emulate DES_* API + */ + +#define DES_key_schedule des_key_schedule +#define DES_cblock des_cblock +#define DES_set_key(k, ks) \ + des_set_key((k), *(ks)) +#define DES_ecb_encrypt(i, o, k, e) \ + des_ecb_encrypt((i), (o), *(k), (e)) +#define DES_ncbc_encrypt(i, o, l, k, iv, e) \ + des_ncbc_encrypt((i), (o), (l), *(k), (iv), (e)) +#define DES_ecb3_encrypt(i, o, k1, k2, k3, e) \ + des_ecb3_encrypt((des_cblock *)(i), (des_cblock *)(o), \ + *(k1), *(k2), *(k3), (e)) +#define DES_ede3_cbc_encrypt(i, o, l, k1, k2, k3, iv, e) \ + des_ede3_cbc_encrypt((i), (o), \ + (l), *(k1), *(k2), *(k3), (iv), (e)) + +/* + * Emulate newer digest API. + */ + +static void +EVP_MD_CTX_init(EVP_MD_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +static int +EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + return 1; +} + +static int +EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine) +{ + EVP_DigestInit(ctx, md); + return 1; +} + +static int +EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len) +{ + EVP_DigestFinal(ctx, res, len); + return 1; +} +#endif /* old OpenSSL */ + +/* + * Provide SHA2 for older OpenSSL < 0.9.8 + */ +#if OPENSSL_VERSION_NUMBER < 0x00908000L + +#include "sha2.c" +#include "internal-sha2.c" + +typedef void (*init_f) (PX_MD *md); + +static int +compat_find_digest(const char *name, PX_MD **res) +{ + init_f init = NULL; + + if (pg_strcasecmp(name, "sha224") == 0) + init = init_sha224; + else if (pg_strcasecmp(name, "sha256") == 0) + init = init_sha256; + else if (pg_strcasecmp(name, "sha384") == 0) + init = init_sha384; + else if (pg_strcasecmp(name, "sha512") == 0) + init = init_sha512; + else + return PXE_NO_HASH; + + *res = px_alloc(sizeof(PX_MD)); + init(*res); + return 0; +} +#else +#define compat_find_digest(name, res) (PXE_NO_HASH) +#endif + +/* + * Hashes + */ + +typedef struct OSSLDigest +{ + const EVP_MD *algo; + EVP_MD_CTX ctx; +} OSSLDigest; + +static unsigned +digest_result_size(PX_MD *h) +{ + OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + + return EVP_MD_CTX_size(&digest->ctx); +} + +static unsigned +digest_block_size(PX_MD *h) +{ + OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + + return EVP_MD_CTX_block_size(&digest->ctx); +} + +static void +digest_reset(PX_MD *h) +{ + OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + + EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL); +} + +static void +digest_update(PX_MD *h, const uint8 *data, unsigned dlen) +{ + OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + + EVP_DigestUpdate(&digest->ctx, data, dlen); +} + +static void +digest_finish(PX_MD *h, uint8 *dst) +{ + OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + + EVP_DigestFinal_ex(&digest->ctx, dst, NULL); +} + +static void +digest_free(PX_MD *h) +{ + OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + + EVP_MD_CTX_cleanup(&digest->ctx); + + px_free(digest); + px_free(h); +} + +static int px_openssl_initialized = 0; + +/* PUBLIC functions */ + +int +px_find_digest(const char *name, PX_MD **res) +{ + const EVP_MD *md; + PX_MD *h; + OSSLDigest *digest; + + if (!px_openssl_initialized) + { + px_openssl_initialized = 1; + OpenSSL_add_all_algorithms(); + } + + md = EVP_get_digestbyname(name); + if (md == NULL) + return compat_find_digest(name, res); + + digest = px_alloc(sizeof(*digest)); + digest->algo = md; + + EVP_MD_CTX_init(&digest->ctx); + if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0) + return -1; + + h = px_alloc(sizeof(*h)); + h->result_size = digest_result_size; + h->block_size = digest_block_size; + h->reset = digest_reset; + h->update = digest_update; + h->finish = digest_finish; + h->free = digest_free; + h->p.ptr = (void *) digest; + + *res = h; + return 0; +} + +/* + * Ciphers + * + * The problem with OpenSSL is that the EVP* family + * of functions does not allow enough flexibility + * and forces some of the parameters (keylen, + * padding) to SSL defaults. + * + * So need to manage ciphers ourselves. + */ + +struct ossl_cipher +{ + int (*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv); + int (*encrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res); + int (*decrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res); + + int block_size; + int max_key_size; + int stream_cipher; +}; + +typedef struct +{ + union + { + struct + { + BF_KEY key; + int num; + } bf; + struct + { + DES_key_schedule key_schedule; + } des; + struct + { + DES_key_schedule k1, + k2, + k3; + } des3; + CAST_KEY cast_key; + AES_KEY aes_key; + } u; + uint8 key[MAX_KEY]; + uint8 iv[MAX_IV]; + unsigned klen; + unsigned init; + const struct ossl_cipher *ciph; +} ossldata; + +/* generic */ + +static unsigned +gen_ossl_block_size(PX_Cipher *c) +{ + ossldata *od = (ossldata *) c->ptr; + + return od->ciph->block_size; +} + +static unsigned +gen_ossl_key_size(PX_Cipher *c) +{ + ossldata *od = (ossldata *) c->ptr; + + return od->ciph->max_key_size; +} + +static unsigned +gen_ossl_iv_size(PX_Cipher *c) +{ + unsigned ivlen; + ossldata *od = (ossldata *) c->ptr; + + ivlen = od->ciph->block_size; + return ivlen; +} + +static void +gen_ossl_free(PX_Cipher *c) +{ + ossldata *od = (ossldata *) c->ptr; + + memset(od, 0, sizeof(*od)); + px_free(od); + px_free(c); +} + +/* Blowfish */ + +/* + * Check if strong crypto is supported. Some openssl installations + * support only short keys and unfortunately BF_set_key does not return any + * error value. This function tests if is possible to use strong key. + */ +static int +bf_check_supported_key_len(void) +{ + static const uint8 key[56] = { + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69, + 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, + 0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, + 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; + static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53}; + static uint8 out[8]; + + BF_KEY bf_key; + + /* encrypt with 448bits key and verify output */ + BF_set_key(&bf_key, 56, key); + BF_ecb_encrypt(data, out, &bf_key, BF_ENCRYPT); + + if (memcmp(out, res, 8) != 0) + return 0; /* Output does not match -> strong cipher is + * not supported */ + return 1; +} + +static int +bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) +{ + ossldata *od = c->ptr; + static int bf_is_strong = -1; + + /* + * Test if key len is supported. BF_set_key silently cut large keys and it + * could be be a problem when user transfer crypted data from one server + * to another. + */ + + if (bf_is_strong == -1) + bf_is_strong = bf_check_supported_key_len(); + + if (!bf_is_strong && klen > 16) + return PXE_KEY_TOO_BIG; + + /* Key len is supported. We can use it. */ + BF_set_key(&od->u.bf.key, klen, key); + if (iv) + memcpy(od->iv, iv, BF_BLOCK); + else + memset(od->iv, 0, BF_BLOCK); + od->u.bf.num = 0; + return 0; +} + +static int +bf_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + unsigned bs = gen_ossl_block_size(c); + unsigned i; + ossldata *od = c->ptr; + + for (i = 0; i < dlen / bs; i++) + BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_ENCRYPT); + return 0; +} + +static int +bf_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + unsigned bs = gen_ossl_block_size(c), + i; + ossldata *od = c->ptr; + + for (i = 0; i < dlen / bs; i++) + BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_DECRYPT); + return 0; +} + +static int +bf_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + ossldata *od = c->ptr; + + BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT); + return 0; +} + +static int +bf_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + ossldata *od = c->ptr; + + BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT); + return 0; +} + +static int +bf_cfb64_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + ossldata *od = c->ptr; + + BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, + &od->u.bf.num, BF_ENCRYPT); + return 0; +} + +static int +bf_cfb64_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + ossldata *od = c->ptr; + + BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, + &od->u.bf.num, BF_DECRYPT); + return 0; +} + +/* DES */ + +static int +ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) +{ + ossldata *od = c->ptr; + DES_cblock xkey; + + memset(&xkey, 0, sizeof(xkey)); + memcpy(&xkey, key, klen > 8 ? 8 : klen); + DES_set_key(&xkey, &od->u.des.key_schedule); + memset(&xkey, 0, sizeof(xkey)); + + if (iv) + memcpy(od->iv, iv, 8); + else + memset(od->iv, 0, 8); + return 0; +} + +static int +ossl_des_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_ecb_encrypt((DES_cblock *) (data + i * bs), + (DES_cblock *) (res + i * bs), + &od->u.des.key_schedule, 1); + return 0; +} + +static int +ossl_des_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_ecb_encrypt((DES_cblock *) (data + i * bs), + (DES_cblock *) (res + i * bs), + &od->u.des.key_schedule, 0); + return 0; +} + +static int +ossl_des_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, + uint8 *res) +{ + ossldata *od = c->ptr; + + DES_ncbc_encrypt(data, res, dlen, &od->u.des.key_schedule, + (DES_cblock *) od->iv, 1); + return 0; +} + +static int +ossl_des_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, + uint8 *res) +{ + ossldata *od = c->ptr; + + DES_ncbc_encrypt(data, res, dlen, &od->u.des.key_schedule, + (DES_cblock *) od->iv, 0); + 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(&xkey3, 0, sizeof(xkey3)); + 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((void *) (data + i * bs), (void *) (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((void *) (data + i * bs), (void *) (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_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) +{ + ossldata *od = c->ptr; + unsigned bs = gen_ossl_block_size(c); + + CAST_set_key(&od->u.cast_key, klen, key); + if (iv) + memcpy(od->iv, iv, bs); + else + memset(od->iv, 0, bs); + return 0; +} + +static int +ossl_cast_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; + + for (; data <= end; data += bs, res += bs) + CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_ENCRYPT); + return 0; +} + +static int +ossl_cast_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; + + for (; data <= end; data += bs, res += bs) + CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_DECRYPT); + return 0; +} + +static int +ossl_cast_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + ossldata *od = c->ptr; + + CAST_cbc_encrypt(data, res, dlen, &od->u.cast_key, od->iv, CAST_ENCRYPT); + return 0; +} + +static int +ossl_cast_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) +{ + ossldata *od = c->ptr; + + CAST_cbc_encrypt(data, res, dlen, &od->u.cast_key, od->iv, CAST_DECRYPT); + return 0; +} + +/* 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 int +ossl_aes_key_init(ossldata *od, int type) +{ + int err; + + /* + * Strong key support could be missing on some openssl installations. We + * must check return value from set key function. + */ + if (type == AES_ENCRYPT) + err = AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key); + else + err = AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key); + + if (err == 0) + { + od->init = 1; + return 0; + } + od->init = 0; + return PXE_KEY_TOO_BIG; +} + +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; + int err; + + if (!od->init) + if ((err = ossl_aes_key_init(od, AES_ENCRYPT)) != 0) + return err; + + 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; + int err; + + if (!od->init) + if ((err = ossl_aes_key_init(od, AES_DECRYPT)) != 0) + return err; + + 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; + int err; + + if (!od->init) + if ((err = ossl_aes_key_init(od, AES_ENCRYPT)) != 0) + return err; + + 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; + int err; + + if (!od->init) + if ((err = ossl_aes_key_init(od, AES_DECRYPT)) != 0) + return err; + + AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT); + return 0; +} + +/* + * aliases + */ + +static PX_Alias ossl_aliases[] = { + {"bf", "bf-cbc"}, + {"blowfish", "bf-cbc"}, + {"blowfish-cbc", "bf-cbc"}, + {"blowfish-ecb", "bf-ecb"}, + {"blowfish-cfb", "bf-cfb"}, + {"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_bf_cbc = { + bf_init, bf_cbc_encrypt, bf_cbc_decrypt, + 64 / 8, 448 / 8, 0 +}; + +static const struct ossl_cipher ossl_bf_ecb = { + bf_init, bf_ecb_encrypt, bf_ecb_decrypt, + 64 / 8, 448 / 8, 0 +}; + +static const struct ossl_cipher ossl_bf_cfb = { + bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt, + 64 / 8, 448 / 8, 1 +}; + +static const struct ossl_cipher ossl_des_ecb = { + ossl_des_init, ossl_des_ecb_encrypt, ossl_des_ecb_decrypt, + 64 / 8, 64 / 8, 0 +}; + +static const struct ossl_cipher ossl_des_cbc = { + ossl_des_init, ossl_des_cbc_encrypt, ossl_des_cbc_decrypt, + 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_cast_cbc = { + ossl_cast_init, ossl_cast_cbc_encrypt, ossl_cast_cbc_decrypt, + 64 / 8, 128 / 8, 0 +}; + +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 +}; + +/* + * 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}, + {"des3-ecb", &ossl_des3_ecb}, + {"des3-cbc", &ossl_des3_cbc}, + {"cast5-ecb", &ossl_cast_ecb}, + {"cast5-cbc", &ossl_cast_cbc}, + {"aes-ecb", &ossl_aes_ecb}, + {"aes-cbc", &ossl_aes_cbc}, + {NULL} +}; + +/* PUBLIC functions */ + +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) == 0) + break; + if (i->name == NULL) + return PXE_NO_CIPHER; + + 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; + return 0; +} + + +static int openssl_random_init = 0; + +/* + * OpenSSL random should re-feeded occasionally. From /dev/urandom + * preferably. + */ +static void +init_openssl_rand(void) +{ + 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_rand(); + + res = RAND_bytes(dst, count); + if (res == 1) + return count; + + return PXE_OSSL_RAND_ERROR; +} + +int +px_get_pseudo_random_bytes(uint8 *dst, unsigned count) +{ + int res; + + if (!openssl_random_init) + init_openssl_rand(); + + res = RAND_pseudo_bytes(dst, count); + if (res == 0 || res == 1) + return count; + + return PXE_OSSL_RAND_ERROR; +} + +int +px_add_entropy(const uint8 *data, unsigned count) +{ + /* + * estimate 0 bits + */ + RAND_add(data, count, 0); + return 0; +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto--1.0.sql ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/pgcrypto--1.0.sql b/contrib/pgcrypto/pgcrypto--1.0.sql new file mode 100644 index 0000000..347825e --- /dev/null +++ b/contrib/pgcrypto/pgcrypto--1.0.sql @@ -0,0 +1,202 @@ +/* contrib/pgcrypto/pgcrypto--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit + +CREATE FUNCTION digest(text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_digest' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION digest(bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_digest' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION hmac(text, text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_hmac' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION hmac(bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_hmac' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION crypt(text, text) +RETURNS text +AS 'MODULE_PATHNAME', 'pg_crypt' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION gen_salt(text) +RETURNS text +AS 'MODULE_PATHNAME', 'pg_gen_salt' +LANGUAGE C VOLATILE STRICT; + +CREATE FUNCTION gen_salt(text, int4) +RETURNS text +AS 'MODULE_PATHNAME', 'pg_gen_salt_rounds' +LANGUAGE C VOLATILE STRICT; + +CREATE FUNCTION encrypt(bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_encrypt' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION decrypt(bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_decrypt' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION encrypt_iv(bytea, bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_encrypt_iv' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION decrypt_iv(bytea, bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_decrypt_iv' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION gen_random_bytes(int4) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_random_bytes' +LANGUAGE C VOLATILE STRICT; + +-- +-- pgp_sym_encrypt(data, key) +-- +CREATE FUNCTION pgp_sym_encrypt(text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text' +LANGUAGE C STRICT; + +CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea' +LANGUAGE C STRICT; + +-- +-- pgp_sym_encrypt(data, key, args) +-- +CREATE FUNCTION pgp_sym_encrypt(text, text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text' +LANGUAGE C STRICT; + +CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea' +LANGUAGE C STRICT; + +-- +-- pgp_sym_decrypt(data, key) +-- +CREATE FUNCTION pgp_sym_decrypt(bytea, text) +RETURNS text +AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea' +LANGUAGE C IMMUTABLE STRICT; + +-- +-- pgp_sym_decrypt(data, key, args) +-- +CREATE FUNCTION pgp_sym_decrypt(bytea, text, text) +RETURNS text +AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea' +LANGUAGE C IMMUTABLE STRICT; + +-- +-- pgp_pub_encrypt(data, key) +-- +CREATE FUNCTION pgp_pub_encrypt(text, bytea) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text' +LANGUAGE C STRICT; + +CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea' +LANGUAGE C STRICT; + +-- +-- pgp_pub_encrypt(data, key, args) +-- +CREATE FUNCTION pgp_pub_encrypt(text, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text' +LANGUAGE C STRICT; + +CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea' +LANGUAGE C STRICT; + +-- +-- pgp_pub_decrypt(data, key) +-- +CREATE FUNCTION pgp_pub_decrypt(bytea, bytea) +RETURNS text +AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea' +LANGUAGE C IMMUTABLE STRICT; + +-- +-- pgp_pub_decrypt(data, key, psw) +-- +CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text) +RETURNS text +AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea' +LANGUAGE C IMMUTABLE STRICT; + +-- +-- pgp_pub_decrypt(data, key, psw, arg) +-- +CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text, text) +RETURNS text +AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea' +LANGUAGE C IMMUTABLE STRICT; + +-- +-- PGP key ID +-- +CREATE FUNCTION pgp_key_id(bytea) +RETURNS text +AS 'MODULE_PATHNAME', 'pgp_key_id_w' +LANGUAGE C IMMUTABLE STRICT; + +-- +-- pgp armor +-- +CREATE FUNCTION armor(bytea) +RETURNS text +AS 'MODULE_PATHNAME', 'pg_armor' +LANGUAGE C IMMUTABLE STRICT; + +CREATE FUNCTION dearmor(text) +RETURNS bytea +AS 'MODULE_PATHNAME', 'pg_dearmor' +LANGUAGE C IMMUTABLE STRICT; http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql b/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql new file mode 100644 index 0000000..fe8d4c4 --- /dev/null +++ b/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql @@ -0,0 +1,38 @@ +/* contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit + +ALTER EXTENSION pgcrypto ADD function digest(text,text); +ALTER EXTENSION pgcrypto ADD function digest(bytea,text); +ALTER EXTENSION pgcrypto ADD function hmac(text,text,text); +ALTER EXTENSION pgcrypto ADD function hmac(bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function crypt(text,text); +ALTER EXTENSION pgcrypto ADD function gen_salt(text); +ALTER EXTENSION pgcrypto ADD function gen_salt(text,integer); +ALTER EXTENSION pgcrypto ADD function encrypt(bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function decrypt(bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function encrypt_iv(bytea,bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function decrypt_iv(bytea,bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function gen_random_bytes(integer); +ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt(text,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt_bytea(bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt(text,text,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt_bytea(bytea,text,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt(bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt_bytea(bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt(bytea,text,text); +ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt_bytea(bytea,text,text); +ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt(text,bytea); +ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt_bytea(bytea,bytea); +ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt(text,bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt_bytea(bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt(bytea,bytea); +ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt_bytea(bytea,bytea); +ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt(bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt_bytea(bytea,bytea,text); +ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt(bytea,bytea,text,text); +ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt_bytea(bytea,bytea,text,text); +ALTER EXTENSION pgcrypto ADD function pgp_key_id(bytea); +ALTER EXTENSION pgcrypto ADD function armor(bytea); +ALTER EXTENSION pgcrypto ADD function dearmor(text); http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.c ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c new file mode 100644 index 0000000..a441ca7 --- /dev/null +++ b/contrib/pgcrypto/pgcrypto.c @@ -0,0 +1,469 @@ +/* + * pgcrypto.c + * Various cryptographic stuff for PostgreSQL. + * + * 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. + * + * contrib/pgcrypto/pgcrypto.c + */ + +#include "postgres.h" + +#include + +#include "parser/scansup.h" +#include "utils/builtins.h" + +#include "px.h" +#include "px-crypt.h" +#include "pgcrypto.h" + +PG_MODULE_MAGIC; + +/* private stuff */ + +typedef int (*PFN) (const char *name, void **res); +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(PG_FUNCTION_ARGS) +{ + bytea *arg; + text *name; + unsigned len, + hlen; + PX_MD *md; + bytea *res; + + name = PG_GETARG_TEXT_P(1); + + /* will give error if fails */ + md = find_provider(name, (PFN) px_find_digest, "Digest", 0); + + hlen = px_md_result_size(md); + + res = (text *) palloc(hlen + VARHDRSZ); + SET_VARSIZE(res, hlen + VARHDRSZ); + + arg = PG_GETARG_BYTEA_P(0); + len = VARSIZE(arg) - VARHDRSZ; + + px_md_update(md, (uint8 *) VARDATA(arg), len); + px_md_finish(md, (uint8 *) VARDATA(res)); + px_md_free(md); + + PG_FREE_IF_COPY(arg, 0); + PG_FREE_IF_COPY(name, 1); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: hmac(data:bytea, key:bytea, type:text) returns bytea */ +PG_FUNCTION_INFO_V1(pg_hmac); + +Datum +pg_hmac(PG_FUNCTION_ARGS) +{ + bytea *arg; + bytea *key; + text *name; + unsigned len, + hlen, + klen; + PX_HMAC *h; + bytea *res; + + name = PG_GETARG_TEXT_P(2); + + /* will give error if fails */ + h = find_provider(name, (PFN) px_find_hmac, "HMAC", 0); + + hlen = px_hmac_result_size(h); + + res = (text *) palloc(hlen + VARHDRSZ); + SET_VARSIZE(res, hlen + VARHDRSZ); + + arg = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + len = VARSIZE(arg) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + + px_hmac_init(h, (uint8 *) VARDATA(key), klen); + px_hmac_update(h, (uint8 *) VARDATA(arg), len); + px_hmac_finish(h, (uint8 *) VARDATA(res)); + px_hmac_free(h); + + PG_FREE_IF_COPY(arg, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(name, 2); + + PG_RETURN_BYTEA_P(res); +} + + +/* SQL function: pg_gen_salt(text) returns text */ +PG_FUNCTION_INFO_V1(pg_gen_salt); + +Datum +pg_gen_salt(PG_FUNCTION_ARGS) +{ + text *arg0 = PG_GETARG_TEXT_PP(0); + int len; + char buf[PX_MAX_SALT_LEN + 1]; + + text_to_cstring_buffer(arg0, buf, sizeof(buf)); + len = px_gen_salt(buf, buf, 0); + if (len < 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("gen_salt: %s", px_strerror(len)))); + + PG_FREE_IF_COPY(arg0, 0); + + PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len)); +} + +/* SQL function: pg_gen_salt(text, int4) returns text */ +PG_FUNCTION_INFO_V1(pg_gen_salt_rounds); + +Datum +pg_gen_salt_rounds(PG_FUNCTION_ARGS) +{ + text *arg0 = PG_GETARG_TEXT_PP(0); + int rounds = PG_GETARG_INT32(1); + int len; + char buf[PX_MAX_SALT_LEN + 1]; + + text_to_cstring_buffer(arg0, buf, sizeof(buf)); + len = px_gen_salt(buf, buf, rounds); + if (len < 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("gen_salt: %s", px_strerror(len)))); + + PG_FREE_IF_COPY(arg0, 0); + + PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len)); +} + +/* SQL function: pg_crypt(psw:text, salt:text) returns text */ +PG_FUNCTION_INFO_V1(pg_crypt); + +Datum +pg_crypt(PG_FUNCTION_ARGS) +{ + text *arg0 = PG_GETARG_TEXT_PP(0); + text *arg1 = PG_GETARG_TEXT_PP(1); + char *buf0, + *buf1, + *cres, + *resbuf; + text *res; + + buf0 = text_to_cstring(arg0); + buf1 = text_to_cstring(arg1); + + resbuf = palloc0(PX_MAX_CRYPT); + + cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT); + + pfree(buf0); + pfree(buf1); + + if (cres == NULL) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("crypt(3) returned NULL"))); + + res = cstring_to_text(cres); + + pfree(resbuf); + + PG_FREE_IF_COPY(arg0, 0); + PG_FREE_IF_COPY(arg1, 1); + + 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) +{ + int err; + bytea *data, + *key, + *res; + text *type; + PX_Combo *c; + unsigned dlen, + klen, + rlen; + + type = PG_GETARG_TEXT_P(2); + c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + + rlen = px_combo_encrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, (uint8 *) VARDATA(key), klen, NULL, 0); + if (!err) + err = px_combo_encrypt(c, (uint8 *) VARDATA(data), dlen, + (uint8 *) VARDATA(res), &rlen); + px_combo_free(c); + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(type, 2); + + if (err) + { + pfree(res); + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("encrypt error: %s", px_strerror(err)))); + } + + SET_VARSIZE(res, VARHDRSZ + rlen); + 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) +{ + int err; + bytea *data, + *key, + *res; + text *type; + PX_Combo *c; + unsigned dlen, + klen, + rlen; + + type = PG_GETARG_TEXT_P(2); + c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + + rlen = px_combo_decrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, (uint8 *) VARDATA(key), klen, NULL, 0); + if (!err) + err = px_combo_decrypt(c, (uint8 *) VARDATA(data), dlen, + (uint8 *) VARDATA(res), &rlen); + + px_combo_free(c); + + if (err) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("decrypt error: %s", px_strerror(err)))); + + SET_VARSIZE(res, VARHDRSZ + rlen); + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(type, 2); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_encrypt_iv(bytea, bytea, bytea, text) returns bytea */ +PG_FUNCTION_INFO_V1(pg_encrypt_iv); + +Datum +pg_encrypt_iv(PG_FUNCTION_ARGS) +{ + int err; + bytea *data, + *key, + *iv, + *res; + text *type; + PX_Combo *c; + unsigned dlen, + klen, + ivlen, + rlen; + + type = PG_GETARG_TEXT_P(3); + c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + iv = PG_GETARG_BYTEA_P(2); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + ivlen = VARSIZE(iv) - VARHDRSZ; + + rlen = px_combo_encrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, (uint8 *) VARDATA(key), klen, + (uint8 *) VARDATA(iv), ivlen); + if (!err) + err = px_combo_encrypt(c, (uint8 *) VARDATA(data), dlen, + (uint8 *) VARDATA(res), &rlen); + + px_combo_free(c); + + if (err) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("encrypt_iv error: %s", px_strerror(err)))); + + SET_VARSIZE(res, VARHDRSZ + rlen); + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(iv, 2); + PG_FREE_IF_COPY(type, 3); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_decrypt_iv(bytea, bytea, bytea, text) returns bytea */ +PG_FUNCTION_INFO_V1(pg_decrypt_iv); + +Datum +pg_decrypt_iv(PG_FUNCTION_ARGS) +{ + int err; + bytea *data, + *key, + *iv, + *res; + text *type; + PX_Combo *c; + unsigned dlen, + klen, + rlen, + ivlen; + + type = PG_GETARG_TEXT_P(3); + c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); + + data = PG_GETARG_BYTEA_P(0); + key = PG_GETARG_BYTEA_P(1); + iv = PG_GETARG_BYTEA_P(2); + dlen = VARSIZE(data) - VARHDRSZ; + klen = VARSIZE(key) - VARHDRSZ; + ivlen = VARSIZE(iv) - VARHDRSZ; + + rlen = px_combo_decrypt_len(c, dlen); + res = palloc(VARHDRSZ + rlen); + + err = px_combo_init(c, (uint8 *) VARDATA(key), klen, + (uint8 *) VARDATA(iv), ivlen); + if (!err) + err = px_combo_decrypt(c, (uint8 *) VARDATA(data), dlen, + (uint8 *) VARDATA(res), &rlen); + + px_combo_free(c); + + if (err) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("decrypt_iv error: %s", px_strerror(err)))); + + SET_VARSIZE(res, VARHDRSZ + rlen); + + PG_FREE_IF_COPY(data, 0); + PG_FREE_IF_COPY(key, 1); + PG_FREE_IF_COPY(iv, 2); + PG_FREE_IF_COPY(type, 3); + + PG_RETURN_BYTEA_P(res); +} + +/* SQL function: pg_random_bytes(int4) returns bytea */ +PG_FUNCTION_INFO_V1(pg_random_bytes); + +Datum +pg_random_bytes(PG_FUNCTION_ARGS) +{ + int err; + int len = PG_GETARG_INT32(0); + bytea *res; + + if (len < 1 || len > 1024) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("Length not in range"))); + + res = palloc(VARHDRSZ + len); + SET_VARSIZE(res, VARHDRSZ + len); + + /* generate result */ + err = px_get_random_bytes((uint8 *) VARDATA(res), len); + if (err < 0) + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + errmsg("Random generator error: %s", px_strerror(err)))); + + PG_RETURN_BYTEA_P(res); +} + +static void * +find_provider(text *name, + PFN provider_lookup, + char *desc, int silent) +{ + void *res; + char *buf; + int err; + + buf = downcase_truncate_identifier(VARDATA(name), + VARSIZE(name) - VARHDRSZ, + false); + + err = provider_lookup(buf, &res); + + if (err && !silent) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("Cannot use \"%s\": %s", buf, px_strerror(err)))); + + pfree(buf); + + return err ? NULL : res; +} http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.control ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/pgcrypto.control b/contrib/pgcrypto/pgcrypto.control new file mode 100644 index 0000000..8375cf9 --- /dev/null +++ b/contrib/pgcrypto/pgcrypto.control @@ -0,0 +1,5 @@ +# pgcrypto extension +comment = 'cryptographic functions' +default_version = '1.0' +module_pathname = '$libdir/pgcrypto' +relocatable = true http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.h ---------------------------------------------------------------------- diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h new file mode 100644 index 0000000..6284ba2 --- /dev/null +++ b/contrib/pgcrypto/pgcrypto.h @@ -0,0 +1,49 @@ +/* + * pgcrypto.h + * Header file for pgcrypto. + * + * Copyright (c) 2000 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. + * + * contrib/pgcrypto/pgcrypto.h + */ + +#ifndef _PG_CRYPTO_H +#define _PG_CRYPTO_H + +#include "fmgr.h" + +/* exported functions */ +Datum pg_digest(PG_FUNCTION_ARGS); +Datum pg_hmac(PG_FUNCTION_ARGS); +Datum pg_gen_salt(PG_FUNCTION_ARGS); +Datum pg_gen_salt_rounds(PG_FUNCTION_ARGS); +Datum pg_crypt(PG_FUNCTION_ARGS); +Datum pg_encrypt(PG_FUNCTION_ARGS); +Datum pg_decrypt(PG_FUNCTION_ARGS); +Datum pg_encrypt_iv(PG_FUNCTION_ARGS); +Datum pg_decrypt_iv(PG_FUNCTION_ARGS); +Datum pg_random_bytes(PG_FUNCTION_ARGS); + +#endif