Browse code

Refactored HMAC functions

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>

Adriaan de Jong authored on 2011/06/24 00:18:32
Showing 4 changed files
... ...
@@ -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