diff options
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r-- | src/util/crypto_ecc.c | 102 |
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 | */ |
123 | static void | 125 | static 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 | */ |
143 | static void | 145 | static void |
144 | mpi_print (unsigned char *buf, | 146 | mpi_print (unsigned char *buf, |
@@ -227,7 +229,7 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv) | |||
227 | static void | 229 | static void |
228 | point_to_public_key (gcry_mpi_point_t q, | 230 | point_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 | */ |
256 | void | 258 | void |
257 | GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | 259 | GNUNET_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 | */ |
281 | char * | 283 | char * |
282 | GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicKey *pub) | 284 | GNUNET_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 | */ |
314 | int | 316 | int |
315 | GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc, | 317 | GNUNET_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 | */ |
342 | static gcry_sexp_t | 344 | static gcry_sexp_t |
343 | decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub) | 345 | decode_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 | */ |
672 | int | 675 | int |
@@ -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 | */ |
728 | int | 731 | int |
729 | GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | 732 | GNUNET_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 | */ |
779 | int | 782 | int |
780 | GNUNET_CRYPTO_ecc_verify (uint32_t purpose, | 783 | GNUNET_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 | */ | ||
842 | static gcry_sexp_t | ||
843 | decode_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 | */ |
840 | int | 878 | int |
841 | GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | 879 | GNUNET_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 | */ |
901 | static gcry_mpi_t | 939 | static gcry_mpi_t |
902 | derive_h (const struct GNUNET_CRYPTO_EccPublicKey *pub, | 940 | derive_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 | */ |
973 | void | 1011 | void |
974 | GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pub, | 1012 | GNUNET_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; |