5 #include "sw/device/lib/crypto/impl/integrity.h"
10 #include "sw/device/lib/testing/rand_testutils.h"
11 #include "sw/device/lib/testing/test_framework/check.h"
18 #include "hmac_testvectors.h"
21 #define MODULE_ID MAKE_MODULE_ID('h', 's', 't')
27 "Hash and Hmac contexts are expected to be of the same length");
44 typedef enum hmac_test_progress {
46 kHmacTestNotStarted = 0,
48 kHmacTestFeedSegment1 = 1,
50 kHmacTestFeedSegment2 = 2,
53 kHmacTestFeedSegment3 = 3,
56 kHmacTestFeedSegment4 = 4,
58 kHmacTestFinalize = 5,
61 } hmac_test_progress_t;
68 hmac_test_vector_t *hmac_test_vector;
74 size_t segment_idx[4];
76 hmac_test_progress_t progress;
82 kHmacExtendedTestVectors[2 *
ARRAYSIZE(kHmacTestVectors)];
93 static void vectors_populate(
void) {
95 hmac_test_vector_t *cur_vec;
97 for (
size_t i = 0; i <
ARRAYSIZE(kHmacTestVectors); i++) {
98 cur_ext_vec = &kHmacExtendedTestVectors[i];
99 cur_vec = &kHmacTestVectors[i];
100 cur_ext_vec->hmac_test_vector = cur_vec;
101 cur_ext_vec->original_idx = i;
102 cur_ext_vec->segment_count = rand_testutils_gen32_range(1, 4);
107 cur_ext_vec->segment_idx[0] = 0;
108 cur_ext_vec->segment_idx[2] =
109 rand_testutils_gen32_range(0, cur_vec->message.len);
110 cur_ext_vec->segment_idx[1] =
111 rand_testutils_gen32_range(0, cur_ext_vec->segment_idx[2]);
112 cur_ext_vec->segment_idx[3] = rand_testutils_gen32_range(
113 cur_ext_vec->segment_idx[2], cur_vec->message.len);
114 cur_ext_vec->progress = kHmacTestNotStarted;
118 for (
size_t i = 0; i <
ARRAYSIZE(kHmacTestVectors); i++) {
119 cur_ext_vec = &kHmacExtendedTestVectors[
ARRAYSIZE(kHmacTestVectors) + i];
120 cur_vec = &kHmacTestVectors[i];
121 cur_ext_vec->hmac_test_vector = cur_vec;
122 cur_ext_vec->original_idx = i;
123 cur_ext_vec->segment_count = 0;
124 cur_ext_vec->progress = kHmacTestNotStarted;
129 rand_testutils_shuffle(kHmacExtendedTestVectors,
132 for (
size_t i = 0; i <
ARRAYSIZE(kHmacExtendedTestVectors); i++) {
133 cur_ext_vec = &kHmacExtendedTestVectors[i];
134 cur_vec = cur_ext_vec->hmac_test_vector;
135 LOG_INFO(
"Vector order = %d, original_vector_id = %d", i,
136 cur_ext_vec->original_idx);
138 "segment_count = %d, segment_idx = [%d, %d, %d, %d], message_len = %d",
139 cur_ext_vec->segment_count, cur_ext_vec->segment_idx[0],
140 cur_ext_vec->segment_idx[1], cur_ext_vec->segment_idx[2],
141 cur_ext_vec->segment_idx[3],
142 cur_ext_vec->hmac_test_vector->message.len);
155 static status_t get_hash_mode(hmac_test_vector_t *test_vec,
157 switch (test_vec->test_operation) {
158 case kHmacTestOperationSha256:
159 *hash_mode = kOtcryptoHashModeSha256;
161 case kHmacTestOperationSha384:
162 *hash_mode = kOtcryptoHashModeSha384;
164 case kHmacTestOperationSha512:
165 *hash_mode = kOtcryptoHashModeSha512;
168 return OTCRYPTO_BAD_ARGS;
180 hmac_test_vector_t *current_test_vector) {
182 current_test_vector->key.checksum =
183 integrity_blinded_checksum(¤t_test_vector->key);
187 switch (current_test_vector->test_operation) {
188 case kHmacTestOperationSha256:
190 case kHmacTestOperationSha384:
192 case kHmacTestOperationSha512:
193 TRY(get_hash_mode(current_test_vector, &hash_mode));
196 case kHmacTestOperationHmacSha256:
198 case kHmacTestOperationHmacSha384:
200 case kHmacTestOperationHmacSha512:
202 ¤t_test_vector->key));
205 return OTCRYPTO_BAD_ARGS;
216 static status_t hmac_oneshot(hmac_test_vector_t *current_test_vector) {
218 current_test_vector->key.checksum =
219 integrity_blinded_checksum(¤t_test_vector->key);
222 size_t digest_len = current_test_vector->digest.len;
224 uint32_t act_tag[kSha512DigestWords];
234 switch (current_test_vector->test_operation) {
235 case kHmacTestOperationSha256:
237 case kHmacTestOperationSha384:
239 case kHmacTestOperationSha512:
240 TRY(get_hash_mode(current_test_vector, &hash_digest.mode));
241 TRY(
otcrypto_hash(current_test_vector->message, hash_digest));
243 case kHmacTestOperationHmacSha256:
245 case kHmacTestOperationHmacSha384:
247 case kHmacTestOperationHmacSha512:
248 TRY(
otcrypto_hmac(¤t_test_vector->key, current_test_vector->message,
252 return OTCRYPTO_BAD_ARGS;
254 LOG_INFO(
"Comparing result for %s.", current_test_vector->vector_identifier);
255 CHECK_ARRAYS_EQ(act_tag, current_test_vector->digest.data, digest_len);
273 hmac_test_vector_t *current_test_vector,
274 size_t segment_start,
size_t segment_len) {
276 .data = ¤t_test_vector->message.data[segment_start],
280 switch (current_test_vector->test_operation) {
281 case kHmacTestOperationSha256:
283 case kHmacTestOperationSha384:
285 case kHmacTestOperationSha512:
288 case kHmacTestOperationHmacSha256:
290 case kHmacTestOperationHmacSha384:
292 case kHmacTestOperationHmacSha512:
296 return OTCRYPTO_BAD_ARGS;
310 hmac_test_vector_t *current_test_vector) {
312 size_t digest_len = current_test_vector->digest.len;
314 uint32_t act_tag[kSha512DigestWords];
324 switch (current_test_vector->test_operation) {
325 case kHmacTestOperationSha256:
327 case kHmacTestOperationSha384:
329 case kHmacTestOperationSha512:
330 TRY(get_hash_mode(current_test_vector, &hash_digest.mode));
333 case kHmacTestOperationHmacSha256:
335 case kHmacTestOperationHmacSha384:
337 case kHmacTestOperationHmacSha512:
341 return OTCRYPTO_BAD_ARGS;
343 LOG_INFO(
"Comparing result for %s.", current_test_vector->vector_identifier);
344 CHECK_ARRAYS_EQ(act_tag, current_test_vector->digest.data, digest_len);
367 if (test_ext_vec->progress == kHmacTestDone) {
372 if (test_ext_vec->segment_count == 0 &&
373 test_ext_vec->progress == kHmacTestNotStarted) {
374 LOG_INFO(
"Invoking oneshot HMAC for vector #%d",
375 test_ext_vec->original_idx);
376 hmac_oneshot(test_ext_vec->hmac_test_vector);
378 test_ext_vec->progress = kHmacTestDone;
384 if (test_ext_vec->segment_count == 0 || test_ext_vec->segment_count > 4) {
385 return OTCRYPTO_BAD_ARGS;
389 if (test_ext_vec->progress == kHmacTestNotStarted) {
390 LOG_INFO(
"Initializing HMAC stream for vector #%d",
391 test_ext_vec->original_idx);
392 ctx_init(&test_ext_vec->hash_ctx, test_ext_vec->hmac_test_vector);
393 test_ext_vec->progress = kHmacTestFeedSegment1;
397 if (test_ext_vec->progress == kHmacTestFinalize) {
398 LOG_INFO(
"Finalizing HMAC stream for vector #%d",
399 test_ext_vec->original_idx);
400 hmac_finalize(&test_ext_vec->hash_ctx, test_ext_vec->hmac_test_vector);
401 test_ext_vec->progress = kHmacTestDone;
406 if (test_ext_vec->progress == test_ext_vec->segment_count) {
407 size_t segment_start =
408 test_ext_vec->segment_idx[test_ext_vec->progress - 1];
410 test_ext_vec->hmac_test_vector->message.len - segment_start;
412 if (segment_start > test_ext_vec->hmac_test_vector->message.len) {
413 return OTCRYPTO_BAD_ARGS;
415 LOG_INFO(
"Streaming the last segment #%d of vector #%d.",
416 test_ext_vec->progress, test_ext_vec->original_idx);
417 feed_msg(&test_ext_vec->hash_ctx, test_ext_vec->hmac_test_vector,
418 segment_start, segment_len);
419 test_ext_vec->progress = kHmacTestFinalize;
423 if (test_ext_vec->progress < test_ext_vec->segment_count) {
424 size_t segment_start =
425 test_ext_vec->segment_idx[test_ext_vec->progress - 1];
427 test_ext_vec->segment_idx[test_ext_vec->progress] - segment_start;
428 LOG_INFO(
"Streaming segment #%d of vector #%d.", test_ext_vec->progress,
429 test_ext_vec->original_idx);
430 feed_msg(&test_ext_vec->hash_ctx, test_ext_vec->hmac_test_vector,
431 segment_start, segment_len);
432 test_ext_vec->progress++;
435 return OTCRYPTO_BAD_ARGS;
445 for (
size_t i = kHmacTestNotStarted; i < kHmacTestDone; i++) {
446 for (
size_t j = 0; j <
ARRAYSIZE(kHmacExtendedTestVectors); j++) {
447 TRY(process_segment(&kHmacExtendedTestVectors[j]));
453 OTTF_DEFINE_TEST_CONFIG();
455 LOG_INFO(
"Testing cryptolib SHA-2/HMAC with parallel multiple streams.");
458 return status_ok(test_result);