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 key[ hmac_keysize ( digest ) ];
105 uint8_t hmac[digest->digestsize];
106
107 /* Sanity checks */
108 okx ( sizeof ( ctx ) == ( digest->ctxsize + digest->blocksize ),
109 file, line );
110 okx ( sizeof ( key ) == digest->blocksize, file, line );
111 okx ( test->expected_len == digest->digestsize, file, line );
112
113 /* Calculate HMAC */
114 DBGC ( test, "HMAC-%s key:\n", digest->name );
115 DBGC_HDA ( test, 0, test->key, test->key_len );
116 DBGC ( test, "HMAC-%s data:\n", digest->name );
117 DBGC_HDA ( test, 0, test->data, test->data_len );
118 hmac_init ( digest, ctx, test->key, test->key_len );
119 hmac_update ( digest, ctx, test->data, test->data_len );
120 hmac_final ( digest, ctx, hmac );
121 DBGC ( test, "HMAC-%s result:\n", digest->name );
122 DBGC_HDA ( test, 0, hmac, sizeof ( hmac ) );
123 okx ( memcmp ( hmac, test->expected, test->expected_len ) == 0,
124 file, line );
125
126 /* Calculate HMAC using reduced key */
127 hmac_key ( digest, ctx, test->key, test->key_len, key );
128 DBGC ( test, "HMAC-%s key:\n", digest->name );
129 DBGC_HDA ( test, 0, key, sizeof ( key ) );
130 hmac_init_key ( digest, ctx, key );
131 hmac_update ( digest, ctx, test->data, test->data_len );
132 hmac_final ( digest, ctx, hmac );
133 DBGC ( test, "HMAC-%s result:\n", digest->name );
134 DBGC_HDA ( test, 0, hmac, sizeof ( hmac ) );
135 okx ( memcmp ( hmac, test->expected, test->expected_len ) == 0,
136 file, line );
137}
138#define hmac_ok( test ) hmac_okx ( test, __FILE__, __LINE__ )
139
140/* Empty key and data */
141HMAC_TEST ( hmac_empty, &sha256_algorithm, KEY(), DATA(),
142 EXPECTED ( 0xb6, 0x13, 0x67, 0x9a, 0x08, 0x14, 0xd9, 0xec, 0x77,
143 0x2f, 0x95, 0xd7, 0x78, 0xc3, 0x5f, 0xc5, 0xff, 0x16,
144 0x97, 0xc4, 0x93, 0x71, 0x56, 0x53, 0xc6, 0xc7, 0x12,
145 0x14, 0x42, 0x92, 0xc5, 0xad ) );
146
147/* "Hello world" */
149 KEY ( 'H', 'e', 'l', 'l', 'o' ),
150 DATA ( 'W', 'o', 'r', 'l', 'd' ),
151 EXPECTED ( 0x59, 0x16, 0x8e, 0x30, 0x9f, 0x2c, 0x97, 0xdd, 0x04,
152 0xe4, 0x5b, 0xe3, 0xe7, 0x9b, 0xd9, 0xac, 0xb6, 0xd2,
153 0x2f, 0xda, 0x65, 0x46, 0xc0, 0x0c, 0x53, 0x92, 0x82,
154 0xc4, 0x1e, 0xeb, 0x91, 0x6e ) );
155
156/* "Hello world" using SHA-1 */
157HMAC_TEST ( hmac_hw_sha1, &sha1_algorithm,
158 KEY ( 'H', 'e', 'l', 'l', 'o' ),
159 DATA ( 'W', 'o', 'r', 'l', 'd' ),
160 EXPECTED ( 0x9e, 0x29, 0xcf, 0x6d, 0x48, 0x90, 0x49, 0x9e, 0xf8,
161 0x5a, 0x31, 0x47, 0x55, 0x7b, 0x1a, 0x45, 0xd5, 0xae,
162 0xd1, 0x77 ) );
163
164/* "Hello world" using MD5 */
165HMAC_TEST ( hmac_hw_md5, &md5_algorithm,
166 KEY ( 'H', 'e', 'l', 'l', 'o' ),
167 DATA ( 'W', 'o', 'r', 'l', 'd' ),
168 EXPECTED ( 0xc7, 0x1c, 0x0c, 0xd0, 0xdc, 0x24, 0x49, 0xbd, 0xd8,
169 0x9d, 0x28, 0xeb, 0x03, 0xbe, 0xf2, 0x04 ) );
170
171/* Block-length key */
173 KEY ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
174 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
175 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
176 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
177 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
178 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
179 0x3c, 0x3d, 0x3e, 0x3f ),
180 DATA ( 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' ),
181 EXPECTED ( 0xdd, 0x05, 0xcc, 0xe6, 0xd6, 0xaf, 0x91, 0x61, 0x4b,
182 0xaf, 0x35, 0x6b, 0x86, 0x0a, 0x05, 0x67, 0x25, 0x22,
183 0xf0, 0x54, 0xd2, 0x5f, 0xd7, 0xe1, 0x54, 0x26, 0x01,
184 0x16, 0xfd, 0x8a, 0xf3, 0x5b ) );
185
186/* Over-length key */
188 KEY ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
189 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
190 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
191 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
192 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
193 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
194 0x3c, 0x3d, 0x3e, 0x3f, 0x40 ),
195 DATA ( 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' ),
196 EXPECTED ( 0x4f, 0x0f, 0x42, 0x07, 0xda, 0x84, 0x3d, 0x2a, 0x34,
197 0xae, 0x5d, 0xd9, 0x05, 0x1e, 0x96, 0xa8, 0xb6, 0xef,
198 0xa1, 0xcd, 0x49, 0x5b, 0xea, 0x30, 0xbf, 0x47, 0x3b,
199 0xdc, 0xa9, 0x86, 0xbb, 0x31 ) );
200
201/**
202 * Perform HMAC self-tests
203 *
204 */
205static void hmac_test_exec ( void ) {
206
207 hmac_ok ( &hmac_empty );
208 hmac_ok ( &hmac_hw );
209 hmac_ok ( &hmac_hw_sha1 );
210 hmac_ok ( &hmac_hw_md5 );
211 hmac_ok ( &hmac_maxlen );
212 hmac_ok ( &hmac_overlen );
213}
214
215/** HMAC self-tests */
217 .name = "hmac",
218 .exec = hmac_test_exec,
219};
struct golan_eq_context ctx
Definition CIB_PRM.h:0
union @162305117151260234136356364136041353210355154177 key
#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:530
#define DBGC_HDA(...)
Definition compiler.h:531
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *secret, size_t len)
Initialise HMAC.
Definition hmac.c:106
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition hmac.c:124
void hmac_key(struct digest_algorithm *digest, void *ctx, const void *secret, size_t len, void *key)
Construct HMAC reduced key.
Definition hmac.c:59
void hmac_init_key(struct digest_algorithm *digest, void *ctx, const void *key)
Initialise HMAC from reduced key.
Definition hmac.c:82
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:62
static size_t hmac_ctxsize(struct digest_algorithm *digest)
Calculate HMAC context size.
Definition hmac.h:48
static size_t hmac_keysize(struct digest_algorithm *digest)
Calculate HMAC reduced key size.
Definition hmac.h:35
#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:138
#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:205
#define DATA(...)
Define inline data.
Definition hmac_test.c:46
String functions.
MD5 algorithm.
struct digest_algorithm md5_algorithm
SHA-1 algorithm.
struct digest_algorithm sha1_algorithm
SHA-256 algorithm.
struct digest_algorithm sha256_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