1
1
/* seskey.c - make sesssion keys etc.
2
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
* 2006 Free Software Foundation, Inc.
4
5
* This file is part of GnuPG.
6
7
* GnuPG is free software; you can redistribute it and/or modify
7
8
* 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
* the Free Software Foundation; either version 3 of the License, or
9
10
* (at your option) any later version.
11
12
* GnuPG is distributed in the hope that it will be useful,
39
38
make_session_key( DEK *dek )
44
dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
46
if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB,
43
dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
45
if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB,
47
46
(GCRY_CIPHER_SECURE
48
47
| (dek->algo >= 100 ?
49
48
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 );
68
log_fatal (_("cannot avoid weak key for symmetric cipher; "
69
"tried %d times!\n"), i);
50
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
51
for (i=0; i < 16; i++ )
53
rc = gcry_cipher_setkey (chd, dek->key, dek->keylen);
56
gcry_cipher_close (chd);
59
if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
61
log_info(_("weak key created - retrying\n") );
62
/* Renew the session key until we get a non-weak key. */
63
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM);
65
log_fatal (_("cannot avoid weak key for symmetric cipher; "
66
"tried %d times!\n"), i);
130
127
break; /* okay: no zero bytes */
131
k += k/128; /* better get some more */
132
pp = gcry_random_bytes_secure( k, GCRY_STRONG_RANDOM);
133
for(j=0; j < i && k ; j++ )
128
k += k/128 + 3; /* better get some more */
129
pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
130
for(j=0; j < i && k ;) {
138
138
memcpy( frame+n, p, i );
142
142
frame[n++] = dek->algo;
143
143
memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
144
144
frame[n++] = csum >>8;
145
145
frame[n++] = csum;
146
assert (n == nframe);
149
log_printhex ("encoded session key:", frame, nframe );
146
assert( n == nframe );
151
147
if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
158
154
static gcry_mpi_t
159
155
do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
160
const byte *asn, size_t asnlen, int v3compathack )
156
const byte *asn, size_t asnlen )
162
int nframe = (nbits+7) / 8;
158
size_t nframe = (nbits+7) / 8;
171
167
/* We encode the MD in this way:
173
* 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
169
* 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
175
171
* PAD consists of FF bytes.
177
frame = gcry_md_is_secure (md)? xmalloc_secure (nframe): xmalloc (nframe);
173
frame = gcry_md_is_secure (md)? xmalloc_secure (nframe) : xmalloc (nframe);
180
frame[n++] = v3compathack? algo : 1; /* block type */
176
frame[n++] = 1; /* block type */
181
177
i = nframe - len - asnlen -3 ;
183
179
memset( frame+n, 0xff, i ); n += i;
185
181
memcpy( frame+n, asn, asnlen ); n += asnlen;
186
182
memcpy( frame+n, gcry_md_read (md, algo), len ); n += len;
187
183
assert( n == nframe );
188
185
if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe ))
189
/* Note that PGP before version 2.3 encoded the MD as:
191
* 0 1 MD(16 bytes) 0 PAD(n bytes) 1
193
* The MD is always 16 bytes here because it's always MD5. We do
194
* not support pre-v2.3 signatures, but I'm including this comment
195
* so the information is easily found in the future.
195
202
/****************
196
203
* Encode a message digest into an MPI.
197
* v3compathack is used to work around a bug in old GnuPG versions
198
* which did put the algo identifier inseatd of the block type 1 into
199
* the encoded value. Setting this flag forces the old behaviour.
204
* If it's for a DSA signature, make sure that the hash is large
205
* enough to fill up q. If the hash is too big, take the leftmost
202
encode_md_value (int pubkey_algo, gcry_md_hd_t md, int hash_algo,
203
unsigned int nbits, int v3compathack )
209
encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
210
gcry_md_hd_t md, int hash_algo)
205
int algo = hash_algo? hash_algo : gcry_md_get_algo (md);
206
212
gcry_mpi_t frame;
208
if (pubkey_algo == GCRY_PK_DSA)
217
if((pk?pk->pubkey_algo:sk->pubkey_algo) == GCRY_PK_DSA)
210
size_t n = gcry_md_get_algo_dlen(hash_algo);
213
log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
216
if (gcry_mpi_scan( &frame, GCRYMPI_FMT_USG,
217
gcry_md_read (md, hash_algo), n, &n ) )
219
/* It's a DSA signature, so find out the size of q. */
221
size_t qbytes = gcry_mpi_get_nbits (pk?pk->pkey[1]:sk->skey[1]);
223
/* Make sure it is a multiple of 8 bits. */
227
log_error(_("DSA requires the hash length to be a"
228
" multiple of 8 bits\n"));
232
/* Don't allow any q smaller than 160 bits. This might need a
233
revisit as the DSA2 design firms up, but for now, we don't
234
want someone to issue signatures from a key with a 16-bit q
235
or something like that, which would look correct but allow
236
trivial forgeries. Yes, I know this rules out using MD5 with
240
log_error (_("DSA key %s uses an unsafe (%u bit) hash\n"),
241
pk?keystr_from_pk(pk):keystr_from_sk(sk),
242
(unsigned int)qbytes);
248
/* Check if we're too short. Too long is safe as we'll
249
automatically left-truncate. */
250
if (gcry_md_get_algo_dlen (hash_algo) < qbytes)
252
log_error (_("DSA key %s requires a %u bit or larger hash\n"),
253
pk?keystr_from_pk(pk):keystr_from_sk(sk),
254
(unsigned int)(qbytes*8));
258
if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG,
259
gcry_md_read (md, hash_algo), qbytes, &qbytes))
226
rc = gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, NULL, &asnlen);
268
rc = gcry_md_test_algo (hash_algo);
270
rc = gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, NULL, &asnlen);
228
log_fatal("can't get OID of algo %d: %s\n",
229
algo, gpg_strerror (rc));
272
log_fatal ("can't get OID of algo %d: %s\n",
273
hash_algo, gpg_strerror (rc));
230
274
asn = xmalloc (asnlen);
231
if( gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, asn, &asnlen ) )
275
if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) )
233
frame = do_encode_md( md, algo, gcry_md_get_algo_dlen( algo ),
234
nbits, asn, asnlen, v3compathack );
277
frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (hash_algo),
278
gcry_mpi_get_nbits (pk?pk->pkey[0]:sk->skey[0]),