diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-10-17 21:16:37 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-10-17 21:16:37 +0000 |
commit | 1e97e9b8006fa195f14d02fbe0282afd1e4809ff (patch) | |
tree | ad56de929806d0b5575894406573dd8b324fcaa1 | |
parent | 8c4f13e5109054a8f7ad3555b6db51c81eec5e0b (diff) | |
download | gnunet-1e97e9b8006fa195f14d02fbe0282afd1e4809ff.tar.gz gnunet-1e97e9b8006fa195f14d02fbe0282afd1e4809ff.zip |
-ecc sign/verify only
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 52 | ||||
-rw-r--r-- | src/util/crypto_ecc.c | 129 | ||||
-rw-r--r-- | src/util/test_crypto_ecc.c | 147 |
3 files changed, 20 insertions, 308 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 59f1dad78..3bb60d9e5 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -270,7 +270,7 @@ struct GNUNET_CRYPTO_EccSignaturePurpose | |||
270 | struct GNUNET_CRYPTO_EccSignature | 270 | struct GNUNET_CRYPTO_EccSignature |
271 | { | 271 | { |
272 | /** | 272 | /** |
273 | * Overall size of the encrypted data. | 273 | * Overall size of the signature data. |
274 | */ | 274 | */ |
275 | uint16_t size; | 275 | uint16_t size; |
276 | 276 | ||
@@ -319,23 +319,6 @@ struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded | |||
319 | 319 | ||
320 | 320 | ||
321 | /** | 321 | /** |
322 | * ECC Encrypted data. | ||
323 | */ | ||
324 | struct GNUNET_CRYPTO_EccEncryptedData | ||
325 | { | ||
326 | /** | ||
327 | * Overall size of the encrypted data. | ||
328 | */ | ||
329 | uint16_t size; | ||
330 | |||
331 | /** | ||
332 | * S-expression, padded with zeros. | ||
333 | */ | ||
334 | char encoding[GNUNET_CRYPTO_ECC_DATA_ENCODING_LENGTH]; | ||
335 | }; | ||
336 | |||
337 | |||
338 | /** | ||
339 | * @brief type for session keys | 322 | * @brief type for session keys |
340 | */ | 323 | */ |
341 | struct GNUNET_CRYPTO_AesSessionKey | 324 | struct GNUNET_CRYPTO_AesSessionKey |
@@ -1325,39 +1308,6 @@ GNUNET_CRYPTO_ecc_setup_hostkey (const char *cfg_name); | |||
1325 | 1308 | ||
1326 | 1309 | ||
1327 | /** | 1310 | /** |
1328 | * Encrypt a block with the public key of another host that uses the | ||
1329 | * same cipher. | ||
1330 | * | ||
1331 | * @param block the block to encrypt | ||
1332 | * @param size the size of block | ||
1333 | * @param publicKey the encoded public key used to encrypt | ||
1334 | * @param target where to store the encrypted block | ||
1335 | * @returns GNUNET_SYSERR on error, GNUNET_OK if ok | ||
1336 | */ | ||
1337 | int | ||
1338 | GNUNET_CRYPTO_ecc_encrypt (const void *block, size_t size, | ||
1339 | const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded | ||
1340 | *publicKey, | ||
1341 | struct GNUNET_CRYPTO_EccEncryptedData *target); | ||
1342 | |||
1343 | |||
1344 | /** | ||
1345 | * Decrypt a given block with the hostkey. | ||
1346 | * | ||
1347 | * @param key the key with which to decrypt this block | ||
1348 | * @param block the data to decrypt, encoded as returned by encrypt | ||
1349 | * @param result pointer to a location where the result can be stored | ||
1350 | * @param max the maximum number of bits to store for the result, if | ||
1351 | * the decrypted block is bigger, an error is returned | ||
1352 | * @return the size of the decrypted block, -1 on error | ||
1353 | */ | ||
1354 | ssize_t | ||
1355 | GNUNET_CRYPTO_ecc_decrypt (const struct GNUNET_CRYPTO_EccPrivateKey *key, | ||
1356 | const struct GNUNET_CRYPTO_EccEncryptedData *block, | ||
1357 | void *result, size_t max); | ||
1358 | |||
1359 | |||
1360 | /** | ||
1361 | * Sign a given block. | 1311 | * Sign a given block. |
1362 | * | 1312 | * |
1363 | * @param key private key to use for the signing | 1313 | * @param key private key to use for the signing |
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 | */ | ||
939 | int | ||
940 | GNUNET_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 | */ | ||
991 | ssize_t | ||
992 | GNUNET_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 | * |
diff --git a/src/util/test_crypto_ecc.c b/src/util/test_crypto_ecc.c index d61ba816e..4cb8f1dbc 100644 --- a/src/util/test_crypto_ecc.c +++ b/src/util/test_crypto_ecc.c | |||
@@ -39,147 +39,6 @@ static struct GNUNET_CRYPTO_EccPrivateKey *key; | |||
39 | 39 | ||
40 | 40 | ||
41 | static int | 41 | static int |
42 | testEncryptDecrypt () | ||
43 | { | ||
44 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pkey; | ||
45 | struct GNUNET_CRYPTO_EccEncryptedData target; | ||
46 | char result[MAX_TESTVAL]; | ||
47 | int i; | ||
48 | struct GNUNET_TIME_Absolute start; | ||
49 | int ok; | ||
50 | |||
51 | FPRINTF (stderr, "%s", "W"); | ||
52 | GNUNET_CRYPTO_ecc_key_get_public (key, &pkey); | ||
53 | ok = 0; | ||
54 | start = GNUNET_TIME_absolute_get (); | ||
55 | for (i = 0; i < ITER; i++) | ||
56 | { | ||
57 | FPRINTF (stderr, "%s", "."); | ||
58 | if (GNUNET_SYSERR == | ||
59 | GNUNET_CRYPTO_ecc_encrypt (TESTSTRING, strlen (TESTSTRING) + 1, &pkey, | ||
60 | &target)) | ||
61 | { | ||
62 | FPRINTF (stderr, "%s", "GNUNET_CRYPTO_ecc_encrypt returned SYSERR\n"); | ||
63 | ok++; | ||
64 | continue; | ||
65 | } | ||
66 | if (-1 == | ||
67 | GNUNET_CRYPTO_ecc_decrypt (key, &target, result, | ||
68 | strlen (TESTSTRING) + 1)) | ||
69 | { | ||
70 | FPRINTF (stderr, "%s", "GNUNET_CRYPTO_ecc_decrypt returned SYSERR\n"); | ||
71 | ok++; | ||
72 | continue; | ||
73 | |||
74 | } | ||
75 | if (strncmp (TESTSTRING, result, strlen (TESTSTRING)) != 0) | ||
76 | { | ||
77 | printf ("%s != %.*s - testEncryptDecrypt failed!\n", TESTSTRING, | ||
78 | (int) MAX_TESTVAL, result); | ||
79 | ok++; | ||
80 | continue; | ||
81 | } | ||
82 | } | ||
83 | printf ("%d ECC encrypt/decrypt operations %s (%d failures)\n", | ||
84 | ITER, | ||
85 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES), | ||
86 | ok); | ||
87 | if (ok == 0) | ||
88 | return GNUNET_OK; | ||
89 | return GNUNET_SYSERR; | ||
90 | } | ||
91 | |||
92 | |||
93 | #if PERF | ||
94 | static int | ||
95 | testEncryptPerformance () | ||
96 | { | ||
97 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pkey; | ||
98 | struct GNUNET_CRYPTO_EccEncryptedData target; | ||
99 | int i; | ||
100 | struct GNUNET_TIME_Absolute start; | ||
101 | int ok; | ||
102 | |||
103 | FPRINTF (stderr, "%s", "W"); | ||
104 | GNUNET_CRYPTO_ecc_key_get_public (key, &pkey); | ||
105 | ok = 0; | ||
106 | start = GNUNET_TIME_absolute_get (); | ||
107 | for (i = 0; i < ITER; i++) | ||
108 | { | ||
109 | FPRINTF (stderr, "%s", "."); | ||
110 | if (GNUNET_SYSERR == | ||
111 | GNUNET_CRYPTO_ecc_encrypt (TESTSTRING, strlen (TESTSTRING) + 1, &pkey, | ||
112 | &target)) | ||
113 | { | ||
114 | FPRINTF (stderr, "%s", "GNUNET_CRYPTO_ecc_encrypt returned SYSERR\n"); | ||
115 | ok++; | ||
116 | continue; | ||
117 | } | ||
118 | } | ||
119 | printf ("%d ECC encrypt operations %llu ms (%d failures)\n", ITER, | ||
120 | (unsigned long long) | ||
121 | GNUNET_TIME_absolute_get_duration (start).rel_value, ok); | ||
122 | if (ok != 0) | ||
123 | return GNUNET_SYSERR; | ||
124 | return GNUNET_OK; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | static int | ||
129 | testEncryptDecryptSK () | ||
130 | { | ||
131 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pkey; | ||
132 | struct GNUNET_CRYPTO_EccEncryptedData target; | ||
133 | struct GNUNET_CRYPTO_AesSessionKey insk; | ||
134 | struct GNUNET_CRYPTO_AesSessionKey outsk; | ||
135 | int i; | ||
136 | struct GNUNET_TIME_Absolute start; | ||
137 | int ok; | ||
138 | |||
139 | FPRINTF (stderr, "%s", "W"); | ||
140 | GNUNET_CRYPTO_ecc_key_get_public (key, &pkey); | ||
141 | ok = 0; | ||
142 | start = GNUNET_TIME_absolute_get (); | ||
143 | for (i = 0; i < ITER; i++) | ||
144 | { | ||
145 | FPRINTF (stderr, "%s", "."); | ||
146 | GNUNET_CRYPTO_aes_create_session_key (&insk); | ||
147 | if (GNUNET_SYSERR == | ||
148 | GNUNET_CRYPTO_ecc_encrypt (&insk, | ||
149 | sizeof (struct GNUNET_CRYPTO_AesSessionKey), | ||
150 | &pkey, &target)) | ||
151 | { | ||
152 | FPRINTF (stderr, "%s", "GNUNET_CRYPTO_ecc_encrypt returned SYSERR\n"); | ||
153 | ok++; | ||
154 | continue; | ||
155 | } | ||
156 | if (-1 == | ||
157 | GNUNET_CRYPTO_ecc_decrypt (key, &target, &outsk, | ||
158 | sizeof (struct GNUNET_CRYPTO_AesSessionKey))) | ||
159 | { | ||
160 | FPRINTF (stderr, "%s", "GNUNET_CRYPTO_ecc_decrypt returned SYSERR\n"); | ||
161 | ok++; | ||
162 | continue; | ||
163 | } | ||
164 | if (0 != | ||
165 | memcmp (&insk, &outsk, sizeof (struct GNUNET_CRYPTO_AesSessionKey))) | ||
166 | { | ||
167 | printf ("testEncryptDecryptSK failed!\n"); | ||
168 | ok++; | ||
169 | continue; | ||
170 | } | ||
171 | } | ||
172 | printf ("%d ECC encrypt/decrypt SK operations %s (%d failures)\n", | ||
173 | ITER, | ||
174 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES), | ||
175 | ok); | ||
176 | if (ok != 0) | ||
177 | return GNUNET_SYSERR; | ||
178 | return GNUNET_OK; | ||
179 | } | ||
180 | |||
181 | |||
182 | static int | ||
183 | testSignVerify () | 42 | testSignVerify () |
184 | { | 43 | { |
185 | struct GNUNET_CRYPTO_EccSignature sig; | 44 | struct GNUNET_CRYPTO_EccSignature sig; |
@@ -330,15 +189,9 @@ main (int argc, char *argv[]) | |||
330 | failureCount++; | 189 | failureCount++; |
331 | GNUNET_SCHEDULER_run (&test_async_creation, NULL); | 190 | GNUNET_SCHEDULER_run (&test_async_creation, NULL); |
332 | #if PERF | 191 | #if PERF |
333 | if (GNUNET_OK != testEncryptPerformance ()) | ||
334 | failureCount++; | ||
335 | if (GNUNET_OK != testSignPerformance ()) | 192 | if (GNUNET_OK != testSignPerformance ()) |
336 | failureCount++; | 193 | failureCount++; |
337 | #endif | 194 | #endif |
338 | if (GNUNET_OK != testEncryptDecryptSK ()) | ||
339 | failureCount++; | ||
340 | if (GNUNET_OK != testEncryptDecrypt ()) | ||
341 | failureCount++; | ||
342 | if (GNUNET_OK != testSignVerify ()) | 195 | if (GNUNET_OK != testSignVerify ()) |
343 | failureCount++; | 196 | failureCount++; |
344 | GNUNET_CRYPTO_ecc_key_free (key); | 197 | GNUNET_CRYPTO_ecc_key_free (key); |