]>
Commit | Line | Data |
---|---|---|
440e5d80 | 1 | /* |
0789c7d8 | 2 | * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. |
58964a49 | 3 | * |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
440e5d80 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
58964a49 RE |
8 | */ |
9 | ||
dbde4726 P |
10 | /* |
11 | * HMAC low level APIs are deprecated for public use, but still ok for internal | |
12 | * use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
58964a49 RE |
16 | #include <stdio.h> |
17 | #include <string.h> | |
18 | #include <stdlib.h> | |
f5d7a031 | 19 | |
176db6dc | 20 | #include "internal/nelem.h" |
55f78baf | 21 | |
0f113f3e | 22 | # include <openssl/hmac.h> |
b1413d9b | 23 | # include <openssl/sha.h> |
0f113f3e MC |
24 | # ifndef OPENSSL_NO_MD5 |
25 | # include <openssl/md5.h> | |
26 | # endif | |
58964a49 | 27 | |
0f113f3e MC |
28 | # ifdef CHARSET_EBCDIC |
29 | # include <openssl/ebcdic.h> | |
30 | # endif | |
a53955d8 | 31 | |
623d1056 RS |
32 | #include "testutil.h" |
33 | ||
0f113f3e MC |
34 | # ifndef OPENSSL_NO_MD5 |
35 | static struct test_st { | |
f53537b1 | 36 | const char key[16]; |
0f113f3e | 37 | int key_len; |
f53537b1 | 38 | const unsigned char data[64]; |
0f113f3e | 39 | int data_len; |
f53537b1 | 40 | const char *digest; |
2cfbdd71 | 41 | } test[8] = { |
0f113f3e MC |
42 | { |
43 | "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54, | |
f53537b1 | 44 | "e9139d1e6ee064ef8cf514fc7dc83e86", |
0f113f3e MC |
45 | }, |
46 | { | |
1057c2c3 | 47 | "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", |
73ff6d68 | 48 | 16, "Hi There", 8, |
f53537b1 | 49 | "9294727a3638bb1c13f48ef8158bfc9d", |
0f113f3e MC |
50 | }, |
51 | { | |
52 | "Jefe", 4, "what do ya want for nothing?", 28, | |
f53537b1 | 53 | "750c783e6ab0b503eaa86e310a5db738", |
0f113f3e MC |
54 | }, |
55 | { | |
1057c2c3 | 56 | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", |
73ff6d68 | 57 | 16, { |
0f113f3e MC |
58 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, |
59 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, | |
60 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, | |
61 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, | |
62 | 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd | |
f53537b1 | 63 | }, 50, "56be34521d144c88dbb8c733f0e8b3f6", |
0f113f3e | 64 | }, |
2cfbdd71 MC |
65 | { |
66 | "", 0, "My test data", 12, | |
f53537b1 | 67 | "61afdecb95429ef494d61fdee15990cabf0826fc" |
2cfbdd71 MC |
68 | }, |
69 | { | |
70 | "", 0, "My test data", 12, | |
f53537b1 | 71 | "2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776" |
2cfbdd71 MC |
72 | }, |
73 | { | |
74 | "123456", 6, "My test data", 12, | |
f53537b1 | 75 | "bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd" |
2cfbdd71 MC |
76 | }, |
77 | { | |
8a3c000c | 78 | "12345", 5, "My test data again", 18, |
f53537b1 | 79 | "a12396ceddd2a85f4c656bc1e0aa50c78cffde3e" |
2cfbdd71 | 80 | } |
0f113f3e MC |
81 | }; |
82 | # endif | |
58964a49 | 83 | |
2cfbdd71 MC |
84 | static char *pt(unsigned char *md, unsigned int len); |
85 | ||
623d1056 | 86 | |
0f113f3e | 87 | # ifndef OPENSSL_NO_MD5 |
623d1056 RS |
88 | static int test_hmac_md5(int idx) |
89 | { | |
0f113f3e | 90 | char *p; |
0f113f3e MC |
91 | # ifdef CHARSET_EBCDIC |
92 | ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); | |
93 | ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); | |
94 | ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); | |
95 | ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); | |
96 | # endif | |
a53955d8 | 97 | |
623d1056 RS |
98 | p = pt(HMAC(EVP_md5(), |
99 | test[idx].key, test[idx].key_len, | |
100 | test[idx].data, test[idx].data_len, NULL, NULL), | |
101 | MD5_DIGEST_LENGTH); | |
102 | ||
0a8a6afd | 103 | return TEST_ptr(p) && TEST_str_eq(p, test[idx].digest); |
623d1056 RS |
104 | } |
105 | # endif | |
106 | ||
31a80694 | 107 | static int test_hmac_bad(void) |
623d1056 RS |
108 | { |
109 | HMAC_CTX *ctx = NULL; | |
110 | int ret = 0; | |
2cfbdd71 | 111 | |
bf7c6817 | 112 | ctx = HMAC_CTX_new(); |
623d1056 RS |
113 | if (!TEST_ptr(ctx) |
114 | || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) | |
115 | || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) | |
116 | || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len)) | |
117 | || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha1(), NULL)) | |
118 | || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len))) | |
119 | goto err; | |
120 | ||
121 | ret = 1; | |
122 | err: | |
123 | HMAC_CTX_free(ctx); | |
124 | return ret; | |
125 | } | |
126 | ||
31a80694 | 127 | static int test_hmac_run(void) |
623d1056 RS |
128 | { |
129 | char *p; | |
130 | HMAC_CTX *ctx = NULL; | |
131 | unsigned char buf[EVP_MAX_MD_SIZE]; | |
132 | unsigned int len; | |
133 | int ret = 0; | |
b1413d9b | 134 | |
f06c5547 P |
135 | if (!TEST_ptr(ctx = HMAC_CTX_new())) |
136 | return 0; | |
a87a0a6e | 137 | HMAC_CTX_reset(ctx); |
623d1056 RS |
138 | |
139 | if (!TEST_ptr(ctx) | |
140 | || !TEST_ptr_null(HMAC_CTX_get_md(ctx)) | |
141 | || !TEST_false(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) | |
142 | || !TEST_false(HMAC_Update(ctx, test[4].data, test[4].data_len)) | |
143 | || !TEST_false(HMAC_Init_ex(ctx, test[4].key, -1, EVP_sha1(), NULL))) | |
144 | goto err; | |
145 | ||
146 | if (!TEST_true(HMAC_Init_ex(ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) | |
147 | || !TEST_true(HMAC_Update(ctx, test[4].data, test[4].data_len)) | |
148 | || !TEST_true(HMAC_Final(ctx, buf, &len))) | |
149 | goto err; | |
150 | ||
2cfbdd71 | 151 | p = pt(buf, len); |
0a8a6afd | 152 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) |
623d1056 RS |
153 | goto err; |
154 | ||
155 | if (!TEST_false(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL))) | |
156 | goto err; | |
157 | ||
158 | if (!TEST_true(HMAC_Init_ex(ctx, test[5].key, test[5].key_len, EVP_sha256(), NULL)) | |
159 | || !TEST_ptr_eq(HMAC_CTX_get_md(ctx), EVP_sha256()) | |
160 | || !TEST_true(HMAC_Update(ctx, test[5].data, test[5].data_len)) | |
161 | || !TEST_true(HMAC_Final(ctx, buf, &len))) | |
162 | goto err; | |
163 | ||
2cfbdd71 | 164 | p = pt(buf, len); |
0a8a6afd | 165 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[5].digest)) |
623d1056 RS |
166 | goto err; |
167 | ||
168 | if (!TEST_true(HMAC_Init_ex(ctx, test[6].key, test[6].key_len, NULL, NULL)) | |
169 | || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len)) | |
170 | || !TEST_true(HMAC_Final(ctx, buf, &len))) | |
171 | goto err; | |
2cfbdd71 | 172 | p = pt(buf, len); |
0a8a6afd | 173 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) |
623d1056 RS |
174 | goto err; |
175 | ||
b1558c0b MC |
176 | /* Test reusing a key */ |
177 | if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, NULL, NULL)) | |
178 | || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len)) | |
179 | || !TEST_true(HMAC_Final(ctx, buf, &len))) | |
180 | goto err; | |
181 | p = pt(buf, len); | |
0a8a6afd | 182 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) |
b1558c0b MC |
183 | goto err; |
184 | ||
185 | /* | |
186 | * Test reusing a key where the digest is provided again but is the same as | |
187 | * last time | |
188 | */ | |
189 | if (!TEST_true(HMAC_Init_ex(ctx, NULL, 0, EVP_sha256(), NULL)) | |
190 | || !TEST_true(HMAC_Update(ctx, test[6].data, test[6].data_len)) | |
191 | || !TEST_true(HMAC_Final(ctx, buf, &len))) | |
192 | goto err; | |
193 | p = pt(buf, len); | |
0a8a6afd | 194 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[6].digest)) |
b1558c0b MC |
195 | goto err; |
196 | ||
623d1056 RS |
197 | ret = 1; |
198 | err: | |
199 | HMAC_CTX_free(ctx); | |
200 | return ret; | |
201 | } | |
202 | ||
203 | ||
31a80694 | 204 | static int test_hmac_single_shot(void) |
623d1056 RS |
205 | { |
206 | char *p; | |
207 | ||
0a8a6afd | 208 | /* Test single-shot with NULL key. */ |
623d1056 RS |
209 | p = pt(HMAC(EVP_sha1(), NULL, 0, test[4].data, test[4].data_len, |
210 | NULL, NULL), SHA_DIGEST_LENGTH); | |
0a8a6afd | 211 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[4].digest)) |
623d1056 RS |
212 | return 0; |
213 | ||
214 | return 1; | |
215 | } | |
216 | ||
217 | ||
31a80694 | 218 | static int test_hmac_copy(void) |
623d1056 RS |
219 | { |
220 | char *p; | |
221 | HMAC_CTX *ctx = NULL, *ctx2 = NULL; | |
222 | unsigned char buf[EVP_MAX_MD_SIZE]; | |
223 | unsigned int len; | |
224 | int ret = 0; | |
225 | ||
226 | ctx = HMAC_CTX_new(); | |
bf7c6817 | 227 | ctx2 = HMAC_CTX_new(); |
623d1056 RS |
228 | if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) |
229 | goto err; | |
230 | ||
231 | if (!TEST_true(HMAC_Init_ex(ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) | |
232 | || !TEST_true(HMAC_Update(ctx, test[7].data, test[7].data_len)) | |
233 | || !TEST_true(HMAC_CTX_copy(ctx2, ctx)) | |
234 | || !TEST_true(HMAC_Final(ctx2, buf, &len))) | |
235 | goto err; | |
236 | ||
2cfbdd71 | 237 | p = pt(buf, len); |
0a8a6afd | 238 | if (!TEST_ptr(p) || !TEST_str_eq(p, test[7].digest)) |
623d1056 RS |
239 | goto err; |
240 | ||
241 | ret = 1; | |
242 | err: | |
bf7c6817 RL |
243 | HMAC_CTX_free(ctx2); |
244 | HMAC_CTX_free(ctx); | |
623d1056 | 245 | return ret; |
0f113f3e | 246 | } |
58964a49 | 247 | |
27f7f527 P |
248 | static int test_hmac_copy_uninited(void) |
249 | { | |
250 | const unsigned char key[24] = {0}; | |
251 | const unsigned char ct[166] = {0}; | |
252 | EVP_PKEY *pkey = NULL; | |
253 | EVP_MD_CTX *ctx = NULL; | |
254 | EVP_MD_CTX *ctx_tmp = NULL; | |
255 | int res = 0; | |
256 | ||
257 | if (!TEST_ptr(ctx = EVP_MD_CTX_new()) | |
258 | || !TEST_ptr(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, | |
259 | key, sizeof(key))) | |
260 | || !TEST_true(EVP_DigestSignInit(ctx, NULL, EVP_sha1(), NULL, pkey)) | |
261 | || !TEST_ptr(ctx_tmp = EVP_MD_CTX_new()) | |
262 | || !TEST_true(EVP_MD_CTX_copy(ctx_tmp, ctx))) | |
263 | goto err; | |
264 | EVP_MD_CTX_free(ctx); | |
265 | ctx = ctx_tmp; | |
266 | ctx_tmp = NULL; | |
267 | ||
268 | if (!TEST_true(EVP_DigestSignUpdate(ctx, ct, sizeof(ct)))) | |
269 | goto err; | |
270 | res = 1; | |
271 | err: | |
272 | EVP_MD_CTX_free(ctx); | |
273 | EVP_MD_CTX_free(ctx_tmp); | |
274 | EVP_PKEY_free(pkey); | |
275 | return res; | |
276 | } | |
277 | ||
0f113f3e | 278 | # ifndef OPENSSL_NO_MD5 |
2cfbdd71 | 279 | static char *pt(unsigned char *md, unsigned int len) |
0f113f3e | 280 | { |
2cfbdd71 | 281 | unsigned int i; |
0f113f3e | 282 | static char buf[80]; |
58964a49 | 283 | |
0a8a6afd DDO |
284 | if (md == NULL) |
285 | return NULL; | |
2cfbdd71 | 286 | for (i = 0; i < len; i++) |
0f113f3e | 287 | sprintf(&(buf[i * 2]), "%02x", md[i]); |
c2500f65 | 288 | return buf; |
0f113f3e MC |
289 | } |
290 | # endif | |
623d1056 | 291 | |
ad887416 | 292 | int setup_tests(void) |
623d1056 RS |
293 | { |
294 | ADD_ALL_TESTS(test_hmac_md5, 4); | |
295 | ADD_TEST(test_hmac_single_shot); | |
296 | ADD_TEST(test_hmac_bad); | |
297 | ADD_TEST(test_hmac_run); | |
298 | ADD_TEST(test_hmac_copy); | |
27f7f527 | 299 | ADD_TEST(test_hmac_copy_uninited); |
ad887416 | 300 | return 1; |
623d1056 RS |
301 | } |
302 |