mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-22 04:38:55 +00:00
egg-dh: Hide gcry_mpi_t from the internal API
This wraps gcry_mpi_t usage in the API with opaque strucs, so it would be easier to port egg-dh to other crypto libraries. Signed-off-by: Daiki Ueno <dueno@src.gnome.org>
This commit is contained in:
parent
39055f245e
commit
47f524e2df
212
egg/egg-dh.c
212
egg/egg-dh.c
@ -26,6 +26,8 @@
|
||||
#include "egg-dh.h"
|
||||
#include "egg-secure-memory.h"
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
/* Enabling this is a complete security compromise */
|
||||
#define DEBUG_DH_SECRET 0
|
||||
|
||||
@ -212,6 +214,19 @@ static const DHGroup dh_groups[] = {
|
||||
}
|
||||
};
|
||||
|
||||
struct egg_dh_params {
|
||||
gcry_mpi_t prime;
|
||||
gcry_mpi_t base;
|
||||
};
|
||||
|
||||
struct egg_dh_pubkey {
|
||||
gcry_mpi_t inner;
|
||||
};
|
||||
|
||||
struct egg_dh_privkey {
|
||||
gcry_mpi_t inner;
|
||||
};
|
||||
|
||||
gboolean
|
||||
egg_dh_default_params_raw (const gchar *name, gconstpointer *prime,
|
||||
gsize *n_prime, gconstpointer *base, gsize *n_base)
|
||||
@ -237,44 +252,61 @@ egg_dh_default_params_raw (const gchar *name, gconstpointer *prime,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
egg_dh_default_params (const gchar *name, gcry_mpi_t *prime, gcry_mpi_t *base)
|
||||
egg_dh_params *
|
||||
egg_dh_default_params (const gchar *name)
|
||||
{
|
||||
const DHGroup *group;
|
||||
gcry_error_t gcry;
|
||||
gcry_mpi_t prime = NULL, base = NULL;
|
||||
egg_dh_params *params = NULL;
|
||||
|
||||
g_return_val_if_fail (name, FALSE);
|
||||
g_return_val_if_fail (name, NULL);
|
||||
|
||||
for (group = dh_groups; group->name; ++group) {
|
||||
if (g_str_equal (group->name, name)) {
|
||||
if (prime) {
|
||||
gcry = gcry_mpi_scan (prime, GCRYMPI_FMT_USG, group->prime, group->n_prime, NULL);
|
||||
g_return_val_if_fail (gcry == 0, FALSE);
|
||||
g_return_val_if_fail (gcry_mpi_get_nbits (*prime) == group->bits, FALSE);
|
||||
}
|
||||
if (base) {
|
||||
gcry = gcry_mpi_scan (base, GCRYMPI_FMT_USG, group->base, group->n_base, NULL);
|
||||
g_return_val_if_fail (gcry == 0, FALSE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
for (group = dh_groups; group->name; ++group)
|
||||
if (g_str_equal (group->name, name))
|
||||
break;
|
||||
if (!group->name)
|
||||
return NULL;
|
||||
|
||||
return FALSE;
|
||||
gcry = gcry_mpi_scan (&prime, GCRYMPI_FMT_USG,
|
||||
group->prime, group->n_prime, NULL);
|
||||
g_return_val_if_fail (gcry == 0, NULL);
|
||||
if (G_UNLIKELY (gcry_mpi_get_nbits (prime) != group->bits))
|
||||
goto error;
|
||||
|
||||
gcry = gcry_mpi_scan (&base, GCRYMPI_FMT_USG,
|
||||
group->base, group->n_base, NULL);
|
||||
if (gcry != 0)
|
||||
goto error;
|
||||
|
||||
params = g_new (struct egg_dh_params, 1);
|
||||
if (!params)
|
||||
goto error;
|
||||
|
||||
params->prime = g_steal_pointer (&prime);
|
||||
params->base = g_steal_pointer (&base);
|
||||
|
||||
error:
|
||||
gcry_mpi_release (prime);
|
||||
gcry_mpi_release (base);
|
||||
return params;
|
||||
}
|
||||
|
||||
gboolean
|
||||
egg_dh_gen_pair (gcry_mpi_t prime, gcry_mpi_t base, guint bits,
|
||||
gcry_mpi_t *pub, gcry_mpi_t *priv)
|
||||
egg_dh_gen_pair (egg_dh_params *params, guint bits,
|
||||
egg_dh_pubkey **pub, egg_dh_privkey **priv)
|
||||
{
|
||||
guint pbits;
|
||||
gcry_mpi_t pub_inner = NULL, priv_inner = NULL;
|
||||
|
||||
g_return_val_if_fail (prime, FALSE);
|
||||
g_return_val_if_fail (base, FALSE);
|
||||
g_return_val_if_fail (params, FALSE);
|
||||
g_return_val_if_fail (pub, FALSE);
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
|
||||
pbits = gcry_mpi_get_nbits (prime);
|
||||
*pub = NULL;
|
||||
*priv = NULL;
|
||||
|
||||
pbits = gcry_mpi_get_nbits (params->prime);
|
||||
g_return_val_if_fail (pbits > 1, FALSE);
|
||||
|
||||
if (bits == 0) {
|
||||
@ -289,28 +321,47 @@ egg_dh_gen_pair (gcry_mpi_t prime, gcry_mpi_t base, guint bits,
|
||||
* need to have a value less than half of prime, we make sure
|
||||
* we bump down.
|
||||
*/
|
||||
*priv = gcry_mpi_snew (bits);
|
||||
g_return_val_if_fail (*priv, FALSE);
|
||||
while (gcry_mpi_cmp_ui (*priv, 0) == 0)
|
||||
gcry_mpi_randomize (*priv, bits, GCRY_STRONG_RANDOM);
|
||||
priv_inner = gcry_mpi_snew (bits);
|
||||
g_return_val_if_fail (priv_inner, FALSE);
|
||||
while (gcry_mpi_cmp_ui (priv_inner, 0) == 0)
|
||||
gcry_mpi_randomize (priv_inner, bits, GCRY_STRONG_RANDOM);
|
||||
|
||||
/* Secret key value must be less than half of p */
|
||||
if (gcry_mpi_get_nbits (*priv) > bits)
|
||||
gcry_mpi_clear_highbit (*priv, bits);
|
||||
if (gcry_mpi_get_nbits (*priv) > pbits - 1)
|
||||
gcry_mpi_clear_highbit (*priv, pbits - 1);
|
||||
g_assert (gcry_mpi_cmp (prime, *priv) > 0);
|
||||
if (gcry_mpi_get_nbits (priv_inner) > bits)
|
||||
gcry_mpi_clear_highbit (priv_inner, bits);
|
||||
if (gcry_mpi_get_nbits (priv_inner) > pbits - 1)
|
||||
gcry_mpi_clear_highbit (priv_inner, pbits - 1);
|
||||
g_assert (gcry_mpi_cmp (params->prime, priv_inner) > 0);
|
||||
|
||||
*pub = gcry_mpi_new (gcry_mpi_get_nbits (*priv));
|
||||
g_return_val_if_fail (*pub, FALSE);
|
||||
gcry_mpi_powm (*pub, base, *priv, prime);
|
||||
pub_inner = gcry_mpi_new (gcry_mpi_get_nbits (priv_inner));
|
||||
if (!pub_inner)
|
||||
goto error;
|
||||
gcry_mpi_powm (pub_inner, params->base, priv_inner, params->prime);
|
||||
|
||||
*priv = g_new0 (struct egg_dh_privkey, 1);
|
||||
if (!*priv)
|
||||
goto error;
|
||||
(*priv)->inner = g_steal_pointer (&priv_inner);
|
||||
|
||||
*pub = g_new0 (struct egg_dh_pubkey, 1);
|
||||
if (!*pub)
|
||||
goto error;
|
||||
(*pub)->inner = g_steal_pointer (&pub_inner);
|
||||
|
||||
return TRUE;
|
||||
error:
|
||||
egg_dh_privkey_free (*priv);
|
||||
egg_dh_pubkey_free (*pub);
|
||||
|
||||
gcry_mpi_release (priv_inner);
|
||||
gcry_mpi_release (pub_inner);
|
||||
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
gpointer
|
||||
egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
|
||||
gcry_mpi_t prime, gsize *bytes)
|
||||
GBytes *
|
||||
egg_dh_gen_secret (egg_dh_pubkey *peer, egg_dh_privkey *priv,
|
||||
egg_dh_params *params)
|
||||
{
|
||||
gcry_error_t gcry;
|
||||
guchar *value;
|
||||
@ -321,17 +372,17 @@ egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
|
||||
|
||||
g_return_val_if_fail (peer, NULL);
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
g_return_val_if_fail (prime, NULL);
|
||||
g_return_val_if_fail (params, NULL);
|
||||
|
||||
bits = gcry_mpi_get_nbits (prime);
|
||||
bits = gcry_mpi_get_nbits (params->prime);
|
||||
g_return_val_if_fail (bits >= 0, NULL);
|
||||
|
||||
k = gcry_mpi_snew (bits);
|
||||
g_return_val_if_fail (k, NULL);
|
||||
gcry_mpi_powm (k, peer, priv, prime);
|
||||
gcry_mpi_powm (k, peer->inner, priv->inner, params->prime);
|
||||
|
||||
/* Write out the secret */
|
||||
gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n_prime, prime);
|
||||
gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n_prime, params->prime);
|
||||
g_return_val_if_fail (gcry == 0, NULL);
|
||||
value = egg_secure_alloc (n_prime);
|
||||
gcry = gcry_mpi_print (GCRYMPI_FMT_USG, value, n_prime, &n_value, k);
|
||||
@ -349,14 +400,83 @@ egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
|
||||
#endif
|
||||
gcry_mpi_release (k);
|
||||
|
||||
*bytes = n_prime;
|
||||
|
||||
#if DEBUG_DH_SECRET
|
||||
gcry_mpi_scan (&k, GCRYMPI_FMT_USG, value, bytes, NULL);
|
||||
gcry_mpi_scan (&k, GCRYMPI_FMT_USG, value, n_prime, NULL);
|
||||
g_printerr ("RAW SECRET: ");
|
||||
gcry_mpi_dump (k);
|
||||
gcry_mpi_release (k);
|
||||
#endif
|
||||
|
||||
return value;
|
||||
return g_bytes_new_with_free_func (value, n_prime,
|
||||
(GDestroyNotify)egg_secure_free,
|
||||
value);
|
||||
}
|
||||
|
||||
void
|
||||
egg_dh_params_free (egg_dh_params *params)
|
||||
{
|
||||
if (!params)
|
||||
return;
|
||||
gcry_mpi_release (params->prime);
|
||||
gcry_mpi_release (params->base);
|
||||
g_free (params);
|
||||
}
|
||||
|
||||
void
|
||||
egg_dh_pubkey_free (egg_dh_pubkey *pubkey)
|
||||
{
|
||||
if (!pubkey)
|
||||
return;
|
||||
if (pubkey->inner)
|
||||
gcry_mpi_release (pubkey->inner);
|
||||
g_free (pubkey);
|
||||
}
|
||||
|
||||
void
|
||||
egg_dh_privkey_free (egg_dh_privkey *privkey)
|
||||
{
|
||||
if (!privkey)
|
||||
return;
|
||||
if (privkey->inner)
|
||||
gcry_mpi_release (privkey->inner);
|
||||
g_free (privkey);
|
||||
}
|
||||
|
||||
GBytes *
|
||||
egg_dh_pubkey_export (const egg_dh_pubkey *pubkey)
|
||||
{
|
||||
gcry_error_t gcry;
|
||||
unsigned char *buffer;
|
||||
size_t n_buffer;
|
||||
|
||||
gcry = gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &n_buffer,
|
||||
pubkey->inner);
|
||||
g_return_val_if_fail (gcry == 0, NULL);
|
||||
|
||||
return g_bytes_new_with_free_func (buffer, n_buffer,
|
||||
gcry_free, buffer);
|
||||
}
|
||||
|
||||
egg_dh_pubkey *
|
||||
egg_dh_pubkey_new_from_bytes (const egg_dh_params *params,
|
||||
GBytes *bytes)
|
||||
{
|
||||
gcry_error_t gcry;
|
||||
gcry_mpi_t inner;
|
||||
egg_dh_pubkey *pub;
|
||||
|
||||
gcry = gcry_mpi_scan (&inner, GCRYMPI_FMT_USG,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes),
|
||||
NULL);
|
||||
g_return_val_if_fail (gcry == 0, NULL);
|
||||
|
||||
pub = g_new (struct egg_dh_pubkey, 1);
|
||||
if (!pub) {
|
||||
gcry_mpi_release (inner);
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
pub->inner = inner;
|
||||
return pub;
|
||||
}
|
||||
|
42
egg/egg-dh.h
42
egg/egg-dh.h
@ -26,27 +26,33 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
typedef struct egg_dh_params egg_dh_params;
|
||||
typedef struct egg_dh_pubkey egg_dh_pubkey;
|
||||
typedef struct egg_dh_privkey egg_dh_privkey;
|
||||
|
||||
gboolean egg_dh_default_params (const gchar *name,
|
||||
gcry_mpi_t *prime,
|
||||
gcry_mpi_t *base);
|
||||
egg_dh_params *egg_dh_default_params (const gchar *name);
|
||||
|
||||
gboolean egg_dh_default_params_raw (const gchar *name,
|
||||
gconstpointer *prime,
|
||||
gsize *n_prime,
|
||||
gconstpointer *base,
|
||||
gsize *n_base);
|
||||
gboolean egg_dh_default_params_raw (const gchar *name,
|
||||
gconstpointer *prime,
|
||||
gsize *n_prime,
|
||||
gconstpointer *base,
|
||||
gsize *n_base);
|
||||
|
||||
gboolean egg_dh_gen_pair (gcry_mpi_t prime,
|
||||
gcry_mpi_t base,
|
||||
guint bits,
|
||||
gcry_mpi_t *pub,
|
||||
gcry_mpi_t *priv);
|
||||
gboolean egg_dh_gen_pair (egg_dh_params *params,
|
||||
guint bits,
|
||||
egg_dh_pubkey **pub,
|
||||
egg_dh_privkey **priv);
|
||||
|
||||
gpointer egg_dh_gen_secret (gcry_mpi_t peer,
|
||||
gcry_mpi_t priv,
|
||||
gcry_mpi_t prime,
|
||||
gsize *bytes);
|
||||
GBytes *egg_dh_gen_secret (egg_dh_pubkey *peer,
|
||||
egg_dh_privkey *priv,
|
||||
egg_dh_params *prime);
|
||||
|
||||
void egg_dh_params_free (egg_dh_params *params);
|
||||
void egg_dh_pubkey_free (egg_dh_pubkey *pubkey);
|
||||
void egg_dh_privkey_free (egg_dh_privkey *privkey);
|
||||
|
||||
GBytes *egg_dh_pubkey_export (const egg_dh_pubkey *pubkey);
|
||||
egg_dh_pubkey *egg_dh_pubkey_new_from_bytes (const egg_dh_params *params,
|
||||
GBytes *bytes);
|
||||
|
||||
#endif /* EGG_DH_H_ */
|
||||
|
@ -40,80 +40,78 @@ EGG_SECURE_DEFINE_GLIB_GLOBALS ();
|
||||
static void
|
||||
test_perform (void)
|
||||
{
|
||||
gcry_mpi_t p, g;
|
||||
gcry_mpi_t x1, X1;
|
||||
gcry_mpi_t x2, X2;
|
||||
gpointer k1, k2;
|
||||
egg_dh_params *params;
|
||||
egg_dh_pubkey *y1;
|
||||
egg_dh_privkey *x1;
|
||||
egg_dh_pubkey *y2;
|
||||
egg_dh_privkey *x2;
|
||||
GBytes *k1, *k2;
|
||||
gboolean ret;
|
||||
gsize n1, n2;
|
||||
|
||||
/* Load up the parameters */
|
||||
if (!egg_dh_default_params ("ietf-ike-grp-modp-768", &p, &g))
|
||||
params = egg_dh_default_params ("ietf-ike-grp-modp-768");
|
||||
if (!params)
|
||||
g_assert_not_reached ();
|
||||
|
||||
/* Generate secrets */
|
||||
ret = egg_dh_gen_pair (p, g, 0, &X1, &x1);
|
||||
ret = egg_dh_gen_pair (params, 0, &y1, &x1);
|
||||
g_assert_true (ret);
|
||||
ret = egg_dh_gen_pair (p, g, 0, &X2, &x2);
|
||||
ret = egg_dh_gen_pair (params, 0, &y2, &x2);
|
||||
g_assert_true (ret);
|
||||
|
||||
/* Calculate keys */
|
||||
k1 = egg_dh_gen_secret (X2, x1, p, &n1);
|
||||
k1 = egg_dh_gen_secret (y1, x2, params);
|
||||
g_assert_nonnull (k1);
|
||||
k2 = egg_dh_gen_secret (X1, x2, p, &n2);
|
||||
k2 = egg_dh_gen_secret (y2, x1, params);
|
||||
g_assert_nonnull (k2);
|
||||
|
||||
/* Keys must be the same */
|
||||
egg_assert_cmpsize (n1, ==, n2);
|
||||
g_assert_true (memcmp (k1, k2, n1) == 0);
|
||||
g_assert_cmpmem (g_bytes_get_data (k1, NULL), g_bytes_get_size (k1),
|
||||
g_bytes_get_data (k2, NULL), g_bytes_get_size (k2));
|
||||
|
||||
gcry_mpi_release (p);
|
||||
gcry_mpi_release (g);
|
||||
gcry_mpi_release (x1);
|
||||
gcry_mpi_release (X1);
|
||||
egg_dh_params_free (params);
|
||||
egg_dh_pubkey_free (y1);
|
||||
egg_dh_privkey_free (x1);
|
||||
egg_secure_free (k1);
|
||||
gcry_mpi_release (x2);
|
||||
gcry_mpi_release (X2);
|
||||
egg_dh_pubkey_free (y2);
|
||||
egg_dh_privkey_free (x2);
|
||||
egg_secure_free (k2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_short_pair (void)
|
||||
{
|
||||
gcry_mpi_t p, g;
|
||||
gcry_mpi_t x1, X1;
|
||||
egg_dh_params *params;
|
||||
egg_dh_pubkey *y1;
|
||||
egg_dh_privkey *x1;
|
||||
GBytes *bytes;
|
||||
gboolean ret;
|
||||
|
||||
/* Load up the parameters */
|
||||
ret = egg_dh_default_params ("ietf-ike-grp-modp-1024", &p, &g);
|
||||
g_assert_true (ret);
|
||||
g_assert_cmpuint (gcry_mpi_get_nbits (p), ==, 1024);
|
||||
params = egg_dh_default_params ("ietf-ike-grp-modp-1024");
|
||||
g_assert_nonnull (params);
|
||||
|
||||
/* Generate secrets */
|
||||
ret = egg_dh_gen_pair (p, g, 512, &X1, &x1);
|
||||
ret = egg_dh_gen_pair (params, 512, &y1, &x1);
|
||||
g_assert_true (ret);
|
||||
g_assert_cmpuint (gcry_mpi_get_nbits (x1), <=, 512);
|
||||
bytes = egg_dh_pubkey_export (y1);
|
||||
g_assert_cmpuint (g_bytes_get_size (bytes), <=, 512);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
gcry_mpi_release (p);
|
||||
gcry_mpi_release (g);
|
||||
gcry_mpi_release (x1);
|
||||
gcry_mpi_release (X1);
|
||||
egg_dh_params_free (params);
|
||||
egg_dh_pubkey_free (y1);
|
||||
egg_dh_privkey_free (x1);
|
||||
}
|
||||
|
||||
static void
|
||||
check_dh_default (const gchar *name, guint bits)
|
||||
{
|
||||
gboolean ret;
|
||||
gcry_mpi_t p, g, check;
|
||||
gcry_mpi_t check;
|
||||
gconstpointer prime, base;
|
||||
gsize n_prime, n_base;
|
||||
gcry_error_t gcry;
|
||||
|
||||
ret = egg_dh_default_params (name, &p, &g);
|
||||
g_assert_true (ret);
|
||||
g_assert_cmpint (gcry_mpi_get_nbits (p), ==, bits);
|
||||
g_assert_cmpint (gcry_mpi_get_nbits (g), <, gcry_mpi_get_nbits (p));
|
||||
|
||||
ret = egg_dh_default_params_raw (name, &prime, &n_prime, &base, &n_base);
|
||||
g_assert_true (ret);
|
||||
g_assert_nonnull (prime);
|
||||
@ -123,16 +121,11 @@ check_dh_default (const gchar *name, guint bits)
|
||||
|
||||
gcry = gcry_mpi_scan (&check, GCRYMPI_FMT_USG, prime, n_prime, NULL);
|
||||
g_assert_true (gcry == 0);
|
||||
g_assert_true (gcry_mpi_cmp (check, p) == 0);
|
||||
gcry_mpi_release (check);
|
||||
|
||||
gcry = gcry_mpi_scan (&check, GCRYMPI_FMT_USG, base, n_base, NULL);
|
||||
g_assert_true (gcry == 0);
|
||||
g_assert_true (gcry_mpi_cmp (check, g) == 0);
|
||||
gcry_mpi_release (check);
|
||||
|
||||
gcry_mpi_release (p);
|
||||
gcry_mpi_release (g);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -180,11 +173,10 @@ test_default_8192 (void)
|
||||
static void
|
||||
test_default_bad (void)
|
||||
{
|
||||
gboolean ret;
|
||||
gcry_mpi_t p, g;
|
||||
egg_dh_params *params;
|
||||
|
||||
ret = egg_dh_default_params ("bad-name", &p, &g);
|
||||
g_assert_false (ret);
|
||||
params = egg_dh_default_params ("bad-name");
|
||||
g_assert_null (params);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "egg/egg-dh.h"
|
||||
#include "egg/egg-hkdf.h"
|
||||
#include "egg/egg-libgcrypt.h"
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
#include "egg/egg-hex.h"
|
||||
@ -37,9 +38,9 @@ struct _SecretSession {
|
||||
gchar *path;
|
||||
const gchar *algorithms;
|
||||
#ifdef WITH_GCRYPT
|
||||
gcry_mpi_t prime;
|
||||
gcry_mpi_t privat;
|
||||
gcry_mpi_t publi;
|
||||
egg_dh_params *params;
|
||||
egg_dh_privkey *privat;
|
||||
egg_dh_pubkey *publi;
|
||||
#endif
|
||||
gpointer key;
|
||||
gsize n_key;
|
||||
@ -55,9 +56,9 @@ _secret_session_free (gpointer data)
|
||||
|
||||
g_free (session->path);
|
||||
#ifdef WITH_GCRYPT
|
||||
gcry_mpi_release (session->publi);
|
||||
gcry_mpi_release (session->privat);
|
||||
gcry_mpi_release (session->prime);
|
||||
egg_dh_pubkey_free (session->publi);
|
||||
egg_dh_privkey_free (session->privat);
|
||||
egg_dh_params_free (session->params);
|
||||
#endif
|
||||
egg_secure_free (session->key);
|
||||
g_free (session);
|
||||
@ -68,41 +69,36 @@ _secret_session_free (gpointer data)
|
||||
static GVariant *
|
||||
request_open_session_aes (SecretSession *session)
|
||||
{
|
||||
gcry_error_t gcry;
|
||||
gcry_mpi_t base;
|
||||
unsigned char *buffer;
|
||||
size_t n_buffer;
|
||||
GBytes *buffer;
|
||||
GVariant *argument;
|
||||
|
||||
g_assert (session->prime == NULL);
|
||||
g_assert (session->params == NULL);
|
||||
g_assert (session->privat == NULL);
|
||||
g_assert (session->publi == NULL);
|
||||
|
||||
egg_libgcrypt_initialize ();
|
||||
|
||||
/* Initialize our local parameters and values */
|
||||
if (!egg_dh_default_params ("ietf-ike-grp-modp-1024",
|
||||
&session->prime, &base))
|
||||
session->params = egg_dh_default_params ("ietf-ike-grp-modp-1024");
|
||||
if (!session->params)
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
#if 0
|
||||
g_printerr ("\n lib prime: ");
|
||||
gcry_mpi_dump (session->prime);
|
||||
g_printerr ("\n lib base: ");
|
||||
gcry_mpi_dump (base);
|
||||
g_printerr ("\n lib params: ");
|
||||
egg_dh_params_dump (session->params);
|
||||
g_printerr ("\n");
|
||||
#endif
|
||||
|
||||
if (!egg_dh_gen_pair (session->prime, base, 0,
|
||||
if (!egg_dh_gen_pair (session->params, 0,
|
||||
&session->publi, &session->privat))
|
||||
g_return_val_if_reached (NULL);
|
||||
gcry_mpi_release (base);
|
||||
|
||||
gcry = gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &n_buffer, session->publi);
|
||||
g_return_val_if_fail (gcry == 0, NULL);
|
||||
argument = g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
|
||||
buffer, n_buffer, TRUE,
|
||||
gcry_free, buffer);
|
||||
buffer = egg_dh_pubkey_export (session->publi);
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
argument = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"),
|
||||
buffer,
|
||||
TRUE);
|
||||
g_bytes_unref (buffer);
|
||||
|
||||
return g_variant_new ("(sv)", ALGORITHMS_AES, argument);
|
||||
}
|
||||
@ -111,14 +107,11 @@ static gboolean
|
||||
response_open_session_aes (SecretSession *session,
|
||||
GVariant *response)
|
||||
{
|
||||
gconstpointer buffer;
|
||||
GBytes *buffer;
|
||||
GVariant *argument;
|
||||
const gchar *sig;
|
||||
gsize n_buffer;
|
||||
gcry_mpi_t peer;
|
||||
gcry_error_t gcry;
|
||||
gpointer ikm;
|
||||
gsize n_ikm;
|
||||
egg_dh_pubkey *peer;
|
||||
GBytes *ikm;
|
||||
|
||||
sig = g_variant_get_type_string (response);
|
||||
g_return_val_if_fail (sig != NULL, FALSE);
|
||||
@ -131,24 +124,27 @@ response_open_session_aes (SecretSession *session,
|
||||
g_assert (session->path == NULL);
|
||||
g_variant_get (response, "(vo)", &argument, &session->path);
|
||||
|
||||
buffer = g_variant_get_fixed_array (argument, &n_buffer, sizeof (guchar));
|
||||
gcry = gcry_mpi_scan (&peer, GCRYMPI_FMT_USG, buffer, n_buffer, NULL);
|
||||
g_return_val_if_fail (gcry == 0, FALSE);
|
||||
buffer = g_variant_get_data_as_bytes (argument);
|
||||
peer = egg_dh_pubkey_new_from_bytes (session->params, buffer);
|
||||
g_bytes_unref (buffer);
|
||||
g_return_val_if_fail (peer != NULL, FALSE);
|
||||
g_variant_unref (argument);
|
||||
|
||||
#if 0
|
||||
g_printerr (" lib publi: ");
|
||||
gcry_mpi_dump (session->publi);
|
||||
egg_dh_pubkey_dump (session->publi);
|
||||
g_printerr ("\n lib peer: ");
|
||||
gcry_mpi_dump (peer);
|
||||
egg_dh_pubkey_dump (peer);
|
||||
g_printerr ("\n");
|
||||
#endif
|
||||
|
||||
ikm = egg_dh_gen_secret (peer, session->privat, session->prime, &n_ikm);
|
||||
gcry_mpi_release (peer);
|
||||
ikm = egg_dh_gen_secret (peer, session->privat, session->params);
|
||||
egg_dh_pubkey_free (peer);
|
||||
|
||||
#if 0
|
||||
g_printerr (" lib ikm: %s\n", egg_hex_encode (ikm, n_ikm));
|
||||
g_printerr (" lib ikm: %s\n",
|
||||
egg_hex_encode (g_bytes_get_data (ikm, NULL),
|
||||
g_bytes_get_size (ikm)));
|
||||
#endif
|
||||
|
||||
if (ikm == NULL) {
|
||||
@ -160,10 +156,13 @@ response_open_session_aes (SecretSession *session,
|
||||
|
||||
session->n_key = 16;
|
||||
session->key = egg_secure_alloc (session->n_key);
|
||||
if (!egg_hkdf_perform ("sha256", ikm, n_ikm, NULL, 0, NULL, 0,
|
||||
if (!egg_hkdf_perform ("sha256",
|
||||
g_bytes_get_data (ikm, NULL),
|
||||
g_bytes_get_size (ikm),
|
||||
NULL, 0, NULL, 0,
|
||||
session->key, session->n_key))
|
||||
g_return_val_if_reached (FALSE);
|
||||
egg_secure_free (ikm);
|
||||
g_bytes_unref (ikm);
|
||||
|
||||
session->algorithms = ALGORITHMS_AES;
|
||||
return TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user