static gboolean gcr_secret_exchange_default_generate_exchange_key (GcrSecretExchange *exchange, const gchar *scheme, guchar **public_key, gsize *n_public_key) { GcrSecretExchangeDefault *data = exchange->pv->default_exchange; if (data == NULL) { data = g_new0 (GcrSecretExchangeDefault, 1); if (!egg_dh_default_params (EXCHANGE_1_IKE_NAME, &data->prime, &data->base)) g_return_val_if_reached (FALSE); exchange->pv->default_exchange = data; exchange->pv->destroy_exchange = gcr_secret_exchange_default_free; } gcry_mpi_release (data->priv); data->priv = NULL; gcry_mpi_release (data->pub); data->pub = NULL; egg_secure_free (data->key); data->key = NULL; if (!egg_dh_gen_pair (data->prime, data->base, 0, &data->pub, &data->priv)) g_return_val_if_reached (FALSE); *public_key = mpi_to_data (data->pub, n_public_key); return *public_key != NULL; }
/** * Negotiates crypto between the calling programm and the prompt * * Reads data from the transport section of input_data and sends the public key back * in the transport section of the output_data. * * Returns TRUE on success **/ static gboolean negotiate_transport_crypto (void) { gcry_mpi_t base, prime, peer; gcry_mpi_t key, pub, priv; gboolean ret = FALSE; gpointer ikm; gsize n_ikm; g_assert (!the_key); base = prime = peer = NULL; key = pub = priv = NULL; /* The DH stuff coming in from our caller */ if (gku_prompt_util_decode_mpi (input_data, "transport", "prime", &prime) && gku_prompt_util_decode_mpi (input_data, "transport", "base", &base) && gku_prompt_util_decode_mpi (input_data, "transport", "public", &peer)) { /* Generate our own public/priv, and then a key, send it back */ if (egg_dh_gen_pair (prime, base, 0, &pub, &priv)) { gku_prompt_util_encode_mpi (output_data, "transport", "public", pub); /* Build up a key we can use */ ikm = egg_dh_gen_secret (peer, priv, prime, &n_ikm); if (ikm != NULL) { n_the_key = 16; the_key = egg_secure_alloc (n_the_key); if (!egg_hkdf_perform ("sha256", ikm, n_ikm, NULL, 0, NULL, 0, the_key, n_the_key)) g_return_val_if_reached (FALSE); ret = TRUE; } } } gcry_mpi_release (base); gcry_mpi_release (prime); gcry_mpi_release (peer); gcry_mpi_release (key); gcry_mpi_release (pub); gcry_mpi_release (priv); return ret; }
static GVariant * request_open_session_aes (SecretSession *session) { gcry_error_t gcry; gcry_mpi_t base; unsigned char *buffer; size_t n_buffer; GVariant *argument; g_assert (session->prime == 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)) 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"); #endif if (!egg_dh_gen_pair (session->prime, base, 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); return g_variant_new ("(sv)", ALGORITHMS_AES, argument); }
/** * Negotiates crypto between the calling programm and the prompt * * Reads data from the transport section of input_data and sends the public key back * in the transport section of the output_data. * * Returns TRUE on success **/ static gboolean negotiate_transport_crypto (void) { gcry_mpi_t base, prime, peer; gcry_mpi_t key, pub, priv; gboolean ret = FALSE; g_assert (!the_key); base = prime = peer = NULL; key = pub = priv = NULL; /* The DH stuff coming in from our caller */ if (gku_prompt_util_decode_mpi (input_data, "transport", "prime", &prime) && gku_prompt_util_decode_mpi (input_data, "transport", "base", &base) && gku_prompt_util_decode_mpi (input_data, "transport", "public", &peer)) { /* Generate our own public/priv, and then a key, send it back */ if (egg_dh_gen_pair (prime, base, 0, &pub, &priv)) { gku_prompt_util_encode_mpi (output_data, "transport", "public", pub); /* Build up a key we can use */ n_the_key = 16; the_key = egg_dh_gen_secret (peer, priv, prime, n_the_key); ret = (the_key != NULL); } } gcry_mpi_release (base); gcry_mpi_release (prime); gcry_mpi_release (peer); gcry_mpi_release (key); gcry_mpi_release (pub); gcry_mpi_release (priv); return ret; }