aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_hkdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_hkdf.c')
-rw-r--r--src/util/crypto_hkdf.c118
1 files changed, 63 insertions, 55 deletions
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c
index 4e4496819..838e37d8d 100644
--- a/src/util/crypto_hkdf.c
+++ b/src/util/crypto_hkdf.c
@@ -74,16 +74,21 @@
74 * @return HMAC, freed by caller via gcry_md_close/_reset 74 * @return HMAC, freed by caller via gcry_md_close/_reset
75 */ 75 */
76static const void * 76static const void *
77doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf, 77doHMAC (gcry_md_hd_t mac,
78 const void *key,
79 size_t key_len,
80 const void *buf,
78 size_t buf_len) 81 size_t buf_len)
79{ 82{
80 if (GPG_ERR_NO_ERROR != gcry_md_setkey (mac, key, key_len)) 83 if (GPG_ERR_NO_ERROR !=
84 gcry_md_setkey (mac, key, key_len))
81 { 85 {
82 GNUNET_break (0); 86 GNUNET_break (0);
83 return NULL; 87 return NULL;
84 } 88 }
85 gcry_md_write (mac, buf, buf_len); 89 gcry_md_write (mac,
86 90 buf,
91 buf_len);
87 return (const void *) gcry_md_read (mac, 0); 92 return (const void *) gcry_md_read (mac, 0);
88} 93}
89 94
@@ -98,9 +103,13 @@ doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf,
98 * @param prk result buffer (allocated by caller; at least gcry_md_dlen() bytes) 103 * @param prk result buffer (allocated by caller; at least gcry_md_dlen() bytes)
99 * @return #GNUNET_YES on success 104 * @return #GNUNET_YES on success
100 */ 105 */
101static int 106static enum GNUNET_GenericReturnValue
102getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm, 107getPRK (gcry_md_hd_t mac,
103 size_t skm_len, void *prk) 108 const void *xts,
109 size_t xts_len,
110 const void *skm,
111 size_t skm_len,
112 void *prk)
104{ 113{
105 const void *ret; 114 const void *ret;
106 size_t dlen; 115 size_t dlen;
@@ -114,9 +123,10 @@ getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm,
114 * salt - optional salt value (a non-secret random value); 123 * salt - optional salt value (a non-secret random value);
115 * if not provided, it is set to a string of HashLen zeros. */ 124 * if not provided, it is set to a string of HashLen zeros. */
116 125
117 if (xts_len == 0) 126 if (0 == xts_len)
118 { 127 {
119 char zero_salt[dlen]; 128 char zero_salt[dlen];
129
120 memset (zero_salt, 0, dlen); 130 memset (zero_salt, 0, dlen);
121 ret = doHMAC (mac, zero_salt, dlen, skm, skm_len); 131 ret = doHMAC (mac, zero_salt, dlen, skm, skm_len);
122 } 132 }
@@ -124,22 +134,23 @@ getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm,
124 { 134 {
125 ret = doHMAC (mac, xts, xts_len, skm, skm_len); 135 ret = doHMAC (mac, xts, xts_len, skm, skm_len);
126 } 136 }
127 if (ret == NULL) 137 if (NULL == ret)
128 return GNUNET_SYSERR; 138 return GNUNET_SYSERR;
129 GNUNET_memcpy (prk, ret, dlen); 139 GNUNET_memcpy (prk,
130 140 ret,
141 dlen);
131 return GNUNET_YES; 142 return GNUNET_YES;
132} 143}
133 144
134 145
135#if DEBUG_HKDF 146#if DEBUG_HKDF
136static void 147static void
137dump (const char *src, const void *p, unsigned int l) 148dump (const char *src,
149 const void *p,
150 unsigned int l)
138{ 151{
139 unsigned int i;
140
141 printf ("\n%s: ", src); 152 printf ("\n%s: ", src);
142 for (i = 0; i < l; i++) 153 for (unsigned int i = 0; i < l; i++)
143 { 154 {
144 printf ("%2x", (int) ((const unsigned char *) p)[i]); 155 printf ("%2x", (int) ((const unsigned char *) p)[i]);
145 } 156 }
@@ -150,23 +161,16 @@ dump (const char *src, const void *p, unsigned int l)
150#endif 161#endif
151 162
152 163
153/** 164enum GNUNET_GenericReturnValue
154 * @brief Derive key 165GNUNET_CRYPTO_hkdf_v (void *result,
155 * @param result buffer for the derived key, allocated by caller 166 size_t out_len,
156 * @param out_len desired length of the derived key 167 int xtr_algo,
157 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... 168 int prf_algo,
158 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... 169 const void *xts,
159 * @param xts salt 170 size_t xts_len,
160 * @param xts_len length of @a xts 171 const void *skm,
161 * @param skm source key material 172 size_t skm_len,
162 * @param skm_len length of @a skm 173 va_list argp)
163 * @param argp va_list of void * & size_t pairs for context chunks
164 * @return #GNUNET_YES on success
165 */
166int
167GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
168 const void *xts, size_t xts_len, const void *skm,
169 size_t skm_len, va_list argp)
170{ 174{
171 gcry_md_hd_t xtr; 175 gcry_md_hd_t xtr;
172 gcry_md_hd_t prf; 176 gcry_md_hd_t prf;
@@ -186,10 +190,14 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
186 if (0 == k) 190 if (0 == k)
187 return GNUNET_SYSERR; 191 return GNUNET_SYSERR;
188 if (GPG_ERR_NO_ERROR != 192 if (GPG_ERR_NO_ERROR !=
189 gcry_md_open (&xtr, xtr_algo, GCRY_MD_FLAG_HMAC)) 193 gcry_md_open (&xtr,
194 xtr_algo,
195 GCRY_MD_FLAG_HMAC))
190 return GNUNET_SYSERR; 196 return GNUNET_SYSERR;
191 if (GPG_ERR_NO_ERROR != 197 if (GPG_ERR_NO_ERROR !=
192 gcry_md_open (&prf, prf_algo, GCRY_MD_FLAG_HMAC)) 198 gcry_md_open (&prf,
199 prf_algo,
200 GCRY_MD_FLAG_HMAC))
193 { 201 {
194 gcry_md_close (xtr); 202 gcry_md_close (xtr);
195 return GNUNET_SYSERR; 203 return GNUNET_SYSERR;
@@ -221,7 +229,8 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
221 } 229 }
222 230
223 memset (result, 0, out_len); 231 memset (result, 0, out_len);
224 if (getPRK (xtr, xts, xts_len, skm, skm_len, prk) != GNUNET_YES) 232 if (GNUNET_YES !=
233 getPRK (xtr, xts, xts_len, skm, skm_len, prk))
225 goto hkdf_error; 234 goto hkdf_error;
226#if DEBUG_HKDF 235#if DEBUG_HKDF
227 dump ("PRK", prk, xtr_len); 236 dump ("PRK", prk, xtr_len);
@@ -276,7 +285,7 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
276 dump ("K(i+1)", plain, plain_len); 285 dump ("K(i+1)", plain, plain_len);
277#endif 286#endif
278 hc = doHMAC (prf, prk, xtr_len, plain, plain_len); 287 hc = doHMAC (prf, prk, xtr_len, plain, plain_len);
279 if (hc == NULL) 288 if (NULL == hc)
280 { 289 {
281 GNUNET_free (plain); 290 GNUNET_free (plain);
282 goto hkdf_error; 291 goto hkdf_error;
@@ -327,32 +336,31 @@ hkdf_ok:
327} 336}
328 337
329 338
330/** 339enum GNUNET_GenericReturnValue
331 * @brief Derive key 340GNUNET_CRYPTO_hkdf (void *result,
332 * @param result buffer for the derived key, allocated by caller 341 size_t out_len,
333 * @param out_len desired length of the derived key 342 int xtr_algo,
334 * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... 343 int prf_algo,
335 * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... 344 const void *xts,
336 * @param xts salt 345 size_t xts_len,
337 * @param xts_len length of @a xts 346 const void *skm,
338 * @param skm source key material
339 * @param skm_len length of @a skm
340 * @return #GNUNET_YES on success
341 */
342int
343GNUNET_CRYPTO_hkdf (void *result, size_t out_len, int xtr_algo, int prf_algo,
344 const void *xts, size_t xts_len, const void *skm,
345 size_t skm_len, ...) 347 size_t skm_len, ...)
346{ 348{
347 va_list argp; 349 va_list argp;
348 int ret; 350 enum GNUNET_GenericReturnValue ret;
349 351
350 va_start (argp, skm_len); 352 va_start (argp, skm_len);
351 ret = 353 ret =
352 GNUNET_CRYPTO_hkdf_v (result, out_len, xtr_algo, prf_algo, xts, xts_len, 354 GNUNET_CRYPTO_hkdf_v (result,
353 skm, skm_len, argp); 355 out_len,
356 xtr_algo,
357 prf_algo,
358 xts,
359 xts_len,
360 skm,
361 skm_len,
362 argp);
354 va_end (argp); 363 va_end (argp);
355
356 return ret; 364 return ret;
357} 365}
358 366