Software APIs
sha384_functest.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/lib/crypto/drivers/entropy.h"
6 #include "sw/device/lib/crypto/impl/status.h"
9 #include "sw/device/lib/testing/test_framework/check.h"
11 
12 /**
13  * First test from:
14  * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA384.pdf
15  */
16 static const unsigned char kOneBlockMessage[] = "abc";
17 static const size_t kOneBlockMessageLen = 3;
18 static const uint8_t kOneBlockExpDigest[] = {
19  0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
20  0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
21  0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
22  0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
23 
24 /**
25  * Second test from:
26  * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA384.pdf
27  */
28 static const unsigned char kTwoBlockMessage[] =
29  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjk"
30  "lmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
31 static const size_t kTwoBlockMessageLen = sizeof(kTwoBlockMessage) - 1;
32 static const uint8_t kTwoBlockExpDigest[] = {
33  0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, 0x3d, 0x19, 0x2f, 0xc7,
34  0x82, 0xcd, 0x1b, 0x47, 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
35  0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, 0xfc, 0xc7, 0xc7, 0x1a,
36  0x55, 0x7e, 0x2d, 0xb9, 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39};
37 
38 /**
39  * Expected digest for an empty message:
40  * =
41  * 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
42  */
43 static const uint8_t kEmptyExpDigest[] = {
44  0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e,
45  0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
46  0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf,
47  0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
48 };
49 
50 /**
51  * Run a single one-shot SHA-384 test.
52  */
53 status_t sha384_test(const unsigned char *msg, const size_t msg_len,
54  const uint8_t *expected_digest) {
55  // Construct a buffer for the message.
56  otcrypto_const_byte_buf_t input_message = {
57  .data = msg,
58  .len = msg_len,
59  };
60 
61  // Allocate space for the computed digest.
62  uint32_t actual_digest_data[384 / 32];
63  otcrypto_hash_digest_t actual_digest = {
64  .data = actual_digest_data,
65  .len = ARRAYSIZE(actual_digest_data),
66  .mode = kOtcryptoHashModeSha384,
67  };
68  TRY(otcrypto_hash(input_message, actual_digest));
69 
70  // Check that the expected and actual digests match.
71  TRY_CHECK_ARRAYS_EQ((unsigned char *)actual_digest_data, expected_digest,
72  sizeof(actual_digest_data));
73 
74  return OTCRYPTO_OK;
75 }
76 
77 /**
78  * Run a test using the SHA-384 streaming API.
79  */
80 status_t sha384_streaming_test(const unsigned char *msg, size_t msg_len,
81  const uint8_t *expected_digest) {
83  TRY(otcrypto_hash_init(&ctx, kOtcryptoHashModeSha384));
84 
85  // Send the message 5 bytes at a time.
86  while (msg_len > 0) {
87  // Construct a buffer for the next update.
88  size_t len = (msg_len <= 5) ? msg_len : 5;
89  otcrypto_const_byte_buf_t input_message = {
90  .data = msg,
91  .len = len,
92  };
93  msg += len;
94  msg_len -= len;
95  TRY(otcrypto_hash_update(&ctx, input_message));
96  }
97 
98  // Allocate space for the computed digest.
99  uint32_t actual_digest_data[384 / 32];
100  otcrypto_hash_digest_t actual_digest = {
101  .data = actual_digest_data,
102  .len = ARRAYSIZE(actual_digest_data),
103  .mode = kOtcryptoHashModeSha384,
104  };
105  TRY(otcrypto_hash_final(&ctx, actual_digest));
106 
107  // Check that the expected and actual digests match.
108  TRY_CHECK_ARRAYS_EQ((unsigned char *)actual_digest_data, expected_digest,
109  sizeof(actual_digest_data));
110 
111  return OTCRYPTO_OK;
112 }
113 
114 static status_t empty_test(void) {
115  return sha384_test(NULL, 0, kEmptyExpDigest);
116 }
117 
118 static status_t one_block_test(void) {
119  return sha384_test(kOneBlockMessage, kOneBlockMessageLen, kOneBlockExpDigest);
120 }
121 
122 static status_t two_block_test(void) {
123  return sha384_test(kTwoBlockMessage, kTwoBlockMessageLen, kTwoBlockExpDigest);
124 }
125 
126 static status_t streaming_test(void) {
127  return sha384_streaming_test(kTwoBlockMessage, kTwoBlockMessageLen,
128  kTwoBlockExpDigest);
129 }
130 
131 OTTF_DEFINE_TEST_CONFIG();
132 
133 // Holds the test result.
134 static volatile status_t test_result;
135 
136 bool test_main(void) {
137  test_result = OK_STATUS();
138  CHECK_STATUS_OK(entropy_complex_init());
139  EXECUTE_TEST(test_result, empty_test);
140  EXECUTE_TEST(test_result, one_block_test);
141  EXECUTE_TEST(test_result, two_block_test);
142  EXECUTE_TEST(test_result, streaming_test);
143  return status_ok(test_result);
144 }