xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/cmd/checksum/sha2_test.c (revision bc7512cc58af2e8bbe5bbf5ca0059b1daa1da897)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://opensource.org/licenses/CDDL-1.0.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2013 Saso Kiselkov. All rights reserved.
24  */
25 
26 /*
27  * This is just to keep the compiler happy about sys/time.h not declaring
28  * gettimeofday due to -D_KERNEL (we can do this since we're actually
29  * running in userspace, but we need -D_KERNEL for the remaining SHA2 code).
30  */
31 #ifdef	_KERNEL
32 #undef	_KERNEL
33 #endif
34 
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <sys/time.h>
40 #define	_SHA2_IMPL
41 #include <sys/sha2.h>
42 #include <sys/stdtypes.h>
43 
44 
45 /*
46  * Test messages from:
47  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
48  */
49 
50 const char	*test_msg0 = "abc";
51 const char	*test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn"
52 	"lmnomnopnopq";
53 const char	*test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
54 	"jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
55 
56 /*
57  * Test digests from:
58  * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
59  */
60 const uint8_t	sha256_test_digests[][32] = {
61 	{
62 		/* for test_msg0 */
63 		0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
64 		0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
65 		0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
66 		0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD
67 	},
68 	{
69 		/* for test_msg1 */
70 		0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
71 		0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
72 		0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
73 		0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1
74 	}
75 	/* no test vector for test_msg2 */
76 };
77 
78 const uint8_t	sha384_test_digests[][48] = {
79 	{
80 		/* for test_msg0 */
81 		0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
82 		0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
83 		0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
84 		0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
85 		0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
86 		0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7
87 	},
88 	{
89 		/* no test vector for test_msg1 */
90 		0
91 	},
92 	{
93 		/* for test_msg2 */
94 		0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
95 		0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
96 		0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
97 		0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
98 		0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
99 		0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39
100 	}
101 };
102 
103 const uint8_t	sha512_test_digests[][64] = {
104 	{
105 		/* for test_msg0 */
106 		0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
107 		0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
108 		0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
109 		0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
110 		0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
111 		0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
112 		0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
113 		0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F
114 	},
115 	{
116 		/* no test vector for test_msg1 */
117 		0
118 	},
119 	{
120 		/* for test_msg2 */
121 		0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
122 		0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
123 		0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
124 		0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
125 		0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
126 		0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
127 		0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
128 		0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09
129 	}
130 };
131 
132 const uint8_t	sha512_224_test_digests[][28] = {
133 	{
134 		/* for test_msg0 */
135 		0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54,
136 		0xDA, 0xAE, 0x75, 0x30, 0x46, 0x08, 0x42, 0xE2,
137 		0x0E, 0x37, 0xED, 0x26, 0x5C, 0xEE, 0xE9, 0xA4,
138 		0x3E, 0x89, 0x24, 0xAA
139 	},
140 	{
141 		/* no test vector for test_msg1 */
142 		0
143 	},
144 	{
145 		/* for test_msg2 */
146 		0x23, 0xFE, 0xC5, 0xBB, 0x94, 0xD6, 0x0B, 0x23,
147 		0x30, 0x81, 0x92, 0x64, 0x0B, 0x0C, 0x45, 0x33,
148 		0x35, 0xD6, 0x64, 0x73, 0x4F, 0xE4, 0x0E, 0x72,
149 		0x68, 0x67, 0x4A, 0xF9
150 	}
151 };
152 
153 const uint8_t	sha512_256_test_digests[][32] = {
154 	{
155 		/* for test_msg0 */
156 		0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9,
157 		0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB,
158 		0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46,
159 		0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23
160 	},
161 	{
162 		/* no test vector for test_msg1 */
163 		0
164 	},
165 	{
166 		/* for test_msg2 */
167 		0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8,
168 		0x40, 0xDA, 0x39, 0x88, 0x12, 0x1D, 0x31, 0xBE,
169 		0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14,
170 		0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A
171 	}
172 };
173 
174 int
175 main(int argc, char *argv[])
176 {
177 	boolean_t	failed = B_FALSE;
178 	uint64_t	cpu_mhz = 0;
179 
180 	if (argc == 2)
181 		cpu_mhz = atoi(argv[1]);
182 
183 #define	SHA2_ALGO_TEST(_m, mode, diglen, testdigest)			\
184 	do {								\
185 		SHA2_CTX		ctx;				\
186 		uint8_t			digest[diglen / 8];		\
187 		SHA2Init(SHA ## mode ## _MECH_INFO_TYPE, &ctx);		\
188 		SHA2Update(&ctx, _m, strlen(_m));			\
189 		SHA2Final(digest, &ctx);				\
190 		(void) printf("SHA%-9sMessage: " #_m			\
191 		    "\tResult: ", #mode);				\
192 		if (memcmp(digest, testdigest, diglen / 8) == 0) {	\
193 			(void) printf("OK\n");				\
194 		} else {						\
195 			(void) printf("FAILED!\n");			\
196 			failed = B_TRUE;				\
197 		}							\
198 	} while (0)
199 
200 #define	SHA2_PERF_TEST(mode, diglen)					\
201 	do {								\
202 		SHA2_CTX	ctx;					\
203 		uint8_t		digest[diglen / 8];			\
204 		uint8_t		block[131072];				\
205 		uint64_t	delta;					\
206 		double		cpb = 0;				\
207 		int		i;					\
208 		struct timeval	start, end;				\
209 		memset(block, 0, sizeof (block));			\
210 		(void) gettimeofday(&start, NULL);			\
211 		SHA2Init(SHA ## mode ## _MECH_INFO_TYPE, &ctx);		\
212 		for (i = 0; i < 8192; i++)				\
213 			SHA2Update(&ctx, block, sizeof (block));	\
214 		SHA2Final(digest, &ctx);				\
215 		(void) gettimeofday(&end, NULL);			\
216 		delta = (end.tv_sec * 1000000llu + end.tv_usec) -	\
217 		    (start.tv_sec * 1000000llu + start.tv_usec);	\
218 		if (cpu_mhz != 0) {					\
219 			cpb = (cpu_mhz * 1e6 * ((double)delta /		\
220 			    1000000)) / (8192 * 128 * 1024);		\
221 		}							\
222 		(void) printf("SHA%-9s%llu us (%.02f CPB)\n", #mode,	\
223 		    (u_longlong_t)delta, cpb);				\
224 	} while (0)
225 
226 	(void) printf("Running algorithm correctness tests:\n");
227 	SHA2_ALGO_TEST(test_msg0, 256, 256, sha256_test_digests[0]);
228 	SHA2_ALGO_TEST(test_msg1, 256, 256, sha256_test_digests[1]);
229 	SHA2_ALGO_TEST(test_msg0, 384, 384, sha384_test_digests[0]);
230 	SHA2_ALGO_TEST(test_msg2, 384, 384, sha384_test_digests[2]);
231 	SHA2_ALGO_TEST(test_msg0, 512, 512, sha512_test_digests[0]);
232 	SHA2_ALGO_TEST(test_msg2, 512, 512, sha512_test_digests[2]);
233 	SHA2_ALGO_TEST(test_msg0, 512_224, 224, sha512_224_test_digests[0]);
234 	SHA2_ALGO_TEST(test_msg2, 512_224, 224, sha512_224_test_digests[2]);
235 	SHA2_ALGO_TEST(test_msg0, 512_256, 256, sha512_256_test_digests[0]);
236 	SHA2_ALGO_TEST(test_msg2, 512_256, 256, sha512_256_test_digests[2]);
237 
238 	if (failed)
239 		return (1);
240 
241 	(void) printf("Running performance tests (hashing 1024 MiB of "
242 	    "data):\n");
243 	SHA2_PERF_TEST(256, 256);
244 	SHA2_PERF_TEST(512, 512);
245 
246 	return (0);
247 }
248