aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-06-12 20:52:22 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-06-12 20:52:22 +0200
commit62b87e57a7f7042d27fe0a80b9194aeae0c14a50 (patch)
tree961a43363dbca413e4b1e65b367c0ffd553cfaf0
parent5957a777076d014b17aada25afe0991397edbacc (diff)
downloadlibbrandt-62b87e57a7f7042d27fe0a80b9194aeae0c14a50.tar.gz
libbrandt-62b87e57a7f7042d27fe0a80b9194aeae0c14a50.zip
add tests for key generation
-rw-r--r--Makefile.am9
-rw-r--r--brandt.c27
-rw-r--r--brandt.h6
-rw-r--r--crypto.c190
-rw-r--r--crypto.h34
-rw-r--r--test.h12
-rw-r--r--test_crypto.c59
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
7libbrandt_la_SOURCES = \ 7libbrandt_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
14libbrandt_la_LDFLAGS = \ 15libbrandt_la_LDFLAGS = \
15 -version-info 0:0:0 16 -version-info 0:0:0
17
18check_PROGRAMS = \
19 test_crypto
20
21test_crypto_SOURCES = test_crypto.c
22test_crypto_LDADD = libbrandt.la -lgcrypt -lgpg-error
23
24TESTS = $(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
7void 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}
diff --git a/brandt.h b/brandt.h
index 1f95d40..b7ebf5b 100644
--- a/brandt.h
+++ b/brandt.h
@@ -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
92void
93BRANDT_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 *
diff --git a/crypto.c b/crypto.c
index 399cd21..e78032e 100644
--- a/crypto.c
+++ b/crypto.c
@@ -26,6 +26,28 @@
26 26
27#define CURVE "Ed25519" 27#define CURVE "Ed25519"
28 28
29struct brandt_ec_skey {
30 unsigned char d[256 / 8];
31};
32
33struct brandt_ec_pkey {
34 unsigned char q_y[256 / 8];
35};
36
37gcry_mpi_point_t ec_gen;
38gcry_ctx_t ec_ctx;
39
40void
41brandt_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
31void 53void
@@ -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 158gcry_mpi_point_t
137/** 159deserialize_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 */
144static gcry_sexp_t
145decode_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 */
221void 241void
222brandt_ecdhe_key_create (struct brandt_dhe_skey *priv) 242brandt_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
261void
262brandt_ec_pkey_compute (gcry_mpi_point_t* pkey, const gcry_mpi_t skey)
263{
264
265}
266
267
268void
269brandt_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 */
304static gcry_sexp_t
305decode_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 */
248void 324void
249brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv, 325brandt_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 */
277int 353int
278brandt_ecdhe (const struct brandt_dhe_skey *priv, 354brandt_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 */
339void 414void
340brandt_ecdhe_key_clear (struct brandt_dhe_skey *pk) 415brandt_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//}
diff --git a/crypto.h b/crypto.h
index c7ba816..28bf4eb 100644
--- a/crypto.h
+++ b/crypto.h
@@ -25,11 +25,16 @@
25#include <gcrypt.h> 25#include <gcrypt.h>
26#include <stdint.h> 26#include <stdint.h>
27 27
28/* --- RANDOM --- */ 28extern gcry_mpi_point_t ec_gen;
29extern gcry_ctx_t ec_ctx;
29 30
30 31
31void brandt_rand_poll (); 32void brandt_crypto_init ();
33
32 34
35/* --- RANDOM --- */
36
37void brandt_rand_poll ();
33 38
34 39
35/* --- HASHING --- */ 40/* --- HASHING --- */
@@ -41,31 +46,16 @@ struct brandt_hash_code {
41void brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret); 46void brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret);
42 47
43 48
44
45/* --- MPI --- */ 49/* --- MPI --- */
46 50
47void brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val); 51void brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val);
48void brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, 52void 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
55struct brandt_dhe_skey { 55/* --- EC --- */
56 unsigned char d[256 / 8];
57};
58
59struct brandt_dhe_pkey {
60 unsigned char q_y[256 / 8];
61};
62 56
63void brandt_ecdhe_key_create (struct brandt_dhe_skey *priv); 57void brandt_ec_skey_create (gcry_mpi_t* skey);
64void brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv, 58void brandt_ec_pkey_compute (gcry_mpi_point_t* pkey, const gcry_mpi_t skey);
65 struct brandt_dhe_pkey *pub); 59void brandt_ec_keypair_create (gcry_mpi_point_t* pkey, gcry_mpi_t* skey);
66int brandt_ecdhe (const struct brandt_dhe_skey *priv,
67 const struct brandt_dhe_pkey *pub,
68 struct brandt_hash_code *key_material);
69void brandt_ecdhe_key_clear (struct brandt_dhe_skey *priv);
70 60
71#endif /* ifndef _BRANDT_CRYPTO_H */ 61#endif /* ifndef _BRANDT_CRYPTO_H */
diff --git a/test.h b/test.h
new file mode 100644
index 0000000..db63350
--- /dev/null
+++ b/test.h
@@ -0,0 +1,12 @@
1#ifndef _BRANDT_TEST_H
2#define _BRANDT_TEST_H
3
4#include <stdio.h>
5
6int tests_run = 0;
7int 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
6int
7test_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
41int
42main (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}