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.c129
1 files changed, 19 insertions, 110 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 88806a8dd..95d157eb1 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -386,14 +386,28 @@ ecc_key_create ()
386 struct GNUNET_CRYPTO_EccPrivateKey *ret; 386 struct GNUNET_CRYPTO_EccPrivateKey *ret;
387 gcry_sexp_t s_key; 387 gcry_sexp_t s_key;
388 gcry_sexp_t s_keyparam; 388 gcry_sexp_t s_keyparam;
389 int rc;
389 390
390 GNUNET_assert (0 == 391 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
391 gcry_sexp_build (&s_keyparam, NULL, 392 "(genkey(ecdsa(curve 10:NIST P-521)))")))
392 "(genkey(ecc(curve \"" CURVE "\")))")); 393 {
393 GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam)); 394 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
395 return NULL;
396 }
397 if (0 != (rc = gcry_pk_genkey (&s_key, s_keyparam)))
398 {
399 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
400 gcry_sexp_release (s_keyparam);
401 return NULL;
402 }
394 gcry_sexp_release (s_keyparam); 403 gcry_sexp_release (s_keyparam);
395#if EXTRA_CHECKS 404#if EXTRA_CHECKS
396 GNUNET_assert (0 == gcry_pk_testkey (s_key)); 405 if (0 != (rc = gcry_pk_testkey (s_key)))
406 {
407 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
408 gcry_sexp_release (s_key);
409 return NULL;
410 }
397#endif 411#endif
398 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccPrivateKey)); 412 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccPrivateKey));
399 ret->sexp = s_key; 413 ret->sexp = s_key;
@@ -927,111 +941,6 @@ GNUNET_CRYPTO_ecc_setup_hostkey (const char *cfg_name)
927 941
928 942
929/** 943/**
930 * Encrypt a block with the public key of another host that uses the
931 * same cipher.
932 *
933 * @param block the block to encrypt
934 * @param size the size of block
935 * @param publicKey the encoded public key used to encrypt
936 * @param target where to store the encrypted block
937 * @returns GNUNET_SYSERR on error, GNUNET_OK if ok
938 */
939int
940GNUNET_CRYPTO_ecc_encrypt (const void *block, size_t size,
941 const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded
942 *publicKey,
943 struct GNUNET_CRYPTO_EccEncryptedData *target)
944{
945 gcry_sexp_t result;
946 gcry_sexp_t data;
947 gcry_sexp_t psexp;
948 gcry_mpi_t val;
949 size_t isize;
950 size_t erroff;
951
952 GNUNET_assert (size <= sizeof (struct GNUNET_HashCode));
953 if (! (psexp = decode_public_key (publicKey)))
954 return GNUNET_SYSERR;
955 isize = size;
956 GNUNET_assert (0 ==
957 gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize));
958 GNUNET_assert (0 ==
959 gcry_sexp_build (&data, &erroff,
960 "(data (flags pkcs1)(value %m))", val));
961 gcry_mpi_release (val);
962 GNUNET_assert (0 == gcry_pk_encrypt (&result, data, psexp));
963 gcry_sexp_release (data);
964 gcry_sexp_release (psexp);
965 isize = gcry_sexp_sprint (result,
966 GCRYSEXP_FMT_DEFAULT,
967 target->encoding,
968 GNUNET_CRYPTO_ECC_DATA_ENCODING_LENGTH);
969 if (0 == isize)
970 {
971 GNUNET_break (0);
972 return GNUNET_SYSERR;
973 }
974 target->size = htons ((uint16_t) (isize + sizeof (uint16_t)));
975 /* padd with zeros */
976 memset (&target->encoding[isize], 0, GNUNET_CRYPTO_ECC_DATA_ENCODING_LENGTH - isize);
977 return GNUNET_OK;
978}
979
980
981/**
982 * Decrypt a given block with the hostkey.
983 *
984 * @param key the key with which to decrypt this block
985 * @param block the data to decrypt, encoded as returned by encrypt
986 * @param result pointer to a location where the result can be stored
987 * @param max the maximum number of bits to store for the result, if
988 * the decrypted block is bigger, an error is returned
989 * @return the size of the decrypted block, -1 on error
990 */
991ssize_t
992GNUNET_CRYPTO_ecc_decrypt (const struct GNUNET_CRYPTO_EccPrivateKey *key,
993 const struct GNUNET_CRYPTO_EccEncryptedData *block,
994 void *result, size_t max)
995{
996 gcry_sexp_t resultsexp;
997 gcry_sexp_t data;
998 size_t erroff;
999 size_t size;
1000 gcry_mpi_t val;
1001 unsigned char *endp;
1002
1003#if EXTRA_CHECKS
1004 GNUNET_assert (0 == gcry_pk_testkey (key->sexp));
1005#endif
1006 size = ntohs (block->size);
1007 if (size < sizeof (uint16_t))
1008 return -1;
1009 GNUNET_assert (0 ==
1010 gcry_sexp_sscan (&data,
1011 &erroff,
1012 block->encoding, size - sizeof (uint16_t)));
1013 GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, key->sexp));
1014 gcry_sexp_release (data);
1015 /* resultsexp has format "(value %m)" */
1016 GNUNET_assert (NULL !=
1017 (val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG)));
1018 gcry_sexp_release (resultsexp);
1019 size = max + GNUNET_CRYPTO_ECC_DATA_ENCODING_LENGTH * 2;
1020 {
1021 unsigned char tmp[size];
1022
1023 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val));
1024 gcry_mpi_release (val);
1025 endp = tmp;
1026 endp += (size - max);
1027 size = max;
1028 memcpy (result, endp, size);
1029 }
1030 return size;
1031}
1032
1033
1034/**
1035 * Convert the data specified in the given purpose argument to an 944 * Convert the data specified in the given purpose argument to an
1036 * S-expression suitable for signature operations. 945 * S-expression suitable for signature operations.
1037 * 946 *