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
39 #define ALLOW_CTX_SIZE 1
49 #define MAX_CHUNK (16*1024*1024)
52 parse_new_len(PullFilter
* src
, int *len_p
)
56 int pkttype
= PKT_NORMAL
;
61 else if (b
>= 192 && b
<= 223)
63 len
= ((unsigned) (b
) - 192) << 8;
80 len
= 1 << (b
& 0x1F);
84 if (len
< 0 || len
> MAX_CHUNK
)
86 px_debug("parse_new_len: weird length");
87 return PXE_PGP_CORRUPT_DATA
;
95 parse_old_len(PullFilter
* src
, int *len_p
, int lentype
)
106 len
= (len
<< 8) | b
;
108 else if (lentype
== 2)
111 len
= (len
<< 8) | b
;
113 len
= (len
<< 8) | b
;
115 len
= (len
<< 8) | b
;
118 if (len
< 0 || len
> MAX_CHUNK
)
120 px_debug("parse_old_len: weird length");
121 return PXE_PGP_CORRUPT_DATA
;
127 /* returns pkttype or 0 on eof */
129 pgp_parse_pkt_hdr(PullFilter
* src
, uint8
*tag
, int *len_p
, int allow_ctx
)
135 /* EOF is normal here, thus we dont use GETBYTE */
136 res
= pullf_read(src
, 1, &p
);
142 if ((*p
& 0x80) == 0)
144 px_debug("pgp_parse_pkt_hdr: not pkt hdr");
145 return PXE_PGP_CORRUPT_DATA
;
151 res
= parse_new_len(src
, len_p
);
156 *tag
= (*p
>> 2) & 0x0F;
158 res
= allow_ctx
? PKT_CONTEXT
: PXE_PGP_CORRUPT_DATA
;
160 res
= parse_old_len(src
, len_p
, lentype
);
175 pktreader_pull(void *priv
, PullFilter
* src
, int len
,
176 uint8
**data_p
, uint8
*buf
, int buflen
)
179 struct PktData
*pkt
= priv
;
181 /* PKT_CONTEXT means: whatever there is */
182 if (pkt
->type
== PKT_CONTEXT
)
183 return pullf_read(src
, len
, data_p
);
187 /* this was last chunk in stream */
188 if (pkt
->type
== PKT_NORMAL
)
191 /* next chunk in stream */
192 res
= parse_new_len(src
, &pkt
->len
);
201 res
= pullf_read(src
, len
, data_p
);
209 pktreader_free(void *priv
)
211 struct PktData
*pkt
= priv
;
213 memset(pkt
, 0, sizeof(*pkt
));
217 static struct PullFilterOps pktreader_filter
= {
218 NULL
, pktreader_pull
, pktreader_free
221 /* needs helper function to pass several parameters */
223 pgp_create_pkt_reader(PullFilter
** pf_p
, PullFilter
* src
, int len
,
224 int pkttype
, PGP_Context
* ctx
)
227 struct PktData
*pkt
= px_alloc(sizeof(*pkt
));
231 res
= pullf_create(pf_p
, &pktreader_filter
, pkt
, src
);
238 * Prefix check filter
242 prefix_init(void **priv_p
, void *arg
, PullFilter
* src
)
244 PGP_Context
*ctx
= arg
;
248 uint8 tmpbuf
[PGP_MAX_BLOCK
+ 2];
250 len
= pgp_get_cipher_block_size(ctx
->cipher_algo
);
251 if (len
> sizeof(tmpbuf
))
254 res
= pullf_read_max(src
, len
+ 2, &buf
, tmpbuf
);
259 px_debug("prefix_init: short read");
260 memset(tmpbuf
, 0, sizeof(tmpbuf
));
261 return PXE_PGP_CORRUPT_DATA
;
264 if (buf
[len
- 2] != buf
[len
] || buf
[len
- 1] != buf
[len
+ 1])
266 px_debug("prefix_init: corrupt prefix");
269 * The original purpose of the 2-byte check was to show user a
270 * friendly "wrong key" message. This made following possible:
272 * "An Attack on CFB Mode Encryption As Used By OpenPGP" by Serge
273 * Mister and Robert Zuccherato
275 * To avoid being 'oracle', we delay reporting, which basically means
276 * we prefer to run into corrupt packet header.
278 * We _could_ throw PXE_PGP_CORRUPT_DATA here, but there is
279 * possibility of attack via timing, so we don't.
281 ctx
->corrupt_prefix
= 1;
283 memset(tmpbuf
, 0, sizeof(tmpbuf
));
287 static struct PullFilterOps prefix_filter
= {
288 prefix_init
, NULL
, NULL
297 decrypt_init(void **priv_p
, void *arg
, PullFilter
* src
)
303 /* we need to write somewhere, so ask for a buffer */
308 decrypt_read(void *priv
, PullFilter
* src
, int len
,
309 uint8
**data_p
, uint8
*buf
, int buflen
)
315 res
= pullf_read(src
, len
, &tmp
);
318 pgp_cfb_decrypt(cfb
, tmp
, res
, buf
);
324 struct PullFilterOps pgp_decrypt_filter
= {
325 decrypt_init
, decrypt_read
, NULL
334 mdc_init(void **priv_p
, void *arg
, PullFilter
* src
)
336 PGP_Context
*ctx
= arg
;
339 return pgp_load_digest(PGP_DIGEST_SHA1
, &ctx
->mdc_ctx
);
345 PGP_Context
*ctx
= priv
;
347 if (ctx
->use_mdcbuf_filter
)
349 px_md_free(ctx
->mdc_ctx
);
354 mdc_finish(PGP_Context
* ctx
, PullFilter
* src
,
355 int len
, uint8
**data_p
)
361 if (len
+ 1 > sizeof(tmpbuf
))
365 res
= pullf_read_max(src
, len
+ 1, data_p
, tmpbuf
);
370 if (ctx
->mdc_checked
== 0)
373 return PXE_PGP_CORRUPT_DATA
;
379 if (ctx
->in_mdc_pkt
> 1)
381 px_debug("mdc_finish: several times here?");
382 return PXE_PGP_CORRUPT_DATA
;
386 /* is the packet sane? */
389 px_debug("mdc_finish: read failed, res=%d", res
);
390 return PXE_PGP_CORRUPT_DATA
;
394 * ok, we got the hash, now check
396 px_md_finish(ctx
->mdc_ctx
, hash
);
397 res
= memcmp(hash
, *data_p
, 20);
399 memset(tmpbuf
, 0, sizeof(tmpbuf
));
402 px_debug("mdc_finish: mdc failed");
403 return PXE_PGP_CORRUPT_DATA
;
405 ctx
->mdc_checked
= 1;
410 mdc_read(void *priv
, PullFilter
* src
, int len
,
411 uint8
**data_p
, uint8
*buf
, int buflen
)
414 PGP_Context
*ctx
= priv
;
416 /* skip this filter? */
417 if (ctx
->use_mdcbuf_filter
)
418 return pullf_read(src
, len
, data_p
);
421 return mdc_finish(ctx
, src
, len
, data_p
);
423 res
= pullf_read(src
, len
, data_p
);
428 px_debug("mdc_read: unexpected eof");
429 return PXE_PGP_CORRUPT_DATA
;
431 px_md_update(ctx
->mdc_ctx
, *data_p
, res
);
436 static struct PullFilterOps mdc_filter
= {
437 mdc_init
, mdc_read
, mdc_free
442 * Combined Pkt reader and MDC hasher.
444 * For the case of SYMENCRYPTED_MDC packet, where
445 * the data part has 'context length', which means
446 * that data packet ends 22 bytes before end of parent
447 * packet, which is silly.
449 #define MDCBUF_LEN 8192
459 uint8 buf
[MDCBUF_LEN
];
463 mdcbuf_init(void **priv_p
, void *arg
, PullFilter
* src
)
465 PGP_Context
*ctx
= arg
;
466 struct MDCBufData
*st
;
468 st
= px_alloc(sizeof(*st
));
469 memset(st
, 0, sizeof(*st
));
470 st
->buflen
= sizeof(st
->buf
);
474 /* take over the work of mdc_filter */
475 ctx
->use_mdcbuf_filter
= 1;
481 mdcbuf_finish(struct MDCBufData
* st
)
488 if (st
->mdc_buf
[0] != 0xD3 || st
->mdc_buf
[1] != 0x14)
490 px_debug("mdcbuf_finish: bad MDC pkt hdr");
491 return PXE_PGP_CORRUPT_DATA
;
493 px_md_update(st
->ctx
->mdc_ctx
, st
->mdc_buf
, 2);
494 px_md_finish(st
->ctx
->mdc_ctx
, hash
);
495 res
= memcmp(hash
, st
->mdc_buf
+ 2, 20);
499 px_debug("mdcbuf_finish: MDC does not match");
500 res
= PXE_PGP_CORRUPT_DATA
;
506 mdcbuf_load_data(struct MDCBufData
* st
, uint8
*src
, int len
)
508 uint8
*dst
= st
->pos
+ st
->avail
;
510 memcpy(dst
, src
, len
);
511 px_md_update(st
->ctx
->mdc_ctx
, src
, len
);
516 mdcbuf_load_mdc(struct MDCBufData
* st
, uint8
*src
, int len
)
518 memmove(st
->mdc_buf
+ st
->mdc_avail
, src
, len
);
519 st
->mdc_avail
+= len
;
523 mdcbuf_refill(struct MDCBufData
* st
, PullFilter
* src
)
529 /* put avail data in start */
530 if (st
->avail
> 0 && st
->pos
!= st
->buf
)
531 memmove(st
->buf
, st
->pos
, st
->avail
);
535 need
= st
->buflen
+ 22 - st
->avail
- st
->mdc_avail
;
536 res
= pullf_read(src
, need
, &data
);
540 return mdcbuf_finish(st
);
545 mdcbuf_load_data(st
, st
->mdc_buf
, st
->mdc_avail
);
548 mdcbuf_load_data(st
, data
, res
- 22);
549 mdcbuf_load_mdc(st
, data
+ res
- 22, 22);
553 int canmove
= st
->mdc_avail
+ res
- 22;
557 mdcbuf_load_data(st
, st
->mdc_buf
, canmove
);
558 st
->mdc_avail
-= canmove
;
559 memmove(st
->mdc_buf
, st
->mdc_buf
+ canmove
, st
->mdc_avail
);
561 mdcbuf_load_mdc(st
, data
, res
);
567 mdcbuf_read(void *priv
, PullFilter
* src
, int len
,
568 uint8
**data_p
, uint8
*buf
, int buflen
)
570 struct MDCBufData
*st
= priv
;
573 if (!st
->eof
&& len
> st
->avail
)
575 res
= mdcbuf_refill(st
, src
);
590 mdcbuf_free(void *priv
)
592 struct MDCBufData
*st
= priv
;
594 px_md_free(st
->ctx
->mdc_ctx
);
595 st
->ctx
->mdc_ctx
= NULL
;
596 memset(st
, 0, sizeof(*st
));
600 static struct PullFilterOps mdcbuf_filter
= {
601 mdcbuf_init
, mdcbuf_read
, mdcbuf_free
606 * Decrypt separate session key
609 decrypt_key(PGP_Context
* ctx
, const uint8
*src
, int len
)
615 res
= pgp_cfb_create(&cfb
, ctx
->s2k_cipher_algo
,
616 ctx
->s2k
.key
, ctx
->s2k
.key_len
, 0, NULL
);
620 pgp_cfb_decrypt(cfb
, src
, 1, &algo
);
624 pgp_cfb_decrypt(cfb
, src
, len
, ctx
->sess_key
);
626 ctx
->sess_key_len
= len
;
627 ctx
->cipher_algo
= algo
;
629 if (pgp_get_cipher_key_size(algo
) != len
)
631 px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
632 algo
, pgp_get_cipher_key_size(algo
), len
);
633 return PXE_PGP_CORRUPT_DATA
;
642 parse_symenc_sesskey(PGP_Context
* ctx
, PullFilter
* src
)
646 uint8 tmpbuf
[PGP_MAX_KEY
+ 2];
650 GETBYTE(src
, ctx
->s2k_cipher_algo
);
653 px_debug("bad key pkt ver");
654 return PXE_PGP_CORRUPT_DATA
;
660 res
= pgp_s2k_read(src
, &ctx
->s2k
);
663 ctx
->s2k_mode
= ctx
->s2k
.mode
;
664 ctx
->s2k_digest_algo
= ctx
->s2k
.digest_algo
;
667 * generate key from password
669 res
= pgp_s2k_process(&ctx
->s2k
, ctx
->s2k_cipher_algo
,
670 ctx
->sym_key
, ctx
->sym_key_len
);
675 * do we have separate session key?
677 res
= pullf_read_max(src
, PGP_MAX_KEY
+ 2, &p
, tmpbuf
);
684 * no, s2k key is session key
686 memcpy(ctx
->sess_key
, ctx
->s2k
.key
, ctx
->s2k
.key_len
);
687 ctx
->sess_key_len
= ctx
->s2k
.key_len
;
688 ctx
->cipher_algo
= ctx
->s2k_cipher_algo
;
690 ctx
->use_sess_key
= 0;
697 if (res
< 17 || res
> PGP_MAX_KEY
+ 1)
699 px_debug("expect key, but bad data");
700 return PXE_PGP_CORRUPT_DATA
;
702 ctx
->use_sess_key
= 1;
703 res
= decrypt_key(ctx
, p
, res
);
706 memset(tmpbuf
, 0, sizeof(tmpbuf
));
711 copy_crlf(MBuf
* dst
, uint8
*data
, int len
, int *got_cr
)
713 uint8
*data_end
= data
+ len
;
715 uint8
*tmp_end
= tmpbuf
+ sizeof(tmpbuf
);
726 while (data
< data_end
)
730 if (data
+ 1 < data_end
)
732 if (*(data
+ 1) == '\n')
744 res
= mbuf_append(dst
, tmpbuf
, p
- tmpbuf
);
752 res
= mbuf_append(dst
, tmpbuf
, p
- tmpbuf
);
760 parse_literal_data(PGP_Context
* ctx
, MBuf
* dst
, PullFilter
* pkt
)
770 GETBYTE(pkt
, name_len
);
775 res
= pullf_read(pkt
, name_len
, &buf
);
784 px_debug("parse_literal_data: unexpected eof");
785 return PXE_PGP_CORRUPT_DATA
;
789 res
= pullf_read_max(pkt
, 4, &buf
, tmpbuf
);
792 px_debug("parse_literal_data: unexpected eof");
793 return PXE_PGP_CORRUPT_DATA
;
795 memset(tmpbuf
, 0, 4);
799 if (type
!= 't' && type
!= 'u')
801 px_debug("parse_literal_data: data type=%c", type
);
802 return PXE_PGP_NOT_TEXT
;
805 ctx
->unicode_mode
= (type
== 'u') ? 1 : 0;
810 res
= pullf_read(pkt
, 32 * 1024, &buf
);
814 if (ctx
->text_mode
&& ctx
->convert_crlf
)
815 res
= copy_crlf(dst
, buf
, res
, &got_cr
);
817 res
= mbuf_append(dst
, buf
, res
);
821 if (res
>= 0 && got_cr
)
822 res
= mbuf_append(dst
, (const uint8
*) "\r", 1);
826 /* process_data_packets and parse_compressed_data call each other */
827 static int process_data_packets(PGP_Context
* ctx
, MBuf
* dst
,
828 PullFilter
* src
, int allow_compr
, int need_mdc
);
831 parse_compressed_data(PGP_Context
* ctx
, MBuf
* dst
, PullFilter
* pkt
)
835 PullFilter
*pf_decompr
;
839 ctx
->compress_algo
= type
;
843 res
= process_data_packets(ctx
, dst
, pkt
, NO_COMPR
, NO_MDC
);
848 res
= pgp_decompress_filter(&pf_decompr
, ctx
, pkt
);
851 res
= process_data_packets(ctx
, dst
, pf_decompr
,
853 pullf_free(pf_decompr
);
857 case PGP_COMPR_BZIP2
:
858 px_debug("parse_compressed_data: bzip2 unsupported");
859 res
= PXE_PGP_UNSUPPORTED_COMPR
;
863 px_debug("parse_compressed_data: unknown compr type");
864 res
= PXE_PGP_CORRUPT_DATA
;
871 process_data_packets(PGP_Context
* ctx
, MBuf
* dst
, PullFilter
* src
,
872 int allow_compr
, int need_mdc
)
879 PullFilter
*pkt
= NULL
;
884 res
= pgp_parse_pkt_hdr(src
, &tag
, &len
, ALLOW_CTX_SIZE
);
889 /* mdc packet should be last */
892 px_debug("process_data_packets: data after mdc");
893 res
= PXE_PGP_CORRUPT_DATA
;
897 /* context length inside SYMENC_MDC needs special handling */
898 if (need_mdc
&& res
== PKT_CONTEXT
)
899 res
= pullf_create(&pkt
, &mdcbuf_filter
, ctx
, src
);
901 res
= pgp_create_pkt_reader(&pkt
, src
, len
, res
, ctx
);
907 case PGP_PKT_LITERAL_DATA
:
909 res
= parse_literal_data(ctx
, dst
, pkt
);
911 case PGP_PKT_COMPRESSED_DATA
:
912 if (allow_compr
== 0)
914 px_debug("process_data_packets: unexpected compression");
915 res
= PXE_PGP_CORRUPT_DATA
;
920 * compr data must be alone
922 px_debug("process_data_packets: only one cmpr pkt allowed");
923 res
= PXE_PGP_CORRUPT_DATA
;
928 res
= parse_compressed_data(ctx
, dst
, pkt
);
932 if (need_mdc
== NO_MDC
)
934 px_debug("process_data_packets: unexpected MDC");
935 res
= PXE_PGP_CORRUPT_DATA
;
939 /* notify mdc_filter */
942 res
= pullf_read(pkt
, 8192, &tmp
);
947 px_debug("process_data_packets: unexpected pkt tag=%d", tag
);
948 res
= PXE_PGP_CORRUPT_DATA
;
966 px_debug("process_data_packets: no data");
967 res
= PXE_PGP_CORRUPT_DATA
;
969 if (need_mdc
&& !got_mdc
&& !ctx
->use_mdcbuf_filter
)
971 px_debug("process_data_packets: got no mdc");
972 res
= PXE_PGP_CORRUPT_DATA
;
978 parse_symenc_data(PGP_Context
* ctx
, PullFilter
* pkt
, MBuf
* dst
)
982 PullFilter
*pf_decrypt
= NULL
;
983 PullFilter
*pf_prefix
= NULL
;
985 res
= pgp_cfb_create(&cfb
, ctx
->cipher_algo
,
986 ctx
->sess_key
, ctx
->sess_key_len
, 1, NULL
);
990 res
= pullf_create(&pf_decrypt
, &pgp_decrypt_filter
, cfb
, pkt
);
994 res
= pullf_create(&pf_prefix
, &prefix_filter
, ctx
, pf_decrypt
);
998 res
= process_data_packets(ctx
, dst
, pf_prefix
, ALLOW_COMPR
, NO_MDC
);
1002 pullf_free(pf_prefix
);
1004 pullf_free(pf_decrypt
);
1012 parse_symenc_mdc_data(PGP_Context
* ctx
, PullFilter
* pkt
, MBuf
* dst
)
1015 PGP_CFB
*cfb
= NULL
;
1016 PullFilter
*pf_decrypt
= NULL
;
1017 PullFilter
*pf_prefix
= NULL
;
1018 PullFilter
*pf_mdc
= NULL
;
1024 px_debug("parse_symenc_mdc_data: pkt ver != 1");
1025 return PXE_PGP_CORRUPT_DATA
;
1028 res
= pgp_cfb_create(&cfb
, ctx
->cipher_algo
,
1029 ctx
->sess_key
, ctx
->sess_key_len
, 0, NULL
);
1033 res
= pullf_create(&pf_decrypt
, &pgp_decrypt_filter
, cfb
, pkt
);
1037 res
= pullf_create(&pf_mdc
, &mdc_filter
, ctx
, pf_decrypt
);
1041 res
= pullf_create(&pf_prefix
, &prefix_filter
, ctx
, pf_mdc
);
1045 res
= process_data_packets(ctx
, dst
, pf_prefix
, ALLOW_COMPR
, NEED_MDC
);
1049 pullf_free(pf_prefix
);
1053 pullf_free(pf_decrypt
);
1061 * skip over packet contents
1064 pgp_skip_packet(PullFilter
* pkt
)
1070 res
= pullf_read(pkt
, 32 * 1024, &tmp
);
1071 return res
< 0 ? res
: 0;
1075 * expect to be at packet end, any data is error
1078 pgp_expect_packet_end(PullFilter
* pkt
)
1085 res
= pullf_read(pkt
, 32 * 1024, &tmp
);
1088 px_debug("pgp_expect_packet_end: got data");
1089 return PXE_PGP_CORRUPT_DATA
;
1092 return res
< 0 ? res
: 0;
1096 pgp_decrypt(PGP_Context
* ctx
, MBuf
* msrc
, MBuf
* mdst
)
1099 PullFilter
*src
= NULL
;
1100 PullFilter
*pkt
= NULL
;
1106 res
= pullf_create_mbuf_reader(&src
, msrc
);
1110 res
= pgp_parse_pkt_hdr(src
, &tag
, &len
, NO_CTX_SIZE
);
1114 res
= pgp_create_pkt_reader(&pkt
, src
, len
, res
, ctx
);
1118 res
= PXE_PGP_CORRUPT_DATA
;
1121 case PGP_PKT_MARKER
:
1122 res
= pgp_skip_packet(pkt
);
1124 case PGP_PKT_PUBENCRYPTED_SESSKEY
:
1125 /* fixme: skip those */
1126 res
= pgp_parse_pubenc_sesskey(ctx
, pkt
);
1129 case PGP_PKT_SYMENCRYPTED_SESSKEY
:
1133 * Theoretically, there could be several keys, both public
1134 * and symmetric, all of which encrypt same session key.
1135 * Decrypt should try with each one, before failing.
1137 px_debug("pgp_decrypt: using first of several keys");
1141 res
= parse_symenc_sesskey(ctx
, pkt
);
1144 case PGP_PKT_SYMENCRYPTED_DATA
:
1146 px_debug("pgp_decrypt: have data but no key");
1148 px_debug("pgp_decrypt: got second data packet");
1152 ctx
->disable_mdc
= 1;
1153 res
= parse_symenc_data(ctx
, pkt
, mdst
);
1156 case PGP_PKT_SYMENCRYPTED_DATA_MDC
:
1158 px_debug("pgp_decrypt: have data but no key");
1160 px_debug("pgp_decrypt: several data pkts not supported");
1164 ctx
->disable_mdc
= 0;
1165 res
= parse_symenc_mdc_data(ctx
, pkt
, mdst
);
1169 px_debug("pgp_decrypt: unknown tag: 0x%02x", tag
);
1184 if (!got_data
|| ctx
->corrupt_prefix
)
1185 res
= PXE_PGP_CORRUPT_DATA
;