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