1/*
2 * Copyright (c) 2011 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <sys/types.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <getopt.h>
29
30#include "ossl-evp.h"
31#include "ossl-evp-cc.h"
32
33#include "test_common.h"
34
35static int verbose = 1;
36
37static int total = 0;
38static int pass = 0;
39static int fail = 0;
40
41/*
42 *  Digest Test Engine.
43 */
44
45typedef const EVP_MD * (*evp_alg_t)(void);
46
47static int
48_test_digest(evp_alg_t alg, stringVector_t *msg[], byteVector_t *md[], const size_t num_tests)
49{
50	size_t i;
51	int rv = 0;
52	EVP_MD_CTX *ctx;
53	const EVP_MD *evp_md = (*alg)();
54	uint8_t buf[EVP_MD_size(evp_md)];
55
56	for (i = 0; i < num_tests; i++) {
57		if (NULL == md[i] || NULL == msg[i] || EVP_MD_size(evp_md) != md[i]->len) {
58			if (verbose) printf("Parameter error\n");
59			return (1);
60		}
61		ctx = EVP_MD_CTX_create();
62		if (NULL == ctx) {
63			if (verbose) printf("EVP_MD_create() failed\n");
64			return (1);
65		}
66		rv = EVP_DigestInit_ex(ctx, evp_md, NULL);
67		if (rv != 1) {
68			if (verbose) printf("EVP_DigestInit_ex() failed\n");
69			EVP_MD_CTX_destroy(ctx);
70			return (1);
71		}
72		rv = EVP_DigestUpdate(ctx, (const void *)msg[i]->value, msg[i]->len);
73		if (rv != 1) {
74			if (verbose) printf("EVP_DigestUpdate() failed\n");
75			EVP_MD_CTX_destroy(ctx);
76			return (1);
77		}
78		unsigned buf_size = (unsigned)EVP_MD_block_size(evp_md);
79		rv = EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &buf_size);
80		EVP_MD_CTX_destroy(ctx);
81		if (rv != 1) {
82			if (verbose) printf("EVP_DigestFinal_ex() failed\n");
83			return (1);
84		}
85		if ((buf_size != EVP_MD_size(evp_md)) ||
86		    (memcmp(buf, md[i]->value, (size_t)buf_size) != 0)) {
87			if (verbose) printf("Result doesn't match vector (%u)\n", (unsigned)i);
88			return (1);
89		}
90	}
91	return (0);
92}
93
94/*
95 * DIGEST_MSG() is for the message (string) to digest.
96 * DIGEST_MD() is for the message digest (in hex).
97 * Parameters: (<Digest Name>, <vector #>, <vector len> <vector data: string or hex numbers>)
98 */
99#define	DIGEST_MSG(NAME, N, VALUE)		static stringVector_t	NAME ## _digest_msg_ ## N =  \
100							{ sizeof(VALUE)-1, VALUE };
101#define	DIGEST_MD(NAME, N, LEN, VALUE...)	static byteVector_t	NAME ## _digest_md_ ## N = \
102							{ LEN, { VALUE } };
103
104/*
105 * DIGEST_TEST() generates the testing code stub.
106 * Parameters: (<Digest Name>, <Number of test vectors>)
107 */
108#define	DIGEST_TEST(ALG_NAME, NUM_TESTS) 						\
109static stringVector_t * ALG_NAME ## _digest_msg_vects[] =				\
110	{ ARRAY_FOR_ ## NUM_TESTS (& ALG_NAME ## _digest_msg_ ) NULL };			\
111											\
112static byteVector_t * ALG_NAME ## _digest_md_vects[] =					\
113	{ ARRAY_FOR_ ## NUM_TESTS (& ALG_NAME ## _digest_md_ ) NULL };			\
114											\
115static int testDigest_ ## ALG_NAME(void) {						\
116	return (_test_digest(EVP_ ## ALG_NAME , 	\
117		ALG_NAME ## _digest_msg_vects, ALG_NAME ## _digest_md_vects, NUM_TESTS));\
118}
119
120/*
121 * MD2 digest test vectors.
122 */
123DIGEST_MSG(md2, 0,	"")
124DIGEST_MD(md2,  0, 16,	0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
125			0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73)
126
127DIGEST_MSG(md2, 1,	"a")
128DIGEST_MD(md2,  1, 16,	0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
129			0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1)
130
131DIGEST_MSG(md2, 2,	"message digest")
132DIGEST_MD(md2,  2, 16,	0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
133			0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0)
134
135DIGEST_MSG(md2, 3,	"abcdefghijklmnopqrstuvwxyz")
136DIGEST_MD(md2,  3, 16,	0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
137			0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b)
138
139DIGEST_MSG(md2, 4,	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl"
140			"mnopqrstuvwxyz0123456789")
141DIGEST_MD(md2,  4, 16,	0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
142			0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd)
143
144DIGEST_MSG(md2, 5,	"123456789012345678901234567890123456789"
145			"01234567890123456789012345678901234567890")
146DIGEST_MD(md2,  5, 16,	0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
147			0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8)
148
149DIGEST_TEST(md2, 6)
150
151/*
152 * MD4 digest test vectors.
153 */
154DIGEST_MSG(md4, 0,	"")
155DIGEST_MD(md4,  0, 16,	0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
156			0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0)
157
158DIGEST_MSG(md4, 1,	"a")
159DIGEST_MD(md4,  1, 16,	0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
160			0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24)
161
162DIGEST_MSG(md4, 2,	"abc")
163DIGEST_MD(md4,  2, 16,	0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
164			0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d)
165
166DIGEST_MSG(md4, 3,	"message digest")
167DIGEST_MD(md4,  3, 16,	0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
168			0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b)
169
170DIGEST_MSG(md4, 4,	"abcdefghijklmnopqrstuvwxyz")
171DIGEST_MD(md4,  4, 16,	0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
172			0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9)
173
174DIGEST_MSG(md4, 5,	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst"
175			"uvwxyz0123456789")
176DIGEST_MD(md4,  5, 16,	0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
177			0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4)
178
179DIGEST_MSG(md4, 6,	"1234567890123456789012345678901234567890123456789"
180			"0123456789012345678901234567890")
181DIGEST_MD(md4,  6, 16,	0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
182			0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36)
183
184DIGEST_TEST(md4, 7)
185
186/*
187 * MD5 digest test vectors.
188 */
189DIGEST_MSG(md5, 0,	"")
190DIGEST_MD(md5,  0, 16,	0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
191			0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e)
192
193DIGEST_MSG(md5, 1,	"a")
194DIGEST_MD(md5,  1, 16,	0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
195			0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61)
196
197DIGEST_MSG(md5, 2,	"abc")
198DIGEST_MD(md5,  2, 16,	0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
199			0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72)
200
201DIGEST_MSG(md5, 3,	"message digest")
202DIGEST_MD(md5,  3, 16,	0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
203			0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0)
204
205DIGEST_MSG(md5, 4,	"abcdefghijklmnopqrstuvwxyz")
206DIGEST_MD(md5,  4, 16,	0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
207			0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b)
208
209DIGEST_MSG(md5, 5,	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst"
210			"uvwxyz0123456789")
211DIGEST_MD(md5,  5, 16,	0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
212			0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f)
213
214DIGEST_MSG(md5, 6,	"1234567890123456789012345678901234567890123456789"
215			"0123456789012345678901234567890")
216DIGEST_MD(md5,  6, 16,	0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
217			0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a)
218
219DIGEST_TEST(md5, 7)
220
221/*
222 * RMD128 digest test vectors.
223 */
224DIGEST_MSG(rmd128, 0,	"")
225DIGEST_MD(rmd128,  0, 16, 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
226			  0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46)
227
228DIGEST_MSG(rmd128, 1,	"a")
229DIGEST_MD(rmd128,  1, 16, 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
230			  0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33)
231
232DIGEST_MSG(rmd128, 2,	"abc")
233DIGEST_MD(rmd128,  2, 16, 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
234			  0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77)
235
236DIGEST_MSG(rmd128, 3,	"message digest")
237DIGEST_MD(rmd128,  3, 16, 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
238			  0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8)
239
240DIGEST_MSG(rmd128, 4,	"abcdefghijklmnopqrstuvwxyz")
241DIGEST_MD(rmd128,  4, 16, 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
242			  0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e)
243
244DIGEST_MSG(rmd128, 5,	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst"
245			"uvwxyz0123456789")
246DIGEST_MD(rmd128,  5, 16, 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
247			  0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02)
248
249DIGEST_TEST(rmd128, 6)
250
251/*
252 * RMD160 digest test vectors.
253 */
254DIGEST_MSG(rmd160, 0,	"")
255DIGEST_MD(rmd160,  0, 20, 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54,
256			  0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48,
257			  0xb2, 0x25, 0x8d, 0x31)
258
259DIGEST_MSG(rmd160, 1,	"a")
260DIGEST_MD(rmd160,  1, 20, 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9,
261			  0xda, 0xae, 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83,
262			  0x5a, 0x46, 0x7f, 0xfe)
263
264DIGEST_MSG(rmd160, 2, "abc")
265DIGEST_MD(rmd160,  2, 20, 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a,
266			  0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87,
267			  0xf1, 0x5a, 0x0b, 0xfc)
268
269DIGEST_MSG(rmd160, 3,	"message digest")
270DIGEST_MD(rmd160,  3, 20, 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5,
271			  0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa,
272			  0x21, 0x59, 0x5f, 0x36)
273
274DIGEST_MSG(rmd160, 4,	"abcdefghijklmnopqrstuvwxyz")
275DIGEST_MD(rmd160,  4, 20, 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b,
276			  0x56, 0xbb, 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65,
277			  0xb3, 0x70, 0x8d, 0xbc)
278
279DIGEST_MSG(rmd160, 5,	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
280DIGEST_MD(rmd160,  5, 20, 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88,
281			  0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a,
282			  0xda, 0x62, 0xeb, 0x2b)
283
284DIGEST_TEST(rmd160, 6)
285
286/*
287 * RMD256 digest test vectors.
288 */
289DIGEST_MSG(rmd256, 0,	"")
290DIGEST_MD(rmd256,  0, 32, 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18,
291			  0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a,
292			  0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63,
293			  0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d)
294
295DIGEST_MSG(rmd256, 1,	"a")
296DIGEST_MD(rmd256,  1, 32, 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9,
297			  0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c,
298			  0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf,
299			  0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25)
300
301DIGEST_MSG(rmd256, 2,	"abc")
302DIGEST_MD(rmd256,  2, 32, 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb,
303			  0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1,
304			  0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e,
305			  0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65)
306
307DIGEST_MSG(rmd256, 3,	"message digest")
308DIGEST_MD(rmd256,  3, 32, 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a,
309			  0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90,
310			  0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55,
311			  0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e)
312
313DIGEST_MSG(rmd256, 4,	"abcdefghijklmnopqrstuvwxyz")
314DIGEST_MD(rmd256,  4, 32, 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16,
315			  0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc,
316			  0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87,
317			  0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33)
318
319DIGEST_MSG(rmd256, 5,	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
320DIGEST_MD(rmd256,  5, 32, 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20,
321			  0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f,
322			  0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1,
323			  0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8)
324
325DIGEST_TEST(rmd256, 6)
326
327/*
328 * RMD320 digest test vectors.
329 */
330DIGEST_MSG(rmd320, 0,	"")
331DIGEST_MD(rmd320,  0, 40, 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc,
332			  0x75, 0xc1, 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41,
333			  0xb9, 0xf2, 0x73, 0x25, 0xeb, 0xc6, 0x1e, 0x85,
334			  0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e, 0xc8, 0x80,
335			  0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8)
336
337DIGEST_MSG(rmd320, 1,	"a")
338DIGEST_MD(rmd320,  1, 40, 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58,
339			  0xa5, 0xa5, 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d,
340			  0xda, 0x66, 0x7a, 0x57, 0x16, 0x56, 0x2c, 0xfc,
341			  0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54, 0x2f, 0x99,
342			  0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d)
343
344DIGEST_MSG(rmd320, 2,	"abc")
345DIGEST_MD(rmd320,  2, 40, 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30,
346			  0xa7, 0x9d, 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30,
347			  0x1e, 0x5a, 0x17, 0x08, 0x5b, 0xef, 0xfd, 0xc1,
348			  0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74, 0xf8, 0x2f,
349			  0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d)
350
351DIGEST_MSG(rmd320, 3,	"message digest")
352DIGEST_MD(rmd320,  3, 40, 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42,
353			  0x2f, 0x68, 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7,
354			  0xb9, 0x85, 0x33, 0xfa, 0x3f, 0x2a, 0x91, 0xd2,
355			  0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d, 0x6b, 0x4e,
356			  0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97)
357
358DIGEST_MSG(rmd320, 4,	"abcdefghijklmnopqrstuvwxyz")
359DIGEST_MD(rmd320,  4, 40, 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a,
360			  0x20, 0x93, 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c,
361			  0x28, 0x34, 0x8c, 0xf4, 0x3f, 0xf6, 0x08, 0x41,
362			  0x97, 0x51, 0x66, 0xbb, 0x40, 0xed, 0x23, 0x40,
363			  0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09)
364
365DIGEST_MSG(rmd320, 5,	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
366DIGEST_MD(rmd320,  5, 40, 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02,
367			  0x1b, 0xa4, 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde,
368			  0x20, 0x60, 0xe2, 0x59, 0xdf, 0x4c, 0x9b, 0xb4,
369			  0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b, 0xbc, 0x74,
370			  0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac)
371
372DIGEST_TEST(rmd320, 6)
373
374/*
375 * SHA1 digest test vectors.
376 */
377DIGEST_MSG(sha1, 0,	"abc")
378DIGEST_MD(sha1,  0, 20,	0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
379			0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
380			0x9c, 0xd0, 0xd8, 0x9d)
381
382DIGEST_MSG(sha1, 1,	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
383DIGEST_MD(sha1,  1, 20,	0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
384			0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
385			0xE5, 0x46, 0x70, 0xF1)
386
387DIGEST_TEST(sha1, 2)
388
389/*
390 * SHA224 digest test vectors.
391 */
392DIGEST_MSG(sha224, 0,	"abc")
393DIGEST_MD(sha224,  0, 28, 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22,
394			  0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3,
395			  0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7,
396			  0xe3, 0x6c, 0x9d, 0xa7)
397
398DIGEST_MSG(sha224, 1,	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
399DIGEST_MD(sha224,  1, 28, 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc,
400			  0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50,
401			  0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19,
402			  0x52, 0x52, 0x25, 0x25)
403
404DIGEST_TEST(sha224, 2)
405
406/*
407 * SHA256 digest test vectors.
408 */
409DIGEST_MSG(sha256, 0,	"abc")
410DIGEST_MD(sha256,  0, 32, 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
411			  0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
412			  0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
413			  0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad)
414
415DIGEST_MSG(sha256, 1,	"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
416DIGEST_MD(sha256,  1, 32, 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
417			  0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
418			  0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
419			  0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1)
420
421DIGEST_TEST(sha256, 2)
422
423/*
424 * SHA384 digest test vectors.
425 */
426DIGEST_MSG(sha384, 0,	"abc")
427DIGEST_MD(sha384,  0, 48, 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
428			  0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
429			  0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
430			  0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
431			  0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
432			  0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7)
433
434DIGEST_MSG(sha384, 1,	"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
435			"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
436DIGEST_MD(sha384,  1, 48, 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
437			  0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
438			  0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
439			  0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
440			  0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
441			  0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39)
442
443DIGEST_TEST(sha384, 2)
444
445/*
446 * SHA512 digest test vectors.
447 */
448DIGEST_MSG(sha512, 0,	"abc")
449DIGEST_MD(sha512,  0, 64, 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
450			  0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
451			  0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
452			  0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
453			  0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
454			  0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
455			  0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
456			  0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f)
457
458DIGEST_MSG(sha512, 1,	"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
459			"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
460DIGEST_MD(sha512,  1, 64, 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
461			  0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
462			  0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
463			  0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
464			  0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
465			  0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
466			  0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
467			  0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09)
468
469DIGEST_TEST(sha512, 2)
470
471static int testAllDigests(void);
472
473/*
474 * Digest test functions array.
475 */
476static testFunction_t digestTestFunctions[] = {
477    { testDigest_md2,		"MD2" },
478    { testDigest_md4,		"MD4" },
479    { testDigest_md5,		"MD5" },
480    { testDigest_rmd128,	"RMD128" },
481    { testDigest_rmd160,	"RMD160" },
482    { testDigest_rmd256, 	"RMD256" },
483    { testDigest_rmd320,	"RMD320" },
484    { testDigest_sha1,		"SHA1" },
485    { testDigest_sha224,	"SHA224" },
486    { testDigest_sha256,	"SHA256" },
487    { testDigest_sha384,	"SHA384" },
488    { testDigest_sha512,	"SHA512" },
489};
490#define numDigestTestFunctions  (sizeof(digestTestFunctions) / sizeof(digestTestFunctions[0]))
491
492
493static int
494testAllDigests(void)
495{
496	unsigned i;
497	int err = 0;
498
499	for (i = 0; i < numDigestTestFunctions; i++) {
500		if (NULL == digestTestFunctions[i].description)
501			continue;
502		if (verbose) printf("[BEGIN] %s\n",  digestTestFunctions[i].description);
503		err = digestTestFunctions[i].funcptr();
504		total++;
505		if (err) {
506			fail++;
507			if (verbose) printf("[FAIL] %s\n", digestTestFunctions[i].description);
508		} else {
509			pass++;
510			if (verbose) printf("[PASS] %s\n", digestTestFunctions[i].description);
511		}
512	}
513	return (fail);
514}
515
516static struct option args[] = {
517	{ "help",       no_argument,    NULL,   'h' },
518	{ "quite",      no_argument,    NULL,   'q' },
519	{ 0, 0, 0, 0 }
520};
521
522static void
523usage (int ret)
524{
525    fprintf(stderr, "usage: %s [--quite/-q] [--help/-h]\n", getprogname());
526    exit (ret);
527}
528
529int
530main(int argc, char **argv)
531{
532    int i, idx = 0, rv = 0;
533
534    setprogname(argv[0]);
535
536    while(1) {
537	    int c = getopt_long(argc, argv, "hq", args, &idx);
538
539	    if (c == -1)
540		    break;
541
542	    switch (c) {
543	    case 'q':
544		    verbose = 0;
545		    break;
546	    case 'h':
547		    usage(0);
548		    break;
549	    case '?':
550	    default:
551		    usage(-1);
552		    break;
553	    }
554    }
555
556    /*
557    argc -= idx;
558    argv += idx;
559    */
560
561    if (verbose) printf("[TEST] Message Digest KATs\n");
562    rv = testAllDigests();
563    if (verbose) {
564	    printf("[SUMMARY]\n");
565	    printf("Total: %d\n", total);
566	    printf("passed: %d\n", pass);
567	    printf("failed: %d\n", fail);
568    }
569
570    return (rv);
571}
572