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