1 /*
2 * gnome-keyring
3 *
4 * Copyright (C) 2008 Stefan Walter
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "config.h"
21
22 #include "egg-asn1-defs.h"
23 #include "egg-asn1x.h"
24 #include "egg-secure-memory.h"
25 #include "egg-symkey.h"
26
27 EGG_SECURE_DECLARE (symkey);
28
29 /* -----------------------------------------------------------------------------
30 * QUARKS
31 */
32
33 static GQuark OID_PBE_MD2_DES_CBC;
34 static GQuark OID_PBE_MD5_DES_CBC;
35 static GQuark OID_PBE_MD2_RC2_CBC;
36 static GQuark OID_PBE_MD5_RC2_CBC;
37 static GQuark OID_PBE_SHA1_DES_CBC;
38 static GQuark OID_PBE_SHA1_RC2_CBC;
39 static GQuark OID_PBES2;
40 static GQuark OID_PBKDF2;
41
42 static GQuark OID_DES_CBC;
43 static GQuark OID_DES_RC2_CBC;
44 static GQuark OID_DES_EDE3_CBC;
45 static GQuark OID_DES_RC5_CBC;
46
47 static GQuark OID_PKCS12_PBE_ARCFOUR_SHA1;
48 static GQuark OID_PKCS12_PBE_RC4_40_SHA1;
49 static GQuark OID_PKCS12_PBE_3DES_SHA1;
50 static GQuark OID_PKCS12_PBE_2DES_SHA1;
51 static GQuark OID_PKCS12_PBE_RC2_128_SHA1;
52 static GQuark OID_PKCS12_PBE_RC2_40_SHA1;
53
54 static GQuark OID_SHA1;
55
56 static void
init_quarks(void)57 init_quarks (void)
58 {
59 static volatile gsize quarks_inited = 0;
60
61 if (g_once_init_enter (&quarks_inited)) {
62
63 #define QUARK(name, value) \
64 name = g_quark_from_static_string(value)
65
66 QUARK (OID_PBE_MD2_DES_CBC, "1.2.840.113549.1.5.1");
67 QUARK (OID_PBE_MD5_DES_CBC, "1.2.840.113549.1.5.3");
68 QUARK (OID_PBE_MD2_RC2_CBC, "1.2.840.113549.1.5.4");
69 QUARK (OID_PBE_MD5_RC2_CBC, "1.2.840.113549.1.5.6");
70 QUARK (OID_PBE_SHA1_DES_CBC, "1.2.840.113549.1.5.10");
71 QUARK (OID_PBE_SHA1_RC2_CBC, "1.2.840.113549.1.5.11");
72
73 QUARK (OID_PBES2, "1.2.840.113549.1.5.13");
74
75 QUARK (OID_PBKDF2, "1.2.840.113549.1.5.12");
76
77 QUARK (OID_DES_CBC, "1.3.14.3.2.7");
78 QUARK (OID_DES_RC2_CBC, "1.2.840.113549.3.2");
79 QUARK (OID_DES_EDE3_CBC, "1.2.840.113549.3.7");
80 QUARK (OID_DES_RC5_CBC, "1.2.840.113549.3.9");
81
82 QUARK (OID_PKCS12_PBE_ARCFOUR_SHA1, "1.2.840.113549.1.12.1.1");
83 QUARK (OID_PKCS12_PBE_RC4_40_SHA1, "1.2.840.113549.1.12.1.2");
84 QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
85 QUARK (OID_PKCS12_PBE_2DES_SHA1, "1.2.840.113549.1.12.1.4");
86 QUARK (OID_PKCS12_PBE_RC2_128_SHA1, "1.2.840.113549.1.12.1.5");
87 QUARK (OID_PKCS12_PBE_RC2_40_SHA1, "1.2.840.113549.1.12.1.6");
88
89 QUARK (OID_SHA1, "1.3.14.3.2.26");
90
91 #undef QUARK
92
93 g_once_init_leave (&quarks_inited, 1);
94 }
95 }
96
97 /* -----------------------------------------------------------------------------
98 * PASSWORD TO KEY/IV
99 */
100
101 gboolean
egg_symkey_generate_simple(int cipher_algo,int hash_algo,const gchar * password,gssize n_password,const guchar * salt,gsize n_salt,int iterations,guchar ** key,guchar ** iv)102 egg_symkey_generate_simple (int cipher_algo, int hash_algo,
103 const gchar *password, gssize n_password,
104 const guchar *salt, gsize n_salt, int iterations,
105 guchar **key, guchar **iv)
106 {
107 gcry_md_hd_t mdh;
108 gcry_error_t gcry;
109 guchar *digest;
110 guchar *digested;
111 guint n_digest;
112 gint pass, i;
113 gint needed_iv, needed_key;
114 guchar *at_iv, *at_key;
115
116 g_assert (cipher_algo);
117 g_assert (hash_algo);
118
119 g_return_val_if_fail (iterations >= 1, FALSE);
120
121 if (!password)
122 n_password = 0;
123 if (n_password == -1)
124 n_password = strlen (password);
125
126 /*
127 * If cipher algo needs more bytes than hash algo has available
128 * then the entire hashing process is done again (with the previous
129 * hash bytes as extra input), and so on until satisfied.
130 */
131
132 needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
133 needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
134
135 gcry = gcry_md_open (&mdh, hash_algo, 0);
136 if (gcry) {
137 g_warning ("couldn't create '%s' hash context: %s",
138 gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
139 return FALSE;
140 }
141
142 n_digest = gcry_md_get_algo_dlen (hash_algo);
143 g_return_val_if_fail (n_digest > 0, FALSE);
144
145 digest = egg_secure_alloc (n_digest);
146 g_return_val_if_fail (digest, FALSE);
147 if (key) {
148 *key = egg_secure_alloc (needed_key);
149 g_return_val_if_fail (*key, FALSE);
150 }
151 if (iv)
152 *iv = g_new0 (guchar, needed_iv);
153
154 at_key = key ? *key : NULL;
155 at_iv = iv ? *iv : NULL;
156
157 for (pass = 0; TRUE; ++pass) {
158 gcry_md_reset (mdh);
159
160 /* Hash in the previous buffer on later passes */
161 if (pass > 0)
162 gcry_md_write (mdh, digest, n_digest);
163
164 if (password)
165 gcry_md_write (mdh, password, n_password);
166 if (salt && n_salt)
167 gcry_md_write (mdh, salt, n_salt);
168 gcry_md_final (mdh);
169 digested = gcry_md_read (mdh, 0);
170 g_return_val_if_fail (digested, FALSE);
171 memcpy (digest, digested, n_digest);
172
173 for (i = 1; i < iterations; ++i) {
174 gcry_md_reset (mdh);
175 gcry_md_write (mdh, digest, n_digest);
176 gcry_md_final (mdh);
177 digested = gcry_md_read (mdh, 0);
178 g_return_val_if_fail (digested, FALSE);
179 memcpy (digest, digested, n_digest);
180 }
181
182 /* Copy as much as possible into the destinations */
183 i = 0;
184 while (needed_key && i < n_digest) {
185 if (at_key)
186 *(at_key++) = digest[i];
187 needed_key--;
188 i++;
189 }
190 while (needed_iv && i < n_digest) {
191 if (at_iv)
192 *(at_iv++) = digest[i];
193 needed_iv--;
194 i++;
195 }
196
197 if (needed_key == 0 && needed_iv == 0)
198 break;
199 }
200
201 egg_secure_free (digest);
202 gcry_md_close (mdh);
203
204 return TRUE;
205 }
206
207 gboolean
egg_symkey_generate_pbe(int cipher_algo,int hash_algo,const gchar * password,gssize n_password,const guchar * salt,gsize n_salt,int iterations,guchar ** key,guchar ** iv)208 egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
209 gssize n_password, const guchar *salt, gsize n_salt, int iterations,
210 guchar **key, guchar **iv)
211 {
212 gcry_md_hd_t mdh;
213 gcry_error_t gcry;
214 guchar *digest;
215 guchar *digested;
216 guint i, n_digest;
217 gint needed_iv, needed_key;
218
219 g_assert (cipher_algo);
220 g_assert (hash_algo);
221
222 g_return_val_if_fail (iterations >= 1, FALSE);
223
224 if (!password)
225 n_password = 0;
226 if (n_password == -1)
227 n_password = strlen (password);
228
229 /*
230 * We only do one pass here.
231 *
232 * The key ends up as the first needed_key bytes of the hash buffer.
233 * The iv ends up as the last needed_iv bytes of the hash buffer.
234 *
235 * The IV may overlap the key (which is stupid) if the wrong pair of
236 * hash/cipher algorithms are chosen.
237 */
238
239 n_digest = gcry_md_get_algo_dlen (hash_algo);
240 g_return_val_if_fail (n_digest > 0, FALSE);
241
242 needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
243 needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
244 if (needed_iv + needed_key > 16 || needed_iv + needed_key > n_digest) {
245 g_warning ("using PBE symkey generation with %s using an algorithm that needs "
246 "too many bytes of key and/or IV: %s",
247 gcry_cipher_algo_name (hash_algo),
248 gcry_cipher_algo_name (cipher_algo));
249 return FALSE;
250 }
251
252 gcry = gcry_md_open (&mdh, hash_algo, 0);
253 if (gcry) {
254 g_warning ("couldn't create '%s' hash context: %s",
255 gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
256 return FALSE;
257 }
258
259 digest = egg_secure_alloc (n_digest);
260 g_return_val_if_fail (digest, FALSE);
261 if (key) {
262 *key = egg_secure_alloc (needed_key);
263 g_return_val_if_fail (*key, FALSE);
264 }
265 if (iv)
266 *iv = g_new0 (guchar, needed_iv);
267
268 if (password)
269 gcry_md_write (mdh, password, n_password);
270 if (salt && n_salt)
271 gcry_md_write (mdh, salt, n_salt);
272 gcry_md_final (mdh);
273 digested = gcry_md_read (mdh, 0);
274 g_return_val_if_fail (digested, FALSE);
275 memcpy (digest, digested, n_digest);
276
277 for (i = 1; i < iterations; ++i)
278 gcry_md_hash_buffer (hash_algo, digest, digest, n_digest);
279
280 /* The first x bytes are the key */
281 if (key) {
282 g_assert (needed_key <= n_digest);
283 memcpy (*key, digest, needed_key);
284 }
285
286 /* The last 16 - x bytes are the iv */
287 if (iv) {
288 g_assert (needed_iv <= n_digest && n_digest >= 16);
289 memcpy (*iv, digest + (16 - needed_iv), needed_iv);
290 }
291
292 egg_secure_free (digest);
293 gcry_md_close (mdh);
294
295 return TRUE;
296 }
297
298 static gboolean
generate_pkcs12(int hash_algo,int type,const gchar * utf8_password,gssize n_password,const guchar * salt,gsize n_salt,int iterations,guchar * output,gsize n_output)299 generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
300 gssize n_password, const guchar *salt, gsize n_salt,
301 int iterations, guchar *output, gsize n_output)
302 {
303 gcry_mpi_t num_b1, num_ij;
304 guchar *hash, *buf_i, *buf_b;
305 const gchar *end_password;
306 gcry_md_hd_t mdh;
307 const gchar *p2;
308 guchar *p;
309 gsize n_hash, i;
310 gunichar unich;
311 gcry_error_t gcry;
312 gsize length;
313
314 num_b1 = num_ij = NULL;
315
316 n_hash = gcry_md_get_algo_dlen (hash_algo);
317 g_return_val_if_fail (n_hash > 0, FALSE);
318
319 if (!utf8_password)
320 n_password = 0;
321 if (n_password == -1)
322 end_password = utf8_password + strlen (utf8_password);
323 else
324 end_password = utf8_password + n_password;
325
326 gcry = gcry_md_open (&mdh, hash_algo, 0);
327 if (gcry) {
328 g_warning ("couldn't create '%s' hash context: %s",
329 gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
330 return FALSE;
331 }
332
333 /* Reqisition me a buffer */
334 hash = egg_secure_alloc (n_hash);
335 buf_i = egg_secure_alloc (128);
336 buf_b = egg_secure_alloc (64);
337 g_return_val_if_fail (hash && buf_i && buf_b, FALSE);
338
339 /* Bring in the salt */
340 p = buf_i;
341 if (salt) {
342 for (i = 0; i < 64; ++i)
343 *(p++) = salt[i % n_salt];
344 } else {
345 memset (p, 0, 64);
346 p += 64;
347 }
348
349 /* Bring in the password, as 16bits per character BMP string, ie: UCS2 */
350 if (utf8_password) {
351 p2 = utf8_password;
352 for (i = 0; i < 64; i += 2) {
353
354 /* Get a character from the string */
355 if (p2 < end_password) {
356 unich = g_utf8_get_char (p2);
357 p2 = g_utf8_next_char (p2);
358
359 /* Get zero null terminator, and loop back to beginning */
360 } else {
361 unich = 0;
362 p2 = utf8_password;
363 }
364
365 /* Encode the bytes received */
366 *(p++) = (unich & 0xFF00) >> 8;
367 *(p++) = (unich & 0xFF);
368 }
369 } else {
370 memset (p, 0, 64);
371 }
372
373 /* Hash and bash */
374 for (;;) {
375 gcry_md_reset (mdh);
376
377 /* Put in the PKCS#12 type of key */
378 for (i = 0; i < 64; ++i)
379 gcry_md_putc (mdh, type);
380
381 /* Bring in the password */
382 gcry_md_write (mdh, buf_i, utf8_password ? 128 : 64);
383
384 /* First iteration done */
385 memcpy (hash, gcry_md_read (mdh, hash_algo), n_hash);
386
387 /* All the other iterations */
388 for (i = 1; i < iterations; i++)
389 gcry_md_hash_buffer (hash_algo, hash, hash, n_hash);
390
391 /* Take out as much as we need */
392 for (i = 0; i < n_hash && n_output; ++i) {
393 *(output++) = hash[i];
394 --n_output;
395 }
396
397 /* Is that enough generated keying material? */
398 if (!n_output)
399 break;
400
401 /* Need more bytes, do some voodoo */
402 for (i = 0; i < 64; ++i)
403 buf_b[i] = hash[i % n_hash];
404 gcry = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, NULL);
405 g_return_val_if_fail (gcry == 0, FALSE);
406 gcry_mpi_add_ui (num_b1, num_b1, 1);
407 for (i = 0; i < 128; i += 64) {
408 gcry = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, NULL);
409 g_return_val_if_fail (gcry == 0, FALSE);
410 gcry_mpi_add (num_ij, num_ij, num_b1);
411 gcry_mpi_clear_highbit (num_ij, 64 * 8);
412 /* We take special care to right align the number in the buffer */
413 gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &length, num_ij);
414 g_return_val_if_fail (gcry == 0 && length <= 64, FALSE);
415 memset (buf_i + i, 0, 64 - length);
416 gcry = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i + (64 - length), 64, NULL, num_ij);
417 g_return_val_if_fail (gcry == 0, FALSE);
418 gcry_mpi_release (num_ij);
419 }
420 }
421
422 egg_secure_free (buf_i);
423 egg_secure_free (buf_b);
424 egg_secure_free (hash);
425 gcry_mpi_release (num_b1);
426 gcry_md_close (mdh);
427
428 return TRUE;
429 }
430
431 gboolean
egg_symkey_generate_pkcs12(int cipher_algo,int hash_algo,const gchar * password,gssize n_password,const guchar * salt,gsize n_salt,int iterations,guchar ** key,guchar ** iv)432 egg_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password,
433 gssize n_password, const guchar *salt, gsize n_salt,
434 int iterations, guchar **key, guchar **iv)
435 {
436 gsize n_block, n_key;
437 gboolean ret = TRUE;
438
439 g_return_val_if_fail (cipher_algo, FALSE);
440 g_return_val_if_fail (hash_algo, FALSE);
441 g_return_val_if_fail (iterations > 0, FALSE);
442
443 n_key = gcry_cipher_get_algo_keylen (cipher_algo);
444 n_block = gcry_cipher_get_algo_blklen (cipher_algo);
445
446 if (password && !g_utf8_validate (password, n_password, NULL)) {
447 g_warning ("invalid non-UTF8 password");
448 g_return_val_if_reached (FALSE);
449 }
450
451 if (key)
452 *key = NULL;
453 if (iv)
454 *iv = NULL;
455
456 /* Generate us an key */
457 if (key) {
458 *key = egg_secure_alloc (n_key);
459 g_return_val_if_fail (*key != NULL, FALSE);
460 ret = generate_pkcs12 (hash_algo, 1, password, n_password, salt, n_salt,
461 iterations, *key, n_key);
462 }
463
464 /* Generate us an iv */
465 if (ret && iv) {
466 if (n_block > 1) {
467 *iv = g_malloc (n_block);
468 ret = generate_pkcs12 (hash_algo, 2, password, n_password, salt, n_salt,
469 iterations, *iv, n_block);
470 } else {
471 *iv = NULL;
472 }
473 }
474
475 /* Cleanup in case of failure */
476 if (!ret) {
477 g_free (iv ? *iv : NULL);
478 egg_secure_free (key ? *key : NULL);
479 }
480
481 return ret;
482 }
483
484 gboolean
egg_symkey_generate_pkcs12_mac(int hash_algo,const gchar * password,gssize n_password,const guchar * salt,gsize n_salt,int iterations,guchar ** key)485 egg_symkey_generate_pkcs12_mac (int hash_algo,
486 const gchar *password,
487 gssize n_password,
488 const guchar *salt,
489 gsize n_salt,
490 int iterations,
491 guchar **key)
492 {
493 gsize n_key;
494 gboolean ret = TRUE;
495
496 g_return_val_if_fail (hash_algo, FALSE);
497 g_return_val_if_fail (iterations > 0, FALSE);
498
499 n_key = gcry_md_get_algo_dlen (hash_algo);
500
501 if (password && !g_utf8_validate (password, n_password, NULL)) {
502 g_warning ("invalid non-UTF8 password");
503 g_return_val_if_reached (FALSE);
504 }
505
506 /* Generate us an key */
507 if (key) {
508 *key = egg_secure_alloc (n_key);
509 g_return_val_if_fail (*key != NULL, FALSE);
510 ret = generate_pkcs12 (hash_algo, 3, password, n_password, salt, n_salt,
511 iterations, *key, n_key);
512 }
513
514 /* Cleanup in case of failure */
515 if (!key)
516 egg_secure_free (key ? *key : NULL);
517
518 return ret;
519 }
520
521 static gboolean
generate_pbkdf2(int hash_algo,const gchar * password,gsize n_password,const guchar * salt,gsize n_salt,guint iterations,guchar * output,gsize n_output)522 generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
523 const guchar *salt, gsize n_salt, guint iterations,
524 guchar *output, gsize n_output)
525 {
526 gcry_md_hd_t mdh;
527 guint u, l, r, i, k;
528 gcry_error_t gcry;
529 guchar *U, *T, *buf;
530 gsize n_buf, n_hash;
531
532 g_return_val_if_fail (hash_algo > 0, FALSE);
533 g_return_val_if_fail (iterations > 0, FALSE);
534 g_return_val_if_fail (n_output > 0, FALSE);
535 g_return_val_if_fail (n_output < G_MAXUINT32, FALSE);
536
537 n_hash = gcry_md_get_algo_dlen (hash_algo);
538 g_return_val_if_fail (n_hash > 0, FALSE);
539
540 gcry = gcry_md_open (&mdh, hash_algo, GCRY_MD_FLAG_HMAC);
541 if (gcry != 0) {
542 g_warning ("couldn't create '%s' hash context: %s",
543 gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
544 return FALSE;
545 }
546
547 /* Get us a temporary buffers */
548 T = egg_secure_alloc (n_hash);
549 U = egg_secure_alloc (n_hash);
550 n_buf = n_salt + 4;
551 buf = egg_secure_alloc (n_buf);
552 g_return_val_if_fail (buf && T && U, FALSE);
553
554 /* n_hash blocks in output, rounding up */
555 l = ((n_output - 1) / n_hash) + 1;
556
557 /* number of bytes in last, rounded up, n_hash block */
558 r = n_output - (l - 1) * n_hash;
559
560 memcpy (buf, salt, n_salt);
561 for (i = 1; i <= l; i++) {
562 memset (T, 0, n_hash);
563 for (u = 1; u <= iterations; u++) {
564 gcry_md_reset (mdh);
565
566 gcry = gcry_md_setkey (mdh, password, n_password);
567 g_return_val_if_fail (gcry == 0, FALSE);
568
569 /* For first iteration on each block add 4 extra bytes */
570 if (u == 1) {
571 buf[n_salt + 0] = (i & 0xff000000) >> 24;
572 buf[n_salt + 1] = (i & 0x00ff0000) >> 16;
573 buf[n_salt + 2] = (i & 0x0000ff00) >> 8;
574 buf[n_salt + 3] = (i & 0x000000ff) >> 0;
575
576 gcry_md_write (mdh, buf, n_buf);
577
578 /* Other iterations, any block */
579 } else {
580 gcry_md_write (mdh, U, n_hash);
581 }
582
583 memcpy (U, gcry_md_read (mdh, hash_algo), n_hash);
584
585 for (k = 0; k < n_hash; k++)
586 T[k] ^= U[k];
587 }
588
589 memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
590 }
591
592 egg_secure_free (T);
593 egg_secure_free (U);
594 egg_secure_free (buf);
595 gcry_md_close (mdh);
596 return TRUE;
597 }
598
599 gboolean
egg_symkey_generate_pbkdf2(int cipher_algo,int hash_algo,const gchar * password,gssize n_password,const guchar * salt,gsize n_salt,int iterations,guchar ** key,guchar ** iv)600 egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
601 const gchar *password, gssize n_password,
602 const guchar *salt, gsize n_salt, int iterations,
603 guchar **key, guchar **iv)
604 {
605 gsize n_key, n_block;
606 gboolean ret = TRUE;
607
608 g_return_val_if_fail (hash_algo, FALSE);
609 g_return_val_if_fail (cipher_algo, FALSE);
610 g_return_val_if_fail (iterations > 0, FALSE);
611
612 n_key = gcry_cipher_get_algo_keylen (cipher_algo);
613 n_block = gcry_cipher_get_algo_blklen (cipher_algo);
614
615 if (key)
616 *key = NULL;
617 if (iv)
618 *iv = NULL;
619
620 if (!password)
621 n_password = 0;
622 if (n_password == -1)
623 n_password = strlen (password);
624
625 /* Generate us an key */
626 if (key) {
627 *key = egg_secure_alloc (n_key);
628 g_return_val_if_fail (*key != NULL, FALSE);
629 ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt,
630 iterations, *key, n_key);
631 }
632
633 /* Generate us an iv */
634 if (ret && iv) {
635 if (n_block > 1) {
636 *iv = g_malloc (n_block);
637 gcry_create_nonce (*iv, n_block);
638 } else {
639 *iv = NULL;
640 }
641 }
642
643 /* Cleanup in case of failure */
644 if (!ret) {
645 g_free (iv ? *iv : NULL);
646 egg_secure_free (key ? *key : NULL);
647 }
648
649 return ret;
650 }
651
652 /* ----------------------------------------------------------------------------
653 * DER encoded cipher params
654 */
655
656
657 static gboolean
read_cipher_pkcs5_pbe(int cipher_algo,int cipher_mode,int hash_algo,const gchar * password,gsize n_password,GNode * data,gcry_cipher_hd_t * cih)658 read_cipher_pkcs5_pbe (int cipher_algo,
659 int cipher_mode,
660 int hash_algo,
661 const gchar *password,
662 gsize n_password,
663 GNode *data,
664 gcry_cipher_hd_t *cih)
665 {
666 GNode *asn = NULL;
667 gcry_error_t gcry;
668 GBytes *salt = NULL;
669 gsize n_block, n_key;
670 gulong iterations;
671 guchar *key = NULL;
672 guchar *iv = NULL;
673 gboolean ret;
674
675 g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
676 g_return_val_if_fail (cih != NULL, FALSE);
677 g_return_val_if_fail (data != NULL, FALSE);
678
679 *cih = NULL;
680 ret = FALSE;
681
682 /* Check if we can use this algorithm */
683 if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
684 gcry_md_test_algo (hash_algo) != 0)
685 goto done;
686
687 asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-PBE-params");
688 g_return_val_if_fail (asn, FALSE);
689
690 if (!egg_asn1x_get_any_into (data, asn))
691 goto done;
692
693 salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "salt", NULL));
694 g_return_val_if_fail (salt != NULL, FALSE);
695 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
696 g_return_val_if_reached (FALSE);
697
698 n_key = gcry_cipher_get_algo_keylen (cipher_algo);
699 g_return_val_if_fail (n_key > 0, FALSE);
700 n_block = gcry_cipher_get_algo_blklen (cipher_algo);
701
702 if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password,
703 g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
704 iterations, &key, n_block > 1 ? &iv : NULL))
705 goto done;
706
707 gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
708 if (gcry != 0) {
709 g_warning ("couldn't create cipher: %s", gcry_strerror (gcry));
710 goto done;
711 }
712
713 if (iv)
714 gcry_cipher_setiv (*cih, iv, n_block);
715 gcry_cipher_setkey (*cih, key, n_key);
716
717 ret = TRUE;
718
719 done:
720 g_free (iv);
721 if (salt != NULL)
722 g_bytes_unref (salt);
723 egg_secure_free (key);
724 egg_asn1x_destroy (asn);
725
726 return ret;
727 }
728
729 #if NOT_SUPPORTED
730 static gboolean
setup_pkcs5_rc2_params(GNode * any,gcry_cipher_hd_t cih)731 setup_pkcs5_rc2_params (GNode *any,
732 gcry_cipher_hd_t cih)
733 {
734 GNode *asn = NULL;
735 gcry_error_t gcry;
736 GBytes *iv = NULL;
737 gulong version;
738 gboolean ret = FALSE;
739
740 g_assert (any != NULL);
741
742 asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-rc2-CBC-params");
743 if (asn == NULL)
744 goto done;
745
746 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "rc2ParameterVersion", NULL), &version))
747 goto done;
748
749 iv = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "iv", NULL));
750 if (!iv)
751 goto done;
752
753 gcry = gcry_cipher_setiv (cih, g_bytes_get_data (iv, NULL), g_bytes_get_size (iv));
754 if (gcry != 0) {
755 g_message ("couldn't set %lu byte iv on cipher", (gulong)g_bytes_get_size (iv));
756 goto done;
757 }
758
759 ret = TRUE;
760
761 done:
762 if (iv != NULL)
763 g_bytes_unref (iv);
764 egg_asn1x_destroy (asn);
765 return ret;
766 }
767 #endif
768
769 static gboolean
setup_pkcs5_des_params(GNode * any,gcry_cipher_hd_t cih)770 setup_pkcs5_des_params (GNode *any,
771 gcry_cipher_hd_t cih)
772 {
773 GNode *asn = NULL;
774 gcry_error_t gcry;
775 GBytes *iv;
776 gboolean ret;
777
778 g_assert (any != NULL);
779
780 asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params");
781 if (!asn)
782 asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-des-CBC-params");
783 if (!asn)
784 return FALSE;
785
786 iv = egg_asn1x_get_string_as_bytes (asn);
787 egg_asn1x_destroy (asn);
788
789 if (!iv)
790 return FALSE;
791
792 gcry = gcry_cipher_setiv (cih, g_bytes_get_data (iv, NULL), g_bytes_get_size (iv));
793 if (gcry != 0) {
794 g_message ("couldn't set %lu byte iv on cipher", (gulong)g_bytes_get_size (iv));
795 ret = FALSE;
796 } else {
797 ret = TRUE;
798 }
799
800 g_bytes_unref (iv);
801 return ret;
802 }
803
804 static gboolean
setup_pkcs5_pbkdf2_params(const gchar * password,gsize n_password,GNode * any,int cipher_algo,gcry_cipher_hd_t cih)805 setup_pkcs5_pbkdf2_params (const gchar *password,
806 gsize n_password,
807 GNode *any,
808 int cipher_algo,
809 gcry_cipher_hd_t cih)
810 {
811 GNode *asn = NULL;
812 gboolean ret;
813 gcry_error_t gcry;
814 guchar *key = NULL;
815 GBytes *salt = NULL;
816 gsize n_key;
817 gulong iterations;
818
819 g_assert (cipher_algo);
820 g_assert (any != NULL);
821
822 ret = FALSE;
823
824 asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-PBKDF2-params");
825 if (!asn)
826 goto done;
827
828 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
829 g_return_val_if_reached (FALSE);
830 salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "salt", "specified", NULL));
831 if (!salt)
832 goto done;
833
834 if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
835 g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
836 iterations, &key, NULL))
837 goto done;
838
839 n_key = gcry_cipher_get_algo_keylen (cipher_algo);
840 g_return_val_if_fail (n_key > 0, FALSE);
841
842 gcry = gcry_cipher_setkey (cih, key, n_key);
843 if (gcry != 0) {
844 g_message ("couldn't set %lu byte key on cipher", (gulong)n_key);
845 goto done;
846 }
847
848 ret = TRUE;
849
850 done:
851 if (salt != NULL)
852 g_bytes_unref (salt);
853 egg_secure_free (key);
854 egg_asn1x_destroy (asn);
855 return ret;
856 }
857
858 static gboolean
read_cipher_pkcs5_pbes2(const gchar * password,gsize n_password,GNode * data,gcry_cipher_hd_t * cih)859 read_cipher_pkcs5_pbes2 (const gchar *password,
860 gsize n_password,
861 GNode *data,
862 gcry_cipher_hd_t *cih)
863 {
864 GNode *asn = NULL;
865 gboolean r, ret;
866 GQuark key_deriv_algo, enc_oid;
867 GNode *params = NULL;
868 gcry_error_t gcry;
869 int algo, mode;
870
871 g_return_val_if_fail (cih != NULL, FALSE);
872 g_return_val_if_fail (data != NULL, FALSE);
873
874 init_quarks ();
875
876 *cih = NULL;
877 ret = FALSE;
878
879 asn = egg_asn1x_get_any_as (data, pkix_asn1_tab, "pkcs-5-PBES2-params");
880 if (!asn)
881 goto done;
882
883 algo = mode = 0;
884
885 /* Read in all the encryption type */
886 enc_oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionScheme", "algorithm", NULL));
887 if (!enc_oid)
888 goto done;
889 if (enc_oid == OID_DES_EDE3_CBC)
890 algo = GCRY_CIPHER_3DES;
891 else if (enc_oid == OID_DES_CBC)
892 algo = GCRY_CIPHER_DES;
893 else if (enc_oid == OID_DES_RC2_CBC)
894 /* GCRY_CIPHER_RFC2268_128 isn't actually implemented in libgcrypt (yet?) */;
895 else if (enc_oid == OID_DES_RC5_CBC)
896 /* RC5 doesn't exist in libgcrypt */;
897
898 /* Unsupported? */
899 if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
900 goto done;
901
902 /* Instantiate our cipher */
903 gcry = gcry_cipher_open (cih, algo, GCRY_CIPHER_MODE_CBC, 0);
904 if (gcry != 0) {
905 g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo)); /* UNREACHABLE: */
906 goto done; /* UNREACHABLE: with normal libgcrypt behavior */
907 }
908
909 /* Read out the parameters. OPTIONAL, but will always find node */
910 params = egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL);
911 g_return_val_if_fail (params != NULL, FALSE);
912
913 switch (algo) {
914 case GCRY_CIPHER_3DES:
915 case GCRY_CIPHER_DES:
916 r = setup_pkcs5_des_params (params, *cih);
917 break;
918 #if 0
919 case GCRY_CIPHER_RFC2268_128:
920 r = setup_pkcs5_rc2_params (params, *cih);
921 break;
922 #endif
923 default:
924 /* Should have been caught on the oid check above */
925 g_assert_not_reached ();
926 r = FALSE;
927 break;
928 };
929
930 if (r != TRUE)
931 goto done;
932
933 /* Read out the key creation paramaters */
934 key_deriv_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "keyDerivationFunc", "algorithm", NULL));
935 if (!key_deriv_algo)
936 goto done;
937 if (key_deriv_algo != OID_PBKDF2) {
938 g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
939 goto done;
940 }
941
942 /* parameters is OPTIONAL, but will always find node */
943 params = egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL);
944 g_return_val_if_fail (params != NULL, FALSE);
945
946 ret = setup_pkcs5_pbkdf2_params (password, n_password, params, algo, *cih);
947
948 done:
949 if (ret != TRUE && *cih) {
950 gcry_cipher_close (*cih);
951 *cih = NULL;
952 }
953
954 egg_asn1x_destroy (asn);
955 return ret;
956 }
957
958 static gboolean
read_cipher_pkcs12_pbe(int cipher_algo,int cipher_mode,const gchar * password,gsize n_password,GNode * data,gcry_cipher_hd_t * cih)959 read_cipher_pkcs12_pbe (int cipher_algo,
960 int cipher_mode,
961 const gchar *password,
962 gsize n_password,
963 GNode *data,
964 gcry_cipher_hd_t *cih)
965 {
966 GNode *asn = NULL;
967 gcry_error_t gcry;
968 gboolean ret;
969 GBytes *salt = NULL;
970 gsize n_block, n_key;
971 gulong iterations;
972 guchar *key = NULL;
973 guchar *iv = NULL;
974
975 g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
976 g_return_val_if_fail (cih != NULL, FALSE);
977 g_return_val_if_fail (data != NULL, FALSE);
978
979 *cih = NULL;
980 ret = FALSE;
981
982 /* Check if we can use this algorithm */
983 if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
984 goto done;
985
986 asn = egg_asn1x_get_any_as (data, pkix_asn1_tab, "pkcs-12-PbeParams");
987 if (!asn)
988 goto done;
989
990 salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "salt", NULL));
991 g_return_val_if_fail (salt != NULL, FALSE);
992 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterations", NULL), &iterations))
993 g_return_val_if_reached (FALSE);
994
995 n_block = gcry_cipher_get_algo_blklen (cipher_algo);
996 n_key = gcry_cipher_get_algo_keylen (cipher_algo);
997
998 /* Generate IV and key using salt read above */
999 if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password, n_password,
1000 g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
1001 iterations, &key, n_block > 1 ? &iv : NULL))
1002 goto done;
1003
1004 gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
1005 if (gcry != 0) {
1006 g_warning ("couldn't create encryption cipher: %s", gcry_strerror (gcry));
1007 goto done;
1008 }
1009
1010 if (iv)
1011 gcry_cipher_setiv (*cih, iv, n_block);
1012 gcry_cipher_setkey (*cih, key, n_key);
1013
1014 ret = TRUE;
1015
1016 done:
1017 if (ret != TRUE && *cih) {
1018 gcry_cipher_close (*cih);
1019 *cih = NULL;
1020 }
1021
1022 if (salt != NULL)
1023 g_bytes_unref (salt);
1024 g_free (iv);
1025 egg_secure_free (key);
1026 egg_asn1x_destroy (asn);
1027 return ret;
1028 }
1029
1030 static gboolean
read_mac_pkcs12_pbe(int hash_algo,const gchar * password,gsize n_password,GNode * data,gcry_md_hd_t * mdh,gsize * digest_len)1031 read_mac_pkcs12_pbe (int hash_algo,
1032 const gchar *password,
1033 gsize n_password,
1034 GNode *data,
1035 gcry_md_hd_t *mdh,
1036 gsize *digest_len)
1037 {
1038 GNode *asn = NULL;
1039 gcry_error_t gcry;
1040 gboolean ret;
1041 gsize n_key;
1042 GBytes *salt = NULL;
1043 gulong iterations;
1044 guchar *key = NULL;
1045
1046 g_return_val_if_fail (hash_algo != 0, FALSE);
1047 g_return_val_if_fail (mdh != NULL, FALSE);
1048 g_return_val_if_fail (data != NULL, FALSE);
1049
1050 *mdh = NULL;
1051 ret = FALSE;
1052
1053 /* Check if we can use this algorithm */
1054 if (gcry_md_algo_info (hash_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
1055 goto done; /* UNREACHABLE: unless libgcrypt changes behavior */
1056
1057 if (egg_asn1x_type (data) == EGG_ASN1X_ANY) {
1058 asn = egg_asn1x_get_any_as (data, pkix_asn1_tab, "pkcs-12-MacData");
1059 if (!asn)
1060 goto done;
1061 data = asn;
1062 }
1063
1064 salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (data, "macSalt", NULL));
1065 if (!salt)
1066 g_return_val_if_reached (FALSE);
1067 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (data, "iterations", NULL), &iterations))
1068 g_return_val_if_reached (FALSE);
1069
1070 n_key = gcry_md_get_algo_dlen (hash_algo);
1071
1072 /* Generate IV and key using salt read above */
1073 if (!egg_symkey_generate_pkcs12_mac (hash_algo, password, n_password,
1074 g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
1075 iterations, &key))
1076 goto done;
1077
1078 gcry = gcry_md_open (mdh, hash_algo, GCRY_MD_FLAG_HMAC);
1079 if (gcry != 0) {
1080 g_warning ("couldn't create mac digest: %s", gcry_strerror (gcry));
1081 goto done;
1082 }
1083
1084 if (digest_len)
1085 *digest_len = n_key;
1086 gcry_md_setkey (*mdh, key, n_key);
1087
1088 ret = TRUE;
1089
1090 done:
1091 if (ret != TRUE && *mdh) {
1092 gcry_md_close (*mdh);
1093 *mdh = NULL;
1094 }
1095
1096 if (salt != NULL)
1097 g_bytes_unref (salt);
1098 egg_secure_free (key);
1099 egg_asn1x_destroy (asn);
1100 return ret;
1101 }
1102
1103 gboolean
egg_symkey_read_cipher(GQuark oid_scheme,const gchar * password,gsize n_password,GNode * data,gcry_cipher_hd_t * cih)1104 egg_symkey_read_cipher (GQuark oid_scheme,
1105 const gchar *password,
1106 gsize n_password,
1107 GNode *data,
1108 gcry_cipher_hd_t *cih)
1109 {
1110 gboolean ret = FALSE;
1111
1112 g_return_val_if_fail (oid_scheme != 0, FALSE);
1113 g_return_val_if_fail (cih != NULL, FALSE);
1114 g_return_val_if_fail (data != NULL, FALSE);
1115
1116 init_quarks ();
1117
1118 /* PKCS#5 PBE */
1119 if (oid_scheme == OID_PBE_MD2_DES_CBC)
1120 ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
1121 GCRY_MD_MD2, password, n_password, data, cih);
1122
1123 else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
1124 /* RC2-64 has no implementation in libgcrypt */;
1125
1126 else if (oid_scheme == OID_PBE_MD5_DES_CBC)
1127 ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
1128 GCRY_MD_MD5, password, n_password, data, cih);
1129 else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
1130 /* RC2-64 has no implementation in libgcrypt */;
1131
1132 else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
1133 ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
1134 GCRY_MD_SHA1, password, n_password, data, cih);
1135 else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
1136 /* RC2-64 has no implementation in libgcrypt */;
1137
1138
1139 /* PKCS#5 PBES2 */
1140 else if (oid_scheme == OID_PBES2)
1141 ret = read_cipher_pkcs5_pbes2 (password, n_password, data, cih);
1142
1143
1144 /* PKCS#12 PBE */
1145 else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
1146 ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM,
1147 password, n_password, data, cih);
1148 else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
1149 /* RC4-40 has no implementation in libgcrypt */;
1150
1151 else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
1152 ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC,
1153 password, n_password, data, cih);
1154 else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1)
1155 /* 2DES has no implementation in libgcrypt */;
1156
1157 else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
1158 ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC,
1159 password, n_password, data, cih);
1160
1161 else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
1162 ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC,
1163 password, n_password, data, cih);
1164
1165 if (ret == FALSE)
1166 g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
1167
1168 return ret;
1169 }
1170
1171 gboolean
egg_symkey_read_mac(GQuark oid_scheme,const gchar * password,gsize n_password,GNode * data,gcry_md_hd_t * mdh,gsize * digest_len)1172 egg_symkey_read_mac (GQuark oid_scheme,
1173 const gchar *password,
1174 gsize n_password,
1175 GNode *data,
1176 gcry_md_hd_t *mdh,
1177 gsize *digest_len)
1178 {
1179 gboolean ret = FALSE;
1180
1181 g_return_val_if_fail (oid_scheme != 0, FALSE);
1182 g_return_val_if_fail (mdh != NULL, FALSE);
1183 g_return_val_if_fail (data != NULL, FALSE);
1184
1185 init_quarks ();
1186
1187 /* PKCS#12 MAC with SHA-1 */
1188 if (oid_scheme == OID_SHA1)
1189 ret = read_mac_pkcs12_pbe (GCRY_MD_SHA1, password, n_password,
1190 data, mdh, digest_len);
1191
1192 if (ret == FALSE)
1193 g_message ("unsupported or invalid mac: %s", g_quark_to_string (oid_scheme));
1194
1195 return ret;
1196 }
1197