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 <stddef.h>
6 #include <stdint.h>
7
8 #include <crypto/bytes.h>
9 #include <unittest/unittest.h>
10 #include <zircon/types.h>
11
12 #include "utils.h"
13
14 namespace crypto {
15 namespace testing {
16 namespace {
17
18 const size_t kSize = 1024;
19
20
AllEqual(const void * buf,uint8_t val,zx_off_t off,size_t len)21 bool AllEqual(const void* buf, uint8_t val, zx_off_t off, size_t len) {
22 BEGIN_HELPER;
23 const uint8_t* u8 = static_cast<const uint8_t*>(buf);
24 size_t end;
25 ASSERT_FALSE(add_overflow(off, len, &end));
26 for (size_t i = off; i < end; ++i) {
27 if(u8[i] != val) {
28 return false;
29 }
30 }
31 END_HELPER;
32 }
33
34 // This test only checks that the routine basically functions; it does NOT assure anything about the
35 // quality of the entropy. That topic is beyond the scope of a deterministic unit test.
TestRandomize(void)36 bool TestRandomize(void) {
37 BEGIN_TEST;
38 Bytes bytes;
39
40 ASSERT_OK(bytes.Resize(kSize));
41 ASSERT_TRUE(AllEqual(bytes.get(), 0, 0, kSize));
42
43 EXPECT_OK(bytes.Randomize(kSize));
44 EXPECT_FALSE(AllEqual(bytes.get(), 0, 0, kSize));
45
46 END_TEST;
47 }
48
TestResize(void)49 bool TestResize(void) {
50 BEGIN_TEST;
51 Bytes bytes;
52 EXPECT_OK(bytes.Resize(kSize, 0xff));
53 EXPECT_EQ(bytes.len(), kSize);
54 EXPECT_NONNULL(bytes.get());
55
56 #if !__has_feature(address_sanitizer)
57 // The ASan allocator reports errors for unreasonable allocation sizes.
58 EXPECT_ZX(bytes.Resize(size_t(-1)), ZX_ERR_NO_MEMORY);
59 EXPECT_EQ(bytes.len(), kSize);
60 EXPECT_NONNULL(bytes.get());
61 EXPECT_TRUE(AllEqual(bytes.get(), 0xff, 0, kSize));
62 #endif
63
64 EXPECT_OK(bytes.Resize(kSize));
65 EXPECT_EQ(bytes.len(), kSize);
66 EXPECT_NONNULL(bytes.get());
67 EXPECT_TRUE(AllEqual(bytes.get(), 0xff, 0, kSize));
68
69 EXPECT_OK(bytes.Resize(kSize / 2));
70 EXPECT_EQ(bytes.len(), kSize / 2);
71 EXPECT_NONNULL(bytes.get());
72 EXPECT_TRUE(AllEqual(bytes.get(), 0xff, 0, kSize / 2));
73
74 EXPECT_OK(bytes.Resize(kSize));
75 EXPECT_EQ(bytes.len(), kSize);
76 EXPECT_NONNULL(bytes.get());
77 EXPECT_TRUE(AllEqual(bytes.get(), 0xff, 0, kSize / 2));
78 EXPECT_TRUE(AllEqual(bytes.get(), 0, kSize / 2, kSize / 2));
79
80 EXPECT_OK(bytes.Resize(0));
81 EXPECT_EQ(bytes.len(), 0U);
82 EXPECT_NULL(bytes.get());
83 END_TEST;
84 }
85
TestCopy(void)86 bool TestCopy(void) {
87 BEGIN_TEST;
88 Bytes bytes, copy;
89 ASSERT_OK(bytes.Resize(kSize));
90
91 uint8_t buf[kSize];
92 memset(buf, 2, kSize);
93 EXPECT_ZX(bytes.Copy(nullptr, kSize, kSize), ZX_ERR_INVALID_ARGS);
94 EXPECT_OK(bytes.Copy(buf, 0, kSize * 10));
95 EXPECT_EQ(bytes.len(), kSize);
96 EXPECT_TRUE(AllEqual(bytes.get(), 0, 0, kSize));
97
98 EXPECT_OK(bytes.Copy(buf, kSize, kSize));
99 EXPECT_TRUE(AllEqual(bytes.get(), 0, 0, kSize));
100 EXPECT_TRUE(AllEqual(bytes.get(), 2, kSize, kSize));
101
102 memset(buf, 1, kSize);
103 EXPECT_OK(bytes.Copy(buf, kSize / 2, kSize / 2));
104 EXPECT_TRUE(AllEqual(bytes.get(), 0, 0, kSize / 2));
105 EXPECT_TRUE(AllEqual(bytes.get(), 1, kSize / 2, kSize / 2));
106 EXPECT_TRUE(AllEqual(bytes.get(), 2, kSize, kSize));
107
108 ASSERT_OK(bytes.Resize(0));
109 EXPECT_OK(bytes.Copy(buf, kSize));
110 EXPECT_EQ(bytes.len(), kSize);
111 EXPECT_TRUE(AllEqual(bytes.get(), 1, 0, kSize));
112
113 EXPECT_OK(copy.Copy(bytes));
114 EXPECT_TRUE(AllEqual(copy.get(), 1, 0, kSize));
115
116 EXPECT_OK(copy.Copy(bytes, kSize));
117 EXPECT_TRUE(AllEqual(copy.get(), 1, 0, kSize * 2));
118
119 END_TEST;
120 }
121
TestArrayAccess(void)122 bool TestArrayAccess(void) {
123 BEGIN_TEST;
124 Bytes bytes;
125 ASSERT_OK(bytes.Resize(kSize, 1));
126 for (size_t i = 0; i < kSize; ++i) {
127 EXPECT_EQ(bytes[i], 1);
128 bytes[i] = 2;
129 }
130 EXPECT_TRUE(AllEqual(bytes.get(), 2, 0, kSize));
131 END_TEST;
132 }
133
TestComparison(void)134 bool TestComparison(void) {
135 BEGIN_TEST;
136 Bytes bytes1, bytes2;
137 ASSERT_OK(bytes1.Randomize(kSize));
138 ASSERT_OK(bytes2.Copy(bytes1.get(), bytes1.len()));
139 EXPECT_TRUE(bytes1 == bytes1);
140 EXPECT_TRUE(bytes2 == bytes2);
141 EXPECT_FALSE(bytes1 != bytes1);
142 EXPECT_FALSE(bytes2 != bytes2);
143 EXPECT_TRUE(bytes1 == bytes2);
144 EXPECT_TRUE(bytes2 == bytes1);
145 EXPECT_FALSE(bytes1 != bytes2);
146 EXPECT_FALSE(bytes2 != bytes1);
147
148 ASSERT_OK(bytes2.Randomize(kSize));
149 EXPECT_TRUE(bytes1 == bytes1);
150 EXPECT_TRUE(bytes2 == bytes2);
151 EXPECT_FALSE(bytes1 != bytes1);
152 EXPECT_FALSE(bytes2 != bytes2);
153 EXPECT_FALSE(bytes1 == bytes2);
154 EXPECT_FALSE(bytes2 == bytes1);
155 EXPECT_TRUE(bytes1 != bytes2);
156 EXPECT_TRUE(bytes2 != bytes1);
157 END_TEST;
158 }
159
160 BEGIN_TEST_CASE(BytesTest)
161 RUN_TEST(TestRandomize)
162 RUN_TEST(TestResize)
163 RUN_TEST(TestCopy)
164 RUN_TEST(TestArrayAccess)
165 RUN_TEST(TestComparison)
166 END_TEST_CASE(BytesTest)
167
168 } // namespace
169 } // namespace testing
170 } // namespace crypto
171