4 * Copyright (C) 2011 Collabora Ltd.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
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 License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * Author: Stef Walter <stefw@collabora.co.uk>
27 #include "egg-secure-memory.h"
34 egg_hkdf_perform (const gchar *hash_algo, gconstpointer input, gsize n_input,
35 gconstpointer salt, gsize n_salt, gconstpointer info,
36 gsize n_info, gpointer output, gsize n_output)
38 gpointer alloc = NULL;
39 gpointer buffer = NULL;
40 gcry_md_hd_t md1, md2;
48 algo = gcry_md_map_name (hash_algo);
49 g_return_val_if_fail (algo != 0, FALSE);
51 hash_len = gcry_md_get_algo_dlen (algo);
52 g_return_val_if_fail (hash_len != 0, FALSE);
53 g_return_val_if_fail (n_output <= 255 * hash_len, FALSE);
55 /* Buffer we need to for intermediate stuff */
56 if (gcry_is_secure (input)) {
57 flags = GCRY_MD_FLAG_SECURE;
58 buffer = gcry_malloc_secure (hash_len);
61 buffer = gcry_malloc (hash_len);
64 g_return_val_if_fail (buffer, FALSE);
67 /* Salt defaults to hash_len zeros */
69 salt = alloc = g_malloc0 (hash_len);
74 gcry = gcry_md_open (&md1, algo, GCRY_MD_FLAG_HMAC | flags);
75 g_return_val_if_fail (gcry == 0, FALSE);
76 gcry = gcry_md_setkey (md1, salt, n_salt);
77 g_return_val_if_fail (gcry == 0, FALSE);
78 gcry_md_write (md1, input, n_input);
81 gcry = gcry_md_open (&md2, algo, GCRY_MD_FLAG_HMAC | flags);
82 g_return_val_if_fail (gcry == 0, FALSE);
83 gcry = gcry_md_setkey (md2, gcry_md_read (md1, algo), hash_len);
84 g_return_val_if_fail (gcry == 0, FALSE);
88 for (i = 1; i < 256; ++i) {
90 gcry_md_write (md2, buffer, n_buffer);
91 gcry_md_write (md2, info, n_info);
92 gcry_md_write (md2, &i, 1);
95 memcpy (buffer, gcry_md_read (md2, algo), n_buffer);
97 step = MIN (n_buffer, n_output);
98 memcpy (at, buffer, step);