mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-21 20:28:52 +00:00
28486191b2
This turns the `-Dgcrypt` build time option into a more generic `-Dcrypto` option, which enables user to choose which cryptographic library to link with. It currently supports libgcrypt (`libgcrypt`) and GnuTLS (`gnutls`); for the latter, GnuTLS 3.8.2 is the minimum required version. Signed-off-by: Daiki Ueno <dueno@src.gnome.org>
111 lines
2.7 KiB
C
111 lines
2.7 KiB
C
/*
|
|
* libsecret
|
|
*
|
|
* Copyright (C) 2023 Daiki Ueno
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2.1 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received copies of the GNU General Public License and
|
|
* the GNU Lesser General Public License along with this program. If
|
|
* not, see http://www.gnu.org/licenses/.
|
|
*
|
|
* Author: Daiki Ueno
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "egg-hkdf.h"
|
|
|
|
#include "egg-secure-memory.h"
|
|
#include <gnutls/crypto.h>
|
|
|
|
EGG_SECURE_DECLARE (hkdf);
|
|
|
|
gboolean
|
|
egg_hkdf_perform (const gchar *hash_algo, gconstpointer input, gsize n_input,
|
|
gconstpointer salt, gsize n_salt, gconstpointer info,
|
|
gsize n_info, gpointer output, gsize n_output)
|
|
{
|
|
static const struct {
|
|
gchar *name;
|
|
gnutls_mac_algorithm_t algo;
|
|
} hash_algos[] = {
|
|
{ "sha1", GNUTLS_MAC_SHA1 },
|
|
{ "sha256", GNUTLS_MAC_SHA256 },
|
|
{ NULL, }
|
|
};
|
|
gnutls_mac_algorithm_t algo = GNUTLS_MAC_UNKNOWN;
|
|
gnutls_datum_t input_datum, salt_datum, info_datum;
|
|
gpointer alloc = NULL;
|
|
gpointer buffer = NULL;
|
|
guint hash_len;
|
|
gsize i;
|
|
int ret;
|
|
gboolean result = TRUE;
|
|
|
|
for (i = 0; hash_algos[i].name; i++) {
|
|
if (g_str_equal (hash_algos[i].name, hash_algo)) {
|
|
algo = hash_algos[i].algo;
|
|
break;
|
|
}
|
|
}
|
|
g_return_val_if_fail (algo != GNUTLS_MAC_UNKNOWN, FALSE);
|
|
|
|
hash_len = gnutls_hmac_get_len (algo);
|
|
g_return_val_if_fail (hash_len != 0, FALSE);
|
|
g_return_val_if_fail (n_output <= 255 * hash_len, FALSE);
|
|
|
|
/* Buffer we need to for intermediate stuff */
|
|
buffer = egg_secure_alloc (hash_len);
|
|
g_return_val_if_fail (buffer, FALSE);
|
|
|
|
/* Salt defaults to hash_len zeros */
|
|
if (!salt) {
|
|
alloc = g_malloc0 (hash_len);
|
|
if (!alloc) {
|
|
result = FALSE;
|
|
goto out;
|
|
}
|
|
salt = alloc;
|
|
n_salt = hash_len;
|
|
}
|
|
|
|
/* Step 1: Extract */
|
|
input_datum.data = (void *)input;
|
|
input_datum.size = n_input;
|
|
salt_datum.data = (void *)salt;
|
|
salt_datum.size = n_salt;
|
|
|
|
ret = gnutls_hkdf_extract (algo, &input_datum, &salt_datum, buffer);
|
|
if (ret < 0) {
|
|
result = FALSE;
|
|
goto out;
|
|
}
|
|
|
|
/* Step 2: Expand */
|
|
input_datum.data = buffer;
|
|
input_datum.size = hash_len;
|
|
info_datum.data = (void *)info;
|
|
info_datum.size = n_info;
|
|
|
|
ret = gnutls_hkdf_expand (algo, &input_datum, &info_datum,
|
|
output, n_output);
|
|
if (ret < 0) {
|
|
result = FALSE;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
g_free (alloc);
|
|
egg_secure_free (buffer);
|
|
return result;
|
|
}
|