Commit df24cb73 authored by Bruce Momjian's avatar Bruce Momjian

Add missing pgcrypto file.

parent 2518e273
This diff is collapsed.
/* $OpenBSD: blf.h,v 1.3 2001/05/15 02:40:35 deraadt Exp $ */
/*
* Blowfish - a fast block cipher designed by Bruce Schneier
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _BLF_H_
#define _BLF_H_
/* Schneier states the maximum key length to be 56 bytes.
* The way how the subkeys are initalized by the key up
* to (N+2)*4 i.e. 72 bytes are utilized.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32 S[4][256]; /* S-Boxes */
uint32 P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
void Blowfish_encipher __P((blf_ctx *, uint32 *));
void Blowfish_decipher __P((blf_ctx *, uint32 *));
void Blowfish_initstate __P((blf_ctx *));
void Blowfish_expand0state __P((blf_ctx *, const uint8 *, uint16));
void Blowfish_expandstate
__P((blf_ctx *, const uint8 *, uint16, const uint8 *, uint16));
/* Standard Blowfish */
void blf_key __P((blf_ctx *, const uint8 *, uint16));
void blf_enc __P((blf_ctx *, uint32 *, uint16));
void blf_dec __P((blf_ctx *, uint32 *, uint16));
/* Converts uint8 to uint32 */
uint32 Blowfish_stream2word __P((const uint8 *, uint16 ,
uint16 *));
void blf_ecb_encrypt __P((blf_ctx *, uint8 *, uint32));
void blf_ecb_decrypt __P((blf_ctx *, uint8 *, uint32));
void blf_cbc_encrypt __P((blf_ctx *, uint8 *, uint8 *, uint32));
void blf_cbc_decrypt __P((blf_ctx *, uint8 *, uint8 *, uint32));
#endif
This diff is collapsed.
This diff is collapsed.
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
*
*/
/* $Id: crypt-md5.c,v 1.1 2001/08/21 01:32:01 momjian Exp $ */
#include <postgres.h>
#include "px.h"
#include "px-crypt.h"
#define MD5_SIZE 16
/*
* UNIX password
*/
char *
px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
{
static char *magic = "$1$"; /*
* This string is magic for
* this algorithm. Having
* it this way, we can get
* get better later on
*/
static char *p;
static const char *sp,
*ep;
unsigned char final[MD5_SIZE];
int sl,
pl,
i;
PX_MD *ctx,
*ctx1;
int err;
unsigned long l;
if (!passwd || dstlen < 120)
return NULL;
/* Refine the Salt first */
sp = salt;
/* If it starts with the magic string, then skip that */
if (!strncmp(sp, magic, strlen(magic)))
sp += strlen(magic);
/* It stops at the first '$', max 8 chars */
for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
continue;
/* get the length of the true salt */
sl = ep - sp;
/* */
err = px_find_digest("md5", &ctx);
if (err)
return NULL;
err = px_find_digest("md5", &ctx1);
/* The password first, since that is what is most unknown */
px_md_update(ctx, pw, strlen(pw));
/* Then our magic string */
px_md_update(ctx, magic, strlen(magic));
/* Then the raw salt */
px_md_update(ctx, sp, sl);
/* Then just as many characters of the MD5(pw,salt,pw) */
px_md_update(ctx1, pw, strlen(pw));
px_md_update(ctx1, sp, sl);
px_md_update(ctx1, pw, strlen(pw));
px_md_finish(ctx1, final);
for (pl = strlen(pw); pl > 0; pl -= MD5_SIZE)
px_md_update(ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl);
/* Don't leave anything around in vm they could use. */
memset(final, 0, sizeof final);
/* Then something really weird... */
for (i = strlen(pw); i; i >>= 1)
if (i & 1)
px_md_update(ctx, final, 1);
else
px_md_update(ctx, pw, 1);
/* Now make the output string */
strcpy(passwd, magic);
strncat(passwd, sp, sl);
strcat(passwd, "$");
px_md_finish(ctx, final);
/*
* and now, just to make sure things don't run too fast
* On a 60 Mhz Pentium this takes 34 msec, so you would
* need 30 seconds to build a 1000 entry dictionary...
*/
for (i = 0; i < 1000; i++)
{
px_md_reset(ctx1);
if (i & 1)
px_md_update(ctx1, pw, strlen(pw));
else
px_md_update(ctx1, final, MD5_SIZE);
if (i % 3)
px_md_update(ctx1, sp, sl);
if (i % 7)
px_md_update(ctx1, pw, strlen(pw));
if (i & 1)
px_md_update(ctx1, final, MD5_SIZE);
else
px_md_update(ctx1, pw, strlen(pw));
px_md_finish(ctx1, final);
}
p = passwd + strlen(passwd);
l = (final[0] << 16) | (final[6] << 8) | final[12];
_crypt_to64(p, l, 4);
p += 4;
l = (final[1] << 16) | (final[7] << 8) | final[13];
_crypt_to64(p, l, 4);
p += 4;
l = (final[2] << 16) | (final[8] << 8) | final[14];
_crypt_to64(p, l, 4);
p += 4;
l = (final[3] << 16) | (final[9] << 8) | final[15];
_crypt_to64(p, l, 4);
p += 4;
l = (final[4] << 16) | (final[10] << 8) | final[5];
_crypt_to64(p, l, 4);
p += 4;
l = final[11];
_crypt_to64(p, l, 2);
p += 2;
*p = '\0';
/* Don't leave anything around in vm they could use. */
memset(final, 0, sizeof final);
px_md_free(ctx1);
px_md_free(ctx);
return passwd;
}
/*
* Copyright (c) 1999
* University of California. 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 author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY 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 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.
*
* $FreeBSD: src/lib/libcrypt/misc.c,v 1.1 1999/09/20 12:45:49 markm Exp $
*
*/
#include "px-crypt.h"
char px_crypt_a64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* 0000000000111111111122222222223333333333444444444455555555556666 */
/* 0123456789012345678901234567890123456789012345678901234567890123 */
void
px_crypt_to64(char *s, unsigned long v, int n)
{
while (--n >= 0)
{
*s++ = px_crypt_a64[v & 0x3f];
v >>= 6;
}
}
/*
* px-crypt.c
* Wrapper for various crypt algorithms.
*
* 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.
*
* $Id: px-crypt.c,v 1.1 2001/08/21 01:32:01 momjian Exp $
*/
#include <postgres.h>
#include "px-crypt.h"
#ifndef PX_SYSTEM_CRYPT
static char *
run_crypt_des(const char *psw, const char *salt,
char *buf, unsigned len)
{
char *res;
res = px_crypt_des(psw, salt);
if (strlen(res) > len - 1)
return NULL;
strcpy(buf, res);
return buf;
}
static char *
run_crypt_md5(const char *psw, const char *salt,
char *buf, unsigned len)
{
char *res;
res = px_crypt_md5(psw, salt, buf, len);
return res;
}
static char *
run_crypt_bf(const char *psw, const char *salt,
char *buf, unsigned len)
{
char *res;
res = _crypt_blowfish_rn(psw, salt, buf, len);
if (!res)
return NULL;
strcpy(buf, res);
return buf;
}
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 */
extern char *crypt(const char *psw, const char *salt);
char *
px_crypt(const char *psw, const char *salt,
char *buf, unsigned len)
{
char *res;
res = crypt(psw, salt);
if (!res || strlen(res) >= len)
return NULL;
strcpy(buf, res);
return buf;
}
#endif
/*
* salt generators
*/
static int my_rand64()
{
return random() % 64;
}
static uint
gen_des_salt(char *buf)
{
buf[0] = px_crypt_a64[my_rand64()];
buf[1] = px_crypt_a64[my_rand64()];
buf[2] = 0;
return 2;
}
static uint
gen_xdes_salt(char *buf)
{
strcpy(buf, "_12345678");
px_crypt_to64(buf+1, (long)PX_XDES_ROUNDS, 4);
px_crypt_to64(buf+5, random(), 4);
return 9;
}
static uint
gen_md5_salt(char *buf)
{
int i;
strcpy(buf, "$1$12345678$");
for (i = 0; i < 8; i++)
buf[3 + i] = px_crypt_a64[my_rand64()];
return 12;
}
static uint
gen_bf_salt(char *buf)
{
int i, count;
char *s;
char saltbuf[16+3];
unsigned slen = 16;
uint32 *v;
for (i = 0; i < slen; i++)
saltbuf[i] = random() & 255;
saltbuf[16] = 0;
saltbuf[17] = 0;
saltbuf[18] = 0;
strcpy(buf, "$2a$00$0123456789012345678901");
count = PX_BF_ROUNDS;
buf[4] = '0' + count / 10;
buf[5] = '0' + count % 10;
s = buf + 7;
for (i = 0; i < slen; )
{
v = (uint32 *)&saltbuf[i];
if (i + 3 <= slen)
px_crypt_to64(s, *v, 4);
else
/* slen-i could be 1,2 make it 2,3 */
px_crypt_to64(s, *v, slen-i+1);
s += 4;
i += 3;
}
s = buf;
/*s = _crypt_gensalt_blowfish_rn(count, saltbuf, 16, buf, PX_MAX_CRYPT);*/
return s ? strlen(s) : 0;
}
struct generator {
char *name;
uint (*gen)(char *buf);
};
static struct generator gen_list [] = {
{ "des", gen_des_salt },
{ "md5", gen_md5_salt },
{ "xdes", gen_xdes_salt },
{ "bf", gen_bf_salt },
{ NULL, NULL }
};
uint
px_gen_salt(const char *salt_type, char *buf)
{
int i;
struct generator *g;
for (i = 0; gen_list[i].name; i++) {
g = &gen_list[i];
if (!strcasecmp(g->name, salt_type))
return g->gen(buf);
}
return 0;
}
/*
* px-crypt.h
* Header file for px_crypt().
*
* 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.
*
* $Id: px-crypt.h,v 1.1 2001/08/21 01:32:01 momjian Exp $
*/
#ifndef _PX_CRYPT_H
#define _PX_CRYPT_H
/* max room for result */
#define PX_MAX_CRYPT 128
/* max salt returned by gen_salt() */
#define PX_MAX_SALT_LEN 128
/* rounds for xdes salt */
/* NetBSD bin/passwd/local_passwd.c has (29 * 25)*/
#define PX_XDES_ROUNDS (29 * 25)
/* rounds for blowfish salt */
#define PX_BF_ROUNDS 6
/*
* 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);
/* misc.c */
extern void px_crypt_to64(char *s, unsigned long v, int n);
extern char px_crypt_a64[];
/* avoid conflicts with system libs */
#define _crypt_to64 px_crypt_to64
#define _crypt_a64 px_crypt_a64
#ifndef PX_SYSTEM_CRYPT
/* disable 'extended DES crypt' */
/* #define DISABLE_XDES */
/* crypt-blowfish.c */
char *_crypt_gensalt_blowfish_rn(unsigned long count,
const char *input, int size,
char *output, int output_size);
char *_crypt_blowfish_rn(const char *key, const char *setting,
char *output, int size);
/* crypt-des.c */
char *px_crypt_des(const char *key, const char *setting);
/* crypt-md5.c */
char *px_crypt_md5(const char *pw, const char *salt,
char *dst, unsigned dstlen);
#endif /* !PX_SYSTEM_CRYPT */
#endif /* _PX_CRYPT_H */
/*
* px-hmac.c
* HMAC implementation.
*
* 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.
*
* $Id: px-hmac.c,v 1.1 2001/08/21 01:32:01 momjian Exp $
*/
#include <postgres.h>
#include "px.h"
#define HMAC_IPAD 0x36
#define HMAC_OPAD 0x5C
static uint
hmac_result_size(PX_HMAC * h)
{
return px_md_result_size(h->md);
}
static uint
hmac_block_size(PX_HMAC * h)
{
return px_md_block_size(h->md);
}
static void
hmac_init(PX_HMAC * h, const uint8 * key, uint klen)
{
uint bs,
hlen,
i;
uint8 *keybuf;
PX_MD *md = h->md;
bs = px_md_block_size(md);
hlen = px_md_result_size(md);
keybuf = px_alloc(bs);
memset(keybuf, 0, bs);
if (klen > bs)
{
px_md_update(md, key, klen);
px_md_finish(md, keybuf);
px_md_reset(md);
}
else
memcpy(keybuf, key, klen);
for (i = 0; i < bs; i++)
{
h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
}
memset(keybuf, 0, bs);
px_free(keybuf);
px_md_update(md, h->p.ipad, bs);
}
static void
hmac_reset(PX_HMAC * h)
{
PX_MD *md = h->md;
uint bs = px_md_block_size(md);
px_md_reset(md);
px_md_update(md, h->p.ipad, bs);
}
static void
hmac_update(PX_HMAC * h, const uint8 * data, uint dlen)
{
px_md_update(h->md, data, dlen);
}
static void
hmac_finish(PX_HMAC * h, uint8 * dst)
{
PX_MD *md = h->md;
uint bs,
hlen;
uint8 *buf;
bs = px_md_block_size(md);
hlen = px_md_result_size(md);
buf = px_alloc(hlen);
px_md_finish(md, buf);
px_md_reset(md);
px_md_update(md, h->p.opad, bs);
px_md_update(md, buf, hlen);
px_md_finish(md, dst);
memset(buf, 0, hlen);
px_free(buf);
}
static void
hmac_free(PX_HMAC * h)
{
uint bs;
bs = px_md_block_size(h->md);
px_md_free(h->md);
memset(h->p.ipad, 0, bs);
memset(h->p.opad, 0, bs);
px_free(h->p.ipad);
px_free(h->p.opad);
px_free(h);
}
/* PUBLIC FUNCTIONS */
int
px_find_hmac(const char *name, PX_HMAC ** res)
{
int err;
PX_MD *md;
PX_HMAC *h;
uint bs;
err = px_find_digest(name, &md);
if (err)
return err;
bs = px_md_block_size(md);
if (bs < 2)
{
px_md_free(md);
return -1;
}
h = px_alloc(sizeof(*h));
h->p.ipad = px_alloc(bs);
h->p.opad = px_alloc(bs);
h->md = md;
h->result_size = hmac_result_size;
h->block_size = hmac_block_size;
h->reset = hmac_reset;
h->update = hmac_update;
h->finish = hmac_finish;
h->free = hmac_free;
h->init = hmac_init;
*res = h;
return 0;
}
/*
* px.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.
*
* $Id: px.c,v 1.1 2001/08/21 01:32:01 momjian Exp $
*/
#include <postgres.h>
#include "px.h"
const char *
px_resolve_alias(const PX_Alias *list, const char *name)
{
while (list->name) {
if (!strcasecmp(list->alias, name))
return list->name;
list++;
}
return name;
}
/*
* combo - cipher + padding (+ checksum)
*/
static uint
combo_encrypt_len(PX_Combo *cx, uint dlen)
{
return dlen + 512;
}
static uint
combo_decrypt_len(PX_Combo *cx, uint dlen)
{
return dlen;
}
static int
combo_init(PX_Combo *cx, const uint8 *key, uint klen,
const uint8 *iv, uint ivlen)
{
int err;
uint bs, ks, ivs;
PX_Cipher *c = cx->cipher;
uint8 *ivbuf = NULL;
uint8 *keybuf;
bs = px_cipher_block_size(c);
ks = px_cipher_key_size(c);
ivs = px_cipher_iv_size(c);
if (ivs > 0) {
ivbuf = px_alloc(ivs);
memset(ivbuf, 0, ivs);
if (ivlen > ivs)
memcpy(ivbuf, iv, ivs);
else
memcpy(ivbuf, iv, ivlen);
}
keybuf = px_alloc(ks);
memset(keybuf, 0, ks);
memcpy(keybuf, key, klen);
err = px_cipher_init(c, keybuf, klen, ivbuf);
if (ivbuf)
px_free(ivbuf);
return err;
}
static int
combo_encrypt(PX_Combo *cx, const uint8 *data, uint dlen,
uint8 *res, uint *rlen)
{
int err = 0;
uint8 *bbuf;
uint bs, maxlen, bpos, i, pad;
PX_Cipher *c = cx->cipher;
bbuf = NULL;
maxlen = *rlen;
bs = px_cipher_block_size(c);
/* encrypt */
if (bs > 1) {
bbuf = px_alloc(bs * 4);
bpos = dlen % bs;
*rlen = dlen - bpos;
memcpy(bbuf, data + *rlen, bpos);
/* encrypt full-block data */
if (*rlen) {
err = px_cipher_encrypt(c, data, *rlen, res);
if (err)
goto out;
}
/* bbuf has now bpos bytes of stuff */
if (cx->padding) {
pad = bs - (bpos % bs);
for (i = 0; i < pad; i++)
bbuf[bpos++] = pad;
} else if (bpos % bs) {
/* ERROR? */
pad = bs - (bpos % bs);
for (i = 0; i < pad; i++)
bbuf[bpos++] = 0;
}
/* encrypt the rest - pad */
if (bpos) {
err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
*rlen += bpos;
}
} else {
/* stream cipher/mode - no pad needed */
err = px_cipher_encrypt(c, data, dlen, res);
if (err)
goto out;
*rlen = dlen;
}
out:
if (bbuf) px_free(bbuf);
return err;
}
static int
combo_decrypt(PX_Combo *cx, const uint8 *data, uint dlen,
uint8 *res, uint *rlen)
{
uint bs, i, pad;
uint pad_ok;
PX_Cipher *c = cx->cipher;
bs = px_cipher_block_size(c);
if (bs > 1 && (dlen % bs) != 0) {
goto block_error;
}
/* decrypt */
*rlen = dlen;
px_cipher_decrypt(c, data, dlen, res);
/* unpad */
if (bs > 1 && cx->padding) {
pad = res[*rlen - 1];
pad_ok = 0;
if (pad > 0 && pad <= bs && pad <= *rlen) {
pad_ok = 1;
for (i = *rlen - pad; i < *rlen; i++)
if (res[i] != pad) {
pad_ok = 0;
break;
}
}
if (pad_ok)
*rlen -= pad;
}
return 0;
/* error reporting should be done in pgcrypto.c */
block_error:
elog(NOTICE, "Data not a multiple of block size");
return -1;
}
static void
combo_free(PX_Combo *cx)
{
if (cx->cipher)
px_cipher_free(cx->cipher);
memset(cx, 0, sizeof(*cx));
px_free(cx);
}
/* PARSER */
static void
parse_cipher_name(char *full, char **cipher, char **pad)
{
char *p, *p2, *q;
*cipher = full;
*pad = NULL;
p = strchr(full, '/');
if (p != NULL)
*p++ = 0;
while (p != NULL) {
if ((q = strchr(p, '/')) != NULL)
*q++ = 0;
if (!*p) {
p = q;
continue;
}
p2 = strchr(p, ':');
if (p2 != NULL) {
*p2++ = 0;
if (!strcmp(p, "pad")) {
*pad = p2;
} else {
elog(ERROR, "Unknown component: '%s'", p);
}
}
p = q;
}
}
/* provider */
int
px_find_combo(const char *name, PX_Combo **res)
{
int err;
char *buf, *s_cipher, *s_pad;
PX_Combo *cx;
cx = px_alloc(sizeof(*cx));
memset(cx, 0, sizeof(*cx));
buf = px_alloc(strlen(name) + 1);
strcpy(buf, name);
parse_cipher_name(buf, &s_cipher, &s_pad);
if (s_cipher == NULL) {
px_free(buf);
px_free(cx);
return -1;
}
err = px_find_cipher(s_cipher, &cx->cipher);
if (err)
goto err1;
if (s_pad != NULL) {
if (!strcmp(s_pad, "pkcs"))
cx->padding = 1;
else if (!strcmp(s_pad, "none"))
cx->padding = 0;
else
goto err1;
} else
cx->padding = 1;
cx->init = combo_init;
cx->encrypt = combo_encrypt;
cx->decrypt = combo_decrypt;
cx->encrypt_len = combo_encrypt_len;
cx->decrypt_len = combo_decrypt_len;
cx->free = combo_free;
px_free(buf);
*res = cx;
return 0;
err1:
if (cx->cipher)
px_cipher_free(cx->cipher);
px_free(cx);
px_free(buf);
return -1;
}
/*
* px.h
* Header file for pgcrypto.
*
* 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.
*
* $Id: px.h,v 1.1 2001/08/21 01:32:01 momjian Exp $
*/
#ifndef __PX_H
#define __PX_H
#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 */
#define PX_MAX_NAMELEN 128
/* max salt returned */
#define PX_MAX_SALT_LEN 128
typedef struct px_digest PX_MD;
typedef struct px_alias PX_Alias;
typedef struct px_hmac PX_HMAC;
typedef struct px_cipher PX_Cipher;
typedef struct px_combo PX_Combo;
struct px_digest {
uint (*result_size)(PX_MD *h);
uint (*block_size)(PX_MD *h);
void (*reset)(PX_MD *h);
void (*update)(PX_MD *h, const uint8 *data, uint dlen);
void (*finish)(PX_MD *h, uint8 *dst);
void (*free)(PX_MD *h);
/* private */
union {
uint code;
const void *ptr;
} p;
};
struct px_alias {
char *alias;
char *name;
};
struct px_hmac {
uint (*result_size)(PX_HMAC *h);
uint (*block_size)(PX_HMAC *h);
void (*reset)(PX_HMAC *h);
void (*update)(PX_HMAC *h, const uint8 *data, uint dlen);
void (*finish)(PX_HMAC *h, uint8 *dst);
void (*free)(PX_HMAC *h);
void (*init)(PX_HMAC *h, const uint8 *key, uint klen);
PX_MD *md;
/* private */
struct {
uint8 *ipad;
uint8 *opad;
} p;
};
struct px_cipher {
uint (*block_size)(PX_Cipher *c);
uint (*key_size)(PX_Cipher *c); /* max key len */
uint (*iv_size)(PX_Cipher *c);
int (*init)(PX_Cipher *c, const uint8 *key, uint klen, const uint8 *iv);
int (*encrypt)(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res);
int (*decrypt)(PX_Cipher *c, const uint8 *data, uint dlen, uint8 *res);
void (*free)(PX_Cipher *c);
/* private */
void *ptr;
int pstat; /* mcrypt uses it */
};
struct px_combo {
int (*init)(PX_Combo *cx, const uint8 *key, uint klen,
const uint8 *iv, uint ivlen);
int (*encrypt)(PX_Combo *cx, const uint8 *data, uint dlen,
uint8 *res, uint *rlen);
int (*decrypt)(PX_Combo *cx, const uint8 *data, uint dlen,
uint8 *res, uint *rlen);
uint (*encrypt_len)(PX_Combo *cx, uint dlen);
uint (*decrypt_len)(PX_Combo *cx, uint dlen);
void (*free)(PX_Combo *cx);
PX_Cipher *cipher;
uint padding;
};
int px_find_digest(const char *name, PX_MD **res);
int px_find_hmac(const char *name, PX_HMAC **res);
int px_find_cipher(const char *name, PX_Cipher **res);
int px_find_combo(const char *name, PX_Combo **res);
const char *px_resolve_alias(const PX_Alias *aliases, const char *name);
#define px_md_result_size(md) (md)->result_size(md)
#define px_md_block_size(md) (md)->block_size(md)
#define px_md_reset(md) (md)->reset(md)
#define px_md_update(md, data, dlen) (md)->update(md, data, dlen)
#define px_md_finish(md, buf) (md)->finish(md, buf)
#define px_md_free(md) (md)->free(md)
#define px_hmac_result_size(hmac) (hmac)->result_size(hmac)
#define px_hmac_block_size(hmac) (hmac)->block_size(hmac)
#define px_hmac_reset(hmac) (hmac)->reset(hmac)
#define px_hmac_init(hmac, key, klen) (hmac)->init(hmac, key, klen)
#define px_hmac_update(hmac, data, dlen) (hmac)->update(hmac, data, dlen)
#define px_hmac_finish(hmac, buf) (hmac)->finish(hmac, buf)
#define px_hmac_free(hmac) (hmac)->free(hmac)
#define px_cipher_key_size(c) (c)->key_size(c)
#define px_cipher_block_size(c) (c)->block_size(c)
#define px_cipher_iv_size(c) (c)->iv_size(c)
#define px_cipher_init(c, k, klen, iv) (c)->init(c, k, klen, iv)
#define px_cipher_encrypt(c, data, dlen, res) \
(c)->encrypt(c, data, dlen, res)
#define px_cipher_decrypt(c, data, dlen, res) \
(c)->decrypt(c, data, dlen, res)
#define px_cipher_free(c) (c)->free(c)
#define px_combo_encrypt_len(c, dlen) (c)->encrypt_len(c, dlen)
#define px_combo_decrypt_len(c, dlen) (c)->decrypt_len(c, dlen)
#define px_combo_init(c, key, klen, iv, ivlen) \
(c)->init(c, key, klen, iv, ivlen)
#define px_combo_encrypt(c, data, dlen, res, rlen) \
(c)->encrypt(c, data, dlen, res, rlen)
#define px_combo_decrypt(c, data, dlen, res, rlen) \
(c)->decrypt(c, data, dlen, res, rlen)
#define px_combo_free(c) (c)->free(c)
#endif /* __PX_H */
This diff is collapsed.
/* $OpenBSD: rijndael.h,v 1.3 2001/05/09 23:01:32 markus Exp $ */
/* This is an independent implementation of the encryption algorithm: */
/* */
/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
#ifndef _RIJNDAEL_H_
#define _RIJNDAEL_H_
/* 1. Standard types for AES cryptography source code */
typedef uint8 u1byte; /* an 8 bit unsigned character type */
typedef uint16 u2byte; /* a 16 bit unsigned integer type */
typedef uint32 u4byte; /* a 32 bit unsigned integer type */
typedef int8 s1byte; /* an 8 bit signed character type */
typedef int16 s2byte; /* a 16 bit signed integer type */
typedef int32 s4byte; /* a 32 bit signed integer type */
typedef struct _rijndael_ctx {
u4byte k_len;
int decrypt;
u4byte e_key[64];
u4byte d_key[64];
} rijndael_ctx;
/* 2. Standard interface for AES cryptographic routines */
/* These are all based on 32 bit unsigned values and will therefore */
/* require endian conversions for big-endian architectures */
rijndael_ctx *
rijndael_set_key __P((rijndael_ctx *, const u4byte *, const u4byte, int));
void rijndael_encrypt __P((rijndael_ctx *, const u4byte *, u4byte *));
void rijndael_decrypt __P((rijndael_ctx *, const u4byte *, u4byte *));
/* conventional interface */
void aes_set_key(rijndael_ctx * ctx, const uint8 *key, uint keybits, int enc);
void aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
void aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
void aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len);
void aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len);
#endif /* _RIJNDAEL_H_ */
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment