aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_hkdf.c
diff options
context:
space:
mode:
authorNils Durner <durner@gnunet.org>2010-10-08 11:16:17 +0000
committerNils Durner <durner@gnunet.org>2010-10-08 11:16:17 +0000
commit5695665772107f5c5b088f957a277efc9e3d089e (patch)
treedafca3c500625f3eccbca496af737ae925400a93 /src/util/crypto_hkdf.c
parentf312e6df17cc5fe5848b53827546312eac899529 (diff)
downloadgnunet-5695665772107f5c5b088f957a277efc9e3d089e.tar.gz
gnunet-5695665772107f5c5b088f957a277efc9e3d089e.zip
style fixes, minor bugfixes
Diffstat (limited to 'src/util/crypto_hkdf.c')
-rw-r--r--src/util/crypto_hkdf.c87
1 files changed, 40 insertions, 47 deletions
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c
index c436e9962..96ff3804b 100644
--- a/src/util/crypto_hkdf.c
+++ b/src/util/crypto_hkdf.c
@@ -24,6 +24,7 @@
24 * @file src/util/crypto_hkdf.c 24 * @file src/util/crypto_hkdf.c
25 * @brief Hash-based KDF as defined in RFC 5869 25 * @brief Hash-based KDF as defined in RFC 5869
26 * @see http://www.rfc-editor.org/rfc/rfc5869.txt 26 * @see http://www.rfc-editor.org/rfc/rfc5869.txt
27 * @todo remove GNUNET references
27 * @author Nils Durner 28 * @author Nils Durner
28 */ 29 */
29 30
@@ -36,6 +37,7 @@
36 37
37/** 38/**
38 * @brief Compute the HMAC 39 * @brief Compute the HMAC
40 * @todo use chunked buffers
39 * @param mac gcrypt MAC handle 41 * @param mac gcrypt MAC handle
40 * @param key HMAC key 42 * @param key HMAC key
41 * @param key_len length of key 43 * @param key_len length of key
@@ -66,8 +68,8 @@ doHMAC (gcry_md_hd_t mac,
66 */ 68 */
67static int 69static int
68getPRK (gcry_md_hd_t mac, 70getPRK (gcry_md_hd_t mac,
69 const void *xts, unsigned long long xts_len, /* FIXME: size_t? */ 71 const void *xts, size_t xts_len,
70 const void *skm, unsigned long long skm_len, 72 const void *skm, size_t skm_len,
71 void *prk) 73 void *prk)
72{ 74{
73 const void *ret; 75 const void *ret;
@@ -115,40 +117,46 @@ dump(const char *src,
115 * @return GNUNET_YES on success 117 * @return GNUNET_YES on success
116 */ 118 */
117int 119int
118GNUNET_CRYPTO_hkdf_v (void *result, unsigned long long out_len, 120GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len,
119 int xtr_algo, int prf_algo, 121 int xtr_algo, int prf_algo,
120 const void *xts, size_t xts_len, 122 const void *xts, size_t xts_len,
121 const void *skm, size_t skm_len, 123 const void *skm, size_t skm_len,
122 va_list argp) 124 va_list argp)
123{ 125{
124 void *prk, *plain;
125 const void *hc; 126 const void *hc;
126 unsigned long long plain_len;
127 unsigned long i, t, d; 127 unsigned long i, t, d;
128 unsigned int k, xtr_len; 128 unsigned int k = gcry_md_get_algo_dlen (prf_algo);
129 unsigned int xtr_len = gcry_md_get_algo_dlen (xtr_algo);
130 char prk[xtr_len];
129 int ret; 131 int ret;
130 gcry_md_hd_t xtr, prf; 132 gcry_md_hd_t xtr, prf;
131 size_t ctx_len; 133 size_t ctx_len;
132 va_list args; 134 va_list args;
133 135
134 prk = plain = NULL; 136 if (k == 0)
135 xtr_len = gcry_md_get_algo_dlen (xtr_algo); 137 return GNUNET_SYSERR;
136 k = gcry_md_get_algo_dlen (prf_algo); 138
137 gcry_md_open(&xtr, xtr_algo, GCRY_MD_FLAG_HMAC); 139 // FIXME: what is the check for?
138 gcry_md_open(&prf, prf_algo, GCRY_MD_FLAG_HMAC); 140 if (out_len > (2 ^ 32 * k))
141 return GNUNET_SYSERR;
142
143 if (gcry_md_open(&xtr, xtr_algo, GCRY_MD_FLAG_HMAC) != GPG_ERR_NO_ERROR)
144 return GNUNET_SYSERR;
139 145
140 if (out_len > (2 ^ 32 * k) || !xtr_algo || !prf_algo) 146 if (gcry_md_open(&prf, prf_algo, GCRY_MD_FLAG_HMAC) != GPG_ERR_NO_ERROR)
147 {
148 gcry_md_close (xtr);
141 return GNUNET_SYSERR; 149 return GNUNET_SYSERR;
150 }
142 151
143 va_copy (args, argp); 152 va_copy (args, argp);
144 for (ctx_len = 0; va_arg (args, void *);) 153
154 ctx_len = 0;
155 while (NULL != va_arg (args, void *))
145 ctx_len += va_arg (args, size_t); 156 ctx_len += va_arg (args, size_t);
146 va_end(args); 157 va_end(args);
147 158
148 prk = GNUNET_malloc (xtr_len);
149
150 memset (result, 0, out_len); 159 memset (result, 0, out_len);
151 gcry_md_reset (xtr);
152 if (getPRK (xtr, xts, xts_len, skm, skm_len, prk) 160 if (getPRK (xtr, xts, xts_len, skm, skm_len, prk)
153 != GNUNET_YES) 161 != GNUNET_YES)
154 goto hkdf_error; 162 goto hkdf_error;
@@ -160,13 +168,13 @@ GNUNET_CRYPTO_hkdf_v (void *result, unsigned long long out_len,
160 d = out_len % k; 168 d = out_len % k;
161 169
162 /* K(1) */ 170 /* K(1) */
163 plain_len = k + ctx_len + 1; 171 {
164 plain = GNUNET_malloc (plain_len); 172 size_t plain_len = k + ctx_len + 1;
165 if (t > 0) 173 char plain[plain_len];
166 { 174 const void *ctx;
167 void *ctx, *dst; 175 char *dst;
168 176
169 dst = plain; 177 dst = plain + k;
170 va_copy (args, argp); 178 va_copy (args, argp);
171 while ((ctx = va_arg (args, void *))) 179 while ((ctx = va_arg (args, void *)))
172 { 180 {
@@ -178,37 +186,21 @@ GNUNET_CRYPTO_hkdf_v (void *result, unsigned long long out_len,
178 } 186 }
179 va_end (args); 187 va_end (args);
180 188
181 memset (dst, 1, 1); 189 if (t > 0)
182 gcry_md_reset (prf); 190 {
191 memset (plain + k + ctx_len, 1, 1);
183#if DEBUG_HKDF 192#if DEBUG_HKDF
184 dump("K(1)", plain, plain_len); 193 dump("K(1)", plain, plain_len);
185#endif 194#endif
186 hc = doHMAC (prf, 195 hc = doHMAC (prf,
187 prk, 196 prk,
188 xtr_len, plain, ctx_len + 1); 197 xtr_len, &plain[k], ctx_len + 1);
189 if (hc == NULL) 198 if (hc == NULL)
190 goto hkdf_error; 199 goto hkdf_error;
191 memcpy (result, hc, k); 200 memcpy (result, hc, k);
192 result += k; 201 result += k;
193 } 202 }
194 203
195 if (t > 1 || d > 0)
196 {
197 void *ctx, *dst;
198
199 dst = plain + k;
200 va_copy (args, argp);
201 while ((ctx = va_arg (args, void *)))
202 {
203 size_t len;
204
205 len = va_arg (args, size_t);
206 memcpy (dst, ctx, len);
207 dst += len;
208 }
209 va_end (args);
210 }
211
212 /* K(i+1) */ 204 /* K(i+1) */
213 for (i = 1; i < t; i++) 205 for (i = 1; i < t; i++)
214 { 206 {
@@ -235,7 +227,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, unsigned long long out_len,
235#if DEBUG_HKDF 227#if DEBUG_HKDF
236 dump("K(t):d", plain, plain_len); 228 dump("K(t):d", plain, plain_len);
237#endif 229#endif
238 hc = doHMAC (prf, prk, xtr_len, plain, plain_len); 230 if (t > 0)
231 hc = doHMAC (prf, prk, xtr_len, plain, plain_len);
232 else
233 hc = doHMAC (prf, prk, xtr_len, plain + k, plain_len - k);
239 if (hc == NULL) 234 if (hc == NULL)
240 goto hkdf_error; 235 goto hkdf_error;
241 memcpy (result, hc, d); 236 memcpy (result, hc, d);
@@ -246,12 +241,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, unsigned long long out_len,
246 241
247 ret = GNUNET_YES; 242 ret = GNUNET_YES;
248 goto hkdf_ok; 243 goto hkdf_ok;
249 244 }
250hkdf_error: 245hkdf_error:
251 ret = GNUNET_SYSERR; 246 ret = GNUNET_SYSERR;
252hkdf_ok: 247hkdf_ok:
253 GNUNET_free (prk);
254 GNUNET_free_non_null (plain);
255 gcry_md_close (prf); 248 gcry_md_close (prf);
256 gcry_md_close (xtr); 249 gcry_md_close (xtr);
257 250
@@ -274,7 +267,7 @@ hkdf_ok:
274 * @return GNUNET_YES on success 267 * @return GNUNET_YES on success
275 */ 268 */
276int 269int
277GNUNET_CRYPTO_hkdf (void *result, unsigned long long out_len, 270GNUNET_CRYPTO_hkdf (void *result, size_t out_len,
278 int xtr_algo, int prf_algo, 271 int xtr_algo, int prf_algo,
279 const void *xts, size_t xts_len, 272 const void *xts, size_t xts_len,
280 const void *skm, size_t skm_len, 273 const void *skm, size_t skm_len,