Update plibc header
[oweals/gnunet.git] / src / util / crypto_ecc.c
index 1215512f46f01d601f8c57b8d1a9f0ceefc4d888..34edec3deca1702f023fcfb8d15e5f3233fd66a3 100644 (file)
  */
 #include "platform.h"
 #include <gcrypt.h>
-#include "gnunet_common.h"
 #include "gnunet_util_lib.h"
 
-#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS 
+#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
 
 /**
  * Name of the curve we are using.  Note that we have hard-coded
  * structs that use 256 bits, so using a bigger curve will require
  * changes that break stuff badly.  The name of the curve given here
  * must be agreed by all peers and be supported by libgcrypt.
- * 
+ *
  * NOTE: this will change to Curve25519 before GNUnet 0.10.0.
  */
 #define CURVE "NIST P-256"
@@ -74,13 +73,13 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
   unsigned int idx;
 
   list = gcry_sexp_find_token (sexp, topname, 0);
-  if (! list)  
-    return 1;  
+  if (! list)
+    return 1;
   l2 = gcry_sexp_cadr (list);
   gcry_sexp_release (list);
   list = l2;
-  if (! list)  
-    return 2;  
+  if (! list)
+    return 2;
 
   idx = 0;
   for (s = elems; *s; s++, idx++)
@@ -137,7 +136,7 @@ adjust (unsigned char *buf,
 
 /**
  * Output the given MPI value to the given buffer.
- * 
+ *
  * @param buf where to output to
  * @param size number of bytes in @a buf
  * @param val value to write to @a buf
@@ -172,7 +171,7 @@ mpi_scan (gcry_mpi_t *result,
   int rc;
 
   if (0 != (rc = gcry_mpi_scan (result,
-                               GCRYMPI_FMT_USG, 
+                               GCRYMPI_FMT_USG,
                                data, size, &size)))
   {
     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
@@ -204,7 +203,7 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
   gcry_mpi_release (d);
   if (0 != rc)
   {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 
+    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
     GNUNET_assert (0);
   }
 #if EXTRA_CHECKS
@@ -225,15 +224,46 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
  * @param q point on curve
  * @param pub public key struct to initialize
  * @param ctx context to use for ECC operations
- */ 
+ */
 static void
-point_to_public_key (gcry_mpi_point_t q,
-                    gcry_ctx_t ctx,
-                    struct GNUNET_CRYPTO_EccPublicSignKey *pub)
+point_to_public_sign_key (gcry_mpi_point_t q,
+                         gcry_ctx_t ctx,
+                         struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
   gcry_mpi_t q_x;
   gcry_mpi_t q_y;
-  
+
+  q_x = gcry_mpi_new (256);
+  q_y = gcry_mpi_new (256);
+  if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
+  {
+    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
+    return;
+  }
+
+  mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
+  mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
+  gcry_mpi_release (q_x);
+  gcry_mpi_release (q_y);
+}
+
+
+/**
+ * Initialize public key struct from the respective point
+ * on the curve.
+ *
+ * @param q point on curve
+ * @param pub public key struct to initialize
+ * @param ctx context to use for ECC operations
+ */
+static void
+point_to_public_encrypt_key (gcry_mpi_point_t q,
+                            gcry_ctx_t ctx,
+                            struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
+{
+  gcry_mpi_t q_x;
+  gcry_mpi_t q_y;
+
   q_x = gcry_mpi_new (256);
   q_y = gcry_mpi_new (256);
   if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
@@ -268,7 +298,32 @@ GNUNET_CRYPTO_ecc_key_get_public_for_signature (const struct GNUNET_CRYPTO_EccPr
   GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
   gcry_sexp_release (sexp);
   q = gcry_mpi_ec_get_point ("q", ctx, 0);
-  point_to_public_key (q, ctx, pub);
+  point_to_public_sign_key (q, ctx, pub);
+  gcry_ctx_release (ctx);
+  gcry_mpi_point_release (q);
+}
+
+
+/**
+ * Extract the public key for the given private key.
+ *
+ * @param priv the private key
+ * @param pub where to write the public key
+ */
+void
+GNUNET_CRYPTO_ecc_key_get_public_for_encryption (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
+                                                struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
+{
+  gcry_sexp_t sexp;
+  gcry_ctx_t ctx;
+  gcry_mpi_point_t q;
+
+  sexp = decode_private_key (priv);
+  GNUNET_assert (NULL != sexp);
+  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
+  gcry_sexp_release (sexp);
+  q = gcry_mpi_ec_get_point ("q", ctx, 0);
+  point_to_public_encrypt_key (q, ctx, pub);
   gcry_ctx_release (ctx);
   gcry_mpi_point_release (q);
 }
@@ -291,9 +346,9 @@ GNUNET_CRYPTO_ecc_public_sign_key_to_string (const struct GNUNET_CRYPTO_EccPubli
     keylen += 5 - keylen % 5;
   keylen /= 5;
   pubkeybuf = GNUNET_malloc (keylen + 1);
-  end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, 
-                                      sizeof (struct GNUNET_CRYPTO_EccPublicSignKey), 
-                                      pubkeybuf, 
+  end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
+                                      sizeof (struct GNUNET_CRYPTO_EccPublicSignKey),
+                                      pubkeybuf,
                                       keylen);
   if (NULL == end)
   {
@@ -314,7 +369,7 @@ GNUNET_CRYPTO_ecc_public_sign_key_to_string (const struct GNUNET_CRYPTO_EccPubli
  * @return #GNUNET_OK on success
  */
 int
-GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc, 
+GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc,
                                          size_t enclen,
                                          struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
@@ -353,7 +408,7 @@ decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
   mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
   mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
   q = gcry_mpi_point_new (256);
-  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); 
+  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
   gcry_mpi_release (q_x);
   gcry_mpi_release (q_y);
 
@@ -369,6 +424,19 @@ decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 }
 
 
+/**
+ * @ingroup crypto
+ * Clear memory that was used to store a private key.
+ *
+ * @param pk location of the key
+ */
+void
+GNUNET_CRYPTO_ecc_key_clear (struct GNUNET_CRYPTO_EccPrivateKey *pk)
+{
+  memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EccPrivateKey));
+}
+
+
 /**
  * Create a new private key. Caller must free return value.
  *
@@ -435,8 +503,8 @@ GNUNET_CRYPTO_ecc_key_get_anonymous ()
 
   if (once)
     return &anonymous;
-  mpi_print (anonymous.d, 
-            sizeof (anonymous.d), 
+  mpi_print (anonymous.d,
+            sizeof (anonymous.d),
             GCRYMPI_CONST_ONE);
   once = 1;
   return &anonymous;
@@ -632,7 +700,7 @@ GNUNET_CRYPTO_ecc_key_create_from_configuration (const struct GNUNET_CONFIGURATI
   struct GNUNET_CRYPTO_EccPrivateKey *priv;
   char *fn;
 
-  if (GNUNET_OK != 
+  if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &fn))
     return NULL;
   priv = GNUNET_CRYPTO_ecc_key_create_from_file (fn);
@@ -673,11 +741,10 @@ GNUNET_CRYPTO_ecc_setup_key (const char *cfg_name)
  *         could not be retrieved
  */
 int
-GNUNET_CRYPTO_get_host_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
                                  struct GNUNET_PeerIdentity *dst)
 {
   struct GNUNET_CRYPTO_EccPrivateKey *priv;
-  struct GNUNET_CRYPTO_EccPublicSignKey pub;
 
   if (NULL == (priv = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg)))
   {
@@ -685,9 +752,8 @@ GNUNET_CRYPTO_get_host_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
                 _("Could not load peer's private key\n"));
     return GNUNET_SYSERR;
   }
