3
* Various cryptographic stuff for PostgreSQL.
5
* Copyright (c) 2001 Marko Kreen
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* contrib/pgcrypto/px.c
42
static const struct error_desc px_err_list[] = {
43
{PXE_OK, "Everything ok"},
44
{PXE_ERR_GENERIC, "Some PX error (not specified)"},
45
{PXE_NO_HASH, "No such hash algorithm"},
46
{PXE_NO_CIPHER, "No such cipher algorithm"},
47
{PXE_NOTBLOCKSIZE, "Data not a multiple of block size"},
48
{PXE_BAD_OPTION, "Unknown option"},
49
{PXE_BAD_FORMAT, "Badly formatted type"},
50
{PXE_KEY_TOO_BIG, "Key was too big"},
51
{PXE_CIPHER_INIT, "Cipher cannot be initalized ?"},
52
{PXE_HASH_UNUSABLE_FOR_HMAC, "This hash algorithm is unusable for HMAC"},
53
{PXE_DEV_READ_ERROR, "Error reading from random device"},
54
{PXE_OSSL_RAND_ERROR, "OpenSSL PRNG error"},
55
{PXE_BUG, "pgcrypto bug"},
56
{PXE_ARGUMENT_ERROR, "Illegal argument to function"},
57
{PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"},
58
{PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"},
59
{PXE_MCRYPT_INTERNAL, "mcrypt internal error"},
60
{PXE_NO_RANDOM, "No strong random source"},
61
{PXE_DECRYPT_FAILED, "Decryption failed"},
62
{PXE_PGP_CORRUPT_DATA, "Wrong key or corrupt data"},
63
{PXE_PGP_CORRUPT_ARMOR, "Corrupt ascii-armor"},
64
{PXE_PGP_UNSUPPORTED_COMPR, "Unsupported compression algorithm"},
65
{PXE_PGP_UNSUPPORTED_CIPHER, "Unsupported cipher algorithm"},
66
{PXE_PGP_UNSUPPORTED_HASH, "Unsupported digest algorithm"},
67
{PXE_PGP_COMPRESSION_ERROR, "Compression error"},
68
{PXE_PGP_NOT_TEXT, "Not text data"},
69
{PXE_PGP_UNEXPECTED_PKT, "Unexpected packet in key data"},
71
"public-key functions disabled - "
72
"pgcrypto needs OpenSSL for bignums"},
73
{PXE_PGP_MATH_FAILED, "Math operation failed"},
74
{PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
75
{PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
76
{PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
77
{PXE_PGP_WRONG_KEY, "Wrong key"},
78
{PXE_PGP_MULTIPLE_KEYS,
79
"Several keys given - pgcrypto does not handle keyring"},
80
{PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
81
{PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
82
{PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
83
{PXE_PGP_KEYPKT_CORRUPT, "Corrupt key packet"},
84
{PXE_PGP_NO_USABLE_KEY, "No encryption key found"},
85
{PXE_PGP_NEED_SECRET_PSW, "Need password for secret key"},
86
{PXE_PGP_BAD_S2K_MODE, "Bad S2K mode"},
87
{PXE_PGP_UNSUPPORTED_PUBALGO, "Unsupported public key algorithm"},
88
{PXE_PGP_MULTIPLE_SUBKEYS, "Several subkeys not supported"},
90
/* fake this as PXE_PGP_CORRUPT_DATA */
91
{PXE_MBUF_SHORT_READ, "Corrupt data"},
99
const struct error_desc *e;
101
for (e = px_err_list; e->desc; e++)
104
return "Bad error code";
109
px_resolve_alias(const PX_Alias *list, const char *name)
113
if (pg_strcasecmp(list->alias, name) == 0)
120
static void (*debug_handler) (const char *) = NULL;
123
px_set_debug_handler(void (*handler) (const char *))
125
debug_handler = handler;
129
px_debug(const char *fmt,...)
138
vsnprintf(buf, sizeof(buf), fmt, ap);
145
* combo - cipher + padding (+ checksum)
149
combo_encrypt_len(PX_Combo *cx, unsigned dlen)
155
combo_decrypt_len(PX_Combo *cx, unsigned dlen)
161
combo_init(PX_Combo *cx, const uint8 *key, unsigned klen,
162
const uint8 *iv, unsigned ivlen)
167
PX_Cipher *c = cx->cipher;
171
ks = px_cipher_key_size(c);
173
ivs = px_cipher_iv_size(c);
176
ivbuf = px_alloc(ivs);
177
memset(ivbuf, 0, ivs);
179
memcpy(ivbuf, iv, ivs);
181
memcpy(ivbuf, iv, ivlen);
186
keybuf = px_alloc(ks);
187
memset(keybuf, 0, ks);
188
memcpy(keybuf, key, klen);
190
err = px_cipher_init(c, keybuf, klen, ivbuf);
200
combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
201
uint8 *res, unsigned *rlen)
210
PX_Cipher *c = cx->cipher;
213
bs = px_cipher_block_size(c);
218
bbuf = px_alloc(bs * 4);
221
memcpy(bbuf, data + *rlen, bpos);
223
/* encrypt full-block data */
226
err = px_cipher_encrypt(c, data, *rlen, res);
231
/* bbuf has now bpos bytes of stuff */
234
pad = bs - (bpos % bs);
235
for (i = 0; i < pad; i++)
241
pad = bs - (bpos % bs);
242
for (i = 0; i < pad; i++)
246
/* encrypt the rest - pad */
249
err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
255
/* stream cipher/mode - no pad needed */
256
err = px_cipher_encrypt(c, data, dlen, res);
269
combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
270
uint8 *res, unsigned *rlen)
277
PX_Cipher *c = cx->cipher;
279
/* decide whether zero-length input is allowed */
282
/* with padding, empty ciphertext is not allowed */
284
return PXE_DECRYPT_FAILED;
286
/* without padding, report empty result */
291
bs = px_cipher_block_size(c);
292
if (bs > 1 && (dlen % bs) != 0)
297
px_cipher_decrypt(c, data, dlen, res);
300
if (bs > 1 && cx->padding)
302
pad = res[*rlen - 1];
304
if (pad > 0 && pad <= bs && pad <= *rlen)
307
for (i = *rlen - pad; i < *rlen; i++)
322
return PXE_NOTBLOCKSIZE;
326
combo_free(PX_Combo *cx)
329
px_cipher_free(cx->cipher);
330
memset(cx, 0, sizeof(*cx));
337
parse_cipher_name(char *full, char **cipher, char **pad)
346
p = strchr(full, '/');
351
if ((q = strchr(p, '/')) != NULL)
363
if (!strcmp(p, "pad"))
366
return PXE_BAD_OPTION;
369
return PXE_BAD_FORMAT;
379
px_find_combo(const char *name, PX_Combo **res)
388
cx = px_alloc(sizeof(*cx));
389
memset(cx, 0, sizeof(*cx));
391
buf = px_alloc(strlen(name) + 1);
394
err = parse_cipher_name(buf, &s_cipher, &s_pad);
402
err = px_find_cipher(s_cipher, &cx->cipher);
408
if (!strcmp(s_pad, "pkcs"))
410
else if (!strcmp(s_pad, "none"))
418
cx->init = combo_init;
419
cx->encrypt = combo_encrypt;
420
cx->decrypt = combo_decrypt;
421
cx->encrypt_len = combo_encrypt_len;
422
cx->decrypt_len = combo_decrypt_len;
423
cx->free = combo_free;
433
px_cipher_free(cx->cipher);
436
return PXE_NO_CIPHER;