diff options
author | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-12 20:52:22 +0200 |
---|---|---|
committer | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-12 20:52:22 +0200 |
commit | 62b87e57a7f7042d27fe0a80b9194aeae0c14a50 (patch) | |
tree | 961a43363dbca413e4b1e65b367c0ffd553cfaf0 | |
parent | 5957a777076d014b17aada25afe0991397edbacc (diff) | |
download | libbrandt-62b87e57a7f7042d27fe0a80b9194aeae0c14a50.tar.gz libbrandt-62b87e57a7f7042d27fe0a80b9194aeae0c14a50.zip |
add tests for key generation
-rw-r--r-- | Makefile.am | 9 | ||||
-rw-r--r-- | brandt.c | 27 | ||||
-rw-r--r-- | brandt.h | 6 | ||||
-rw-r--r-- | crypto.c | 190 | ||||
-rw-r--r-- | crypto.h | 34 | ||||
-rw-r--r-- | test.h | 12 | ||||
-rw-r--r-- | test_crypto.c | 59 |
7 files changed, 274 insertions, 63 deletions
diff --git a/Makefile.am b/Makefile.am index d13e662..8264db3 100644 --- a/Makefile.am +++ b/Makefile.am | |||
@@ -5,6 +5,7 @@ lib_LTLIBRARIES = \ | |||
5 | libbrandt.la | 5 | libbrandt.la |
6 | 6 | ||
7 | libbrandt_la_SOURCES = \ | 7 | libbrandt_la_SOURCES = \ |
8 | brandt.c \ | ||
8 | crypto.c \ | 9 | crypto.c \ |
9 | util.c | 10 | util.c |
10 | 11 | ||
@@ -13,3 +14,11 @@ libbrandt_la_LIBADD = \ | |||
13 | 14 | ||
14 | libbrandt_la_LDFLAGS = \ | 15 | libbrandt_la_LDFLAGS = \ |
15 | -version-info 0:0:0 | 16 | -version-info 0:0:0 |
17 | |||
18 | check_PROGRAMS = \ | ||
19 | test_crypto | ||
20 | |||
21 | test_crypto_SOURCES = test_crypto.c | ||
22 | test_crypto_LDADD = libbrandt.la -lgcrypt -lgpg-error | ||
23 | |||
24 | TESTS = $(check_PROGRAMS) | ||
diff --git a/brandt.c b/brandt.c new file mode 100644 index 0000000..dd88643 --- /dev/null +++ b/brandt.c | |||
@@ -0,0 +1,27 @@ | |||
1 | |||
2 | #include <gcrypt.h> | ||
3 | |||
4 | #include "crypto.h" | ||
5 | #include "util.h" | ||
6 | |||
7 | void BRANDT_init () | ||
8 | { | ||
9 | gcry_error_t err = 0; | ||
10 | if (!gcry_check_version("1.6.0")) { | ||
11 | eprintf("libgcrypt version mismatch"); | ||
12 | } | ||
13 | |||
14 | /* SECMEM cannot be resized dynamically. We do not know how much we need */ | ||
15 | if ((err = gcry_control(GCRYCTL_DISABLE_SECMEM, 0))) | ||
16 | weprintf("failed to set libgcrypt option DISABLE_SECMEM: %s", | ||
17 | gcry_strerror(err)); | ||
18 | |||
19 | /* ecc is slow otherwise. */ | ||
20 | if ((err = gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0))) | ||
21 | weprintf("failed to set libgcrypt option ENABLE_QUICK_RANDOM: %s", | ||
22 | gcry_strerror(err)); | ||
23 | |||
24 | gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); | ||
25 | brandt_rand_poll(); | ||
26 | brandt_crypto_init(); | ||
27 | } | ||
@@ -22,6 +22,9 @@ | |||
22 | #ifndef _BRANDT_BRANDT_H | 22 | #ifndef _BRANDT_BRANDT_H |
23 | #define _BRANDT_BRANDT_H | 23 | #define _BRANDT_BRANDT_H |
24 | 24 | ||
25 | #include <unistd.h> | ||
26 | #include <stdint.h> | ||
27 | |||
25 | /** | 28 | /** |
26 | * FIXME. | 29 | * FIXME. |
27 | */ | 30 | */ |
@@ -86,6 +89,9 @@ typedef void | |||
86 | uint16_t price); | 89 | uint16_t price); |
87 | 90 | ||
88 | 91 | ||
92 | void | ||
93 | BRANDT_init (); | ||
94 | |||
89 | /** | 95 | /** |
90 | * Join an auction described by the @a auction_data parameter. | 96 | * Join an auction described by the @a auction_data parameter. |
91 | * | 97 | * |
@@ -26,6 +26,28 @@ | |||
26 | 26 | ||
27 | #define CURVE "Ed25519" | 27 | #define CURVE "Ed25519" |
28 | 28 | ||
29 | struct brandt_ec_skey { | ||
30 | unsigned char d[256 / 8]; | ||
31 | }; | ||
32 | |||
33 | struct brandt_ec_pkey { | ||
34 | unsigned char q_y[256 / 8]; | ||
35 | }; | ||
36 | |||
37 | gcry_mpi_point_t ec_gen; | ||
38 | gcry_ctx_t ec_ctx; | ||
39 | |||
40 | void | ||
41 | brandt_crypto_init () | ||
42 | { | ||
43 | gcry_error_t rc; | ||
44 | |||
45 | rc = gcry_mpi_ec_new (&ec_ctx, NULL, CURVE); | ||
46 | brandt_assert_gpgerr (rc); | ||
47 | ec_gen = gcry_mpi_ec_get_point ("g", ec_ctx, 0); | ||
48 | brandt_assert (NULL != ec_gen); | ||
49 | } | ||
50 | |||
29 | /* --- RANDOM --- */ | 51 | /* --- RANDOM --- */ |
30 | 52 | ||
31 | void | 53 | void |
@@ -132,28 +154,31 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) | |||
132 | brandt_assert_gpgerr (rc); | 154 | brandt_assert_gpgerr (rc); |
133 | } | 155 | } |
134 | 156 | ||
135 | /* --- ECDHE --- */ | 157 | /* |
136 | 158 | gcry_mpi_point_t | |
137 | /** | 159 | deserialize_point(const struct brandt_point* data, const int len) |
138 | * Convert the given private key from the network format to the | ||
139 | * S-expression that can be used by libgcrypt. | ||
140 | * | ||
141 | * @param priv private key to decode | ||
142 | * @return NULL on error | ||
143 | */ | ||
144 | static gcry_sexp_t | ||
145 | decode_private_ecdhe_key (const struct brandt_dhe_skey *priv) | ||
146 | { | 160 | { |
147 | gcry_sexp_t result; | 161 | gcry_sexp_t s; |
162 | gcry_ctx_t ctx; | ||
163 | gcry_mpi_point_t ret; | ||
148 | gcry_error_t rc; | 164 | gcry_error_t rc; |
149 | 165 | ||
150 | rc = gcry_sexp_build (&result, NULL, | 166 | rc = gcry_sexp_build(&s, NULL, "(public-key(ecc(curve " CURVE ")(q %b)))", |
151 | "(private-key(ecc(curve \"" CURVE "\")" | 167 | len, data); |
152 | "(d %b)))", | 168 | brandt_assert_gpgerr(rc); |
153 | (int)sizeof (priv->d), priv->d); | 169 | |
154 | brandt_assert_gpgerr (rc); | 170 | rc = gcry_mpi_ec_new(&ctx, s, NULL); |
155 | return result; | 171 | brandt_assert_gpgerr(rc); |
172 | gcry_sexp_release(s); | ||
173 | |||
174 | ret = gcry_mpi_ec_get_point("q", ctx, 0); | ||
175 | brandt_assert(ret); | ||
176 | gcry_ctx_release(ctx); | ||
177 | return ret; | ||
156 | } | 178 | } |
179 | */ | ||
180 | |||
181 | /* --- EC --- */ | ||
157 | 182 | ||
158 | /** | 183 | /** |
159 | * Extract values from an S-expression. | 184 | * Extract values from an S-expression. |
@@ -213,30 +238,81 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, | |||
213 | return 0; | 238 | return 0; |
214 | } | 239 | } |
215 | 240 | ||
216 | /** | ||
217 | * Create a new private key. | ||
218 | * | ||
219 | * @param priv where to write the private key | ||
220 | */ | ||
221 | void | 241 | void |
222 | brandt_ecdhe_key_create (struct brandt_dhe_skey *priv) | 242 | brandt_ec_skey_create (gcry_mpi_t* skey) |
223 | { | 243 | { |
224 | gcry_sexp_t priv_sexp; | ||
225 | gcry_sexp_t s_keyparam; | 244 | gcry_sexp_t s_keyparam; |
245 | gcry_sexp_t priv_sexp; | ||
226 | gcry_mpi_t d; | 246 | gcry_mpi_t d; |
227 | gcry_error_t rc; | 247 | gcry_error_t rc; |
228 | 248 | ||
229 | rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" | 249 | rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" |
230 | "(flags)))") | 250 | "(flags)))"); |
231 | brandt_assert_gpgerr (rc); | 251 | brandt_assert_gpgerr (rc); |
232 | rc = gcry_pk_genkey (&priv_sexp, s_keyparam) | 252 | rc = gcry_pk_genkey (&priv_sexp, s_keyparam); |
233 | brandt_assert_gpgerr (rc); | 253 | brandt_assert_gpgerr (rc); |
234 | gcry_sexp_release (s_keyparam); | 254 | gcry_sexp_release (s_keyparam); |
235 | rc = key_from_sexp (&d, priv_sexp, "private-key", "d") | 255 | rc = key_from_sexp (skey, priv_sexp, "private-key", "d"); |
236 | brandt_assert_gpgerr (rc); | 256 | brandt_assert_gpgerr (rc); |
237 | gcry_sexp_release (priv_sexp); | 257 | gcry_sexp_release (priv_sexp); |
238 | brandt_mpi_print_unsigned (priv->d, sizeof (priv->d), d); | 258 | } |
239 | gcry_mpi_release (d); | 259 | |
260 | |||
261 | void | ||
262 | brandt_ec_pkey_compute (gcry_mpi_point_t* pkey, const gcry_mpi_t skey) | ||
263 | { | ||
264 | |||
265 | } | ||
266 | |||
267 | |||
268 | void | ||
269 | brandt_ec_keypair_create (gcry_mpi_point_t* pkey, gcry_mpi_t* skey) | ||
270 | { | ||
271 | gcry_error_t rc; | ||
272 | gcry_sexp_t s_keyparam; | ||
273 | gcry_sexp_t priv_sexp; | ||
274 | gcry_ctx_t ctx; | ||
275 | |||
276 | rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" | ||
277 | "(flags)))"); | ||
278 | brandt_assert_gpgerr (rc); | ||
279 | |||
280 | rc = gcry_pk_genkey (&priv_sexp, s_keyparam); | ||
281 | brandt_assert_gpgerr (rc); | ||
282 | gcry_sexp_release (s_keyparam); | ||
283 | |||
284 | rc = key_from_sexp (skey, priv_sexp, "private-key", "d"); | ||
285 | brandt_assert_gpgerr (rc); | ||
286 | |||
287 | rc = gcry_mpi_ec_new (&ctx, priv_sexp, NULL); | ||
288 | brandt_assert_gpgerr (rc); | ||
289 | gcry_sexp_release (priv_sexp); | ||
290 | |||
291 | *pkey = gcry_mpi_ec_get_point("q", ctx, 0); | ||
292 | brandt_assert (NULL != *pkey); | ||
293 | gcry_ctx_release (ctx); | ||
294 | } | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Convert the given private key from the network format to the | ||
299 | * S-expression that can be used by libgcrypt. | ||
300 | * | ||
301 | * @param priv private key to decode | ||
302 | * @return NULL on error | ||
303 | */ | ||
304 | static gcry_sexp_t | ||
305 | decode_private_ecdhe_key (const struct brandt_ec_skey *priv) | ||
306 | { | ||
307 | gcry_sexp_t result; | ||
308 | gcry_error_t rc; | ||
309 | |||
310 | rc = gcry_sexp_build (&result, NULL, | ||
311 | "(private-key(ecc(curve \"" CURVE "\")" | ||
312 | "(d %b)))", | ||
313 | (int)sizeof (priv->d), priv->d); | ||
314 | brandt_assert_gpgerr (rc); | ||
315 | return result; | ||
240 | } | 316 | } |
241 | 317 | ||
242 | /** | 318 | /** |
@@ -246,8 +322,8 @@ brandt_ecdhe_key_create (struct brandt_dhe_skey *priv) | |||
246 | * @param pub where to write the public key | 322 | * @param pub where to write the public key |
247 | */ | 323 | */ |
248 | void | 324 | void |
249 | brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv, | 325 | brandt_ecdhe_key_get_public (const struct brandt_ec_skey *priv, |
250 | struct brandt_dhe_pkey *pub) | 326 | struct brandt_ec_pkey *pub) |
251 | { | 327 | { |
252 | gcry_sexp_t sexp; | 328 | gcry_sexp_t sexp; |
253 | gcry_ctx_t ctx; | 329 | gcry_ctx_t ctx; |
@@ -275,8 +351,8 @@ brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv, | |||
275 | * @return 0 on error, 1 on success | 351 | * @return 0 on error, 1 on success |
276 | */ | 352 | */ |
277 | int | 353 | int |
278 | brandt_ecdhe (const struct brandt_dhe_skey *priv, | 354 | brandt_ecdhe (const struct brandt_ec_skey *priv, |
279 | const struct brandt_dhe_pkey *pub, | 355 | const struct brandt_ec_pkey *pub, |
280 | struct brandt_hash_code *key_material) | 356 | struct brandt_hash_code *key_material) |
281 | { | 357 | { |
282 | gcry_error_t rc; | 358 | gcry_error_t rc; |
@@ -331,13 +407,45 @@ brandt_ecdhe (const struct brandt_dhe_skey *priv, | |||
331 | } | 407 | } |
332 | 408 | ||
333 | /** | 409 | /** |
334 | * @ingroup crypto | ||
335 | * Clear memory that was used to store a private key. | 410 | * Clear memory that was used to store a private key. |
336 | * | 411 | * |
337 | * @param pk location of the key | 412 | * @param skey location of the key |
338 | */ | 413 | */ |
339 | void | 414 | void |
340 | brandt_ecdhe_key_clear (struct brandt_dhe_skey *pk) | 415 | brandt_ec_key_clear (struct brandt_ec_skey *skey) |
341 | { | 416 | { |
342 | memset (pk, 0, sizeof (struct brandt_dhe_skey)); | 417 | memset (skey, 0, sizeof (struct brandt_ec_skey)); |
343 | } | 418 | } |
419 | |||
420 | /** | ||
421 | * Generate a random value mod n. | ||
422 | * | ||
423 | * @param edc ECC context | ||
424 | * @return random value mod n. | ||
425 | */ | ||
426 | //gcry_mpi_t | ||
427 | //GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc) | ||
428 | //{ | ||
429 | // gcry_mpi_t n; | ||
430 | // unsigned int highbit; | ||
431 | // gcry_mpi_t r; | ||
432 | // | ||
433 | // n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); | ||
434 | // | ||
435 | // /* check public key for number of bits, bail out if key is all zeros */ | ||
436 | // highbit = 256; /* Curve25519 */ | ||
437 | // while ( (! gcry_mpi_test_bit (n, highbit)) && | ||
438 | // (0 != highbit) ) | ||
439 | // highbit--; | ||
440 | // GNUNET_assert (0 != highbit); | ||
441 | // /* generate fact < n (without bias) */ | ||
442 | // GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | ||
443 | // do { | ||
444 | // gcry_mpi_randomize (r, | ||
445 | // highbit + 1, | ||
446 | // GCRY_STRONG_RANDOM); | ||
447 | // } | ||
448 | // while (gcry_mpi_cmp (r, n) >= 0); | ||
449 | // gcry_mpi_release (n); | ||
450 | // return r; | ||
451 | //} | ||
@@ -25,11 +25,16 @@ | |||
25 | #include <gcrypt.h> | 25 | #include <gcrypt.h> |
26 | #include <stdint.h> | 26 | #include <stdint.h> |
27 | 27 | ||
28 | /* --- RANDOM --- */ | 28 | extern gcry_mpi_point_t ec_gen; |
29 | extern gcry_ctx_t ec_ctx; | ||
29 | 30 | ||
30 | 31 | ||
31 | void brandt_rand_poll (); | 32 | void brandt_crypto_init (); |
33 | |||
32 | 34 | ||
35 | /* --- RANDOM --- */ | ||
36 | |||
37 | void brandt_rand_poll (); | ||
33 | 38 | ||
34 | 39 | ||
35 | /* --- HASHING --- */ | 40 | /* --- HASHING --- */ |
@@ -41,31 +46,16 @@ struct brandt_hash_code { | |||
41 | void brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret); | 46 | void brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret); |
42 | 47 | ||
43 | 48 | ||
44 | |||
45 | /* --- MPI --- */ | 49 | /* --- MPI --- */ |
46 | 50 | ||
47 | void brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val); | 51 | void brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val); |
48 | void brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, | 52 | void brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size); |
49 | size_t size); | ||
50 | |||
51 | |||
52 | 53 | ||
53 | /* --- ECDHE --- */ | ||
54 | 54 | ||
55 | struct brandt_dhe_skey { | 55 | /* --- EC --- */ |
56 | unsigned char d[256 / 8]; | ||
57 | }; | ||
58 | |||
59 | struct brandt_dhe_pkey { | ||
60 | unsigned char q_y[256 / 8]; | ||
61 | }; | ||
62 | 56 | ||
63 | void brandt_ecdhe_key_create (struct brandt_dhe_skey *priv); | 57 | void brandt_ec_skey_create (gcry_mpi_t* skey); |
64 | void brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv, | 58 | void brandt_ec_pkey_compute (gcry_mpi_point_t* pkey, const gcry_mpi_t skey); |
65 | struct brandt_dhe_pkey *pub); | 59 | void brandt_ec_keypair_create (gcry_mpi_point_t* pkey, gcry_mpi_t* skey); |
66 | int brandt_ecdhe (const struct brandt_dhe_skey *priv, | ||
67 | const struct brandt_dhe_pkey *pub, | ||
68 | struct brandt_hash_code *key_material); | ||
69 | void brandt_ecdhe_key_clear (struct brandt_dhe_skey *priv); | ||
70 | 60 | ||
71 | #endif /* ifndef _BRANDT_CRYPTO_H */ | 61 | #endif /* ifndef _BRANDT_CRYPTO_H */ |
@@ -0,0 +1,12 @@ | |||
1 | #ifndef _BRANDT_TEST_H | ||
2 | #define _BRANDT_TEST_H | ||
3 | |||
4 | #include <stdio.h> | ||
5 | |||
6 | int tests_run = 0; | ||
7 | int ret = 0; | ||
8 | |||
9 | #define check(cond, message) do { if (!(cond)) { fputs(message, stderr); return 0; } } while (0) | ||
10 | #define run(test) do { tests_run++; if (!test()) ret = 1; } while (0) | ||
11 | |||
12 | #endif | ||
diff --git a/test_crypto.c b/test_crypto.c new file mode 100644 index 0000000..67894eb --- /dev/null +++ b/test_crypto.c | |||
@@ -0,0 +1,59 @@ | |||
1 | |||
2 | #include "brandt.h" | ||
3 | #include "crypto.h" | ||
4 | #include "test.h" | ||
5 | |||
6 | int | ||
7 | test_brandt_ec_keypair_create () | ||
8 | { | ||
9 | gcry_mpi_t skey; | ||
10 | gcry_mpi_t x1 = gcry_mpi_new(0); | ||
11 | gcry_mpi_t x2 = gcry_mpi_new(0); | ||
12 | gcry_mpi_t y1 = gcry_mpi_new(0); | ||
13 | gcry_mpi_t y2 = gcry_mpi_new(0); | ||
14 | gcry_mpi_point_t pkey1; | ||
15 | gcry_mpi_point_t pkey2 = gcry_mpi_point_new(0); | ||
16 | |||
17 | brandt_ec_keypair_create (&pkey1, &skey); | ||
18 | check(skey, "no sec key created"); | ||
19 | check(pkey1, "no pub key created"); | ||
20 | check(pkey2, "could not init pkey2"); | ||
21 | check(x1, "could not init x1"); | ||
22 | check(x2, "could not init x2"); | ||
23 | check(y1, "could not init y1"); | ||
24 | check(y2, "could not init y2"); | ||
25 | |||
26 | gcry_mpi_ec_mul(pkey2, skey, ec_gen, ec_ctx); | ||
27 | check(!gcry_mpi_ec_get_affine(x1, y1, pkey1, ec_ctx), "could not get affine coords for pkey1"); | ||
28 | check(!gcry_mpi_ec_get_affine(x2, y2, pkey2, ec_ctx), "could not get affine coords for pkey1"); | ||
29 | check(!gcry_mpi_cmp(x1, x2), "x component does not match"); | ||
30 | check(!gcry_mpi_cmp(y1, y2), "y component does not match"); | ||
31 | |||
32 | gcry_mpi_release(skey); | ||
33 | gcry_mpi_release(x1); | ||
34 | gcry_mpi_release(x2); | ||
35 | gcry_mpi_release(y1); | ||
36 | gcry_mpi_release(y2); | ||
37 | gcry_mpi_point_release(pkey1); | ||
38 | gcry_mpi_point_release(pkey2); | ||
39 | } | ||
40 | |||
41 | int | ||
42 | main (int argc, char *argv[]) | ||
43 | { | ||
44 | int repeat = 100; | ||
45 | int i; | ||
46 | |||
47 | BRANDT_init(); | ||
48 | |||
49 | for (i = 0; i < repeat; i++) | ||
50 | { | ||
51 | run(test_brandt_ec_keypair_create); | ||
52 | } | ||
53 | |||
54 | if (!ret) | ||
55 | { | ||
56 | fputs("All tests passed", stderr); | ||
57 | } | ||
58 | return ret; | ||
59 | } | ||