aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorSalman Qazi <sqazi@google.com>2012-10-05 17:24:14 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2012-10-15 10:33:20 -0400
commitba1ee070909fae01248b8117da1706f3cf2bfd1b (patch)
tree98d982702fdc17a9699387c59583e9a5ecf0b984 /crypto
parent7291a932c6e27d9768e374e9d648086636daf61c (diff)
crypto: vmac - Make VMAC work when blocks aren't aligned
VMAC implementation, as it is, does not work with blocks that are not multiples of 128-bytes. Furthermore, this is a problem when using the implementation on scatterlists, even when the complete plain text is 128-byte multiple, as the pieces that get passed to vmac_update can be pretty much any size. I also added test cases for unaligned blocks. Signed-off-by: Salman Qazi <sqazi@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/testmgr.h33
-rw-r--r--crypto/vmac.c47
2 files changed, 75 insertions, 5 deletions
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 76d7f6cc82f5..f8365e913de9 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -1707,7 +1707,7 @@ static struct hash_testvec aes_xcbc128_tv_template[] = {
1707 } 1707 }
1708}; 1708};
1709 1709
1710#define VMAC_AES_TEST_VECTORS 8 1710#define VMAC_AES_TEST_VECTORS 11
1711static char vmac_string1[128] = {'\x01', '\x01', '\x01', '\x01', 1711static char vmac_string1[128] = {'\x01', '\x01', '\x01', '\x01',
1712 '\x02', '\x03', '\x02', '\x02', 1712 '\x02', '\x03', '\x02', '\x02',
1713 '\x02', '\x04', '\x01', '\x07', 1713 '\x02', '\x04', '\x01', '\x07',
@@ -1723,6 +1723,19 @@ static char vmac_string3[128] = {'a', 'b', 'c', 'a', 'b', 'c',
1723 'a', 'b', 'c', 'a', 'b', 'c', 1723 'a', 'b', 'c', 'a', 'b', 'c',
1724 }; 1724 };
1725 1725
1726static char vmac_string4[17] = {'b', 'c', 'e', 'f',
1727 'i', 'j', 'l', 'm',
1728 'o', 'p', 'r', 's',
1729 't', 'u', 'w', 'x', 'z'};
1730
1731static char vmac_string5[127] = {'r', 'm', 'b', 't', 'c',
1732 'o', 'l', 'k', ']', '%',
1733 '9', '2', '7', '!', 'A'};
1734
1735static char vmac_string6[129] = {'p', 't', '*', '7', 'l',
1736 'i', '!', '#', 'w', '0',
1737 'z', '/', '4', 'A', 'n'};
1738
1726static struct hash_testvec aes_vmac128_tv_template[] = { 1739static struct hash_testvec aes_vmac128_tv_template[] = {
1727 { 1740 {
1728 .key = "\x00\x01\x02\x03\x04\x05\x06\x07" 1741 .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
@@ -1776,6 +1789,24 @@ static struct hash_testvec aes_vmac128_tv_template[] = {
1776 .digest = "\x8b\x32\x8f\xe1\xed\x8f\xfa\xd4", 1789 .digest = "\x8b\x32\x8f\xe1\xed\x8f\xfa\xd4",
1777 .psize = 128, 1790 .psize = 128,
1778 .ksize = 16, 1791 .ksize = 16,
1792 }, {
1793 .key = "a09b5cd!f#07K\x00\x00\x00",
1794 .plaintext = vmac_string4,
1795 .digest = "\xab\xa5\x0f\xea\x42\x4e\xa1\x5f",
1796 .psize = sizeof(vmac_string4),
1797 .ksize = 16,
1798 }, {
1799 .key = "a09b5cd!f#07K\x00\x00\x00",
1800 .plaintext = vmac_string5,
1801 .digest = "\x25\x31\x98\xbc\x1d\xe8\x67\x60",
1802 .psize = sizeof(vmac_string5),
1803 .ksize = 16,
1804 }, {
1805 .key = "a09b5cd!f#07K\x00\x00\x00",
1806 .plaintext = vmac_string6,
1807 .digest = "\xc4\xae\x9b\x47\x95\x65\xeb\x41",
1808 .psize = sizeof(vmac_string6),
1809 .ksize = 16,
1779 }, 1810 },
1780}; 1811};
1781 1812
diff --git a/crypto/vmac.c b/crypto/vmac.c
index f2338ca98368..2eb11a30c29c 100644
--- a/crypto/vmac.c
+++ b/crypto/vmac.c
@@ -375,6 +375,11 @@ static void vhash_update(const unsigned char *m,
375 u64 pkh = ctx->polykey[0]; 375 u64 pkh = ctx->polykey[0];
376 u64 pkl = ctx->polykey[1]; 376 u64 pkl = ctx->polykey[1];
377 377
378 if (!mbytes)
379 return;
380
381 BUG_ON(mbytes % VMAC_NHBYTES);
382
378 mptr = (u64 *)m; 383 mptr = (u64 *)m;
379 i = mbytes / VMAC_NHBYTES; /* Must be non-zero */ 384 i = mbytes / VMAC_NHBYTES; /* Must be non-zero */
380 385
@@ -454,7 +459,7 @@ do_l3:
454} 459}
455 460
456static u64 vmac(unsigned char m[], unsigned int mbytes, 461static u64 vmac(unsigned char m[], unsigned int mbytes,
457 unsigned char n[16], u64 *tagl, 462 const unsigned char n[16], u64 *tagl,
458 struct vmac_ctx_t *ctx) 463 struct vmac_ctx_t *ctx)
459{ 464{
460 u64 *in_n, *out_p; 465 u64 *in_n, *out_p;
@@ -559,8 +564,33 @@ static int vmac_update(struct shash_desc *pdesc, const u8 *p,
559{ 564{
560 struct crypto_shash *parent = pdesc->tfm; 565 struct crypto_shash *parent = pdesc->tfm;
561 struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); 566 struct vmac_ctx_t *ctx = crypto_shash_ctx(parent);
567 int expand;
568 int min;
569
570 expand = VMAC_NHBYTES - ctx->partial_size > 0 ?
571 VMAC_NHBYTES - ctx->partial_size : 0;
572
573 min = len < expand ? len : expand;
574
575 memcpy(ctx->partial + ctx->partial_size, p, min);
576 ctx->partial_size += min;
577
578 if (len < expand)
579 return 0;
562 580
563 vhash_update(p, len, &ctx->__vmac_ctx); 581 vhash_update(ctx->partial, VMAC_NHBYTES, &ctx->__vmac_ctx);
582 ctx->partial_size = 0;
583
584 len -= expand;
585 p += expand;
586
587 if (len % VMAC_NHBYTES) {
588 memcpy(ctx->partial, p + len - (len % VMAC_NHBYTES),
589 len % VMAC_NHBYTES);
590 ctx->partial_size = len % VMAC_NHBYTES;
591 }
592
593 vhash_update(p, len - len % VMAC_NHBYTES, &ctx->__vmac_ctx);
564 594
565 return 0; 595 return 0;
566} 596}
@@ -572,10 +602,20 @@ static int vmac_final(struct shash_desc *pdesc, u8 *out)
572 vmac_t mac; 602 vmac_t mac;
573 u8 nonce[16] = {}; 603 u8 nonce[16] = {};
574 604
575 mac = vmac(NULL, 0, nonce, NULL, ctx); 605 /* vmac() ends up accessing outside the array bounds that
606 * we specify. In appears to access up to the next 2-word
607 * boundary. We'll just be uber cautious and zero the
608 * unwritten bytes in the buffer.
609 */
610 if (ctx->partial_size) {
611 memset(ctx->partial + ctx->partial_size, 0,
612 VMAC_NHBYTES - ctx->partial_size);
613 }
614 mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx);
576 memcpy(out, &mac, sizeof(vmac_t)); 615 memcpy(out, &mac, sizeof(vmac_t));
577 memset(&mac, 0, sizeof(vmac_t)); 616 memset(&mac, 0, sizeof(vmac_t));
578 memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx)); 617 memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx));
618 ctx->partial_size = 0;
579 return 0; 619 return 0;
580} 620}
581 621
@@ -673,4 +713,3 @@ module_exit(vmac_module_exit);
673 713
674MODULE_LICENSE("GPL"); 714MODULE_LICENSE("GPL");
675MODULE_DESCRIPTION("VMAC hash algorithm"); 715MODULE_DESCRIPTION("VMAC hash algorithm");
676