aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c102
1 files changed, 70 insertions, 32 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 755db9bdd..0d90edd51 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -35,6 +35,8 @@
35 * structs that use 256 bits, so using a bigger curve will require 35 * structs that use 256 bits, so using a bigger curve will require
36 * changes that break stuff badly. The name of the curve given here 36 * changes that break stuff badly. The name of the curve given here
37 * must be agreed by all peers and be supported by libgcrypt. 37 * must be agreed by all peers and be supported by libgcrypt.
38 *
39 * NOTE: this will change to Curve25519 before GNUnet 0.10.0.
38 */ 40 */
39#define CURVE "NIST P-256" 41#define CURVE "NIST P-256"
40 42
@@ -113,11 +115,11 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
113 115
114 116
115/** 117/**
116 * If target != size, move target bytes to the end of the size-sized 118 * If target != size, move @a target bytes to the end of the size-sized
117 * buffer and zero out the first target-size bytes. 119 * buffer and zero out the first @a target - @a size bytes.
118 * 120 *
119 * @param buf original buffer 121 * @param buf original buffer
120 * @param size number of bytes in the buffer 122 * @param size number of bytes in @a buf
121 * @param target target size of the buffer 123 * @param target target size of the buffer
122 */ 124 */
123static void 125static void
@@ -137,8 +139,8 @@ adjust (unsigned char *buf,
137 * Output the given MPI value to the given buffer. 139 * Output the given MPI value to the given buffer.
138 * 140 *
139 * @param buf where to output to 141 * @param buf where to output to
140 * @param size number of bytes in buf 142 * @param size number of bytes in @a buf
141 * @param val value to write to buf 143 * @param val value to write to @a buf
142 */ 144 */
143static void 145static void
144mpi_print (unsigned char *buf, 146mpi_print (unsigned char *buf,
@@ -227,7 +229,7 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
227static void 229static void
228point_to_public_key (gcry_mpi_point_t q, 230point_to_public_key (gcry_mpi_point_t q,
229 gcry_ctx_t ctx, 231 gcry_ctx_t ctx,
230 struct GNUNET_CRYPTO_EccPublicKey *pub) 232 struct GNUNET_CRYPTO_EccPublicSignKey *pub)
231{ 233{
232 gcry_mpi_t q_x; 234 gcry_mpi_t q_x;
233 gcry_mpi_t q_y; 235 gcry_mpi_t q_y;
@@ -254,8 +256,8 @@ point_to_public_key (gcry_mpi_point_t q,
254 * @param pub where to write the public key 256 * @param pub where to write the public key
255 */ 257 */
256void 258void
257GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 259GNUNET_CRYPTO_ecc_key_get_public_for_signature (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
258 struct GNUNET_CRYPTO_EccPublicKey *pub) 260 struct GNUNET_CRYPTO_EccPublicSignKey *pub)
259{ 261{
260 gcry_sexp_t sexp; 262 gcry_sexp_t sexp;
261 gcry_ctx_t ctx; 263 gcry_ctx_t ctx;
@@ -276,13 +278,13 @@ GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv
276 * Convert a public key to a string. 278 * Convert a public key to a string.
277 * 279 *
278 * @param pub key to convert 280 * @param pub key to convert
279 * @return string representing 'pub' 281 * @return string representing @a pub
280 */ 282 */
281char * 283char *
282GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicKey *pub) 284GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
283{ 285{
284 char *pubkeybuf; 286 char *pubkeybuf;
285 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicKey)) * 8; 287 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)) * 8;
286 char *end; 288 char *end;
287 289
288 if (keylen % 5 > 0) 290 if (keylen % 5 > 0)
@@ -290,7 +292,7 @@ GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicKey
290 keylen /= 5; 292 keylen /= 5;
291 pubkeybuf = GNUNET_malloc (keylen + 1); 293 pubkeybuf = GNUNET_malloc (keylen + 1);
292 end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, 294 end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
293 sizeof (struct GNUNET_CRYPTO_EccPublicKey), 295 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey),
294 pubkeybuf, 296 pubkeybuf,
295 keylen); 297 keylen);
296 if (NULL == end) 298 if (NULL == end)
@@ -307,16 +309,16 @@ GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicKey
307 * Convert a string representing a public key to a public key. 309 * Convert a string representing a public key to a public key.
308 * 310 *
309 * @param enc encoded public key 311 * @param enc encoded public key
310 * @param enclen number of bytes in enc (without 0-terminator) 312 * @param enclen number of bytes in @a enc (without 0-terminator)
311 * @param pub where to store the public key 313 * @param pub where to store the public key
312 * @return #GNUNET_OK on success 314 * @return #GNUNET_OK on success
313 */ 315 */
314int 316int
315GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc, 317GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc,
316 size_t enclen, 318 size_t enclen,
317 struct GNUNET_CRYPTO_EccPublicKey *pub) 319 struct GNUNET_CRYPTO_EccPublicSignKey *pub)
318{ 320{
319 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicKey)) * 8; 321 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)) * 8;
320 322
321 if (keylen % 5 > 0) 323 if (keylen % 5 > 0)
322 keylen += 5 - keylen % 5; 324 keylen += 5 - keylen % 5;
@@ -326,7 +328,7 @@ GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc,
326 328
327 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, 329 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
328 pub, 330 pub,
329 sizeof (struct GNUNET_CRYPTO_EccPublicKey))) 331 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)))
330 return GNUNET_SYSERR; 332 return GNUNET_SYSERR;
331 return GNUNET_OK; 333 return GNUNET_OK;
332} 334}
@@ -340,7 +342,7 @@ GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc,
340 * @return NULL on error 342 * @return NULL on error
341 */ 343 */
342static gcry_sexp_t 344static gcry_sexp_t
343decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub) 345decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
344{ 346{
345 gcry_sexp_t pub_sexp; 347 gcry_sexp_t pub_sexp;
346 gcry_mpi_t q_x; 348 gcry_mpi_t q_x;
@@ -620,6 +622,7 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
620 * Create a new private key by reading our peer's key from 622 * Create a new private key by reading our peer's key from
621 * the file specified in the configuration. 623 * the file specified in the configuration.
622 * 624 *
625 * @param cfg the configuration to use
623 * @return new private key, NULL on error (for example, 626 * @return new private key, NULL on error (for example,
624 * permission denied) 627 * permission denied)
625 */ 628 */
@@ -666,7 +669,7 @@ GNUNET_CRYPTO_ecc_setup_key (const char *cfg_name)
666 * 669 *
667 * @param cfg configuration to use 670 * @param cfg configuration to use
668 * @param dst pointer to where to write the peer identity 671 * @param dst pointer to where to write the peer identity
669 * @return GNUNET_OK on success, GNUNET_SYSERR if the identity 672 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity
670 * could not be retrieved 673 * could not be retrieved
671 */ 674 */
672int 675int
@@ -674,7 +677,7 @@ GNUNET_CRYPTO_get_host_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
674 struct GNUNET_PeerIdentity *dst) 677 struct GNUNET_PeerIdentity *dst)
675{ 678{
676 struct GNUNET_CRYPTO_EccPrivateKey *priv; 679 struct GNUNET_CRYPTO_EccPrivateKey *priv;
677 struct GNUNET_CRYPTO_EccPublicKey pub; 680 struct GNUNET_CRYPTO_EccPublicSignKey pub;
678 681
679 if (NULL == (priv = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg))) 682 if (NULL == (priv = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg)))
680 { 683 {
@@ -682,7 +685,7 @@ GNUNET_CRYPTO_get_host_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
682 _("Could not load peer's private key\n")); 685 _("Could not load peer's private key\n"));
683 return GNUNET_SYSERR; 686 return GNUNET_SYSERR;
684 } 687 }
685 GNUNET_CRYPTO_ecc_key_get_public (priv, &pub); 688 GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &pub);
686 GNUNET_free (priv); 689 GNUNET_free (priv);
687 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &dst->hashPubKey); 690 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &dst->hashPubKey);
688 return GNUNET_OK; 691 return GNUNET_OK;
@@ -723,7 +726,7 @@ data_to_pkcs1 (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
723 * @param priv private key to use for the signing 726 * @param priv private key to use for the signing
724 * @param purpose what to sign (size, purpose) 727 * @param purpose what to sign (size, purpose)
725 * @param sig where to write the signature 728 * @param sig where to write the signature
726 * @return GNUNET_SYSERR on error, GNUNET_OK on success 729 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
727 */ 730 */
728int 731int
729GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 732GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
@@ -774,14 +777,14 @@ GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
774 * @param validate block to validate (size, purpose, data) 777 * @param validate block to validate (size, purpose, data)
775 * @param sig signature that is being validated 778 * @param sig signature that is being validated
776 * @param pub public key of the signer 779 * @param pub public key of the signer
777 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid 780 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
778 */ 781 */
779int 782int
780GNUNET_CRYPTO_ecc_verify (uint32_t purpose, 783GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
781 const struct GNUNET_CRYPTO_EccSignaturePurpose 784 const struct GNUNET_CRYPTO_EccSignaturePurpose
782 *validate, 785 *validate,
783 const struct GNUNET_CRYPTO_EccSignature *sig, 786 const struct GNUNET_CRYPTO_EccSignature *sig,
784 const struct GNUNET_CRYPTO_EccPublicKey *pub) 787 const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
785{ 788{
786 gcry_sexp_t data; 789 gcry_sexp_t data;
787 gcry_sexp_t sig_sexpr; 790 gcry_sexp_t sig_sexpr;
@@ -808,7 +811,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
808 gcry_mpi_release (r); 811 gcry_mpi_release (r);
809 gcry_mpi_release (s); 812 gcry_mpi_release (s);
810 data = data_to_pkcs1 (validate); 813 data = data_to_pkcs1 (validate);
811 if (! (pub_sexpr = decode_public_key (pub))) 814 if (! (pub_sexpr = decode_public_sign_key (pub)))
812 { 815 {
813 gcry_sexp_release (data); 816 gcry_sexp_release (data);
814 gcry_sexp_release (sig_sexpr); 817 gcry_sexp_release (sig_sexpr);
@@ -830,6 +833,41 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
830 833
831 834
832/** 835/**
836 * Convert the given public key from the network format to the
837 * S-expression that can be used by libgcrypt.
838 *
839 * @param pub public key to decode
840 * @return NULL on error
841 */
842static gcry_sexp_t
843decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
844{
845 gcry_sexp_t pub_sexp;
846 gcry_mpi_t q_x;
847 gcry_mpi_t q_y;
848 gcry_mpi_point_t q;
849 gcry_ctx_t ctx;
850
851 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
852 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
853 q = gcry_mpi_point_new (256);
854 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
855 gcry_mpi_release (q_x);
856 gcry_mpi_release (q_y);
857
858 /* initialize 'ctx' with 'q' */
859 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
860 gcry_mpi_ec_set_point ("q", q, ctx);
861 gcry_mpi_point_release (q);
862
863 /* convert 'ctx' to 'sexp' */
864 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
865 gcry_ctx_release (ctx);
866 return pub_sexp;
867}
868
869
870/**
833 * Derive key material from a public and a private ECC key. 871 * Derive key material from a public and a private ECC key.
834 * 872 *
835 * @param priv private key to use for the ECDH (x) 873 * @param priv private key to use for the ECDH (x)
@@ -839,7 +877,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
839 */ 877 */
840int 878int
841GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 879GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
842 const struct GNUNET_CRYPTO_EccPublicKey *pub, 880 const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub,
843 struct GNUNET_HashCode *key_material) 881 struct GNUNET_HashCode *key_material)
844{ 882{
845 gcry_mpi_point_t result; 883 gcry_mpi_point_t result;
@@ -852,7 +890,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
852 unsigned char xbuf[256 / 8]; 890 unsigned char xbuf[256 / 8];
853 891
854 /* first, extract the q = dP value from the public key */ 892 /* first, extract the q = dP value from the public key */
855 if (! (pub_sexpr = decode_public_key (pub))) 893 if (! (pub_sexpr = decode_public_encrypt_key (pub)))
856 return GNUNET_SYSERR; 894 return GNUNET_SYSERR;
857 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); 895 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
858 gcry_sexp_release (pub_sexpr); 896 gcry_sexp_release (pub_sexpr);
@@ -899,7 +937,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
899 * @return h value 937 * @return h value
900 */ 938 */
901static gcry_mpi_t 939static gcry_mpi_t
902derive_h (const struct GNUNET_CRYPTO_EccPublicKey *pub, 940derive_h (const struct GNUNET_CRYPTO_EccPublicSignKey *pub,
903 const char *label, 941 const char *label,
904 const char *context) 942 const char *context)
905{ 943{
@@ -934,7 +972,7 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
934 const char *label, 972 const char *label,
935 const char *context) 973 const char *context)
936{ 974{
937 struct GNUNET_CRYPTO_EccPublicKey pub; 975 struct GNUNET_CRYPTO_EccPublicSignKey pub;
938 struct GNUNET_CRYPTO_EccPrivateKey *ret; 976 struct GNUNET_CRYPTO_EccPrivateKey *ret;
939 gcry_mpi_t h; 977 gcry_mpi_t h;
940 gcry_mpi_t x; 978 gcry_mpi_t x;
@@ -944,7 +982,7 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
944 982
945 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 983 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
946 n = gcry_mpi_ec_get_mpi ("n", ctx, 1); 984 n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
947 GNUNET_CRYPTO_ecc_key_get_public (priv, &pub); 985 GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &pub);
948 h = derive_h (&pub, label, context); 986 h = derive_h (&pub, label, context);
949 mpi_scan (&x, priv->d, sizeof (priv->d)); 987 mpi_scan (&x, priv->d, sizeof (priv->d));
950 d = gcry_mpi_new (256); 988 d = gcry_mpi_new (256);
@@ -971,10 +1009,10 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
971 * @param result where to write the derived public key 1009 * @param result where to write the derived public key
972 */ 1010 */
973void 1011void
974GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pub, 1012GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey *pub,
975 const char *label, 1013 const char *label,
976 const char *context, 1014 const char *context,
977 struct GNUNET_CRYPTO_EccPublicKey *result) 1015 struct GNUNET_CRYPTO_EccPublicSignKey *result)
978{ 1016{
979 gcry_ctx_t ctx; 1017 gcry_ctx_t ctx;
980 gcry_mpi_t h; 1018 gcry_mpi_t h;