1 /* seskey.c - make sesssion keys etc.
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 * 2006 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
37 * Make a session key and put it into DEK
40 make_session_key( DEK
*dek
)
45 dek
->keylen
= gcry_cipher_get_algo_keylen (dek
->algo
);
47 if (gcry_cipher_open (&chd
, dek
->algo
, GCRY_CIPHER_MODE_CFB
,
50 0 : GCRY_CIPHER_ENABLE_SYNC
))) )
52 gcry_randomize (dek
->key
, dek
->keylen
, GCRY_STRONG_RANDOM
);
53 for (i
=0; i
< 16; i
++ )
55 rc
= gcry_cipher_setkey (chd
, dek
->key
, dek
->keylen
);
58 gcry_cipher_close (chd
);
61 if (gpg_err_code (rc
) != GPG_ERR_WEAK_KEY
)
63 log_info(_("weak key created - retrying\n") );
64 /* Renew the session key until we get a non-weak key. */
65 gcry_randomize (dek
->key
, dek
->keylen
, GCRY_STRONG_RANDOM
);
67 log_fatal (_("cannot avoid weak key for symmetric cipher; "
68 "tried %d times!\n"), i
);
73 * Encode the session key. NBITS is the number of bits which should be used
74 * for packing the session key.
75 * returns: A mpi with the session key (caller must free)
78 encode_session_key (DEK
*dek
, unsigned int nbits
)
80 size_t nframe
= (nbits
+7) / 8;
87 /* The current limitation is that we can only use a session key
88 * whose length is a multiple of BITS_PER_MPI_LIMB
89 * I think we can live with that.
91 if( dek
->keylen
+ 7 > nframe
|| !nframe
)
92 log_bug("can't encode a %d bit key in a %d bits frame\n",
93 dek
->keylen
*8, nbits
);
95 /* We encode the session key in this way:
97 * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
99 * (But how can we store the leading 0 - the external representaion
100 * of MPIs doesn't allow leading zeroes =:-)
102 * RND are non-zero random bytes.
103 * A is the cipher algorithm
104 * DEK is the encryption key (session key) length k depends on the
105 * cipher algorithm (20 is used with blowfish160).
106 * CSUM is the 16 bit checksum over the DEK
109 for( p
= dek
->key
, i
=0; i
< dek
->keylen
; i
++ )
112 frame
= xmalloc_secure( nframe
);
116 i
= nframe
- 6 - dek
->keylen
;
118 p
= gcry_random_bytes_secure (i
, GCRY_STRONG_RANDOM
);
119 /* Replace zero bytes by new values. */
124 /* count the zero bytes */
125 for(j
=k
=0; j
< i
; j
++ )
129 break; /* okay: no zero bytes */
130 k
+= k
/128 + 3; /* better get some more */
131 pp
= gcry_random_bytes_secure (k
, GCRY_STRONG_RANDOM
);
132 for(j
=0; j
< i
&& k
;) {
140 memcpy( frame
+n
, p
, i
);
144 frame
[n
++] = dek
->algo
;
145 memcpy( frame
+n
, dek
->key
, dek
->keylen
); n
+= dek
->keylen
;
146 frame
[n
++] = csum
>>8;
148 assert( n
== nframe
);
149 if (gcry_mpi_scan( &a
, GCRYMPI_FMT_USG
, frame
, n
, &nframe
))
157 do_encode_md( gcry_md_hd_t md
, int algo
, size_t len
, unsigned nbits
,
158 const byte
*asn
, size_t asnlen
)
160 size_t nframe
= (nbits
+7) / 8;
165 if( len
+ asnlen
+ 4 > nframe
)
166 log_bug("can't encode a %d bit MD into a %d bits frame\n",
167 (int)(len
*8), (int)nbits
);
169 /* We encode the MD in this way:
171 * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
173 * PAD consists of FF bytes.
175 frame
= gcry_md_is_secure (md
)? xmalloc_secure (nframe
) : xmalloc (nframe
);
178 frame
[n
++] = 1; /* block type */
179 i
= nframe
- len
- asnlen
-3 ;
181 memset( frame
+n
, 0xff, i
); n
+= i
;
183 memcpy( frame
+n
, asn
, asnlen
); n
+= asnlen
;
184 memcpy( frame
+n
, gcry_md_read (md
, algo
), len
); n
+= len
;
185 assert( n
== nframe
);
187 if (gcry_mpi_scan( &a
, GCRYMPI_FMT_USG
, frame
, n
, &nframe
))
191 /* Note that PGP before version 2.3 encoded the MD as:
193 * 0 1 MD(16 bytes) 0 PAD(n bytes) 1
195 * The MD is always 16 bytes here because it's always MD5. We do
196 * not support pre-v2.3 signatures, but I'm including this comment
197 * so the information is easily found in the future.
205 * Encode a message digest into an MPI.
206 * If it's for a DSA signature, make sure that the hash is large
207 * enough to fill up q. If the hash is too big, take the leftmost
211 encode_md_value (PKT_public_key
*pk
, PKT_secret_key
*sk
,
212 gcry_md_hd_t md
, int hash_algo
)
219 if((pk
?pk
->pubkey_algo
:sk
->pubkey_algo
) == GCRY_PK_DSA
)
221 /* It's a DSA signature, so find out the size of q. */
223 size_t qbytes
= gcry_mpi_get_nbits (pk
?pk
->pkey
[1]:sk
->skey
[1]);
225 /* Make sure it is a multiple of 8 bits. */
229 log_error(_("DSA requires the hash length to be a"
230 " multiple of 8 bits\n"));
234 /* Don't allow any q smaller than 160 bits. This might need a
235 revisit as the DSA2 design firms up, but for now, we don't
236 want someone to issue signatures from a key with a 16-bit q
237 or something like that, which would look correct but allow
238 trivial forgeries. Yes, I know this rules out using MD5 with
242 log_error (_("DSA key %s uses an unsafe (%u bit) hash\n"),
243 pk
?keystr_from_pk(pk
):keystr_from_sk(sk
),
244 (unsigned int)qbytes
);
250 /* Check if we're too short. Too long is safe as we'll
251 automatically left-truncate. */
252 if (gcry_md_get_algo_dlen (hash_algo
) < qbytes
)
254 log_error (_("DSA key %s requires a %u bit or larger hash\n"),
255 pk
?keystr_from_pk(pk
):keystr_from_sk(sk
),
256 (unsigned int)(qbytes
*8));
260 if (gcry_mpi_scan (&frame
, GCRYMPI_FMT_USG
,
261 gcry_md_read (md
, hash_algo
), qbytes
, &qbytes
))
270 rc
= gcry_md_test_algo (hash_algo
);
272 rc
= gcry_md_algo_info (hash_algo
, GCRYCTL_GET_ASNOID
, NULL
, &asnlen
);
274 log_fatal ("can't get OID of algo %d: %s\n",
275 hash_algo
, gpg_strerror (rc
));
276 asn
= xmalloc (asnlen
);
277 if ( gcry_md_algo_info (hash_algo
, GCRYCTL_GET_ASNOID
, asn
, &asnlen
) )
279 frame
= do_encode_md (md
, hash_algo
, gcry_md_get_algo_dlen (hash_algo
),
280 gcry_mpi_get_nbits (pk
?pk
->pkey
[0]:sk
->skey
[0]),