Software APIs
sha512_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/SHA512.pdf
15  */
16 static const unsigned char kOneBlockMessage[] = "abc";
17 static const size_t kOneBlockMessageLen = 3;
18 static const uint8_t kOneBlockExpDigest[] = {
19  0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73,
20  0x49, 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9,
21  0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21,
22  0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23,
23  0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8,
24  0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
25 };
26 
27 /**
28  * Second test from:
29  * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512.pdf
30  */
31 static const unsigned char kTwoBlockMessage[] =
32  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjk"
33  "lmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
34 static const size_t kTwoBlockMessageLen = sizeof(kTwoBlockMessage) - 1;
35 static const uint8_t kTwoBlockExpDigest[] = {
36  0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, 0x8c, 0xf4, 0xf7,
37  0x28, 0x14, 0xfc, 0x14, 0x3f, 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f,
38  0x7f, 0xa1, 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, 0x50,
39  0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, 0x33, 0x1b, 0x99, 0xde,
40  0xc4, 0xb5, 0x43, 0x3a, 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26,
41  0x54, 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09};
42 
43 /**
44  * Run a single one-shot SHA-512 test.
45  */
46 status_t sha512_test(const unsigned char *msg, const size_t msg_len,
47  const uint8_t *expected_digest) {
48  // Construct a buffer for the message.
49  otcrypto_const_byte_buf_t input_message = {
50  .data = msg,
51  .len = msg_len,
52  };
53 
54  // Allocate space for the computed digest.
55  uint32_t actual_digest_data[512 / 32];
56  otcrypto_hash_digest_t actual_digest = {
57  .len = ARRAYSIZE(actual_digest_data),
58  .data = actual_digest_data,
59  .mode = kOtcryptoHashModeSha512,
60  };
61  TRY(otcrypto_hash(input_message, actual_digest));
62 
63  // Check that the expected and actual digests match.
64  TRY_CHECK_ARRAYS_EQ((unsigned char *)actual_digest_data, expected_digest,
65  sizeof(actual_digest_data));
66 
67  return OTCRYPTO_OK;
68 }
69 
70 /**
71  * Run a test using the SHA-512 streaming API.
72  */
73 status_t sha512_streaming_test(const unsigned char *msg, size_t msg_len,
74  const uint8_t *expected_digest) {
76  TRY(otcrypto_hash_init(&ctx, kOtcryptoHashModeSha512));
77 
78  // Send the message 5 bytes at a time.
79  while (msg_len > 0) {
80  // Construct a buffer for the next update.
81  size_t len = (msg_len <= 5) ? msg_len : 5;
82  otcrypto_const_byte_buf_t input_message = {
83  .data = msg,
84  .len = len,
85  };
86  msg += len;
87  msg_len -= len;
88  TRY(otcrypto_hash_update(&ctx, input_message));
89  }
90 
91  // Allocate space for the computed digest.
92  uint32_t actual_digest_data[512 / 32];
93  otcrypto_hash_digest_t actual_digest = {
94  .data = actual_digest_data,
95  .len = ARRAYSIZE(actual_digest_data),
96  .mode = kOtcryptoHashModeSha512,
97  };
98  TRY(otcrypto_hash_final(&ctx, actual_digest));
99 
100  // Check that the expected and actual digests match.
101  TRY_CHECK_ARRAYS_EQ((unsigned char *)actual_digest_data, expected_digest,
102  sizeof(actual_digest_data));
103 
104  return OTCRYPTO_OK;
105 }
106 
107 static status_t one_block_test(void) {
108  return sha512_test(kOneBlockMessage, kOneBlockMessageLen, kOneBlockExpDigest);
109 }
110 
111 static status_t two_block_test(void) {
112  return sha512_test(kTwoBlockMessage, kTwoBlockMessageLen, kTwoBlockExpDigest);
113 }
114 
115 static status_t streaming_test(void) {
116  return sha512_streaming_test(kTwoBlockMessage, kTwoBlockMessageLen,
117  kTwoBlockExpDigest);
118 }
119 
120 OTTF_DEFINE_TEST_CONFIG();
121 
122 // Holds the test result.
123 static volatile status_t test_result;
124 
125 bool test_main(void) {
126  test_result = OK_STATUS();
127  CHECK_STATUS_OK(entropy_complex_init());
128  EXECUTE_TEST(test_result, one_block_test);
129  EXECUTE_TEST(test_result, two_block_test);
130  EXECUTE_TEST(test_result, streaming_test);
131  return status_ok(test_result);
132 }