aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNils Durner <durner@gnunet.org>2010-10-03 13:29:09 +0000
committerNils Durner <durner@gnunet.org>2010-10-03 13:29:09 +0000
commit9d9853441df5b565f6932fcf7fbb156b2d929392 (patch)
tree87d09554c804030a48fe33e46206c91dc312bf12 /src
parentb7c95147188502651e4cb2b60c7062137f73e878 (diff)
downloadgnunet-9d9853441df5b565f6932fcf7fbb156b2d929392.tar.gz
gnunet-9d9853441df5b565f6932fcf7fbb156b2d929392.zip
KDF code
Diffstat (limited to 'src')
-rw-r--r--src/core/gnunet-service-core.c46
-rw-r--r--src/include/gnunet_crypto_lib.h136
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/crypto_aes.c37
-rw-r--r--src/util/crypto_hash.c47
-rw-r--r--src/util/crypto_kdf.c88
-rw-r--r--src/util/crypto_random.c22
7 files changed, 349 insertions, 28 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 9496d2209..8ceb92ac6 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -2122,10 +2122,11 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
2122 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); 2122 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
2123 em->iv_seed = ph->iv_seed; 2123 em->iv_seed = ph->iv_seed;
2124 esize = used - ENCRYPTED_HEADER_SIZE; 2124 esize = used - ENCRYPTED_HEADER_SIZE;
2125 GNUNET_CRYPTO_hmac (&n->encrypt_key, 2125// FIXME NILS
2126 &ph->sequence_number, 2126// GNUNET_CRYPTO_hmac (&n->encrypt_key,
2127 esize - sizeof (GNUNET_HashCode), 2127// &ph->sequence_number,
2128 &ph->hmac); 2128// esize - sizeof (GNUNET_HashCode),
2129// &ph->hmac);
2129 GNUNET_CRYPTO_hash (&ph->iv_seed, sizeof (uint32_t), &iv); 2130 GNUNET_CRYPTO_hash (&ph->iv_seed, sizeof (uint32_t), &iv);
2130#if DEBUG_HANDSHAKE 2131#if DEBUG_HANDSHAKE
2131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3356,24 +3357,25 @@ handle_encrypted_message (struct Neighbour *n,
3356 return; 3357 return;
3357 pt = (struct EncryptedMessage *) buf; 3358 pt = (struct EncryptedMessage *) buf;
3358 /* validate hash */ 3359 /* validate hash */
3359 GNUNET_CRYPTO_hmac (&n->decrypt_key, 3360// FIXME NILS
3360 &pt->sequence_number, 3361// GNUNET_CRYPTO_hmac (&n->decrypt_key,
3361 size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode), &ph); 3362// &pt->sequence_number,
3362#if DEBUG_HANDSHAKE 3363// size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode), &ph);
3363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3364//#if DEBUG_HANDSHAKE
3364 "V-Hashed %u bytes of plaintext (`%s') using IV `%d'\n", 3365// GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3365 (unsigned int) (size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode)), 3366// "V-Hashed %u bytes of plaintext (`%s') using IV `%d'\n",
3366 GNUNET_h2s (&ph), 3367// (unsigned int) (size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode)),
3367 (int) m->iv_seed); 3368// GNUNET_h2s (&ph),
3368#endif 3369// (int) m->iv_seed);
3369 if (0 != memcmp (&ph, 3370//#endif
3370 &pt->hmac, 3371// if (0 != memcmp (&ph,
3371 sizeof (GNUNET_HashCode))) 3372// &pt->hmac,
3372 { 3373// sizeof (GNUNET_HashCode)))
3373 /* checksum failed */ 3374// {
3374 GNUNET_break_op (0); 3375// /* checksum failed */
3375 return; 3376// GNUNET_break_op (0);
3376 } 3377// return;
3378// }
3377 3379
3378 /* validate sequence number */ 3380 /* validate sequence number */
3379 snum = ntohl (pt->sequence_number); 3381 snum = ntohl (pt->sequence_number);
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 126c599b9..baea6859a 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -57,7 +57,12 @@ enum GNUNET_CRYPTO_Quality
57 /** 57 /**
58 * High-quality operations are desired. 58 * High-quality operations are desired.
59 */ 59 */
60 GNUNET_CRYPTO_QUALITY_STRONG 60 GNUNET_CRYPTO_QUALITY_STRONG,
61
62 /**
63 * Randomness for IVs etc. is required.
64 */
65 GNUNET_CRYPTO_QUALITY_NONCE
61}; 66};
62 67
63 68
@@ -87,6 +92,11 @@ enum GNUNET_CRYPTO_Quality
87 92
88 93
89/** 94/**
95 * Length of a hash value
96 */
97#define GNUNET_CRYPTO_HASH_LENGTH 512/8
98
99/**
90 * The private information of an RSA key pair. 100 * The private information of an RSA key pair.
91 */ 101 */
92struct GNUNET_CRYPTO_RsaPrivateKey; 102struct GNUNET_CRYPTO_RsaPrivateKey;
@@ -201,6 +211,15 @@ struct GNUNET_CRYPTO_AesInitializationVector
201}; 211};
202 212
203 213
214/**
215 * @brief type for (message) authentication keys
216 */
217struct GNUNET_CRYPTO_AuthKey
218{
219 unsigned char key[GNUNET_CRYPTO_HASH_LENGTH];
220};
221
222
204/* **************** Functions and Macros ************* */ 223/* **************** Functions and Macros ************* */
205 224
206 225
@@ -257,7 +276,6 @@ unsigned int *GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode,
257void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey 276void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey
258 *key); 277 *key);
259 278
260
261/** 279/**
262 * Check that a new session key is well-formed. 280 * Check that a new session key is well-formed.
263 * 281 *
@@ -306,6 +324,34 @@ ssize_t GNUNET_CRYPTO_aes_decrypt (const void *block,
306 324
307 325
308/** 326/**
327 * @brief Derive an IV
328 * @param iv initialization vector
329 * @param skey session key
330 * @param salt salt for the derivation
331 * @param salt_len size of the salt
332 * @param ... pairs of void * & size_t for context chunks, terminated by NULL
333 */
334void
335GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
336 const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
337 size_t salt_len, ...);
338
339
340/**
341 * @brief Derive an IV
342 * @param iv initialization vector
343 * @param skey session key
344 * @param salt salt for the derivation
345 * @param salt_len size of the salt
346 * @param argp pairs of void * & size_t for context chunks, terminated by NULL
347 */
348void
349GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv,
350 const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
351 size_t salt_len, va_list argp);
352
353
354/**
309 * Convert hash to ASCII encoding. 355 * Convert hash to ASCII encoding.
310 * @param block the hash code 356 * @param block the hash code
311 * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be 357 * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be
@@ -362,7 +408,7 @@ void GNUNET_CRYPTO_hash (const void *block,
362 * @param hmac where to store the hmac 408 * @param hmac where to store the hmac
363 */ 409 */
364void 410void
365GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AesSessionKey *key, 411GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
366 const void *plaintext, 412 const void *plaintext,
367 size_t plaintext_len, 413 size_t plaintext_len,
368 GNUNET_HashCode *hmac); 414 GNUNET_HashCode *hmac);
@@ -526,6 +572,37 @@ int GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
526 572
527 573
528/** 574/**
575 * @brief Derive an authentication key
576 * @param key authentication key
577 * @param rkey root key
578 * @param salt salt
579 * @param salt_len size of the salt
580 * @param argp pair of void * & size_t for context chunks, terminated by NULL
581 */
582void
583GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key,
584 const struct GNUNET_CRYPTO_AesSessionKey *rkey,
585 const void *salt,
586 const size_t salt_len,
587 const va_list argp);
588
589
590/**
591 * @brief Derive an authentication key
592 * @param key authentication key
593 * @param rkey root key
594 * @param salt salt
595 * @param salt_len size of the salt
596 * @param ... pair of void * & size_t for context chunks, terminated by NULL
597 */
598void
599GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key,
600 const struct GNUNET_CRYPTO_AesSessionKey *rkey,
601 const void *salt,
602 const size_t salt_len,
603 ...);
604
605/**
529 * @brief Derive key 606 * @brief Derive key
530 * @param result buffer for the derived key, allocated by caller 607 * @param result buffer for the derived key, allocated by caller
531 * @param out_len desired length of the derived key 608 * @param out_len desired length of the derived key
@@ -546,6 +623,59 @@ GNUNET_CRYPTO_hkdf (void *result, const unsigned long long out_len,
546 623
547 624
548/** 625/**
626 * @brief Derive key
627 * @param result buffer for the derived key, allocated by caller
628 * @param out_len desired length of the derived key
629 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_...
630 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_...
631 * @param xts salt
632 * @param xts_len length of xts
633 * @param skm source key material
634 * @param skm_len length of skm
635 * @param argp va_list of void * & size_t pairs for context chunks
636 * @return GNUNET_YES on success
637 */
638int
639GNUNET_CRYPTO_hkdf_v (void *result, const unsigned long long out_len,
640 int xtr_algo, int prf_algo, const void *xts, const size_t xts_len,
641 const void *skm, const size_t skm_len, va_list argp);
642
643
644/**
645 * @brief Derive key
646 * @param result buffer for the derived key, allocated by caller
647 * @param out_len desired length of the derived key
648 * @param xts salt
649 * @param xts_len length of xts
650 * @param skm source key material
651 * @param skm_len length of skm
652 * @param argp va_list of void * & size_t pairs for context chunks
653 * @return GNUNET_YES on success
654 */
655int
656GNUNET_CRYPTO_kdf_v (void *result, const unsigned long long out_len,
657 const void *xts, const size_t xts_len, const void *skm,
658 const size_t skm_len, va_list argp);
659
660
661/**
662 * @brief Derive key
663 * @param result buffer for the derived key, allocated by caller
664 * @param out_len desired length of the derived key
665 * @param xts salt
666 * @param xts_len length of xts
667 * @param skm source key material
668 * @param skm_len length of skm
669 * @param ... void * & size_t pairs for context chunks
670 * @return GNUNET_YES on success
671 */
672int
673GNUNET_CRYPTO_kdf (void *result, const unsigned long long out_len,
674 const void *xts, const size_t xts_len, const void *skm,
675 const size_t skm_len, ...);
676
677
678/**
549 * Create a new private key. Caller must free return value. 679 * Create a new private key. Caller must free return value.
550 * 680 *
551 * @return fresh private key 681 * @return fresh private key
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 2f7edd301..7975c5da1 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -41,6 +41,7 @@ libgnunetutil_la_SOURCES = \
41 crypto_crc.c \ 41 crypto_crc.c \
42 crypto_hash.c \ 42 crypto_hash.c \
43 crypto_hkdf.c \ 43 crypto_hkdf.c \
44 crypto_kdf.c \
44 crypto_ksk.c \ 45 crypto_ksk.c \
45 crypto_random.c \ 46 crypto_random.c \
46 crypto_rsa.c \ 47 crypto_rsa.c \
diff --git a/src/util/crypto_aes.c b/src/util/crypto_aes.c
index a44c2d133..bf618ffc3 100644
--- a/src/util/crypto_aes.c
+++ b/src/util/crypto_aes.c
@@ -148,4 +148,41 @@ GNUNET_CRYPTO_aes_decrypt (const void *block,
148 return size; 148 return size;
149} 149}
150 150
151/**
152 * @brief Derive an IV
153 * @param iv initialization vector
154 * @param skey session key
155 * @param salt salt for the derivation
156 * @param salt_len size of the salt
157 * @param ... pairs of void * & size_t for context chunks, terminated by NULL
158 */
159void
160GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
161 const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
162 size_t salt_len, ...)
163{
164 va_list argp;
165
166 va_start (argp, salt_len);
167 GNUNET_CRYPTO_aes_derive_iv_v (iv, skey, salt, salt_len, argp);
168 va_end (argp);
169}
170
171/**
172 * @brief Derive an IV
173 * @param iv initialization vector
174 * @param skey session key
175 * @param salt salt for the derivation
176 * @param salt_len size of the salt
177 * @param argp pairs of void * & size_t for context chunks, terminated by NULL
178 */
179void
180GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv,
181 const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
182 size_t salt_len, va_list argp)
183{
184 GNUNET_CRYPTO_kdf_v (iv->iv, sizeof(iv->iv), salt, salt_len, skey->key,
185 sizeof(skey->key), argp);
186}
187
151/* end of crypto_aes.c */ 188/* end of crypto_aes.c */
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index 0fb2451b2..db911aa5f 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -832,6 +832,48 @@ GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
832 832
833 833
834/** 834/**
835 * @brief Derive an authentication key
836 * @param key authentication key
837 * @param rkey root key
838 * @param salt salt
839 * @param salt_len size of the salt
840 * @param ... pair of void * & size_t for context chunks, terminated by NULL
841 */
842void
843GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key,
844 const struct GNUNET_CRYPTO_AesSessionKey *rkey,
845 const void *salt,
846 const size_t salt_len,
847 ...)
848{
849 va_list argp;
850
851 va_start (argp, salt_len);
852 GNUNET_CRYPTO_hmac_derive_key_v (key, rkey, salt, salt_len, argp);
853 va_end (argp);
854}
855
856
857/**
858 * @brief Derive an authentication key
859 * @param key authentication key
860 * @param rkey root key
861 * @param salt salt
862 * @param salt_len size of the salt
863 * @param argp pair of void * & size_t for context chunks, terminated by NULL
864 */
865void
866GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key,
867 const struct GNUNET_CRYPTO_AesSessionKey *rkey,
868 const void *salt,
869 const size_t salt_len,
870 const va_list argp)
871{
872 GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key), salt, salt_len, rkey->key,
873 sizeof(rkey->key), argp);
874}
875
876/**
835 * Calculate HMAC of a message (RFC 2104) 877 * Calculate HMAC of a message (RFC 2104)
836 * 878 *
837 * @param key secret key 879 * @param key secret key
@@ -840,7 +882,7 @@ GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
840 * @param hmac where to store the hmac 882 * @param hmac where to store the hmac
841 */ 883 */
842void 884void
843GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AesSessionKey *key, 885GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
844 const void *plaintext, 886 const void *plaintext,
845 size_t plaintext_len, 887 size_t plaintext_len,
846 GNUNET_HashCode *hmac) 888 GNUNET_HashCode *hmac)
@@ -852,8 +894,7 @@ GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AesSessionKey *key,
852 struct sha512_ctx sctx; 894 struct sha512_ctx sctx;
853 895
854 memset (&kh, 0, sizeof (kh)); 896 memset (&kh, 0, sizeof (kh));
855 GNUNET_assert (sizeof (GNUNET_HashCode) > sizeof (struct GNUNET_CRYPTO_AesSessionKey)); 897 memcpy (&kh, key->key, sizeof (struct GNUNET_CRYPTO_AuthKey));
856 memcpy (&kh, key, sizeof (struct GNUNET_CRYPTO_AesSessionKey));
857 memset (&ipad, 0x5c, sizeof (ipad)); 898 memset (&ipad, 0x5c, sizeof (ipad));
858 memset (&opad, 0x36, sizeof (opad)); 899 memset (&opad, 0x36, sizeof (opad));
859 GNUNET_CRYPTO_hash_xor (&ipad, &kh, &ipad); 900 GNUNET_CRYPTO_hash_xor (&ipad, &kh, &ipad);
diff --git a/src/util/crypto_kdf.c b/src/util/crypto_kdf.c
new file mode 100644
index 000000000..785603c8c
--- /dev/null
+++ b/src/util/crypto_kdf.c
@@ -0,0 +1,88 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/util/crypto_kdf.c
23 * @brief Key derivation
24 * @author Nils Durner
25 */
26
27#include <gcrypt.h>
28
29#include "platform.h"
30#include "gnunet_crypto_lib.h"
31
32/**
33 * @brief Derive key
34 * @param result buffer for the derived key, allocated by caller
35 * @param out_len desired length of the derived key
36 * @param xts salt
37 * @param xts_len length of xts
38 * @param skm source key material
39 * @param skm_len length of skm
40 * @param argp va_list of void * & size_t pairs for context chunks
41 * @return GNUNET_YES on success
42 */
43int
44GNUNET_CRYPTO_kdf_v (void *result, const unsigned long long out_len,
45 const void *xts, const size_t xts_len, const void *skm,
46 const size_t skm_len, va_list argp)
47{
48 /*
49 "Finally, we point out to a particularly advantageous instantiation using
50 HMAC-SHA512 as XTR and HMAC-SHA256 in PRF* (in which case the output from SHA-512 is
51 truncated to 256 bits). This makes sense in two ways: First, the extraction part is where we need a
52 stronger hash function due to the unconventional demand from the hash function in the extraction
53 setting. Second, as shown in Section 6, using HMAC with a truncated output as an extractor
54 allows to prove the security of HKDF under considerably weaker assumptions on the underlying
55 hash function."
56
57 http://eprint.iacr.org/2010/264
58 */
59
60 return GNUNET_CRYPTO_hkdf_v (result, out_len, GCRY_MD_SHA512, GCRY_MD_SHA256,
61 xts, xts_len, skm, skm_len, argp);
62}
63
64/**
65 * @brief Derive key
66 * @param result buffer for the derived key, allocated by caller
67 * @param out_len desired length of the derived key
68 * @param xts salt
69 * @param xts_len length of xts
70 * @param skm source key material
71 * @param skm_len length of skm
72 * @param ... void * & size_t pairs for context chunks
73 * @return GNUNET_YES on success
74 */
75int
76GNUNET_CRYPTO_kdf (void *result, const unsigned long long out_len,
77 const void *xts, const size_t xts_len, const void *skm,
78 const size_t skm_len, ...)
79{
80 va_list argp;
81 int ret;
82
83 va_start(argp, skm_len);
84 ret = GNUNET_CRYPTO_kdf_v (result, out_len, xts, xts_len, skm, skm_len, argp);
85 va_end(argp);
86
87 return ret;
88}
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index 0a092cdcc..14d87b1cd 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -76,6 +76,17 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i)
76 while (ret >= ul); 76 while (ret >= ul);
77 return ret % i; 77 return ret % i;
78 } 78 }
79 else if (mode == GNUNET_CRYPTO_QUALITY_NONCE)
80 {
81 ul = UINT32_MAX - (UINT32_MAX % i);
82 do
83 {
84 gcry_create_nonce(&ret, sizeof(ret));
85 }
86 while (ret >= ul);
87
88 return ret % i;
89 }
79 else 90 else
80 { 91 {
81 ret = i * weak_random (); 92 ret = i * weak_random ();
@@ -142,6 +153,17 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
142 while (ret >= ul); 153 while (ret >= ul);
143 return ret % max; 154 return ret % max;
144 } 155 }
156 else if (mode == GNUNET_CRYPTO_QUALITY_NONCE)
157 {
158 ul = UINT64_MAX - (UINT64_MAX % max);
159 do
160 {
161 gcry_create_nonce(&ret, sizeof(ret));
162 }
163 while (ret >= ul);
164
165 return ret % max;
166 }
145 else 167 else
146 { 168 {
147 ret = max * weak_random (); 169 ret = max * weak_random ();