145818ee1SMatthew Ahrens /*
245818ee1SMatthew Ahrens  * CDDL HEADER START
345818ee1SMatthew Ahrens  *
445818ee1SMatthew Ahrens  * The contents of this file are subject to the terms of the
545818ee1SMatthew Ahrens  * Common Development and Distribution License (the "License").
645818ee1SMatthew Ahrens  * You may not use this file except in compliance with the License.
745818ee1SMatthew Ahrens  *
845818ee1SMatthew Ahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
945818ee1SMatthew Ahrens  * or http://opensource.org/licenses/CDDL-1.0.
1045818ee1SMatthew Ahrens  * See the License for the specific language governing permissions
1145818ee1SMatthew Ahrens  * and limitations under the License.
1245818ee1SMatthew Ahrens  *
1345818ee1SMatthew Ahrens  * When distributing Covered Code, include this CDDL HEADER in each
1445818ee1SMatthew Ahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1545818ee1SMatthew Ahrens  * If applicable, add the following below this CDDL HEADER, with the
1645818ee1SMatthew Ahrens  * fields enclosed by brackets "[]" replaced with your own identifying
1745818ee1SMatthew Ahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
1845818ee1SMatthew Ahrens  *
1945818ee1SMatthew Ahrens  * CDDL HEADER END
2045818ee1SMatthew Ahrens  */
2145818ee1SMatthew Ahrens 
2245818ee1SMatthew Ahrens /*
2345818ee1SMatthew Ahrens  * Copyright 2013 Saso Kiselkov. All rights reserved.
2445818ee1SMatthew Ahrens  */
2545818ee1SMatthew Ahrens 
2645818ee1SMatthew Ahrens /*
2745818ee1SMatthew Ahrens  * This is just to keep the compiler happy about sys/time.h not declaring
2845818ee1SMatthew Ahrens  * gettimeofday due to -D_KERNEL (we can do this since we're actually
2945818ee1SMatthew Ahrens  * running in userspace, but we need -D_KERNEL for the remaining SHA2 code).
3045818ee1SMatthew Ahrens  */
3145818ee1SMatthew Ahrens #ifdef	_KERNEL
3245818ee1SMatthew Ahrens #undef	_KERNEL
3345818ee1SMatthew Ahrens #endif
3445818ee1SMatthew Ahrens 
3545818ee1SMatthew Ahrens #include <sys/varargs.h>
3645818ee1SMatthew Ahrens #include <stdlib.h>
3745818ee1SMatthew Ahrens #include <strings.h>
3845818ee1SMatthew Ahrens #include <stdio.h>
3945818ee1SMatthew Ahrens #include <sys/time.h>
4045818ee1SMatthew Ahrens #define	_SHA2_IMPL
4145818ee1SMatthew Ahrens #include <sys/sha2.h>
4245818ee1SMatthew Ahrens #include <note.h>
4345818ee1SMatthew Ahrens 
4445818ee1SMatthew Ahrens /*
4545818ee1SMatthew Ahrens  * Test messages from:
4645818ee1SMatthew Ahrens  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
4745818ee1SMatthew Ahrens  */
4845818ee1SMatthew Ahrens 
4945818ee1SMatthew Ahrens const char	*test_msg0 = "abc";
5045818ee1SMatthew Ahrens const char	*test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn"
5145818ee1SMatthew Ahrens 	"lmnomnopnopq";
5245818ee1SMatthew Ahrens const char	*test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
5345818ee1SMatthew Ahrens 	"jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
5445818ee1SMatthew Ahrens 
5545818ee1SMatthew Ahrens /*
5645818ee1SMatthew Ahrens  * Test digests from:
5745818ee1SMatthew Ahrens  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
5845818ee1SMatthew Ahrens  */
5945818ee1SMatthew Ahrens const uint8_t	sha256_test_digests[][32] = {
6045818ee1SMatthew Ahrens 	{
6145818ee1SMatthew Ahrens 		/* for test_msg0 */
6245818ee1SMatthew Ahrens 		0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
6345818ee1SMatthew Ahrens 		0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
6445818ee1SMatthew Ahrens 		0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
6545818ee1SMatthew Ahrens 		0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD
6645818ee1SMatthew Ahrens 	},
6745818ee1SMatthew Ahrens 	{
6845818ee1SMatthew Ahrens 		/* for test_msg1 */
6945818ee1SMatthew Ahrens 		0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
7045818ee1SMatthew Ahrens 		0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
7145818ee1SMatthew Ahrens 		0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
7245818ee1SMatthew Ahrens 		0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1
7345818ee1SMatthew Ahrens 	}
7445818ee1SMatthew Ahrens 	/* no test vector for test_msg2 */
7545818ee1SMatthew Ahrens };
7645818ee1SMatthew Ahrens 
7745818ee1SMatthew Ahrens const uint8_t	sha384_test_digests[][48] = {
7845818ee1SMatthew Ahrens 	{
7945818ee1SMatthew Ahrens 		/* for test_msg0 */
8045818ee1SMatthew Ahrens 		0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
8145818ee1SMatthew Ahrens 		0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
8245818ee1SMatthew Ahrens 		0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
8345818ee1SMatthew Ahrens 		0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
8445818ee1SMatthew Ahrens 		0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
8545818ee1SMatthew Ahrens 		0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7
8645818ee1SMatthew Ahrens 	},
8745818ee1SMatthew Ahrens 	{
8845818ee1SMatthew Ahrens 		/* no test vector for test_msg1 */
89*0c3cd038SMatthew Ahrens 		0
9045818ee1SMatthew Ahrens 	},
9145818ee1SMatthew Ahrens 	{
9245818ee1SMatthew Ahrens 		/* for test_msg2 */
9345818ee1SMatthew Ahrens 		0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
9445818ee1SMatthew Ahrens 		0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
9545818ee1SMatthew Ahrens 		0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
9645818ee1SMatthew Ahrens 		0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
9745818ee1SMatthew Ahrens 		0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
9845818ee1SMatthew Ahrens 		0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39
9945818ee1SMatthew Ahrens 	}
10045818ee1SMatthew Ahrens };
10145818ee1SMatthew Ahrens 
10245818ee1SMatthew Ahrens const uint8_t	sha512_test_digests[][64] = {
10345818ee1SMatthew Ahrens 	{
10445818ee1SMatthew Ahrens 		/* for test_msg0 */
10545818ee1SMatthew Ahrens 		0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
10645818ee1SMatthew Ahrens 		0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
10745818ee1SMatthew Ahrens 		0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
10845818ee1SMatthew Ahrens 		0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
10945818ee1SMatthew Ahrens 		0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
11045818ee1SMatthew Ahrens 		0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
11145818ee1SMatthew Ahrens 		0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
11245818ee1SMatthew Ahrens 		0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F
11345818ee1SMatthew Ahrens 	},
11445818ee1SMatthew Ahrens 	{
11545818ee1SMatthew Ahrens 		/* no test vector for test_msg1 */
116*0c3cd038SMatthew Ahrens 		0
11745818ee1SMatthew Ahrens 	},
11845818ee1SMatthew Ahrens 	{
11945818ee1SMatthew Ahrens 		/* for test_msg2 */
12045818ee1SMatthew Ahrens 		0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
12145818ee1SMatthew Ahrens 		0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
12245818ee1SMatthew Ahrens 		0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
12345818ee1SMatthew Ahrens 		0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
12445818ee1SMatthew Ahrens 		0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
12545818ee1SMatthew Ahrens 		0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
12645818ee1SMatthew Ahrens 		0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
12745818ee1SMatthew Ahrens 		0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09
12845818ee1SMatthew Ahrens 	}
12945818ee1SMatthew Ahrens };
13045818ee1SMatthew Ahrens 
13145818ee1SMatthew Ahrens const uint8_t	sha512_224_test_digests[][28] = {
13245818ee1SMatthew Ahrens 	{
13345818ee1SMatthew Ahrens 		/* for test_msg0 */
13445818ee1SMatthew Ahrens 		0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54,
13545818ee1SMatthew Ahrens 		0xDA, 0xAE, 0x75, 0x30, 0x46, 0x08, 0x42, 0xE2,
13645818ee1SMatthew Ahrens 		0x0E, 0x37, 0xED, 0x26, 0x5C, 0xEE, 0xE9, 0xA4,
13745818ee1SMatthew Ahrens 		0x3E, 0x89, 0x24, 0xAA
13845818ee1SMatthew Ahrens 	},
13945818ee1SMatthew Ahrens 	{
14045818ee1SMatthew Ahrens 		/* no test vector for test_msg1 */
141*0c3cd038SMatthew Ahrens 		0
14245818ee1SMatthew Ahrens 	},
14345818ee1SMatthew Ahrens 	{
14445818ee1SMatthew Ahrens 		/* for test_msg2 */
14545818ee1SMatthew Ahrens 		0x23, 0xFE, 0xC5, 0xBB, 0x94, 0xD6, 0x0B, 0x23,
14645818ee1SMatthew Ahrens 		0x30, 0x81, 0x92, 0x64, 0x0B, 0x0C, 0x45, 0x33,
14745818ee1SMatthew Ahrens 		0x35, 0xD6, 0x64, 0x73, 0x4F, 0xE4, 0x0E, 0x72,
14845818ee1SMatthew Ahrens 		0x68, 0x67, 0x4A, 0xF9
14945818ee1SMatthew Ahrens 	}
15045818ee1SMatthew Ahrens };
15145818ee1SMatthew Ahrens 
15245818ee1SMatthew Ahrens const uint8_t	sha512_256_test_digests[][32] = {
15345818ee1SMatthew Ahrens 	{
15445818ee1SMatthew Ahrens 		/* for test_msg0 */
15545818ee1SMatthew Ahrens 		0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9,
15645818ee1SMatthew Ahrens 		0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB,
15745818ee1SMatthew Ahrens 		0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46,
15845818ee1SMatthew Ahrens 		0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23
15945818ee1SMatthew Ahrens 	},
16045818ee1SMatthew Ahrens 	{
16145818ee1SMatthew Ahrens 		/* no test vector for test_msg1 */
162*0c3cd038SMatthew Ahrens 		0
16345818ee1SMatthew Ahrens 	},
16445818ee1SMatthew Ahrens 	{
16545818ee1SMatthew Ahrens 		/* for test_msg2 */
16645818ee1SMatthew Ahrens 		0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8,
16745818ee1SMatthew Ahrens 		0x40, 0xDA, 0x39, 0x88, 0x12, 0x1D, 0x31, 0xBE,
16845818ee1SMatthew Ahrens 		0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14,
16945818ee1SMatthew Ahrens 		0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A
17045818ee1SMatthew Ahrens 	}
17145818ee1SMatthew Ahrens };
17245818ee1SMatthew Ahrens 
17345818ee1SMatthew Ahrens /*
17445818ee1SMatthew Ahrens  * Local reimplementation of cmn_err, since it's used in sha2.c.
17545818ee1SMatthew Ahrens  */
17645818ee1SMatthew Ahrens /*ARGSUSED*/
17745818ee1SMatthew Ahrens void
cmn_err(int level,char * format,...)17845818ee1SMatthew Ahrens cmn_err(int level, char *format, ...)
17945818ee1SMatthew Ahrens {
18045818ee1SMatthew Ahrens 	va_list ap;
18145818ee1SMatthew Ahrens 	va_start(ap, format);
18245818ee1SMatthew Ahrens 	/* LINTED: E_SEC_PRINTF_VAR_FMT */
18345818ee1SMatthew Ahrens 	(void) vfprintf(stderr, format, ap);
18445818ee1SMatthew Ahrens 	va_end(ap);
18545818ee1SMatthew Ahrens }
18645818ee1SMatthew Ahrens 
18745818ee1SMatthew Ahrens int
main(int argc,char * argv[])18845818ee1SMatthew Ahrens main(int argc, char *argv[])
18945818ee1SMatthew Ahrens {
19045818ee1SMatthew Ahrens 	boolean_t	failed = B_FALSE;
19145818ee1SMatthew Ahrens 	uint64_t	cpu_mhz = 0;
19245818ee1SMatthew Ahrens 
19345818ee1SMatthew Ahrens 	if (argc == 2)
19445818ee1SMatthew Ahrens 		cpu_mhz = atoi(argv[1]);
19545818ee1SMatthew Ahrens 
19645818ee1SMatthew Ahrens #define	SHA2_ALGO_TEST(_m, mode, diglen, testdigest)			\
19745818ee1SMatthew Ahrens 	do {								\
19845818ee1SMatthew Ahrens 		SHA2_CTX		ctx;				\
19945818ee1SMatthew Ahrens 		uint8_t			digest[diglen / 8];		\
20045818ee1SMatthew Ahrens 		SHA2Init(SHA ## mode ## _MECH_INFO_TYPE, &ctx);		\
20145818ee1SMatthew Ahrens 		SHA2Update(&ctx, _m, strlen(_m));			\
20245818ee1SMatthew Ahrens 		SHA2Final(digest, &ctx);				\
20345818ee1SMatthew Ahrens 		(void) printf("SHA%-9sMessage: " #_m			\
20445818ee1SMatthew Ahrens 		    "\tResult: ", #mode);				\
20545818ee1SMatthew Ahrens 		if (bcmp(digest, testdigest, diglen / 8) == 0) {	\
20645818ee1SMatthew Ahrens 			(void) printf("OK\n");				\
20745818ee1SMatthew Ahrens 		} else {						\
20845818ee1SMatthew Ahrens 			(void) printf("FAILED!\n");			\
20945818ee1SMatthew Ahrens 			failed = B_TRUE;				\
21045818ee1SMatthew Ahrens 		}							\
21145818ee1SMatthew Ahrens 		NOTE(CONSTCOND)						\
21245818ee1SMatthew Ahrens 	} while (0)
21345818ee1SMatthew Ahrens 
21445818ee1SMatthew Ahrens #define	SHA2_PERF_TEST(mode, diglen)					\
21545818ee1SMatthew Ahrens 	do {								\
21645818ee1SMatthew Ahrens 		SHA2_CTX	ctx;					\
21745818ee1SMatthew Ahrens 		uint8_t		digest[diglen / 8];			\
21845818ee1SMatthew Ahrens 		uint8_t		block[131072];				\
21945818ee1SMatthew Ahrens 		uint64_t	delta;					\
22045818ee1SMatthew Ahrens 		double		cpb = 0;				\
22145818ee1SMatthew Ahrens 		int		i;					\
22245818ee1SMatthew Ahrens 		struct timeval	start, end;				\
22345818ee1SMatthew Ahrens 		bzero(block, sizeof (block));				\
22445818ee1SMatthew Ahrens 		(void) gettimeofday(&start, NULL);			\
22545818ee1SMatthew Ahrens 		SHA2Init(SHA ## mode ## _MECH_INFO_TYPE, &ctx);		\
22645818ee1SMatthew Ahrens 		for (i = 0; i < 8192; i++)				\
22745818ee1SMatthew Ahrens 			SHA2Update(&ctx, block, sizeof (block));	\
22845818ee1SMatthew Ahrens 		SHA2Final(digest, &ctx);				\
22945818ee1SMatthew Ahrens 		(void) gettimeofday(&end, NULL);			\
23045818ee1SMatthew Ahrens 		delta = (end.tv_sec * 1000000llu + end.tv_usec) -	\
23145818ee1SMatthew Ahrens 		    (start.tv_sec * 1000000llu + start.tv_usec);	\
23245818ee1SMatthew Ahrens 		if (cpu_mhz != 0) {					\
23345818ee1SMatthew Ahrens 			cpb = (cpu_mhz * 1e6 * ((double)delta /		\
23445818ee1SMatthew Ahrens 			    1000000)) / (8192 * 128 * 1024);		\
23545818ee1SMatthew Ahrens 		}							\
23645818ee1SMatthew Ahrens 		(void) printf("SHA%-9s%llu us (%.02f CPB)\n", #mode,	\
23745818ee1SMatthew Ahrens 		    (u_longlong_t)delta, cpb);				\
23845818ee1SMatthew Ahrens 		NOTE(CONSTCOND)						\
23945818ee1SMatthew Ahrens 	} while (0)
24045818ee1SMatthew Ahrens 
24145818ee1SMatthew Ahrens 	(void) printf("Running algorithm correctness tests:\n");
24245818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg0, 256, 256, sha256_test_digests[0]);
24345818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg1, 256, 256, sha256_test_digests[1]);
24445818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg0, 384, 384, sha384_test_digests[0]);
24545818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg2, 384, 384, sha384_test_digests[2]);
24645818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg0, 512, 512, sha512_test_digests[0]);
24745818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg2, 512, 512, sha512_test_digests[2]);
24845818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg0, 512_224, 224, sha512_224_test_digests[0]);
24945818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg2, 512_224, 224, sha512_224_test_digests[2]);
25045818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg0, 512_256, 256, sha512_256_test_digests[0]);
25145818ee1SMatthew Ahrens 	SHA2_ALGO_TEST(test_msg2, 512_256, 256, sha512_256_test_digests[2]);
25245818ee1SMatthew Ahrens 
25345818ee1SMatthew Ahrens 	if (failed)
25445818ee1SMatthew Ahrens 		return (1);
25545818ee1SMatthew Ahrens 
25645818ee1SMatthew Ahrens 	(void) printf("Running performance tests (hashing 1024 MiB of "
25745818ee1SMatthew Ahrens 	    "data):\n");
25845818ee1SMatthew Ahrens 	SHA2_PERF_TEST(256, 256);
25945818ee1SMatthew Ahrens 	SHA2_PERF_TEST(512, 512);
26045818ee1SMatthew Ahrens 
26145818ee1SMatthew Ahrens 	return (0);
26245818ee1SMatthew Ahrens }
263