1 /* seskey.c - make sesssion keys etc.
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
34 * Make a session key and put it into DEK
37 make_session_key( DEK *dek )
42 dek->keylen = cipher_get_keylen( dek->algo ) / 8;
44 chd = cipher_open( dek->algo, CIPHER_MODE_AUTO_CFB, 1 );
45 for(i=0; i < 16; i++ ) {
46 rc = cipher_setkey( chd, dek->key, dek->keylen );
51 log_info(_("weak key created - retrying\n") );
52 /* Renew the session key until we get a non-weak key. */
53 randomize_buffer( dek->key, dek->keylen, 1 );
56 "cannot avoid weak key for symmetric cipher; tried %d times!\n"),
62 * Encode the session key. NBITS is the number of bits which should be used
63 * for packing the session key.
64 * returns: A mpi with the session key (caller must free)
67 encode_session_key( DEK *dek, unsigned nbits )
69 int nframe = (nbits+7) / 8;
76 /* the current limitation is that we can only use a session key
77 * whose length is a multiple of BITS_PER_MPI_LIMB
78 * I think we can live with that.
80 if( dek->keylen + 7 > nframe || !nframe )
81 log_bug("can't encode a %d bit key in a %d bits frame\n",
82 dek->keylen*8, nbits );
84 /* We encode the session key in this way:
86 * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
88 * (But how can we store the leading 0 - the external representaion
89 * of MPIs doesn't allow leading zeroes =:-)
91 * RND are non-zero random bytes.
92 * A is the cipher algorithm
93 * DEK is the encryption key (session key) length k depends on the
94 * cipher algorithm (20 is used with blowfish160).
95 * CSUM is the 16 bit checksum over the DEK
98 for( p = dek->key, i=0; i < dek->keylen; i++ )
101 frame = m_alloc_secure( nframe );
105 i = nframe - 6 - dek->keylen;
107 p = get_random_bits( i*8, 1, 1 );
108 /* replace zero bytes by new values */
113 /* count the zero bytes */
114 for(j=k=0; j < i; j++ )
118 break; /* okay: no zero bytes */
119 k += k/128; /* better get some more */
120 pp = get_random_bits( k*8, 1, 1);
121 for(j=0; j < i && k ; j++ )
126 memcpy( frame+n, p, i );
130 frame[n++] = dek->algo;
131 memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
132 frame[n++] = csum >>8;
134 assert( n == nframe );
135 a = mpi_alloc_secure( (nframe+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
136 mpi_set_buffer( a, frame, nframe, 0 );
143 do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits,
144 const byte *asn, size_t asnlen )
146 int nframe = (nbits+7) / 8;
151 if( len + asnlen + 4 > nframe )
152 log_bug("can't encode a %d bit MD into a %d bits frame\n",
153 (int)(len*8), (int)nbits);
155 /* We encode the MD in this way:
157 * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
159 * PAD consists of FF bytes.
161 frame = md_is_secure(md)? m_alloc_secure( nframe ) : m_alloc( nframe );
165 i = nframe - len - asnlen -3 ;
167 memset( frame+n, 0xff, i ); n += i;
169 memcpy( frame+n, asn, asnlen ); n += asnlen;
170 memcpy( frame+n, md_read(md, algo), len ); n += len;
171 assert( n == nframe );
172 a = md_is_secure(md)?
173 mpi_alloc_secure( (nframe+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB )
174 : mpi_alloc( (nframe+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
175 mpi_set_buffer( a, frame, nframe, 0 );
182 encode_md_value( int pubkey_algo, MD_HANDLE md, int hash_algo, unsigned nbits )
184 int algo = hash_algo? hash_algo : md_get_algo(md);
186 size_t asnlen, mdlen;
189 if( pubkey_algo == PUBKEY_ALGO_DSA ) {
190 frame = md_is_secure(md)? mpi_alloc_secure((md_digest_length(hash_algo)
191 +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB )
192 : mpi_alloc((md_digest_length(hash_algo)
193 +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
194 mpi_set_buffer( frame, md_read(md, hash_algo),
195 md_digest_length(hash_algo), 0 );
198 asn = md_asn_oid( algo, &asnlen, &mdlen );
199 frame = do_encode_md( md, algo, mdlen, nbits, asn, asnlen );