diff options
Diffstat (limited to 'src/util/crypto_hkdf.c')
-rw-r--r-- | src/util/crypto_hkdf.c | 118 |
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 | */ |
76 | static const void * | 76 | static const void * |
77 | doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf, | 77 | doHMAC (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 | */ |
101 | static int | 106 | static enum GNUNET_GenericReturnValue |
102 | getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm, | 107 | getPRK (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 |
136 | static void | 147 | static void |
137 | dump (const char *src, const void *p, unsigned int l) | 148 | dump (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 | /** | 164 | enum GNUNET_GenericReturnValue |
154 | * @brief Derive key | 165 | GNUNET_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 | */ | ||
166 | int | ||
167 | GNUNET_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 | /** | 339 | enum GNUNET_GenericReturnValue |
331 | * @brief Derive key | 340 | GNUNET_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 | */ | ||
342 | int | ||
343 | GNUNET_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 | ||