1 /* encr-data.c - process an encrypted data packet
2 * Copyright (C) 1998 Free Software Foundation, Inc.
4 * This file is part of GNUPG.
6 * GNUPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
35 static int decode_filter( void *opaque, int control, IOBUF a,
36 byte *buf, size_t *ret_len);
39 CIPHER_HANDLE cipher_hd;
40 } decode_filter_ctx_t;
45 * Decrypt the data, specified by ED with the key DEK.
48 decrypt_data( PKT_encrypted *ed, DEK *dek )
50 decode_filter_ctx_t dfx;
57 const char *s = cipher_algo_to_string( dek->algo );
59 log_info(_("%s encrypted data\n"), s );
61 log_info(_("encrypted with unknown algorithm %d\n"), dek->algo );
63 if( (rc=check_cipher_algo(dek->algo)) )
65 blocksize = cipher_get_blocksize(dek->algo);
66 if( !blocksize || blocksize > 16 )
67 log_fatal("unsupported blocksize %u\n", blocksize );
68 if( ed->len && ed->len < (blocksize+2) )
69 log_bug("Nanu\n"); /* oops: found a bug */
71 dfx.cipher_hd = cipher_open( dek->algo, CIPHER_MODE_AUTO_CFB, 1 );
72 rc = cipher_setkey( dfx.cipher_hd, dek->key, dek->keylen );
73 if( rc == G10ERR_WEAK_KEY )
74 log_info(_("WARNING: Message was encrypted with "
75 "a weak key in the symmetric cipher.\n"));
77 log_error("key setup failed: %s\n", g10_errstr(rc) );
79 cipher_setiv( dfx.cipher_hd, NULL );
82 iobuf_set_limit( ed->buf, ed->len );
84 for(i=0; i < (blocksize+2) && ed->len; i++, ed->len-- )
85 temp[i] = iobuf_get(ed->buf);
88 for(i=0; i < (blocksize+2); i++ )
89 if( (c=iobuf_get(ed->buf)) == -1 )
94 cipher_decrypt( dfx.cipher_hd, temp, temp, blocksize+2);
95 cipher_sync( dfx.cipher_hd );
97 if( p[blocksize-2] != p[blocksize] || p[blocksize-1] != p[blocksize+1] ) {
98 cipher_close(dfx.cipher_hd);
99 return G10ERR_BAD_KEY;
101 iobuf_push_filter( ed->buf, decode_filter, &dfx );
102 proc_packets(ed->buf);
103 iobuf_pop_filter( ed->buf, decode_filter, &dfx );
105 iobuf_set_limit( ed->buf, 0 ); /* disable the readlimit */
107 iobuf_clear_eof( ed->buf );
109 cipher_close(dfx.cipher_hd);
114 decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
116 decode_filter_ctx_t *fc = opaque;
117 size_t n, size = *ret_len;
121 if( control == IOBUFCTRL_UNDERFLOW ) {
123 for(n=0; n < size; n++ ) {
124 if( (c = iobuf_get(a)) == -1 )
130 cipher_decrypt( fc->cipher_hd, buf, buf, n);
135 else if( control == IOBUFCTRL_DESC ) {
136 *(char**)buf = "decode_filter";