Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
... | ... |
@@ -174,15 +174,13 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, |
174 | 174 |
/* HMAC the ciphertext (or plaintext if !cipher) */ |
175 | 175 |
if (ctx->hmac) |
176 | 176 |
{ |
177 |
- int hmac_len; |
|
178 |
- uint8_t *output; |
|
177 |
+ uint8_t *output = NULL; |
|
179 | 178 |
|
180 |
- HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL); |
|
181 |
- HMAC_Update (ctx->hmac, BPTR (&work), BLEN (&work)); |
|
182 |
- output = buf_prepend (&work, HMAC_size (ctx->hmac)); |
|
179 |
+ hmac_ctx_reset (ctx->hmac); |
|
180 |
+ hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work)); |
|
181 |
+ output = buf_prepend (&work, hmac_ctx_size(ctx->hmac)); |
|
183 | 182 |
ASSERT (output); |
184 |
- HMAC_Final (ctx->hmac, output, (unsigned int *)&hmac_len); |
|
185 |
- ASSERT (hmac_len == HMAC_size (ctx->hmac)); |
|
183 |
+ hmac_ctx_final (ctx->hmac, output); |
|
186 | 184 |
} |
187 | 185 |
|
188 | 186 |
*buf = work; |
... | ... |
@@ -226,21 +224,18 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, |
226 | 226 |
{ |
227 | 227 |
int hmac_len; |
228 | 228 |
uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */ |
229 |
- int in_hmac_len; |
|
230 | 229 |
|
231 |
- HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL); |
|
230 |
+ hmac_ctx_reset(ctx->hmac); |
|
232 | 231 |
|
233 | 232 |
/* Assume the length of the input HMAC */ |
234 |
- hmac_len = HMAC_size (ctx->hmac); |
|
233 |
+ hmac_len = hmac_ctx_size (ctx->hmac); |
|
235 | 234 |
|
236 | 235 |
/* Authentication fails if insufficient data in packet for HMAC */ |
237 | 236 |
if (buf->len < hmac_len) |
238 | 237 |
CRYPT_ERROR ("missing authentication info"); |
239 | 238 |
|
240 |
- HMAC_Update (ctx->hmac, BPTR (buf) + hmac_len, |
|
241 |
- BLEN (buf) - hmac_len); |
|
242 |
- HMAC_Final (ctx->hmac, local_hmac, (unsigned int *)&in_hmac_len); |
|
243 |
- ASSERT (hmac_len == in_hmac_len); |
|
239 |
+ hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len); |
|
240 |
+ hmac_ctx_final (ctx->hmac, local_hmac); |
|
244 | 241 |
|
245 | 242 |
/* Compare locally computed HMAC with packet HMAC */ |
246 | 243 |
if (memcmp (local_hmac, BPTR (buf), hmac_len)) |
... | ... |
@@ -439,31 +434,6 @@ init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
439 | 439 |
gc_free (&gc); |
440 | 440 |
} |
441 | 441 |
|
442 |
-static void |
|
443 |
-init_hmac (HMAC_CTX *ctx, const EVP_MD *digest, |
|
444 |
- struct key *key, const struct key_type *kt, const char *prefix) |
|
445 |
-{ |
|
446 |
- struct gc_arena gc = gc_new (); |
|
447 |
- |
|
448 |
- HMAC_CTX_init (ctx); |
|
449 |
- HMAC_Init_ex (ctx, key->hmac, kt->hmac_length, digest, NULL); |
|
450 |
- msg (D_HANDSHAKE, |
|
451 |
- "%s: Using %d bit message hash '%s' for HMAC authentication", |
|
452 |
- prefix, HMAC_size (ctx) * 8, OBJ_nid2sn (EVP_MD_type (digest))); |
|
453 |
- |
|
454 |
- /* make sure we used a big enough key */ |
|
455 |
- ASSERT (HMAC_size (ctx) <= kt->hmac_length); |
|
456 |
- |
|
457 |
- dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix, |
|
458 |
- format_hex (key->hmac, kt->hmac_length, 0, &gc)); |
|
459 |
- dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d", |
|
460 |
- prefix, |
|
461 |
- EVP_MD_size (digest), |
|
462 |
- EVP_MD_block_size (digest)); |
|
463 |
- |
|
464 |
- gc_free (&gc); |
|
465 |
-} |
|
466 |
- |
|
467 | 442 |
/* |
468 | 443 |
* Build a struct key_type. |
469 | 444 |
*/ |
... | ... |
@@ -547,8 +517,9 @@ init_key_ctx (struct key_ctx *ctx, struct key *key, |
547 | 547 |
} |
548 | 548 |
if (kt->digest && kt->hmac_length > 0) |
549 | 549 |
{ |
550 |
- ALLOC_OBJ (ctx->hmac, HMAC_CTX); |
|
551 |
- init_hmac (ctx->hmac, kt->digest, key, kt, prefix); |
|
550 |
+ ALLOC_OBJ(ctx->hmac, hmac_ctx_t); |
|
551 |
+ hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest, |
|
552 |
+ prefix); |
|
552 | 553 |
} |
553 | 554 |
} |
554 | 555 |
|
... | ... |
@@ -563,8 +534,8 @@ free_key_ctx (struct key_ctx *ctx) |
563 | 563 |
} |
564 | 564 |
if (ctx->hmac) |
565 | 565 |
{ |
566 |
- HMAC_CTX_cleanup (ctx->hmac); |
|
567 |
- free (ctx->hmac); |
|
566 |
+ hmac_ctx_cleanup(ctx->hmac); |
|
567 |
+ free(ctx->hmac); |
|
568 | 568 |
ctx->hmac = NULL; |
569 | 569 |
} |
570 | 570 |
} |
... | ... |
@@ -264,4 +264,64 @@ void md_ctx_update (md_ctx_t *ctx, const uint8_t *src, int src_len); |
264 | 264 |
void md_ctx_final (md_ctx_t *ctx, uint8_t *dst); |
265 | 265 |
|
266 | 266 |
|
267 |
+/* |
|
268 |
+ * |
|
269 |
+ * Generic HMAC functions |
|
270 |
+ * |
|
271 |
+ */ |
|
272 |
+ |
|
273 |
+/* |
|
274 |
+ * Initialises the given HMAC context, using the given digest |
|
275 |
+ * and key. |
|
276 |
+ * |
|
277 |
+ * @param ctx HMAC context to intialise |
|
278 |
+ * @param key The key to use for the HMAC |
|
279 |
+ * @param key_len The key length to use |
|
280 |
+ * @param kt Static message digest parameters |
|
281 |
+ * @param prefix Prefix to use when printing debug information. |
|
282 |
+ * |
|
283 |
+ */ |
|
284 |
+void hmac_ctx_init (hmac_ctx_t *ctx, const uint8_t *key, int key_length, |
|
285 |
+ const md_kt_t *kt, const char *prefix); |
|
286 |
+ |
|
287 |
+/* |
|
288 |
+ * Free the given HMAC context. |
|
289 |
+ * |
|
290 |
+ * @param ctx HMAC context |
|
291 |
+ */ |
|
292 |
+void hmac_ctx_cleanup(hmac_ctx_t *ctx); |
|
293 |
+ |
|
294 |
+/* |
|
295 |
+ * Returns the size of the HMAC output by the given HMAC Context |
|
296 |
+ * |
|
297 |
+ * @param ctx HMAC context. |
|
298 |
+ * |
|
299 |
+ * @return Size of the HMAC, or \0 if ctx is NULL. |
|
300 |
+ */ |
|
301 |
+int hmac_ctx_size (const hmac_ctx_t *ctx); |
|
302 |
+ |
|
303 |
+/* |
|
304 |
+ * Resets the given HMAC context, preserving the associated key information |
|
305 |
+ * |
|
306 |
+ * @param ctx HMAC context. May not be NULL. |
|
307 |
+ */ |
|
308 |
+void hmac_ctx_reset (hmac_ctx_t *ctx); |
|
309 |
+ |
|
310 |
+/* |
|
311 |
+ * Process the given data for use in the HMAC. |
|
312 |
+ * |
|
313 |
+ * @param ctx HMAC context. May not be NULL. |
|
314 |
+ * @param src The buffer to HMAC. May not be NULL. |
|
315 |
+ * @param src_len The length of the incoming buffer. |
|
316 |
+ */ |
|
317 |
+void hmac_ctx_update (hmac_ctx_t *ctx, const uint8_t *src, int src_len); |
|
318 |
+ |
|
319 |
+/* |
|
320 |
+ * Output the HMAC to the given buffer. |
|
321 |
+ * |
|
322 |
+ * @param ctx HMAC context. May not be NULL. |
|
323 |
+ * @param dst buffer to write the HMAC to. May not be NULL. |
|
324 |
+ */ |
|
325 |
+void hmac_ctx_final (hmac_ctx_t *ctx, uint8_t *dst); |
|
326 |
+ |
|
267 | 327 |
#endif /* CRYPTO_BACKEND_H_ */ |
... | ... |
@@ -551,3 +551,76 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst) |
551 | 551 |
|
552 | 552 |
EVP_DigestFinal(ctx, dst, &in_md_len); |
553 | 553 |
} |
554 |
+ |
|
555 |
+ |
|
556 |
+/* |
|
557 |
+ * |
|
558 |
+ * Generic HMAC functions |
|
559 |
+ * |
|
560 |
+ */ |
|
561 |
+ |
|
562 |
+ |
|
563 |
+void |
|
564 |
+hmac_ctx_init (HMAC_CTX *ctx, const uint8_t *key, int key_len, |
|
565 |
+ const EVP_MD *kt, const char *prefix) |
|
566 |
+{ |
|
567 |
+ struct gc_arena gc = gc_new (); |
|
568 |
+ |
|
569 |
+ ASSERT(NULL != kt && NULL != ctx); |
|
570 |
+ |
|
571 |
+ CLEAR(*ctx); |
|
572 |
+ |
|
573 |
+ HMAC_CTX_init (ctx); |
|
574 |
+ HMAC_Init_ex (ctx, key, key_len, kt, NULL); |
|
575 |
+ |
|
576 |
+ if (prefix) |
|
577 |
+ msg (D_HANDSHAKE, |
|
578 |
+ "%s: Using %d bit message hash '%s' for HMAC authentication", |
|
579 |
+ prefix, HMAC_size (ctx) * 8, OBJ_nid2sn (EVP_MD_type (kt))); |
|
580 |
+ |
|
581 |
+ /* make sure we used a big enough key */ |
|
582 |
+ ASSERT (HMAC_size (ctx) <= key_len); |
|
583 |
+ |
|
584 |
+ if (prefix) |
|
585 |
+ dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix, |
|
586 |
+ format_hex (key, key_len, 0, &gc)); |
|
587 |
+ if (prefix) |
|
588 |
+ dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d", |
|
589 |
+ prefix, |
|
590 |
+ EVP_MD_size (kt), |
|
591 |
+ EVP_MD_block_size (kt)); |
|
592 |
+ |
|
593 |
+ gc_free (&gc); |
|
594 |
+} |
|
595 |
+ |
|
596 |
+void |
|
597 |
+hmac_ctx_cleanup(HMAC_CTX *ctx) |
|
598 |
+{ |
|
599 |
+ HMAC_CTX_cleanup (ctx); |
|
600 |
+} |
|
601 |
+ |
|
602 |
+int |
|
603 |
+hmac_ctx_size (const HMAC_CTX *ctx) |
|
604 |
+{ |
|
605 |
+ return HMAC_size (ctx); |
|
606 |
+} |
|
607 |
+ |
|
608 |
+void |
|
609 |
+hmac_ctx_reset (HMAC_CTX *ctx) |
|
610 |
+{ |
|
611 |
+ HMAC_Init_ex (ctx, NULL, 0, NULL, NULL); |
|
612 |
+} |
|
613 |
+ |
|
614 |
+void |
|
615 |
+hmac_ctx_update (HMAC_CTX *ctx, const uint8_t *src, int src_len) |
|
616 |
+{ |
|
617 |
+ HMAC_Update (ctx, src, src_len); |
|
618 |
+} |
|
619 |
+ |
|
620 |
+void |
|
621 |
+hmac_ctx_final (HMAC_CTX *ctx, uint8_t *dst) |
|
622 |
+{ |
|
623 |
+ unsigned int in_hmac_len = 0; |
|
624 |
+ |
|
625 |
+ HMAC_Final (ctx, dst, &in_hmac_len); |
|
626 |
+} |
... | ... |
@@ -80,13 +80,14 @@ gen_md4_hash (const char* data, int data_len, char *result) |
80 | 80 |
static void |
81 | 81 |
gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result) |
82 | 82 |
{ |
83 |
- unsigned int len; |
|
84 |
- |
|
85 |
- HMAC_CTX c; |
|
86 |
- HMAC_Init (&c, key, key_len, EVP_md5()); |
|
87 |
- HMAC_Update (&c, (const unsigned char *)data, data_len); |
|
88 |
- HMAC_Final (&c, (unsigned char *)result, &len); |
|
89 |
- HMAC_CTX_cleanup(&c); |
|
83 |
+ const md_kt_t *md5_kt = md_kt_get("MD5"); |
|
84 |
+ hmac_ctx_t hmac_ctx; |
|
85 |
+ CLEAR(hmac_ctx); |
|
86 |
+ |
|
87 |
+ hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt, NULL); |
|
88 |
+ hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len); |
|
89 |
+ hmac_ctx_final(&hmac_ctx, (unsigned char *)result); |
|
90 |
+ hmac_ctx_cleanup(&hmac_ctx); |
|
90 | 91 |
} |
91 | 92 |
|
92 | 93 |
static void |