1 /*****************************************************************************
2 Copyright (c) 2018, Intel Corporation
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice,
8 this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of Intel Corporation nor the names of its contributors
13 may be used to endorse or promote products derived from this software
14 without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *****************************************************************************/
33 #include <intel-ipsec-mb.h>
34 #include "gcm_ctr_vectors_test.h"
37 int hmac_sha1_test(const enum arch_type arch
, struct MB_MGR
*mb_mgr
);
40 #define digest_size 20
41 #define digest96_size 12
44 * Test vectors from https://tools.ietf.org/html/rfc2202
49 * key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
53 * digest = 0xb617318655057264e28bc0b6fb378c8ef146be00
55 #define test_case1 "1"
58 #define digest_len1 digest_size
59 static const uint8_t key1
[key_len1
] = {
60 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
61 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
62 0x0b, 0x0b, 0x0b, 0x0b
64 static const char data1
[] = "Hi There";
65 static const uint8_t digest1
[digest_len1
] = {
66 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
67 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
68 0xf1, 0x46, 0xbe, 0x00
75 * data = "what do ya want for nothing?"
77 * digest = 0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
79 #define test_case2 "2"
82 #define digest_len2 digest_size
83 static const char key2
[] = "Jefe";
84 static const char data2
[] = "what do ya want for nothing?";
85 static const uint8_t digest2
[digest_len2
] = {
86 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
87 0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
88 0x25, 0x9a, 0x7c, 0x79
93 * key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
95 * data = 0xdd repeated 50 times
97 * digest = 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3
99 #define test_case3 "3"
102 #define digest_len3 digest_size
103 static const uint8_t key3
[key_len3
] = {
104 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
105 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
106 0xaa, 0xaa, 0xaa, 0xaa
108 static const uint8_t data3
[data_len3
] = {
109 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
110 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
111 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
112 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
113 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
114 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
117 static const uint8_t digest3
[digest_len3
] = {
118 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
119 0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
120 0x63, 0xf1, 0x75, 0xd3
125 * key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819
127 * data = 0xcd repeated 50 times
129 * digest = 0x4c9007f4026250c6bc8414f9bf50c86c2d7235da
131 #define test_case4 "4"
134 #define digest_len4 digest_size
135 static const uint8_t key4
[key_len4
] = {
136 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
137 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
138 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
141 static const uint8_t data4
[data_len4
] = {
142 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
143 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
144 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
145 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
146 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
147 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
150 static const uint8_t digest4
[digest_len4
] = {
151 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
152 0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
153 0x2d, 0x72, 0x35, 0xda
158 * key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
160 * data = "Test With Truncation"
162 * digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04
163 * digest-96 = 0x4c1a03424b55e07fe7f27be1
165 #define test_case5 "5"
168 #define digest_len5 digest_size
169 static const uint8_t key5
[key_len5
] = {
170 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
171 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
172 0x0c, 0x0c, 0x0c, 0x0c
174 static const char data5
[] = "Test With Truncation";
175 static const uint8_t digest5
[digest_len5
] = {
176 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f,
177 0xe7, 0xf2, 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32,
178 0x4a, 0x9a, 0x5a, 0x04
181 #define test_case5_96 "5-96"
182 #define key_len5_96 key_len5
183 #define data_len5_96 data_len5
184 #define digest_len5_96 digest96_size
186 #define data5_96 data5
187 static const uint8_t digest5_96
[digest_len5_96
] = {
188 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f,
189 0xe7, 0xf2, 0x7b, 0xe1
194 * key = 0xaa repeated 80 times
196 * data = "Test Using Larger Than Block-Size Key - Hash Key First"
198 * digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112
200 #define test_case6 "6"
203 #define digest_len6 digest_size
204 static const uint8_t key6
[key_len6
] = {
205 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
206 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
207 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
208 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
209 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
210 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
211 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
212 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
213 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
214 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
216 static const char data6
[] =
217 "Test Using Larger Than Block-Size Key - Hash Key First";
218 static const uint8_t digest6
[digest_len6
] = {
219 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
220 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
221 0xed, 0x40, 0x21, 0x12
226 * key = 0xaa repeated 80 times
228 * data = "Test Using Larger Than Block-Size Key and Larger
229 * Than One Block-Size Data"
231 * digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91
233 #define test_case7 "7"
236 #define digest_len7 digest_size
237 static const uint8_t key7
[key_len7
] = {
238 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
239 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
240 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
241 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
242 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
243 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
244 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
245 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
246 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
247 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
249 static const char data7
[] =
250 "Test Using Larger Than Block-Size Key and "
251 "Larger Than One Block-Size Data";
252 static const uint8_t digest7
[digest_len7
] = {
253 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
254 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
255 0xbb, 0xff, 0x1a, 0x91
259 * Test vector from https://csrc.nist.gov/csrc/media/publications/fips/198/
260 * archive/2002-03-06/documents/fips-198a.pdf
262 #define test_case8 "8"
265 #define digest_len8 digest96_size
266 static const uint8_t key8
[key_len8
] = {
267 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
268 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
269 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
270 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
271 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
272 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
275 static const char data8
[] = "Sample #4";
276 static const uint8_t digest8
[digest_len8
] = {
277 0x9e, 0xa8, 0x86, 0xef, 0xe2, 0x68, 0xdb, 0xec,
278 0xce, 0x42, 0x0c, 0x75
281 #define HMAC_SHA1_TEST_VEC(num) \
283 (const uint8_t *) key##num, key_len##num, \
284 (const uint8_t *) data##num, data_len##num, \
285 (const uint8_t *) digest##num, digest_len##num }
287 static const struct hmac_sha1_rfc2202_vector
{
288 const char *test_case
;
293 const uint8_t *digest
;
295 } hmac_sha1_vectors
[] = {
296 HMAC_SHA1_TEST_VEC(1),
297 HMAC_SHA1_TEST_VEC(2),
298 HMAC_SHA1_TEST_VEC(3),
299 HMAC_SHA1_TEST_VEC(4),
300 HMAC_SHA1_TEST_VEC(5),
301 HMAC_SHA1_TEST_VEC(5_96
),
302 HMAC_SHA1_TEST_VEC(6),
303 HMAC_SHA1_TEST_VEC(7),
304 HMAC_SHA1_TEST_VEC(8)
308 hmac_sha1_job_ok(const struct hmac_sha1_rfc2202_vector
*vec
,
309 const struct JOB_AES_HMAC
*job
,
311 const uint8_t *padding
,
312 const size_t sizeof_padding
)
314 if (job
->status
!= STS_COMPLETED
) {
315 printf("line:%d job error status:%d ", __LINE__
, job
->status
);
320 if (memcmp(padding
, &auth
[sizeof_padding
+ vec
->digest_len
],
322 printf("hash overwrite tail\n");
323 hexdump(stderr
, "Target",
324 &auth
[sizeof_padding
+ vec
->digest_len
],
329 if (memcmp(padding
, &auth
[0], sizeof_padding
)) {
330 printf("hash overwrite head\n");
331 hexdump(stderr
, "Target", &auth
[0], sizeof_padding
);
335 if (memcmp(vec
->digest
, &auth
[sizeof_padding
],
337 printf("hash mismatched\n");
338 hexdump(stderr
, "Received", &auth
[sizeof_padding
],
340 hexdump(stderr
, "Expected", vec
->digest
,
348 test_hmac_sha1(struct MB_MGR
*mb_mgr
,
349 const struct hmac_sha1_rfc2202_vector
*vec
,
352 struct JOB_AES_HMAC
*job
;
354 uint8_t **auths
= malloc(num_jobs
* sizeof(void *));
355 int i
= 0, jobs_rx
= 0, ret
= -1;
356 uint8_t key
[block_size
];
357 uint8_t buf
[block_size
];
358 DECLARE_ALIGNED(uint8_t ipad_hash
[digest_size
], 16);
359 DECLARE_ALIGNED(uint8_t opad_hash
[digest_size
], 16);
363 fprintf(stderr
, "Can't allocate buffer memory\n");
367 memset(padding
, -1, sizeof(padding
));
368 memset(auths
, 0, num_jobs
* sizeof(void *));
370 for (i
= 0; i
< num_jobs
; i
++) {
371 const size_t alloc_len
=
372 vec
->digest_len
+ (sizeof(padding
) * 2);
374 auths
[i
] = malloc(alloc_len
);
375 if (auths
[i
] == NULL
) {
376 fprintf(stderr
, "Can't allocate buffer memory\n");
379 memset(auths
[i
], -1, alloc_len
);
382 /* prepare the key */
383 memset(key
, 0, sizeof(key
));
384 if (vec
->key_len
<= block_size
) {
385 memcpy(key
, vec
->key
, vec
->key_len
);
386 key_len
= (int) vec
->key_len
;
388 IMB_SHA1(mb_mgr
, vec
->key
, vec
->key_len
, key
);
389 key_len
= digest_size
;
392 /* compute ipad hash */
393 memset(buf
, 0x36, sizeof(buf
));
394 for (i
= 0; i
< key_len
; i
++)
396 IMB_SHA1_ONE_BLOCK(mb_mgr
, buf
, ipad_hash
);
398 /* compute opad hash */
399 memset(buf
, 0x5c, sizeof(buf
));
400 for (i
= 0; i
< key_len
; i
++)
402 IMB_SHA1_ONE_BLOCK(mb_mgr
, buf
, opad_hash
);
404 /* empty the manager */
405 while ((job
= IMB_FLUSH_JOB(mb_mgr
)) != NULL
)
408 for (i
= 0; i
< num_jobs
; i
++) {
409 job
= IMB_GET_NEXT_JOB(mb_mgr
);
410 job
->aes_enc_key_expanded
= NULL
;
411 job
->aes_dec_key_expanded
= NULL
;
412 job
->cipher_direction
= ENCRYPT
;
413 job
->chain_order
= HASH_CIPHER
;
415 job
->aes_key_len_in_bytes
= 0;
416 job
->auth_tag_output
= auths
[i
] + sizeof(padding
);
417 job
->auth_tag_output_len_in_bytes
= vec
->digest_len
;
419 job
->iv_len_in_bytes
= 0;
420 job
->src
= vec
->data
;
421 job
->cipher_start_src_offset_in_bytes
= 0;
422 job
->msg_len_to_cipher_in_bytes
= 0;
423 job
->hash_start_src_offset_in_bytes
= 0;
424 job
->msg_len_to_hash_in_bytes
= vec
->data_len
;
425 job
->u
.HMAC
._hashed_auth_key_xor_ipad
= ipad_hash
;
426 job
->u
.HMAC
._hashed_auth_key_xor_opad
= opad_hash
;
427 job
->cipher_mode
= NULL_CIPHER
;
428 job
->hash_alg
= SHA1
;
430 job
->user_data
= auths
[i
];
432 job
= IMB_SUBMIT_JOB(mb_mgr
);
436 * SHANI HMAC-SHA implementation can return a completed
437 * job after 2nd submission
440 printf("%d Unexpected return from submit_job\n",
444 if (!hmac_sha1_job_ok(vec
, job
, job
->user_data
,
445 padding
, sizeof(padding
)))
450 while ((job
= IMB_FLUSH_JOB(mb_mgr
)) != NULL
) {
452 if (!hmac_sha1_job_ok(vec
, job
, job
->user_data
,
453 padding
, sizeof(padding
)))
457 if (jobs_rx
!= num_jobs
) {
458 printf("Expected %d jobs, received %d\n", num_jobs
, jobs_rx
);
464 /* empty the manager before next tests */
465 while ((job
= IMB_FLUSH_JOB(mb_mgr
)) != NULL
)
468 for (i
= 0; i
< num_jobs
; i
++) {
469 if (auths
[i
] != NULL
)
481 test_hmac_sha1_std_vectors(struct MB_MGR
*mb_mgr
, const int num_jobs
)
483 const int vectors_cnt
=
484 sizeof(hmac_sha1_vectors
) / sizeof(hmac_sha1_vectors
[0]);
488 printf("HMAC-SHA1 standard test vectors (N jobs = %d):\n", num_jobs
);
489 for (vect
= 1; vect
<= vectors_cnt
; vect
++) {
490 const int idx
= vect
- 1;
492 printf("[%d/%d] RFC2202 Test Case %s key_len:%d data_len:%d "
495 hmac_sha1_vectors
[idx
].test_case
,
496 (int) hmac_sha1_vectors
[idx
].key_len
,
497 (int) hmac_sha1_vectors
[idx
].data_len
,
498 (int) hmac_sha1_vectors
[idx
].digest_len
);
503 if (test_hmac_sha1(mb_mgr
, &hmac_sha1_vectors
[idx
], num_jobs
)) {
504 printf("error #%d\n", vect
);
513 hmac_sha1_test(const enum arch_type arch
,
514 struct MB_MGR
*mb_mgr
)
518 (void) arch
; /* unused */
520 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 1);
521 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 3);
522 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 4);
523 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 5);
524 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 7);
525 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 8);
526 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 9);
527 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 15);
528 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 16);
529 errors
+= test_hmac_sha1_std_vectors(mb_mgr
, 17);