aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_crypto_lib.h11
-rw-r--r--src/util/crypto_hkdf.c45
-rw-r--r--src/util/test_crypto_hkdf.c74
3 files changed, 103 insertions, 27 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 8a8e71a96..126c599b9 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -527,6 +527,8 @@ int GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
527 527
528/** 528/**
529 * @brief Derive key 529 * @brief Derive key
530 * @param result buffer for the derived key, allocated by caller
531 * @param out_len desired length of the derived key
530 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... 532 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_...
531 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... 533 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_...
532 * @param xts salt 534 * @param xts salt
@@ -535,15 +537,12 @@ int GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
535 * @param skm_len length of skm 537 * @param skm_len length of skm
536 * @param ctx context info 538 * @param ctx context info
537 * @param ctx_len length of ctx 539 * @param ctx_len length of ctx
538 * @param out_len desired length of the derived key
539 * @param result buffer for the derived key, allocated by caller
540 * @return GNUNET_YES on success 540 * @return GNUNET_YES on success
541 */ 541 */
542int 542int
543GNUNET_CRYPTO_hkdf (int xtr_algo, int prf_algo, const void *xts, 543GNUNET_CRYPTO_hkdf (void *result, const unsigned long long out_len,
544 const size_t xts_len, const void *skm, const size_t skm_len, 544 int xtr_algo, int prf_algo, const void *xts, const size_t xts_len,
545 const void *ctx, const size_t ctx_len, const unsigned long long out_len, 545 const void *skm, const size_t skm_len, ...);
546 void *result);
547 546
548 547
549/** 548/**
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c
index e442aef1c..4415b7551 100644
--- a/src/util/crypto_hkdf.c
+++ b/src/util/crypto_hkdf.c
@@ -93,6 +93,8 @@ static void dump(char *src, void *p, unsigned int l)
93 93
94/** 94/**
95 * @brief Derive key 95 * @brief Derive key
96 * @param result buffer for the derived key, allocated by caller
97 * @param out_len desired length of the derived key
96 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... 98 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_...
97 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... 99 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_...
98 * @param xts salt 100 * @param xts salt
@@ -101,15 +103,12 @@ static void dump(char *src, void *p, unsigned int l)
101 * @param skm_len length of skm 103 * @param skm_len length of skm
102 * @param ctx context info 104 * @param ctx context info
103 * @param ctx_len length of ctx 105 * @param ctx_len length of ctx
104 * @param out_len desired length of the derived key
105 * @param result buffer for the derived key, allocated by caller
106 * @return GNUNET_YES on success 106 * @return GNUNET_YES on success
107 */ 107 */
108int 108int
109GNUNET_CRYPTO_hkdf (int xtr_algo, int prf_algo, const void *xts, 109GNUNET_CRYPTO_hkdf (void *result, const unsigned long long out_len,
110 const size_t xts_len, const void *skm, const size_t skm_len, 110 int xtr_algo, int prf_algo, const void *xts, const size_t xts_len,
111 const void *ctx, const size_t ctx_len, const unsigned long long out_len, 111 const void *skm, const size_t skm_len, ...)
112 void *result)
113{ 112{
114 void *prk, *hc, *plain; 113 void *prk, *hc, *plain;
115 unsigned long long plain_len; 114 unsigned long long plain_len;
@@ -117,6 +116,8 @@ GNUNET_CRYPTO_hkdf (int xtr_algo, int prf_algo, const void *xts,
117 unsigned int k, xtr_len; 116 unsigned int k, xtr_len;
118 int ret; 117 int ret;
119 gcry_md_hd_t xtr, prf; 118 gcry_md_hd_t xtr, prf;
119 size_t ctx_len;
120 va_list argp;
120 121
121 prk = plain = NULL; 122 prk = plain = NULL;
122 xtr_len = gcry_md_get_algo_dlen (xtr_algo); 123 xtr_len = gcry_md_get_algo_dlen (xtr_algo);
@@ -127,6 +128,11 @@ GNUNET_CRYPTO_hkdf (int xtr_algo, int prf_algo, const void *xts,
127 if (out_len > (2 ^ 32 * k) || !xtr_algo || !prf_algo) 128 if (out_len > (2 ^ 32 * k) || !xtr_algo || !prf_algo)
128 return GNUNET_SYSERR; 129 return GNUNET_SYSERR;
129 130
131 va_start(argp, skm_len);
132 for (ctx_len = 0; va_arg (argp, void *);)
133 ctx_len += va_arg (argp, size_t);
134 va_end(argp);
135
130 prk = GNUNET_malloc (xtr_len); 136 prk = GNUNET_malloc (xtr_len);
131 137
132 memset (result, 0, out_len); 138 memset (result, 0, out_len);
@@ -146,8 +152,21 @@ GNUNET_CRYPTO_hkdf (int xtr_algo, int prf_algo, const void *xts,
146 plain = GNUNET_malloc (plain_len); 152 plain = GNUNET_malloc (plain_len);
147 if (t > 0) 153 if (t > 0)
148 { 154 {
149 memcpy (plain, ctx, ctx_len); 155 void *ctx, *dst;
150 memset (plain + ctx_len, 1, 1); 156
157 dst = plain;
158 va_start (argp, skm_len);
159 while ((ctx = va_arg (argp, void *)))
160 {
161 size_t len;
162
163 len = va_arg (argp, size_t);
164 memcpy (dst, ctx, len);
165 dst += len;
166 }
167 va_end (argp);
168
169 memset (dst, 1, 1);
151 gcry_md_reset (prf); 170 gcry_md_reset (prf);
152#if DEBUG_HKDF 171#if DEBUG_HKDF
153 dump("K(1)", plain, plain_len); 172 dump("K(1)", plain, plain_len);
@@ -160,7 +179,15 @@ GNUNET_CRYPTO_hkdf (int xtr_algo, int prf_algo, const void *xts,
160 } 179 }
161 180
162 if (t > 1 || d > 0) 181 if (t > 1 || d > 0)
163 memcpy (plain + k, ctx, ctx_len); 182 {
183 void *ctx, *dst;
184
185 dst = plain + k;
186 va_start(argp, skm_len);
187 while ((ctx = va_arg (argp, void *)))
188 memcpy (dst, ctx, va_arg (argp, size_t));
189 va_end (argp);
190 }
164 191
165 /* K(i+1) */ 192 /* K(i+1) */
166 for (i = 1; i < t; i++) 193 for (i = 1; i < t; i++)
diff --git a/src/util/test_crypto_hkdf.c b/src/util/test_crypto_hkdf.c
index ec215fd34..1b4d368aa 100644
--- a/src/util/test_crypto_hkdf.c
+++ b/src/util/test_crypto_hkdf.c
@@ -48,8 +48,8 @@ tc1 ()
48 int l = 42; 48 int l = 42;
49 49
50 memset (result, 0, sizeof(result)); 50 memset (result, 0, sizeof(result));
51 GNUNET_assert (GNUNET_CRYPTO_hkdf(GCRY_MD_SHA256, GCRY_MD_SHA256, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info), 51 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA256, GCRY_MD_SHA256, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info),
52 l, result) == GNUNET_YES); 52 NULL) == GNUNET_YES);
53 GNUNET_assert (memcmp(result, okm, l) == 0); 53 GNUNET_assert (memcmp(result, okm, l) == 0);
54 GNUNET_assert (memcmp(result + l, "\0", 2) == 0); 54 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
55} 55}
@@ -89,8 +89,8 @@ tc2 ()
89 int l = 82; 89 int l = 82;
90 90
91 memset (result, 0, sizeof(result)); 91 memset (result, 0, sizeof(result));
92 GNUNET_assert (GNUNET_CRYPTO_hkdf(GCRY_MD_SHA256, GCRY_MD_SHA256, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info), 92 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA256, GCRY_MD_SHA256, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info),
93 l, result) == GNUNET_YES); 93 NULL) == GNUNET_YES);
94 GNUNET_assert (memcmp(result, okm, l) == 0); 94 GNUNET_assert (memcmp(result, okm, l) == 0);
95 GNUNET_assert (memcmp(result + l, "\0", 2) == 0); 95 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
96} 96}
@@ -108,8 +108,8 @@ tc3 ()
108 int l = 42; 108 int l = 42;
109 109
110 memset (result, 0, sizeof(result)); 110 memset (result, 0, sizeof(result));
111 GNUNET_assert (GNUNET_CRYPTO_hkdf(GCRY_MD_SHA256, GCRY_MD_SHA256, NULL, 0, ikm, sizeof(ikm), NULL, 0, 111 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA256, GCRY_MD_SHA256, NULL, 0, ikm, sizeof(ikm), NULL, 0,
112 l, result) == GNUNET_YES); 112 NULL) == GNUNET_YES);
113 GNUNET_assert (memcmp(result, okm, l) == 0); 113 GNUNET_assert (memcmp(result, okm, l) == 0);
114 GNUNET_assert (memcmp(result + l, "\0", 2) == 0); 114 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
115} 115}
@@ -131,8 +131,8 @@ tc4 ()
131 int l = 42; 131 int l = 42;
132 132
133 memset (result, 0, sizeof(result)); 133 memset (result, 0, sizeof(result));
134 GNUNET_assert (GNUNET_CRYPTO_hkdf(GCRY_MD_SHA1, GCRY_MD_SHA1, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info), 134 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA1, GCRY_MD_SHA1, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info),
135 l, result) == GNUNET_YES); 135 NULL) == GNUNET_YES);
136 GNUNET_assert (memcmp(result, okm, l) == 0); 136 GNUNET_assert (memcmp(result, okm, l) == 0);
137 GNUNET_assert (memcmp(result + l, "\0", 2) == 0); 137 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
138} 138}
@@ -172,8 +172,8 @@ tc5 ()
172 int l = 82; 172 int l = 82;
173 173
174 memset (result, 0, sizeof(result)); 174 memset (result, 0, sizeof(result));
175 GNUNET_assert (GNUNET_CRYPTO_hkdf(GCRY_MD_SHA1, GCRY_MD_SHA1, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info), 175 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA1, GCRY_MD_SHA1, salt, sizeof(salt), ikm, sizeof(ikm), info, sizeof(info),
176 l, result) == GNUNET_YES); 176 NULL) == GNUNET_YES);
177 GNUNET_assert (memcmp(result, okm, l) == 0); 177 GNUNET_assert (memcmp(result, okm, l) == 0);
178 GNUNET_assert (memcmp(result + l, "\0", 2) == 0); 178 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
179} 179}
@@ -191,8 +191,52 @@ tc6 ()
191 int l = 42; 191 int l = 42;
192 192
193 memset (result, 0, sizeof(result)); 193 memset (result, 0, sizeof(result));
194 GNUNET_assert (GNUNET_CRYPTO_hkdf(GCRY_MD_SHA1, GCRY_MD_SHA1, NULL, 0, ikm, sizeof(ikm), NULL, 0, 194 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA1, GCRY_MD_SHA1, NULL, 0, ikm, sizeof(ikm), NULL, 0,
195 l, result) == GNUNET_YES); 195 NULL) == GNUNET_YES);
196 GNUNET_assert (memcmp(result, okm, l) == 0);
197 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
198}
199
200void
201tc7 ()
202{
203 unsigned char ikm[80] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
204 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
205 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
206 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
207 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
208 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
209 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
210 unsigned char salt[80] = { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
211 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
212 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81,
213 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
214 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
215 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
216 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf };
217 unsigned char info1[80] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
218 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,
219 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
220 0xd0, 0xd1 };
221 unsigned char info2[80] = { 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
222 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5,
223 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1,
224 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,
225 0xfe, 0xff };
226 unsigned char okm[82] = { 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1,
227 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d,
228 0x92, 0x19, 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3,
229 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2,
230 0x17, 0x3c, 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c,
231 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f,
232 0x4c, 0x43, 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4 };
233 char result[84];
234 int l = 82;
235
236 memset (result, 0, sizeof(result));
237 GNUNET_assert (GNUNET_CRYPTO_hkdf(result, l, GCRY_MD_SHA1, GCRY_MD_SHA1, salt,
238 sizeof(salt), ikm, sizeof(ikm), info1, sizeof(info1), info2, sizeof(info2),
239 NULL) == GNUNET_YES);
196 GNUNET_assert (memcmp(result, okm, l) == 0); 240 GNUNET_assert (memcmp(result, okm, l) == 0);
197 GNUNET_assert (memcmp(result + l, "\0", 2) == 0); 241 GNUNET_assert (memcmp(result + l, "\0", 2) == 0);
198} 242}
@@ -201,11 +245,17 @@ int
201main () 245main ()
202{ 246{
203 GNUNET_log_setup ("test-crypto-hkdf", "WARNING", NULL); 247 GNUNET_log_setup ("test-crypto-hkdf", "WARNING", NULL);
248
249 /* Official test vectors */
204 tc1(); 250 tc1();
205 tc2(); 251 tc2();
206 tc3(); 252 tc3();
207 tc4(); 253 tc4();
208 tc5(); 254 tc5();
209 tc6(); 255 tc6();
256
257 /* Additional tests */
258 tc7();
259
210 return 0; 260 return 0;
211} 261}