iPXE
hmac_test.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26/** @file
27 *
28 * HMAC self-tests
29 *
30 */
31
32/* Forcibly enable assertions */
33#undef NDEBUG
34
35#include <string.h>
36#include <ipxe/hmac.h>
37#include <ipxe/md5.h>
38#include <ipxe/sha1.h>
39#include <ipxe/sha256.h>
40#include <ipxe/test.h>
41
42/** Define inline key data */
43#define KEY(...) { __VA_ARGS__ }
44
45/** Define inline data */
46#define DATA(...) { __VA_ARGS__ }
47
48/** Define inline expected HMAC */
49#define EXPECTED(...) { __VA_ARGS__ }
50
51/** An HMAC test */
52struct hmac_test {
53 /** Digest algorithm */
55 /** Key */
56 const void *key;
57 /** Length of key */
58 size_t key_len;
59 /** Data */
60 const void *data;
61 /** Length of data */
62 size_t data_len;
63 /** Expected HMAC */
64 const void *expected;
65 /** Length of expected HMAC */
67};
68
69/**
70 * Define an HMAC test
71 *
72 * @v name Test name
73 * @v DIGEST Digest algorithm
74 * @v KEY Key
75 * @v DATA Data
76 * @v EXPECTED Expected HMAC
77 * @ret test HMAC test
78 */
79#define HMAC_TEST( name, DIGEST, KEY, DATA, EXPECTED ) \
80 static const uint8_t name ## _key[] = KEY; \
81 static const uint8_t name ## _data[] = DATA; \
82 static const uint8_t name ## _expected[] = EXPECTED; \
83 static struct hmac_test name = { \
84 .digest = DIGEST, \
85 .key = name ## _key, \
86 .key_len = sizeof ( name ## _key ), \
87 .data = name ## _data, \
88 .data_len = sizeof ( name ## _data ), \
89 .expected = name ## _expected, \
90 .expected_len = sizeof ( name ## _expected ), \
91 }
92
93/**
94 * Report an HMAC test result
95 *
96 * @v test HMAC test
97 * @v file Test code file
98 * @v line Test code line
99 */
100static void hmac_okx ( struct hmac_test *test, const char *file,
101 unsigned int line ) {
102 struct digest_algorithm *digest = test->digest;
103 uint8_t ctx[ hmac_ctxsize ( digest ) ];
104 uint8_t hmac[digest->digestsize];
105
106 /* Sanity checks */
107 okx ( sizeof ( ctx ) == ( digest->ctxsize + digest->blocksize ),
108 file, line );
109 okx ( test->expected_len == digest->digestsize, file, line );
110
111 /* Calculate HMAC */
112 DBGC ( test, "HMAC-%s key:\n", digest->name );
113 DBGC_HDA ( test, 0, test->key, test->key_len );
114 DBGC ( test, "HMAC-%s data:\n", digest->name );
115 DBGC_HDA ( test, 0, test->data, test->data_len );
116 hmac_init ( digest, ctx, test->key, test->key_len );
117 hmac_update ( digest, ctx, test->data, test->data_len );
118 hmac_final ( digest, ctx, hmac );
119 DBGC ( test, "HMAC-%s result:\n", digest->name );
120 DBGC_HDA ( test, 0, hmac, sizeof ( hmac ) );
121
122 /* Compare against expected result */
123 okx ( memcmp ( hmac, test->expected, test->expected_len ) == 0,
124 file, line );
125}
126#define hmac_ok( test ) hmac_okx ( test, __FILE__, __LINE__ )
127
128/* Empty key and data */
129HMAC_TEST ( hmac_empty, &sha256_algorithm, KEY(), DATA(),
130 EXPECTED ( 0xb6, 0x13, 0x67, 0x9a, 0x08, 0x14, 0xd9, 0xec, 0x77,
131 0x2f, 0x95, 0xd7, 0x78, 0xc3, 0x5f, 0xc5, 0xff, 0x16,
132 0x97, 0xc4, 0x93, 0x71, 0x56, 0x53, 0xc6, 0xc7, 0x12,
133 0x14, 0x42, 0x92, 0xc5, 0xad ) );
134
135/* "Hello world" */
137 KEY ( 'H', 'e', 'l', 'l', 'o' ),
138 DATA ( 'W', 'o', 'r', 'l', 'd' ),
139 EXPECTED ( 0x59, 0x16, 0x8e, 0x30, 0x9f, 0x2c, 0x97, 0xdd, 0x04,
140 0xe4, 0x5b, 0xe3, 0xe7, 0x9b, 0xd9, 0xac, 0xb6, 0xd2,
141 0x2f, 0xda, 0x65, 0x46, 0xc0, 0x0c, 0x53, 0x92, 0x82,
142 0xc4, 0x1e, 0xeb, 0x91, 0x6e ) );
143
144/* "Hello world" using SHA-1 */
145HMAC_TEST ( hmac_hw_sha1, &sha1_algorithm,
146 KEY ( 'H', 'e', 'l', 'l', 'o' ),
147 DATA ( 'W', 'o', 'r', 'l', 'd' ),
148 EXPECTED ( 0x9e, 0x29, 0xcf, 0x6d, 0x48, 0x90, 0x49, 0x9e, 0xf8,
149 0x5a, 0x31, 0x47, 0x55, 0x7b, 0x1a, 0x45, 0xd5, 0xae,
150 0xd1, 0x77 ) );
151
152/* "Hello world" using MD5 */
153HMAC_TEST ( hmac_hw_md5, &md5_algorithm,
154 KEY ( 'H', 'e', 'l', 'l', 'o' ),
155 DATA ( 'W', 'o', 'r', 'l', 'd' ),
156 EXPECTED ( 0xc7, 0x1c, 0x0c, 0xd0, 0xdc, 0x24, 0x49, 0xbd, 0xd8,
157 0x9d, 0x28, 0xeb, 0x03, 0xbe, 0xf2, 0x04 ) );
158
159/* Block-length key */
161 KEY ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
162 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
163 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
164 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
165 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
166 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
167 0x3c, 0x3d, 0x3e, 0x3f ),
168 DATA ( 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' ),
169 EXPECTED ( 0xdd, 0x05, 0xcc, 0xe6, 0xd6, 0xaf, 0x91, 0x61, 0x4b,
170 0xaf, 0x35, 0x6b, 0x86, 0x0a, 0x05, 0x67, 0x25, 0x22,
171 0xf0, 0x54, 0xd2, 0x5f, 0xd7, 0xe1, 0x54, 0x26, 0x01,
172 0x16, 0xfd, 0x8a, 0xf3, 0x5b ) );
173
174/* Over-length key */
176 KEY ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
177 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
178 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
179 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
180 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
181 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
182 0x3c, 0x3d, 0x3e, 0x3f, 0x40 ),
183 DATA ( 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' ),
184 EXPECTED ( 0x4f, 0x0f, 0x42, 0x07, 0xda, 0x84, 0x3d, 0x2a, 0x34,
185 0xae, 0x5d, 0xd9, 0x05, 0x1e, 0x96, 0xa8, 0xb6, 0xef,
186 0xa1, 0xcd, 0x49, 0x5b, 0xea, 0x30, 0xbf, 0x47, 0x3b,
187 0xdc, 0xa9, 0x86, 0xbb, 0x31 ) );
188
189/**
190 * Perform HMAC self-tests
191 *
192 */
193static void hmac_test_exec ( void ) {
194
195 hmac_ok ( &hmac_empty );
196 hmac_ok ( &hmac_hw );
197 hmac_ok ( &hmac_hw_sha1 );
198 hmac_ok ( &hmac_hw_md5 );
199 hmac_ok ( &hmac_maxlen );
200 hmac_ok ( &hmac_overlen );
201}
202
203/** HMAC self-tests */
205 .name = "hmac",
206 .exec = hmac_test_exec,
207};
struct golan_eq_context ctx
Definition CIB_PRM.h:0
#define DATA(...)
Define inline data.
Definition acpi_test.c:74
unsigned char uint8_t
Definition stdint.h:10
#define KEY(...)
Define inline key.
Definition cipher_test.h:45
#define EXPECTED(...)
Define inline expected result point.
static int test
Definition epic100.c:73
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *key, size_t key_len)
Initialise HMAC.
Definition hmac.c:58
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition hmac.c:88
Keyed-Hashing for Message Authentication.
static void hmac_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Update HMAC.
Definition hmac.h:43
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition hmac.h:29
#define HMAC_TEST(name, DIGEST, KEY, DATA, EXPECTED)
Define an HMAC test.
Definition hmac_test.c:79
static void hmac_okx(struct hmac_test *test, const char *file, unsigned int line)
Report an HMAC test result.
Definition hmac_test.c:100
#define hmac_ok(test)
Definition hmac_test.c:126
#define KEY(...)
Define inline key data.
Definition hmac_test.c:43
static void hmac_test_exec(void)
Perform HMAC self-tests.
Definition hmac_test.c:193
#define DATA(...)
Define inline data.
Definition hmac_test.c:46
String functions.
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition md5.c:287
MD5 algorithm.
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition sha1.c:258
SHA-1 algorithm.
struct digest_algorithm sha256_algorithm
SHA-256 algorithm.
Definition sha256.c:265
SHA-256 algorithm.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
size_t blocksize
Block size.
Definition crypto.h:25
size_t ctxsize
Context size.
Definition crypto.h:23
const char * name
Algorithm name.
Definition crypto.h:21
An HMAC test.
Definition hmac_test.c:52
const void * key
Key.
Definition hmac_test.c:56
size_t expected_len
Length of expected HMAC.
Definition hmac_test.c:66
size_t data_len
Length of data.
Definition hmac_test.c:62
size_t key_len
Length of key.
Definition hmac_test.c:58
const void * expected
Expected HMAC.
Definition hmac_test.c:64
struct digest_algorithm * digest
Digest algorithm.
Definition hmac_test.c:54
const void * data
Data.
Definition hmac_test.c:60
A self-test set.
Definition test.h:15
Self-test infrastructure.
#define okx(success, file, line)
Report test result.
Definition test.h:44
#define __self_test
Declare a self-test.
Definition test.h:32