changeset 21071:cefb6b37260f

lib: Add test vectors for message digests
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Sat, 05 Nov 2016 19:06:33 +0200
parents c50031ebc182
children f670c77eafcb
files src/lib/test-hash-method.c
diffstat 1 files changed, 302 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/test-hash-method.c	Sat Nov 05 11:48:27 2016 +0200
+++ b/src/lib/test-hash-method.c	Sat Nov 05 19:06:33 2016 +0200
@@ -32,7 +32,7 @@
 	test_end();
 }
 
-void test_hash_method(void)
+static void test_hash_method_boundary(void)
 {
 	unsigned int i;
 
@@ -49,3 +49,304 @@
 	for (i = 0; hash_methods[i] != NULL; i++)
 		test_hash_method_one(hash_methods[i]);
 }
+
+static void test_hash_methods_fips() {
+	const char *last_method = NULL;
+
+	struct {
+		const char *method;
+		const void *input;
+		size_t ilen;
+		size_t rounds;
+		const void *output;
+		size_t olen;
+	} test_vectors[] =
+	{
+		{ "md4",
+			"",
+			0,
+			1,
+			"\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31"
+			"\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0",
+			128 / 8
+		},
+		{ "md4",
+			"abc",
+			3,
+			1,
+			"\xa4\x48\x01\x7a\xaf\x21\xd8\x52"
+			"\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d",
+			128 / 8
+		},
+		{ "md4",
+			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
+			"ghijklmnopqrstuvwxyz0123456789",
+			62,
+			1,
+			"\x04\x3f\x85\x82\xf2\x41\xdb\x35"
+			"\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4",
+			128 / 8
+		},
+		{ "md5",
+			"",
+			0,
+			1,
+			"\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04"
+			"\xe9\x80\x09\x98\xec\xf8\x42\x7e",
+			128 / 8
+		},
+		{ "md5",
+			"abc",
+			3,
+			1,
+			"\x90\x01\x50\x98\x3c\xd2\x4f\xb0"
+			"\xd6\x96\x3f\x7d\x28\xe1\x7f\x72",
+			128 / 8
+		},
+		{ "md5",
+			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
+			"ghijklmnopqrstuvwxyz0123456789",
+			62,
+			1,
+			"\xd1\x74\xab\x98\xd2\x77\xd9\xf5"
+			"\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f",
+			128 / 8
+		},
+		{ "sha1",
+			"",
+			0,
+			1,
+			"\xda\x39\xa3\xee\x5e\x6b\x4b\x0d"
+			"\x32\x55\xbf\xef\x95\x60\x18\x90"
+			"\xaf\xd8\x07\x09",
+			160 / 8
+		},
+		{ "sha1",
+			"abc",
+			3,
+			1,
+			"\xa9\x99\x3e\x36\x47\x06\x81\x6a"
+			"\xba\x3e\x25\x71\x78\x50\xc2\x6c"
+			"\x9c\xd0\xd8\x9d",
+			160 / 8
+		},
+		{ "sha1",
+			"abcdbcdecdefdefgefghfghighijhijk"
+			"ijkljklmklmnlmnomnopnopq",
+			56,
+			1,
+			"\x84\x98\x3e\x44\x1c\x3b\xd2\x6e"
+			"\xba\xae\x4a\xa1\xf9\x51\x29\xe5"
+			"\xe5\x46\x70\xf1",
+			160 / 8
+		},
+		{ "sha3-256",
+			"",
+			0,
+			1,
+			"\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66"
+			"\x51\xc1\x47\x56\xa0\x61\xd6\x62"
+ 			"\xf5\x80\xff\x4d\xe4\x3b\x49\xfa"
+			"\x82\xd8\x0a\x4b\x80\xf8\x43\x4a",
+			256 / 8
+		},
+		{ "sha3-256",
+			"\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a"
+			"\x93\xd1\x56\x43\xd7\x18\x1d\x2a"
+			"\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f"
+			"\x20\xed\x21\xf1\x47\xbe\xf7\x32"
+			"\xbf\x3a\x60\xef\x40\x67\xc3\x73"
+			"\x4b\x85\xbc\x8c\xd4\x71\x78\x0f"
+			"\x10\xdc\x9e\x82\x91\xb5\x83\x39"
+			"\xa6\x77\xb9\x60\x21\x8f\x71\xe7"
+			"\x93\xf2\x79\x7a\xea\x34\x94\x06"
+			"\x51\x28\x29\x06\x5d\x37\xbb\x55"
+			"\xea\x79\x6f\xa4\xf5\x6f\xd8\x89"
+			"\x6b\x49\xb2\xcd\x19\xb4\x32\x15"
+			"\xad\x96\x7c\x71\x2b\x24\xe5\x03"
+			"\x2d\x06\x52\x32\xe0\x2c\x12\x74"
+			"\x09\xd2\xed\x41\x46\xb9\xd7\x5d"
+			"\x76\x3d\x52\xdb\x98\xd9\x49\xd3"
+			"\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+			1080 / 8,
+			1,
+			"\xa1\x9e\xee\x92\xbb\x20\x97\xb6"
+			"\x4e\x82\x3d\x59\x77\x98\xaa\x18"
+			"\xbe\x9b\x7c\x73\x6b\x80\x59\xab"
+			"\xfd\x67\x79\xac\x35\xac\x81\xb5",
+			256 / 8
+		},
+		{ "sha3-256",
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3",
+			200,
+			1,
+			"\x79\xf3\x8a\xde\xc5\xc2\x03\x07"
+			"\xa9\x8e\xf7\x6e\x83\x24\xaf\xbf"
+			"\xd4\x6c\xfd\x81\xb2\x2e\x39\x73"
+			"\xc6\x5f\xa1\xbd\x9d\xe3\x17\x87",
+			256 / 8,
+		},
+		{ "sha3-256",
+			"\xa3",
+			1,
+			200,
+			"\x79\xf3\x8a\xde\xc5\xc2\x03\x07"
+			"\xa9\x8e\xf7\x6e\x83\x24\xaf\xbf"
+			"\xd4\x6c\xfd\x81\xb2\x2e\x39\x73"
+			"\xc6\x5f\xa1\xbd\x9d\xe3\x17\x87",
+			256 / 8,
+		},
+		{ "sha3-512",
+			"",
+			0,
+			1,
+			"\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5"
+			"\xc8\xb5\x67\xdc\x18\x5a\x75\x6e"
+			"\x97\xc9\x82\x16\x4f\xe2\x58\x59"
+			"\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6"
+			"\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c"
+			"\x11\xe3\xe9\x40\x2c\x3a\xc5\x58"
+			"\xf5\x00\x19\x9d\x95\xb6\xd3\xe3"
+			"\x01\x75\x85\x86\x28\x1d\xcd\x26",
+			512 / 8
+		},
+		{ "sha3-512",
+			"\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a"
+			"\x93\xd1\x56\x43\xd7\x18\x1d\x2a"
+			"\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f"
+			"\x20\xed\x21\xf1\x47\xbe\xf7\x32"
+			"\xbf\x3a\x60\xef\x40\x67\xc3\x73"
+			"\x4b\x85\xbc\x8c\xd4\x71\x78\x0f"
+			"\x10\xdc\x9e\x82\x91\xb5\x83\x39"
+			"\xa6\x77\xb9\x60\x21\x8f\x71\xe7"
+			"\x93\xf2\x79\x7a\xea\x34\x94\x06"
+			"\x51\x28\x29\x06\x5d\x37\xbb\x55"
+			"\xea\x79\x6f\xa4\xf5\x6f\xd8\x89"
+			"\x6b\x49\xb2\xcd\x19\xb4\x32\x15"
+			"\xad\x96\x7c\x71\x2b\x24\xe5\x03"
+			"\x2d\x06\x52\x32\xe0\x2c\x12\x74"
+			"\x09\xd2\xed\x41\x46\xb9\xd7\x5d"
+			"\x76\x3d\x52\xdb\x98\xd9\x49\xd3"
+			"\xb0\xfe\xd6\xa8\x05\x2f\xbb",
+			1080 / 8,
+			1,
+			"\x75\x75\xa1\xfb\x4f\xc9\xa8\xf9"
+			"\xc0\x46\x6b\xd5\xfc\xa4\x96\xd1"
+			"\xcb\x78\x69\x67\x73\xa2\x12\xa5"
+			"\xf6\x2d\x02\xd1\x4e\x32\x59\xd1"
+			"\x92\xa8\x7e\xba\x44\x07\xdd\x83"
+			"\x89\x35\x27\x33\x14\x07\xb6\xda"
+			"\xda\xad\x92\x0d\xbc\x46\x48\x9b"
+			"\x67\x74\x93\xce\x5f\x20\xb5\x95",
+			512 / 8
+		},
+		{ "sha3-512",
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+			"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3",
+			200,
+			1,
+			"\xe7\x6d\xfa\xd2\x20\x84\xa8\xb1"
+			"\x46\x7f\xcf\x2f\xfa\x58\x36\x1b"
+			"\xec\x76\x28\xed\xf5\xf3\xfd\xc0"
+			"\xe4\x80\x5d\xc4\x8c\xae\xec\xa8"
+			"\x1b\x7c\x13\xc3\x0a\xdf\x52\xa3"
+			"\x65\x95\x84\x73\x9a\x2d\xf4\x6b"
+			"\xe5\x89\xc5\x1c\xa1\xa4\xa8\x41"
+			"\x6d\xf6\x54\x5a\x1c\xe8\xba\x00",
+			512 / 8,
+		},
+		{ "sha3-512",
+			"\xa3",
+			1,
+			200,
+			"\xe7\x6d\xfa\xd2\x20\x84\xa8\xb1"
+			"\x46\x7f\xcf\x2f\xfa\x58\x36\x1b"
+			"\xec\x76\x28\xed\xf5\xf3\xfd\xc0"
+			"\xe4\x80\x5d\xc4\x8c\xae\xec\xa8"
+			"\x1b\x7c\x13\xc3\x0a\xdf\x52\xa3"
+			"\x65\x95\x84\x73\x9a\x2d\xf4\x6b"
+			"\xe5\x89\xc5\x1c\xa1\xa4\xa8\x41"
+			"\x6d\xf6\x54\x5a\x1c\xe8\xba\x00",
+			512 / 8,
+		},
+	};
+
+	for(size_t i = 0; i < N_ELEMENTS(test_vectors); i++) {
+
+		if (last_method == NULL ||
+		    strcmp(last_method, test_vectors[i].method) != 0) {
+			if (last_method != NULL)
+				test_end();
+			last_method = test_vectors[i].method;
+			test_begin(t_strdup_printf("hash method %s (test vectors)",
+				   last_method));
+		}
+		const struct hash_method *method =
+			hash_method_lookup(test_vectors[i].method);
+		unsigned char context[method->context_size];
+		unsigned char result[method->digest_size];
+		test_assert_idx(method->digest_size == test_vectors[i].olen, i);
+		method->init(context);
+		for(size_t n = 0; n < test_vectors[i].rounds; n++)
+			method->loop(context, test_vectors[i].input,
+				     test_vectors[i].ilen);
+		method->result(context, result);
+		test_assert_idx(memcmp(result, test_vectors[i].output,
+				       test_vectors[i].olen) == 0, i);
+	}
+
+	test_end();
+}
+
+void test_hash_method(void)
+{
+	test_hash_method_boundary();
+	test_hash_methods_fips();
+}