Software APIs
drbg_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/base/status.h"
6 #include "sw/device/lib/crypto/drivers/entropy.h"
9 #include "sw/device/lib/testing/randomness_quality.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
12 
14 
15 #define MODULE_ID MAKE_MODULE_ID('t', 's', 't')
16 
17 OTTF_DEFINE_TEST_CONFIG();
18 
19 static const uint32_t kTestSeed[12] = {
20  0x73bec010, 0x9262474c, 0x16a30f76, 0x531b51de, 0x2ee494e5, 0xdfec9db3,
21  0xcb7a879d, 0x5600419c, 0xca79b0b0, 0xdda33b5c, 0xa468649e, 0xdf5d73fa};
22 // Note that the word order in the expected output is reversed compared to the
23 // NIST reference.
24 static const uint32_t kExpOutput[16] = {
25  0xd1c07cd9, 0x5af8a7f1, 0x1012c84c, 0xe48bb8cb, 0x87189e99, 0xd40fccb1,
26  0x771c619b, 0xdf82ab22, 0x80b1dc2f, 0x2581f391, 0x64f7ac0c, 0x510494b3,
27  0xa43c41b7, 0xdb17514c, 0x87b107ae, 0x793e01c5,
28 };
29 static const otcrypto_const_byte_buf_t kEmptyBuffer = {
30  .data = NULL,
31  .len = 0,
32 };
33 
34 static status_t kat_test(void) {
35  otcrypto_const_byte_buf_t entropy = {
36  .data = (const unsigned char *)kTestSeed,
37  .len = sizeof(kTestSeed),
38  };
39 
40  // Instantiate DRBG.
41  TRY(otcrypto_drbg_manual_instantiate(entropy, /*perso_string=*/kEmptyBuffer));
42 
43  uint32_t actual_output_words[ARRAYSIZE(kExpOutput)];
44  otcrypto_word32_buf_t actual_output = {
45  .data = actual_output_words,
46  .len = ARRAYSIZE(actual_output_words),
47  };
48 
49  // Generate output twice.
50  LOG_INFO("Generating...");
51  TRY(otcrypto_drbg_manual_generate(/*additional_input=*/kEmptyBuffer,
52  actual_output));
53  LOG_INFO("Generating again...");
54  TRY(otcrypto_drbg_manual_generate(/*additional_input=*/kEmptyBuffer,
55  actual_output));
56 
57  // Compare second result to expected output.
58  TRY_CHECK_ARRAYS_EQ(kExpOutput, actual_output_words, ARRAYSIZE(kExpOutput));
59  TRY_CHECK_ARRAYS_EQ(kExpOutput, kExpOutput, 0);
60 
61  return OK_STATUS();
62 }
63 
64 static status_t random_test(void) {
65  // Instantiate DRBG.
66  TRY(otcrypto_drbg_instantiate(/*perso_string=*/kEmptyBuffer));
67 
68  // Generate a relatively large amount of output data.
69  uint32_t output_data[1024];
70  otcrypto_word32_buf_t output = {
71  .data = output_data,
72  .len = ARRAYSIZE(output_data),
73  };
74  TRY(otcrypto_drbg_generate(/*additional_input=*/kEmptyBuffer, output));
75 
76  // Run a basic randomness-quality check on the output.
77  return randomness_quality_monobit_test(
78  (unsigned char *)output_data, sizeof(output_data),
79  kRandomnessQualitySignificanceOnePercent);
80 }
81 
82 bool test_main(void) {
83  status_t result = OK_STATUS();
84 
85  // Initialize the entropy complex.
86  CHECK_STATUS_OK(entropy_complex_init());
87  CHECK_STATUS_OK(entropy_complex_check());
88 
89  EXECUTE_TEST(result, kat_test);
90  EXECUTE_TEST(result, random_test);
91  return status_ok(result);
92 }