]>
Commit | Line | Data |
---|---|---|
4fd460bf LM |
1 | /* |
2 | * QEMU Crypto hmac algorithms tests | |
3 | * | |
4 | * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. | |
5 | * | |
6 | * Authors: | |
7 | * Longpeng(Mike) <longpeng2@huawei.com> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2 or | |
10 | * (at your option) any later version. See the COPYING file in the | |
11 | * top-level directory. | |
12 | * | |
13 | */ | |
14 | ||
15 | #include "qemu/osdep.h" | |
16 | #include "crypto/init.h" | |
17 | #include "crypto/hmac.h" | |
18 | ||
19 | #define INPUT_TEXT1 "ABCDEFGHIJKLMNOPQRSTUVWXY" | |
20 | #define INPUT_TEXT2 "Zabcdefghijklmnopqrstuvwx" | |
21 | #define INPUT_TEXT3 "yz0123456789" | |
22 | #define INPUT_TEXT INPUT_TEXT1 \ | |
23 | INPUT_TEXT2 \ | |
24 | INPUT_TEXT3 | |
25 | ||
26 | #define KEY "monkey monkey monkey monkey" | |
27 | ||
28 | typedef struct QCryptoHmacTestData QCryptoHmacTestData; | |
29 | struct QCryptoHmacTestData { | |
30 | QCryptoHashAlgorithm alg; | |
31 | const char *hex_digest; | |
32 | }; | |
33 | ||
34 | static QCryptoHmacTestData test_data[] = { | |
35 | { | |
36 | .alg = QCRYPTO_HASH_ALG_MD5, | |
37 | .hex_digest = | |
38 | "ede9cb83679ba82d88fbeae865b3f8fc", | |
39 | }, | |
40 | { | |
41 | .alg = QCRYPTO_HASH_ALG_SHA1, | |
42 | .hex_digest = | |
43 | "c7b5a631e3aac975c4ededfcd346e469" | |
44 | "dbc5f2d1", | |
45 | }, | |
46 | { | |
47 | .alg = QCRYPTO_HASH_ALG_SHA224, | |
48 | .hex_digest = | |
49 | "5f768179dbb29ca722875d0f461a2e2f" | |
50 | "597d0210340a84df1a8e9c63", | |
51 | }, | |
52 | { | |
53 | .alg = QCRYPTO_HASH_ALG_SHA256, | |
54 | .hex_digest = | |
55 | "3798f363c57afa6edaffe39016ca7bad" | |
56 | "efd1e670afb0e3987194307dec3197db", | |
57 | }, | |
58 | { | |
59 | .alg = QCRYPTO_HASH_ALG_SHA384, | |
60 | .hex_digest = | |
61 | "d218680a6032d33dccd9882d6a6a7164" | |
62 | "64f26623be257a9b2919b185294f4a49" | |
63 | "9e54b190bfd6bc5cedd2cd05c7e65e82", | |
64 | }, | |
65 | { | |
66 | .alg = QCRYPTO_HASH_ALG_SHA512, | |
67 | .hex_digest = | |
68 | "835a4f5b3750b4c1fccfa88da2f746a4" | |
69 | "900160c9f18964309bb736c13b59491b" | |
70 | "8e32d37b724cc5aebb0f554c6338a3b5" | |
71 | "94c4ba26862b2dadb59b7ede1d08d53e", | |
72 | }, | |
73 | { | |
74 | .alg = QCRYPTO_HASH_ALG_RIPEMD160, | |
75 | .hex_digest = | |
76 | "94964ed4c1155b62b668c241d67279e5" | |
77 | "8a711676", | |
78 | }, | |
79 | }; | |
80 | ||
81 | static const char hex[] = "0123456789abcdef"; | |
82 | ||
83 | static void test_hmac_alloc(void) | |
84 | { | |
85 | size_t i; | |
86 | ||
87 | for (i = 0; i < G_N_ELEMENTS(test_data); i++) { | |
88 | QCryptoHmacTestData *data = &test_data[i]; | |
89 | QCryptoHmac *hmac = NULL; | |
90 | uint8_t *result = NULL; | |
91 | size_t resultlen = 0; | |
4fd460bf LM |
92 | const char *exp_output = NULL; |
93 | int ret; | |
94 | size_t j; | |
95 | ||
96 | if (!qcrypto_hmac_supports(data->alg)) { | |
97 | return; | |
98 | } | |
99 | ||
100 | exp_output = data->hex_digest; | |
101 | ||
102 | hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, | |
7ea450b0 | 103 | strlen(KEY), &error_fatal); |
4fd460bf LM |
104 | g_assert(hmac != NULL); |
105 | ||
106 | ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, | |
107 | strlen(INPUT_TEXT), &result, | |
7ea450b0 | 108 | &resultlen, &error_fatal); |
4fd460bf LM |
109 | g_assert(ret == 0); |
110 | ||
111 | for (j = 0; j < resultlen; j++) { | |
112 | g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); | |
113 | g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); | |
114 | } | |
115 | ||
116 | qcrypto_hmac_free(hmac); | |
117 | ||
118 | g_free(result); | |
119 | } | |
120 | } | |
121 | ||
122 | static void test_hmac_prealloc(void) | |
123 | { | |
124 | size_t i; | |
125 | ||
126 | for (i = 0; i < G_N_ELEMENTS(test_data); i++) { | |
127 | QCryptoHmacTestData *data = &test_data[i]; | |
128 | QCryptoHmac *hmac = NULL; | |
129 | uint8_t *result = NULL; | |
130 | size_t resultlen = 0; | |
4fd460bf LM |
131 | const char *exp_output = NULL; |
132 | int ret; | |
133 | size_t j; | |
134 | ||
135 | if (!qcrypto_hmac_supports(data->alg)) { | |
136 | return; | |
137 | } | |
138 | ||
139 | exp_output = data->hex_digest; | |
140 | ||
141 | resultlen = strlen(exp_output) / 2; | |
142 | result = g_new0(uint8_t, resultlen); | |
143 | ||
144 | hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, | |
7ea450b0 | 145 | strlen(KEY), &error_fatal); |
4fd460bf LM |
146 | g_assert(hmac != NULL); |
147 | ||
148 | ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, | |
149 | strlen(INPUT_TEXT), &result, | |
7ea450b0 | 150 | &resultlen, &error_fatal); |
4fd460bf LM |
151 | g_assert(ret == 0); |
152 | ||
153 | exp_output = data->hex_digest; | |
154 | for (j = 0; j < resultlen; j++) { | |
155 | g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); | |
156 | g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); | |
157 | } | |
158 | ||
159 | qcrypto_hmac_free(hmac); | |
160 | ||
161 | g_free(result); | |
162 | } | |
163 | } | |
164 | ||
165 | static void test_hmac_iov(void) | |
166 | { | |
167 | size_t i; | |
168 | ||
169 | for (i = 0; i < G_N_ELEMENTS(test_data); i++) { | |
170 | QCryptoHmacTestData *data = &test_data[i]; | |
171 | QCryptoHmac *hmac = NULL; | |
172 | uint8_t *result = NULL; | |
173 | size_t resultlen = 0; | |
4fd460bf LM |
174 | const char *exp_output = NULL; |
175 | int ret; | |
176 | size_t j; | |
177 | struct iovec iov[3] = { | |
178 | { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) }, | |
179 | { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) }, | |
180 | { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) }, | |
181 | }; | |
182 | ||
183 | if (!qcrypto_hmac_supports(data->alg)) { | |
184 | return; | |
185 | } | |
186 | ||
187 | exp_output = data->hex_digest; | |
188 | ||
189 | hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, | |
7ea450b0 | 190 | strlen(KEY), &error_fatal); |
4fd460bf LM |
191 | g_assert(hmac != NULL); |
192 | ||
193 | ret = qcrypto_hmac_bytesv(hmac, iov, 3, &result, | |
7ea450b0 | 194 | &resultlen, &error_fatal); |
4fd460bf LM |
195 | g_assert(ret == 0); |
196 | ||
197 | for (j = 0; j < resultlen; j++) { | |
198 | g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); | |
199 | g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); | |
200 | } | |
201 | ||
202 | qcrypto_hmac_free(hmac); | |
203 | ||
204 | g_free(result); | |
205 | } | |
206 | } | |
207 | ||
208 | static void test_hmac_digest(void) | |
209 | { | |
210 | size_t i; | |
211 | ||
212 | for (i = 0; i < G_N_ELEMENTS(test_data); i++) { | |
213 | QCryptoHmacTestData *data = &test_data[i]; | |
214 | QCryptoHmac *hmac = NULL; | |
215 | uint8_t *result = NULL; | |
4fd460bf LM |
216 | const char *exp_output = NULL; |
217 | int ret; | |
218 | ||
219 | if (!qcrypto_hmac_supports(data->alg)) { | |
220 | return; | |
221 | } | |
222 | ||
223 | exp_output = data->hex_digest; | |
224 | ||
225 | hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, | |
7ea450b0 | 226 | strlen(KEY), &error_fatal); |
4fd460bf LM |
227 | g_assert(hmac != NULL); |
228 | ||
229 | ret = qcrypto_hmac_digest(hmac, (const char *)INPUT_TEXT, | |
230 | strlen(INPUT_TEXT), (char **)&result, | |
7ea450b0 | 231 | &error_fatal); |
4fd460bf LM |
232 | g_assert(ret == 0); |
233 | ||
234 | g_assert_cmpstr((const char *)result, ==, exp_output); | |
235 | ||
236 | qcrypto_hmac_free(hmac); | |
237 | ||
238 | g_free(result); | |
239 | } | |
240 | } | |
241 | ||
242 | int main(int argc, char **argv) | |
243 | { | |
244 | g_test_init(&argc, &argv, NULL); | |
245 | ||
246 | g_assert(qcrypto_init(NULL) == 0); | |
247 | ||
248 | g_test_add_func("/crypto/hmac/iov", test_hmac_iov); | |
249 | g_test_add_func("/crypto/hmac/alloc", test_hmac_alloc); | |
250 | g_test_add_func("/crypto/hmac/prealloc", test_hmac_prealloc); | |
251 | g_test_add_func("/crypto/hmac/digest", test_hmac_digest); | |
252 | ||
253 | return g_test_run(); | |
254 | } |