5 * Copyright (c) 2005 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/pgp-decrypt.c
39 #define ALLOW_CTX_SIZE 1
49 #define MAX_CHUNK (16*1024*1024)
61 else if (
b >= 192 &&
b <= 223)
63 len = ((unsigned) (
b) - 192) << 8;
80 len = 1 << (
b & 0x1F);
86 px_debug(
"parse_new_len: weird length");
108 else if (lentype == 2)
120 px_debug(
"parse_old_len: weird length");
127/* returns pkttype or 0 on eof */
135 /* EOF is normal here, thus we don't use GETBYTE */
142 if ((*p & 0x80) == 0)
144 px_debug(
"pgp_parse_pkt_hdr: not pkt hdr");
156 *tag = (*p >> 2) & 0x0F;
181 /* PKT_CONTEXT means: whatever there is */
185 while (pkt->
len == 0)
187 /* this was last chunk in stream */
191 /* next chunk in stream */
221/* needs helper function to pass several parameters */
238 * Prefix check filter
239 * https://tools.ietf.org/html/rfc4880#section-5.7
240 * https://tools.ietf.org/html/rfc4880#section-5.13
253 /* Make sure we have space for prefix */
262 px_debug(
"prefix_init: short read");
269 px_debug(
"prefix_init: corrupt prefix");
270 /* report error in pgp_decrypt() */
293 /* we need to write somewhere, so ask for a buffer */
351 /* should not happen */
359 /* mdc_read should not call px_md_update */
372 /* is the packet sane? */
375 px_debug(
"mdc_finish: read failed, res=%d", res);
380 * ok, we got the hash, now check
402 /* skip this filter? */
411 px_debug(
"mdc_read: unexpected eof");
425 * Combined Pkt reader and MDC hasher.
427 * For the case of SYMENCRYPTED_DATA_MDC packet, where
428 * the data part has 'context length', which means
429 * that data packet ends 22 bytes before end of parent
430 * packet, which is silly.
432 #define MDCBUF_LEN 8192
456 /* take over the work of mdc_filter */
472 px_debug(
"mdcbuf_finish: bad MDC pkt hdr");
481 px_debug(
"mdcbuf_finish: MDC does not match");
492 memcpy(dst, src,
len);
511 /* put avail data in start */
588 * Decrypt separate session key
613 px_debug(
"sesskey bad len: algo=%d, expected=%d, got=%d",
650 * generate key from password
658 * do we have separate session key?
667 * no, s2k key is session key
682 px_debug(
"expect key, but bad data");
709 while (
data < data_end)
713 if (
data + 1 < data_end)
715 if (*(
data + 1) ==
'\n')
768 px_debug(
"parse_literal_data: unexpected eof");
776 px_debug(
"parse_literal_data: unexpected eof");
782 * If called from an SQL function that returns text, pgp_decrypt() rejects
783 * inputs not self-identifying as text.
808 if (res >= 0 && got_cr)
813/* process_data_packets and parse_compressed_data call each other */
815 PullFilter *src,
int allow_compr,
int need_mdc);
846 px_debug(
"parse_compressed_data: bzip2 unsupported");
847 /* report error in pgp_decrypt() */
851 * Discard the compressed data, allowing it to first affect any
852 * MDC digest computation.
856 res =
pullf_read(pkt, 32 * 1024, &discard_buf);
864 px_debug(
"parse_compressed_data: unknown compr type");
873 int allow_compr,
int need_mdc)
889 /* mdc packet should be last */
892 px_debug(
"process_data_packets: data after mdc");
898 * Context length inside SYMENCRYPTED_DATA_MDC packet needs special
915 if (allow_compr == 0)
917 px_debug(
"process_data_packets: unexpected compression");
923 * compr data must be alone
925 px_debug(
"process_data_packets: only one cmpr pkt allowed");
937 px_debug(
"process_data_packets: unexpected MDC");
947 px_debug(
"process_data_packets: unexpected pkt tag=%d", tag);
966 px_debug(
"process_data_packets: no data");
971 px_debug(
"process_data_packets: got no mdc");
1024 px_debug(
"parse_symenc_mdc_data: pkt ver != 1");
1061 * skip over packet contents
1075 * expect to be at packet end, any data is error
1086 px_debug(
"pgp_expect_packet_end: got data");
1122 /* fixme: skip those */
1130 * Theoretically, there could be several keys, both public
1131 * and symmetric, all of which encrypt same session key.
1132 * Decrypt should try with each one, before failing.
1134 px_debug(
"pgp_decrypt: using first of several keys");
1143 px_debug(
"pgp_decrypt: have data but no key");
1145 px_debug(
"pgp_decrypt: got second data packet");
1155 px_debug(
"pgp_decrypt: have data but no key");
1157 px_debug(
"pgp_decrypt: several data pkts not supported");
1166 px_debug(
"pgp_decrypt: unknown tag: 0x%02x", tag);
1182 * Report a failure of the prefix_init() "quick check" now, rather than
1183 * upon detection, to hinder timing attacks. pgcrypto is not generally
1184 * secure against timing attacks, but this helps.
1190 * Code interpreting purportedly-decrypted data prior to this stage shall
1191 * report no error other than PXE_PGP_CORRUPT_DATA. (PXE_BUG is okay so
1192 * long as it remains unreachable.) This ensures that an attacker able to
1193 * choose a ciphertext and receive a corresponding decryption error
1194 * message cannot use that oracle to gather clues about the decryption
1195 * key. See "An Attack on CFB Mode Encryption As Used By OpenPGP" by
1196 * Serge Mister and Robert Zuccherato.
1198 * A problematic value in the first octet of a Literal Data or Compressed
1199 * Data packet may indicate a simple user error, such as the need to call
1200 * pgp_sym_decrypt_bytea instead of pgp_sym_decrypt. Occasionally,
1201 * though, it is the first symptom of the encryption key not matching the
1202 * decryption key. When this was the only problem encountered, report a
1203 * specific error to guide the user; otherwise, we will have reported
1204 * PXE_PGP_CORRUPT_DATA before now. A key mismatch makes the other errors
1205 * into red herrings, and this avoids leaking clues to attackers.
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
int pullf_create_mbuf_reader(PullFilter **mp_p, MBuf *src)
int mbuf_append(MBuf *dst, const uint8 *buf, int len)
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
void pullf_free(PullFilter *pf)
void pfree(void *pointer)
void * palloc0(Size size)
void pgp_cfb_free(PGP_CFB *ctx)
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, int resync, uint8 *iv)
int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
static struct PullFilterOps prefix_filter
static int decrypt_init(void **priv_p, void *arg, PullFilter *src)
int pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
static void mdc_free(void *priv)
static int copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
static int decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
static void mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
static void pktreader_free(void *priv)
static int parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
int pgp_expect_packet_end(PullFilter *pkt)
static int mdc_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
static int mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
static int pktreader_pull(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
static int prefix_init(void **priv_p, void *arg, PullFilter *src)
static void mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
static int parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
static int process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src, int allow_compr, int need_mdc)
static int mdcbuf_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
static int parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
static int parse_old_len(PullFilter *src, int *len_p, int lentype)
static int parse_new_len(PullFilter *src, int *len_p)
static int decrypt_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
static int parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
static int mdc_init(void **priv_p, void *arg, PullFilter *src)
struct PullFilterOps pgp_decrypt_filter
static int mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
int pgp_skip_packet(PullFilter *pkt)
static struct PullFilterOps mdcbuf_filter
static void mdcbuf_free(void *priv)
static int parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
static struct PullFilterOps mdc_filter
int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx)
static struct PullFilterOps pktreader_filter
static int mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
static int mdcbuf_finish(struct MDCBufData *st)
int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
int pgp_get_cipher_block_size(int code)
int pgp_get_cipher_key_size(int code)
int pgp_load_digest(int code, PX_MD **res)
@ PGP_PKT_SYMENCRYPTED_DATA
@ PGP_PKT_COMPRESSED_DATA
@ PGP_PKT_SYMENCRYPTED_SESSKEY
@ PGP_PKT_SYMENCRYPTED_DATA_MDC
@ PGP_PKT_PUBENCRYPTED_SESSKEY
#define s2k_decode_count(cval)
void px_debug(const char *fmt,...)
void px_memset(void *ptr, int c, size_t len)
#define PXE_PGP_UNSUPPORTED_COMPR
#define px_md_finish(md, buf)
#define PXE_PGP_CORRUPT_DATA
#define px_md_update(md, data, dlen)
static unsigned hash(unsigned *uv, int n)
uint8 sess_key[PGP_MAX_KEY]
static StringInfoData tmpbuf