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-hmac.h"
31#include "ossl-evp.h"
32#include "ossl-evp-cc.h"
33
34#include "test_common.h"
35
36static int verbose = 1;
37
38static int total = 0;
39static int pass = 0;
40static int fail = 0;
41
42/*
43 *  HMAC Test Engine.
44 */
45
46typedef const EVP_MD * (*evp_alg_t)(void);
47
48static int
49_hmac_compare(evp_alg_t alg, int i, const void *key, size_t keylen, const void *msg, size_t msglen, const void *md)
50{
51	const EVP_MD *evp_md = (*alg)();
52	unsigned mdlen = EVP_MD_size(evp_md);
53	HMAC_CTX ctx;
54	uint8_t out[mdlen];
55
56	HMAC_CTX_init(&ctx);
57	HMAC_Init_ex(&ctx, key, keylen, evp_md, NULL);
58	HMAC_Update(&ctx, msg, msglen);
59	HMAC_Final(&ctx, out, &mdlen);
60	HMAC_CTX_cleanup(&ctx);
61	if ((mdlen != EVP_MD_size(evp_md)) || (memcmp(out, md, mdlen) != 0)) {
62		if (verbose)  printf("Result doesn't match vector (%d)\n", i);
63		return (1);
64	}
65
66	return (0);
67}
68
69static int
70_test_hmac(evp_alg_t alg, byteVector_t *key[], stringVector_t *msg[], byteVector_t *md[], const size_t num_tests)
71{
72	size_t i;
73	int err = 0;
74
75	for (i = 0; i < num_tests; i++) {
76		err = _hmac_compare(alg, i, key[i]->value, key[i]->len, msg[i]->value,
77		    msg[i]->len, md[i]->value);
78		if (err) return (err);
79	}
80	return (0);
81}
82
83/*
84 * Vector Macros:
85 *
86 * HMAC_KEY() is the HMAC key (in hex).
87 * Parameters: (<Digest Name>, <vector #>, <key length>, <vector data in hex>)
88 * HMAC_MSG() is the message (string) to digest.
89 * HMAC_MD() is the message digest (in hex).
90 * Parameters: (<Digest Name>, <vector #>, <vector length> <vector data: string or hex numbers>)
91 */
92#define	HMAC_KEY(NAME, N, LEN, VALUE...) static byteVector_t	NAME ## _hmac_key_ ## N = \
93						{ LEN, { VALUE } };
94#define	HMAC_MSG(NAME, N, VALUE)	static stringVector_t	NAME ## _hmac_msg_ ## N =  \
95						{ sizeof(VALUE)-1, VALUE };
96#define	HMAC_MD(NAME, N, LEN, VALUE...)	static byteVector_t	NAME ## _hmac_md_ ## N = \
97						{ LEN, { VALUE } };
98
99/*
100 * HMAC_TEST() generates the testing code stub.
101 * Parameters: (<HMAC Name>, <Number of test vectors>)
102 */
103#define	HMAC_TEST(ALG_NAME, NUM_TESTS) 							\
104static byteVector_t * ALG_NAME ## _hmac_key_vects[] =					\
105	{ ARRAY_FOR_ ## NUM_TESTS (& ALG_NAME ## _hmac_key_ ) NULL };			\
106											\
107static stringVector_t * ALG_NAME ## _hmac_msg_vects[] =					\
108	{ ARRAY_FOR_ ## NUM_TESTS (& ALG_NAME ## _hmac_msg_ ) NULL };			\
109											\
110static byteVector_t * ALG_NAME ## _hmac_md_vects[] =					\
111	{ ARRAY_FOR_ ## NUM_TESTS (& ALG_NAME ## _hmac_md_ ) NULL };			\
112											\
113static int testHmac_ ## ALG_NAME(void) {						\
114	return (_test_hmac(EVP_ ## ALG_NAME, 						\
115		ALG_NAME ## _hmac_key_vects, ALG_NAME ## _hmac_msg_vects,		\
116		ALG_NAME ## _hmac_md_vects, NUM_TESTS));				\
117}
118
119/*
120 * HMAC SHA-1 Test Vectors.
121 */
122/* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */
123HMAC_KEY(sha1, 0, 20,	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
124			0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
125			0x40,0x41,0x42,0x43)
126HMAC_MSG(sha1, 0,	"Sample #2")
127HMAC_MD(sha1,  0, 20,	0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19,
128			0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c,
129			0xc6,0xc7,0x5d,0x24)
130
131HMAC_TEST(sha1, 1)
132
133/*
134 * HMAC SHA224 Test Vectors.
135 */
136HMAC_KEY(sha224, 0, 20,	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
137			0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
138			0x40,0x41,0x42,0x43)
139HMAC_MSG(sha224, 0,	"Sample #2")
140HMAC_MD(sha224,  0, 28,	0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb,
141			0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa,
142			0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b,
143			0x8c,0x8d,0x12,0xc7)
144
145HMAC_TEST(sha224, 1)
146
147/*
148 * HMAC SHA256 Test Vectors.
149 */
150HMAC_KEY(sha256, 0, 20,	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
151			0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
152			0x40,0x41,0x42,0x43)
153HMAC_MSG(sha256, 0,	"Sample #2")
154HMAC_MD(sha256,  0, 32,	0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09,
155			0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34,
156			0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38,
157			0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9)
158
159HMAC_TEST(sha256, 1)
160
161/*
162 * HMAC SHA384 Test Vectors.
163 */
164HMAC_KEY(sha384, 0, 20,	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
165			0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
166			0x40,0x41,0x42,0x43)
167HMAC_MSG(sha384, 0,	"Sample #2")
168HMAC_MD(sha384,  0, 48,	0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad,
169			0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6,
170			0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04,
171			0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f,
172			0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50,
173			0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f)
174
175HMAC_TEST(sha384, 1)
176
177/*
178 * HMAC SHA512 Test Vectors.
179 */
180HMAC_KEY(sha512, 0, 20,	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
181			0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
182			0x40,0x41,0x42,0x43)
183HMAC_MSG(sha512, 0,	"Sample #2")
184HMAC_MD(sha512,  0, 64,	0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41,
185			0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac,
186			0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0,
187			0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68,
188			0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f,
189			0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7,
190			0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45,
191			0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05)
192
193HMAC_KEY(sha512, 1, 20, 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
194    			0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
195			0x0b,0x0b,0x0b,0x0b)
196HMAC_MSG(sha512, 1,	"Hi There")
197HMAC_MD(sha512,  1, 64,	0x87,0xaa,0x7c,0xde,0xa5,0xef,0x61,0x9d,
198    			0x4f,0xf0,0xb4,0x24,0x1a,0x1d,0x6c,0xb0,
199			0x23,0x79,0xf4,0xe2,0xce,0x4e,0xc2,0x78,
200			0x7a,0xd0,0xb3,0x05,0x45,0xe1,0x7c,0xde,
201			0xda,0xa8,0x33,0xb7,0xd6,0xb8,0xa7,0x02,
202			0x03,0x8b,0x27,0x4e,0xae,0xa3,0xf4,0xe4,
203			0xbe,0x9d,0x91,0x4e,0xeb,0x61,0xf1,0x70,
204			0x2e,0x69,0x6c,0x20,0x3a,0x12,0x68,0x54)
205HMAC_TEST(sha512, 2)
206
207/*
208 * HMAC MD5 Test Vectors.
209 * Test Vectors from RFC 2104.
210 */
211HMAC_KEY(md5,  0, 16,	0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
212			0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b)
213HMAC_MSG(md5,  0,	"Hi There")
214HMAC_MD(md5,   0, 16,	0x92,0x94,0x72,0x7a,0x36,0x38,0xbb,0x1c,
215			0x13,0xf4,0x8e,0xf8,0x15,0x8b,0xfc,0x9d)
216
217HMAC_KEY(md5,  1,  4,	0x4a,0x65,0x66,0x65)
218HMAC_MSG(md5,  1,	"what do ya want for nothing?")
219HMAC_MD(md5,   1, 16,	0x75,0x0c,0x78,0x3e,0x6a,0xb0,0xb5,0x03,
220			0xea,0xa8,0x6e,0x31,0x0a,0x5d,0xb7,0x38)
221
222HMAC_KEY(md5,  2, 16,	0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
223			0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa)
224HMAC_MSG(md5,  2,	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
225			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
226			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
227			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
228			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd")
229HMAC_MD(md5,   2, 16,	0x56,0xbe,0x34,0x52,0x1d,0x14,0x4c,0x88,
230			0xdb,0xb8,0xc7,0x33,0xf0,0xe8,0xb3,0xf6)
231
232HMAC_TEST(md5, 3)
233
234/*
235 * HMAC RMD128 Test Vectors.
236 * Test Vectors from RFC 2286.
237 */
238HMAC_KEY(rmd128, 0, 16,	0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
239			0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b)
240HMAC_MSG(rmd128, 0,	"Hi There")
241HMAC_MD(rmd128,  0, 16, 0xfb,0xf6,0x1f,0x94,0x92,0xaa,0x4b,0xbf,
242			0x81,0xc1,0x72,0xe8,0x4e,0x07,0x34,0xdb)
243
244HMAC_KEY(rmd128, 1,  4,	0x4a,0x65,0x66,0x65)
245HMAC_MSG(rmd128, 1,	"what do ya want for nothing?")
246HMAC_MD(rmd128,  1, 16, 0x87,0x5f,0x82,0x88,0x62,0xb6,0xb3,0x34,
247			0xb4,0x27,0xc5,0x5f,0x9f,0x7f,0xf0,0x9b)
248
249HMAC_KEY(rmd128, 2, 16,	0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
250			0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa)
251HMAC_MSG(rmd128, 2,	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
252			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
253			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
254			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
255			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd")
256HMAC_MD(rmd128, 2, 16,	0x09,0xf0,0xb2,0x84,0x6d,0x2f,0x54,0x3d,
257			0xa3,0x63,0xcb,0xec,0x8d,0x62,0xa3,0x8d)
258
259HMAC_TEST(rmd128, 3)
260
261/*
262 * HMAC RMD160 Test Vectors.
263 * Test Vectors from RFC 2286.
264 */
265HMAC_KEY(rmd160, 0, 20,	0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
266			0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
267			0x0b,0x0b,0x0b,0x0b)
268HMAC_MSG(rmd160, 0,	"Hi There")
269HMAC_MD(rmd160,  0, 20, 0x24,0xcb,0x4b,0xd6,0x7d,0x20,0xfc,0x1a,
270			0x5d,0x2e,0xd7,0x73,0x2d,0xcc,0x39,0x37,
271			0x7f,0x0a,0x56,0x68)
272
273HMAC_KEY(rmd160, 1,  4,	0x4a,0x65,0x66,0x65)
274HMAC_MSG(rmd160, 1,	"what do ya want for nothing?")
275HMAC_MD(rmd160,  1, 20, 0xdd,0xa6,0xc0,0x21,0x3a,0x48,0x5a,0x9e,
276			0x24,0xf4,0x74,0x20,0x64,0xa7,0xf0,0x33,
277			0xb4,0x3c,0x40,0x69)
278
279HMAC_KEY(rmd160, 2, 20,	0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
280			0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
281			0xaa,0xaa,0xaa,0xaa)
282HMAC_MSG(rmd160, 2,	"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
283			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
284			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
285			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
286			"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd")
287HMAC_MD(rmd160, 2, 20,	0xb0,0xb1,0x05,0x36,0x0d,0xe7,0x59,0x96,
288			0x0a,0xb4,0xf3,0x52,0x98,0xe1,0x16,0xe2,
289			0x95,0xd8,0xe7,0xc1)
290
291HMAC_TEST(rmd160, 3)
292
293/*
294 * HMAC test functions array.
295 */
296static testFunction_t hmacTestFunctions[] = {
297    { testHmac_md5,	"MD5" },
298    { testHmac_sha1,	"SHA1" },
299    { testHmac_sha224,	"SHA224" },
300    { testHmac_sha256,	"SHA256" },
301    { testHmac_sha384,	"SHA384" },
302    { testHmac_sha512,	"SHA512" },
303    { testHmac_rmd128,  "RMD128" },
304    { testHmac_rmd160,  "RMD160" },
305};
306#define	numHmacTestFunctions	(sizeof(hmacTestFunctions) / sizeof(hmacTestFunctions[0]))
307
308static int
309testAllHmacs(void)
310{
311	unsigned i;
312	int err = 0;
313
314	for (i = 0; i < numHmacTestFunctions; i++) {
315		if (NULL == hmacTestFunctions[i].description) continue;
316		if (verbose) printf("[BEGIN] %s HMAC\n", hmacTestFunctions[i].description);
317		err = hmacTestFunctions[i].funcptr();
318		total++;
319		if (err) {
320			fail++;
321			if (verbose) printf("[FAIL] %s HMAC\n", hmacTestFunctions[i].description);
322		} else {
323			pass++;
324			if (verbose) printf("[PASS] %s HMAC\n", hmacTestFunctions[i].description);
325		}
326	}
327	return (fail);
328}
329
330static struct option args[] = {
331	{ "help",       no_argument,    NULL,   'h' },
332	{ "quite",      no_argument,    NULL,   'q' },
333	{ 0, 0, 0, 0 }
334};
335
336static void
337usage (int ret)
338{
339    fprintf(stderr, "usage: %s [--quite/-q] [--help/-h]\n", getprogname());
340    exit (ret);
341}
342
343int
344main(int argc, char **argv)
345{
346    int i, idx = 0, rv = 0;
347
348    setprogname(argv[0]);
349
350    while(1) {
351	    int c = getopt_long(argc, argv, "hq", args, &idx);
352
353	    if (c == -1)
354		break;
355
356	    switch (c) {
357	    case 'q':
358		    verbose = 0;
359		    break;
360	    case 'h':
361		    usage(0);
362		    break;
363	    case '?':
364	    default:
365		    usage(-1);
366		    break;
367	    }
368    }
369
370    /*
371    argc -= idx;
372    argv += idx;
373    */
374
375    if (verbose) printf("[TEST] HMAC KATs\n");
376    rv = testAllHmacs();
377    if (verbose) {
378	    printf("[SUMMARY]\n");
379	    printf("Total: %d\n", total);
380	    printf("passed: %d\n", pass);
381	    printf("failed: %d\n", fail);
382    }
383
384    return (rv);
385}
386