1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <crypto/secret.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <unittest/unittest.h>
9 #include <zircon/types.h>
10 
11 #include "utils.h"
12 
13 namespace crypto {
14 namespace testing {
15 namespace {
16 
17 const size_t kSize = 1024;
18 
TestAllocate(void)19 bool TestAllocate(void) {
20     BEGIN_TEST;
21     Secret secret;
22     uint8_t* buf = nullptr;
23     uint8_t tmp[kSize] = {0};
24 
25     // Pre-allocation
26     EXPECT_EQ(secret.len(), 0U);
27     EXPECT_NULL(secret.get());
28 
29     // Invalid args
30     ASSERT_DEATH(
31         [](void* arg) {
32             uint8_t* buf;
33             static_cast<Secret*>(arg)->Allocate(0, &buf);
34         },
35         &secret, "zero length");
36     ASSERT_DEATH([](void* arg) { static_cast<Secret*>(arg)->Allocate(kSize, nullptr); }, &secret,
37                  "null buffer");
38 
39     // Valid
40     EXPECT_OK(secret.Allocate(kSize, &buf));
41     EXPECT_EQ(secret.len(), kSize);
42     ASSERT_NONNULL(secret.get());
43     EXPECT_EQ(memcmp(secret.get(), tmp, kSize), 0);
44 
45     // Fill with data
46     EXPECT_NONNULL(buf);
47     memset(buf, 1, kSize);
48     memset(tmp, 1, kSize);
49     EXPECT_EQ(memcmp(secret.get(), tmp, kSize), 0);
50 
51     // Ensure memory is reinitialized on reallocation
52     EXPECT_OK(secret.Allocate(kSize, &buf));
53     memset(tmp, 0, kSize);
54     EXPECT_EQ(memcmp(secret.get(), tmp, kSize), 0);
55 
56     END_TEST;
57 }
58 
59 // This test only checks that the routine basically functions; it does NOT assure anything about the
60 // quality of the entropy.  That topic is beyond the scope of a deterministic unit test.
TestGenerate(void)61 bool TestGenerate(void) {
62     BEGIN_TEST;
63 
64     Secret secret;
65     uint8_t tmp[kSize] = {0};
66 
67     // Invalid args
68     ASSERT_DEATH([](void* arg) { static_cast<Secret*>(arg)->Generate(0); }, &secret, "zero length");
69 
70     // Valid
71     EXPECT_OK(secret.Generate(kSize));
72     EXPECT_EQ(secret.len(), kSize);
73     ASSERT_NONNULL(secret.get());
74     EXPECT_NE(memcmp(secret.get(), tmp, kSize), 0);
75     memcpy(tmp, secret.get(), kSize);
76 
77     // Ensure different results on regeneration
78     EXPECT_OK(secret.Generate(kSize));
79     EXPECT_NE(memcmp(secret.get(), tmp, kSize), 0);
80 
81     END_TEST;
82 }
83 
TestClear(void)84 bool TestClear(void) {
85     BEGIN_TEST;
86 
87     Secret secret;
88     secret.Clear();
89 
90     EXPECT_OK(secret.Generate(kSize));
91     EXPECT_EQ(secret.len(), kSize);
92     EXPECT_NONNULL(secret.get());
93 
94     secret.Clear();
95     EXPECT_EQ(secret.len(), 0);
96     EXPECT_NULL(secret.get());
97 
98     secret.Clear();
99 
100     END_TEST;
101 }
102 
103 BEGIN_TEST_CASE(SecretTest)
104 RUN_TEST(TestAllocate)
105 RUN_TEST(TestGenerate)
106 RUN_TEST(TestClear)
107 END_TEST_CASE(SecretTest)
108 
109 } // namespace
110 } // namespace testing
111 } // namespace crypto
112