-  GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &pub);
+  GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &dst->public_key);
   GNUNET_free (priv);
-  GNUNET_CRYPTO_hash (&pub, sizeof (pub), &dst->hashPubKey);
   return GNUNET_OK;
 }
 
@@ -799,7 +865,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
   /* build s-expression for signature */
   mpi_scan (&r, sig->r, sizeof (sig->r));
   mpi_scan (&s, sig->s, sizeof (sig->s));
-  if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, 
+  if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
                                  "(sig-val(ecdsa(r %m)(s %m)))",
                                   r, s)))
   {
@@ -851,7 +917,7 @@ decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
   mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
   mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
   q = gcry_mpi_point_new (256);
-  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); 
+  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
   gcry_mpi_release (q_x);
   gcry_mpi_release (q_y);
 
@@ -879,7 +945,7 @@ int
 GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
                         const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub,
                         struct GNUNET_HashCode *key_material)
-{ 
+{
   gcry_mpi_point_t result;
   gcry_mpi_point_t q;
   gcry_mpi_t d;
@@ -927,7 +993,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
 
 
 /**
- * Derive the 'h' value for key derivation, where 
+ * Derive the 'h' value for key derivation, where
  * 'h = H(l,P)'.
  *
  * @param pub public key for deriviation
@@ -935,8 +1001,8 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
  * @param context additional context to use for HKDF of 'h';
  *        typically the name of the subsystem/application
  * @return h value
- */ 
-static gcry_mpi_t 
+ */
+static gcry_mpi_t
 derive_h (const struct GNUNET_CRYPTO_EccPublicSignKey *pub,
          const char *label,
          const char *context)
@@ -1024,7 +1090,7 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey
   gcry_mpi_point_t v;
 
   GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
-  
+
   /* obtain point 'q' from original public key */
   mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
   mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
@@ -1047,7 +1113,7 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey
   gcry_mpi_release (n);
   gcry_mpi_point_release (q);
   /* convert point 'v' to public key that we return */
-  point_to_public_key (v, ctx, result);
+  point_to_public_sign_key (v, ctx, result);
   gcry_mpi_point_release (v);
   gcry_ctx_release (ctx);
 }