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
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
)
168 PX_Cipher
*c
= cx
->cipher
;
172 bs
= px_cipher_block_size(c
);
173 ks
= px_cipher_key_size(c
);
175 ivs
= px_cipher_iv_size(c
);
178 ivbuf
= px_alloc(ivs
);
179 memset(ivbuf
, 0, ivs
);
181 memcpy(ivbuf
, iv
, ivs
);
183 memcpy(ivbuf
, iv
, ivlen
);
188 keybuf
= px_alloc(ks
);
189 memset(keybuf
, 0, ks
);
190 memcpy(keybuf
, key
, klen
);
192 err
= px_cipher_init(c
, keybuf
, klen
, ivbuf
);
202 combo_encrypt(PX_Combo
* cx
, const uint8
*data
, unsigned dlen
,
203 uint8
*res
, unsigned *rlen
)
213 PX_Cipher
*c
= cx
->cipher
;
217 bs
= px_cipher_block_size(c
);
222 bbuf
= px_alloc(bs
* 4);
225 memcpy(bbuf
, data
+ *rlen
, bpos
);
227 /* encrypt full-block data */
230 err
= px_cipher_encrypt(c
, data
, *rlen
, res
);
235 /* bbuf has now bpos bytes of stuff */
238 pad
= bs
- (bpos
% bs
);
239 for (i
= 0; i
< pad
; i
++)
245 pad
= bs
- (bpos
% bs
);
246 for (i
= 0; i
< pad
; i
++)
250 /* encrypt the rest - pad */
253 err
= px_cipher_encrypt(c
, bbuf
, bpos
, res
+ *rlen
);
259 /* stream cipher/mode - no pad needed */
260 err
= px_cipher_encrypt(c
, data
, dlen
, res
);
273 combo_decrypt(PX_Combo
* cx
, const uint8
*data
, unsigned dlen
,
274 uint8
*res
, unsigned *rlen
)
281 PX_Cipher
*c
= cx
->cipher
;
283 /* decide whether zero-length input is allowed */
286 /* with padding, empty ciphertext is not allowed */
288 return PXE_DECRYPT_FAILED
;
290 /* without padding, report empty result */
295 bs
= px_cipher_block_size(c
);
296 if (bs
> 1 && (dlen
% bs
) != 0)
301 px_cipher_decrypt(c
, data
, dlen
, res
);
304 if (bs
> 1 && cx
->padding
)
306 pad
= res
[*rlen
- 1];
308 if (pad
> 0 && pad
<= bs
&& pad
<= *rlen
)
311 for (i
= *rlen
- pad
; i
< *rlen
; i
++)
326 return PXE_NOTBLOCKSIZE
;
330 combo_free(PX_Combo
* cx
)
333 px_cipher_free(cx
->cipher
);
334 memset(cx
, 0, sizeof(*cx
));
341 parse_cipher_name(char *full
, char **cipher
, char **pad
)
350 p
= strchr(full
, '/');
355 if ((q
= strchr(p
, '/')) != NULL
)
367 if (!strcmp(p
, "pad"))
370 return PXE_BAD_OPTION
;
373 return PXE_BAD_FORMAT
;
383 px_find_combo(const char *name
, PX_Combo
** res
)
392 cx
= px_alloc(sizeof(*cx
));
393 memset(cx
, 0, sizeof(*cx
));
395 buf
= px_alloc(strlen(name
) + 1);
398 err
= parse_cipher_name(buf
, &s_cipher
, &s_pad
);
406 err
= px_find_cipher(s_cipher
, &cx
->cipher
);
412 if (!strcmp(s_pad
, "pkcs"))
414 else if (!strcmp(s_pad
, "none"))
422 cx
->init
= combo_init
;
423 cx
->encrypt
= combo_encrypt
;
424 cx
->decrypt
= combo_decrypt
;
425 cx
->encrypt_len
= combo_encrypt_len
;
426 cx
->decrypt_len
= combo_decrypt_len
;
427 cx
->free
= combo_free
;
437 px_cipher_free(cx
->cipher
);
440 return PXE_NO_CIPHER
;