1 //
2 // Copyright (C) 2016 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <algorithm>
18 #include <string>
19 #include <vector>
20
21 #include <android-base/logging.h>
22 #include <android-base/macros.h>
23 #include <gtest/gtest.h>
24 #include <hardware/nvram.h>
25 #include <openssl/sha.h>
26
27 #include "nvram/hal/tests/scoped_nvram_device.h"
28
29 namespace {
30
31 constexpr uint32_t kTestIndex1 = 0xDEAD0001;
32 constexpr uint32_t kTestIndex2 = 0xDEAD0002;
33 constexpr uint32_t kTestIndexNeverExists = 0xDEAD0003;
34 // Once we run a test that locks writing, that space is burned until reboot.
35 // This value is the base index from which to dynamically burn spaces.
36 constexpr uint32_t kTestIndexBurnBase = 0xDEAD0010;
37 constexpr uint32_t kTestIndexBurnMax = 0xDEAD00FF;
38 constexpr nvram_control_t kDefaultControls[] = {NV_CONTROL_BOOT_WRITE_LOCK,
39 NV_CONTROL_BOOT_READ_LOCK};
40 constexpr char kNoAuth[] = "";
41 // If using authorization with an index returned by GetNextBurnSpace use this
42 // as the value so the space can be cleaned up later.
43 constexpr char kBurnSpaceAuth[] = "hal_test_burn";
44
45 // Returns true if |target| contains |value|.
46 template <typename T>
Contains(T value,const std::vector<T> & target)47 bool Contains(T value, const std::vector<T>& target) {
48 return (std::find(target.begin(), target.end(), value) != target.end());
49 }
50
51 // Returns true if |target| contains all of |values|.
52 template <typename T>
ContainsAll(const std::vector<T> & values,const std::vector<T> & target)53 bool ContainsAll(const std::vector<T>& values,
54 const std::vector<T>& target) {
55 return std::all_of(values.begin(), values.end(),
56 [target](T value) { return Contains(value, target); });
57 }
58
59 // Adds a few safety checks so tests don't get hardware into a state where it
60 // needs factory reset.
61 class SafeScopedNvramDevice : public nvram::ScopedNvramDevice {
62 public:
CreateSpace(uint32_t index,uint64_t size_in_bytes,const std::vector<nvram_control_t> & control_list,const std::string & authorization_value)63 nvram_result_t CreateSpace(uint32_t index,
64 uint64_t size_in_bytes,
65 const std::vector<nvram_control_t>& control_list,
66 const std::string& authorization_value) override {
67 CHECK(!Contains(NV_CONTROL_PERSISTENT_WRITE_LOCK, control_list))
68 << "Do not use NV_CONTROL_PERSISTENT_WRITE_LOCK in tests.";
69 CHECK(!Contains(NV_CONTROL_BOOT_WRITE_LOCK, control_list) ||
70 !Contains(NV_CONTROL_WRITE_AUTHORIZATION, control_list) ||
71 authorization_value == kNoAuth ||
72 authorization_value == kBurnSpaceAuth)
73 << "Do not lock spaces with unknown authorization values.";
74 return nvram::ScopedNvramDevice::CreateSpace(
75 index, size_in_bytes, control_list, authorization_value);
76 }
77
DisableCreate()78 nvram_result_t DisableCreate() override {
79 LOG(FATAL) << "Do not use DisableCreate in tests.";
80 return NV_RESULT_OPERATION_DISABLED;
81 }
82 };
83
84 class ScopedNvramSpace {
85 public:
ScopedNvramSpace(SafeScopedNvramDevice * device,uint32_t index,uint32_t size)86 ScopedNvramSpace(SafeScopedNvramDevice* device, uint32_t index, uint32_t size)
87 : ScopedNvramSpace(device,
88 index,
89 size,
90 std::vector<nvram_control_t>(
91 &kDefaultControls[0],
92 &kDefaultControls[arraysize(kDefaultControls)]),
93 kNoAuth) {}
94
ScopedNvramSpace(SafeScopedNvramDevice * device,uint32_t index,uint32_t size,const std::vector<nvram_control_t> & control_list)95 ScopedNvramSpace(SafeScopedNvramDevice* device,
96 uint32_t index,
97 uint32_t size,
98 const std::vector<nvram_control_t>& control_list)
99 : ScopedNvramSpace(device,
100 index,
101 size,
102 control_list,
103 kNoAuth) {}
104
ScopedNvramSpace(SafeScopedNvramDevice * device,uint32_t index,uint32_t size,const std::vector<nvram_control_t> & control_list,const std::string & authorization_value)105 ScopedNvramSpace(SafeScopedNvramDevice* device,
106 uint32_t index,
107 uint32_t size,
108 const std::vector<nvram_control_t>& control_list,
109 const std::string& authorization_value)
110 : device_(device),
111 index_(index),
112 authorization_value_(authorization_value) {
113 Create(size, control_list);
114 }
115
~ScopedNvramSpace()116 ~ScopedNvramSpace() { Delete(); }
117
118 private:
Create(uint32_t size,const std::vector<nvram_control_t> & control_list)119 void Create(uint32_t size,
120 const std::vector<nvram_control_t>& control_list) {
121 ASSERT_EQ(
122 NV_RESULT_SUCCESS,
123 device_->CreateSpace(index_, size, control_list, authorization_value_));
124 }
125
Delete()126 void Delete() {
127 ASSERT_EQ(NV_RESULT_SUCCESS,
128 device_->DeleteSpace(index_, authorization_value_));
129 }
130
131 SafeScopedNvramDevice* device_;
132 uint32_t index_;
133 std::string authorization_value_;
134 };
135
136 // Remove all unlocked burn spaces. Returns false on failure.
CleanBurnSpaces(SafeScopedNvramDevice * device)137 bool CleanBurnSpaces(SafeScopedNvramDevice* device) {
138 // Burned spaces will only be available for cleanup after reboot so there's no
139 // sense in attempting cleanup more than once.
140 static bool cleaned = false;
141 if (cleaned) {
142 return true;
143 }
144 bool success = true;
145 cleaned = true;
146 std::vector<uint32_t> space_index_list;
147 if (device->GetSpaceList(&space_index_list) != NV_RESULT_SUCCESS) {
148 return false;
149 }
150 for (uint32_t index : space_index_list) {
151 if (index >= kTestIndexBurnBase && index <= kTestIndexBurnMax) {
152 int write_lock, read_lock;
153 if (device->IsSpaceLocked(index, &write_lock, &read_lock) !=
154 NV_RESULT_SUCCESS) {
155 success = false;
156 continue;
157 }
158 if (!write_lock) {
159 nvram_result_t result = device->DeleteSpace(index, kNoAuth);
160 if (result == NV_RESULT_ACCESS_DENIED) {
161 result = device->DeleteSpace(index, kBurnSpaceAuth);
162 }
163 if (result != NV_RESULT_SUCCESS) {
164 success = false;
165 continue;
166 }
167 }
168 }
169 }
170 return success;
171 }
172
173 // Returns the next available burn space index. If using authorization, the
174 // value MUST be kBurnSpaceAuth.
GetNextBurnSpace(SafeScopedNvramDevice * device,uint32_t * index)175 bool GetNextBurnSpace(SafeScopedNvramDevice* device, uint32_t* index) {
176 if (!CleanBurnSpaces(device)) {
177 return false;
178 }
179 std::vector<uint32_t> space_index_list;
180 if (device->GetSpaceList(&space_index_list) != NV_RESULT_SUCCESS) {
181 return false;
182 }
183 *index = kTestIndexBurnBase;
184 while (Contains(*index, space_index_list)) {
185 (*index)++;
186 }
187 if (*index >= kTestIndexBurnMax) {
188 return false;
189 }
190 return true;
191 }
192
SHA256HashString(const std::string & input)193 std::string SHA256HashString(const std::string& input) {
194 uint8_t hash[SHA256_DIGEST_LENGTH];
195 SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(), hash);
196 return std::string(reinterpret_cast<const char*>(hash), SHA256_DIGEST_LENGTH);
197 }
198
199 } // namespace
200
201 namespace nvram {
202
TEST(NVRAMModuleTest,TotalSize)203 TEST(NVRAMModuleTest, TotalSize) {
204 SafeScopedNvramDevice device;
205 uint64_t total_size = 0;
206 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetTotalSizeInBytes(&total_size));
207 EXPECT_LE(2048u, total_size);
208 };
209
TEST(NVRAMModuleTest,AvailableSize)210 TEST(NVRAMModuleTest, AvailableSize) {
211 SafeScopedNvramDevice device;
212 uint64_t available_size = 0;
213 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetAvailableSizeInBytes(&available_size));
214 uint64_t total_size = 0;
215 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetTotalSizeInBytes(&total_size));
216 EXPECT_LE(available_size, total_size);
217 }
218
TEST(NVRAMModuleTest,MaxSpaceSize)219 TEST(NVRAMModuleTest, MaxSpaceSize) {
220 SafeScopedNvramDevice device;
221 uint64_t max_space_size = 0;
222 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetMaxSpaceSizeInBytes(&max_space_size));
223 uint64_t total_size = 0;
224 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetTotalSizeInBytes(&total_size));
225 EXPECT_LE(max_space_size, total_size);
226 EXPECT_GE(max_space_size, 32u);
227 }
228
TEST(NVRAMModuleTest,MaxSpaces)229 TEST(NVRAMModuleTest, MaxSpaces) {
230 SafeScopedNvramDevice device;
231 uint32_t num_spaces = 0;
232 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetMaxSpaces(&num_spaces));
233 EXPECT_LE(8u, num_spaces);
234 }
235
TEST(NVRAMModuleTest,SpaceList)236 TEST(NVRAMModuleTest, SpaceList) {
237 SafeScopedNvramDevice device;
238 uint32_t max_spaces = 0;
239 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetMaxSpaces(&max_spaces));
240 std::vector<uint32_t> space_index_list;
241 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetSpaceList(&space_index_list));
242 ASSERT_LE(space_index_list.size(), max_spaces);
243
244 // Add a test space and check it gets reported.
245 {
246 ScopedNvramSpace space(&device, kTestIndex1, 32);
247 std::vector<uint32_t> space_index_list2;
248 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetSpaceList(&space_index_list2));
249 ASSERT_EQ(space_index_list.size() + 1, space_index_list2.size());
250 EXPECT_TRUE(ContainsAll(space_index_list, space_index_list2));
251 EXPECT_TRUE(Contains(kTestIndex1, space_index_list2));
252 }
253
254 // Check we're back to the original list.
255 std::vector<uint32_t> space_index_list3;
256 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetSpaceList(&space_index_list3));
257 ASSERT_EQ(space_index_list.size(), space_index_list3.size());
258 EXPECT_TRUE(ContainsAll(space_index_list, space_index_list3));
259 EXPECT_FALSE(Contains(kTestIndex1, space_index_list3));
260 }
261
TEST(NVRAMModuleTest,SpaceSize)262 TEST(NVRAMModuleTest, SpaceSize) {
263 SafeScopedNvramDevice device;
264 ScopedNvramSpace space(&device, kTestIndex1, 17);
265 ScopedNvramSpace space2(&device, kTestIndex2, 32);
266 uint64_t size = 0;
267 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetSpaceSize(kTestIndex1, &size));
268 EXPECT_EQ(17u, size);
269 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetSpaceSize(kTestIndex2, &size));
270 EXPECT_EQ(32u, size);
271 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
272 device.GetSpaceSize(kTestIndexNeverExists, &size));
273 }
274
TEST(NVRAMModuleTest,SpaceControls)275 TEST(NVRAMModuleTest, SpaceControls) {
276 SafeScopedNvramDevice device;
277 ScopedNvramSpace space(&device, kTestIndex1, 32);
278 std::vector<nvram_control_t> expected_control_list(
279 &kDefaultControls[0], &kDefaultControls[arraysize(kDefaultControls)]);
280 std::vector<nvram_control_t> control_list;
281 ASSERT_EQ(NV_RESULT_SUCCESS,
282 device.GetSpaceControls(kTestIndex1, &control_list));
283 ASSERT_EQ(expected_control_list.size(), control_list.size());
284 EXPECT_TRUE(ContainsAll(expected_control_list, control_list));
285 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
286 device.GetSpaceControls(kTestIndexNeverExists, &control_list));
287 }
288
TEST(NVRAMModuleTest,IsLocked)289 TEST(NVRAMModuleTest, IsLocked) {
290 SafeScopedNvramDevice device;
291 ScopedNvramSpace space(&device, kTestIndex1, 32);
292 int write_lock, read_lock;
293 ASSERT_EQ(NV_RESULT_SUCCESS,
294 device.IsSpaceLocked(kTestIndex1, &write_lock, &read_lock));
295 EXPECT_FALSE(read_lock);
296 EXPECT_FALSE(write_lock);
297 ASSERT_EQ(NV_RESULT_SUCCESS, device.EnableReadLock(kTestIndex1, kNoAuth));
298 ASSERT_EQ(NV_RESULT_SUCCESS,
299 device.IsSpaceLocked(kTestIndex1, &write_lock, &read_lock));
300 EXPECT_TRUE(read_lock);
301 EXPECT_FALSE(write_lock);
302 EXPECT_EQ(
303 NV_RESULT_SPACE_DOES_NOT_EXIST,
304 device.IsSpaceLocked(kTestIndexNeverExists, &write_lock, &read_lock));
305 }
306
TEST(NVRAMModuleTest,CreateSmall)307 TEST(NVRAMModuleTest, CreateSmall) {
308 SafeScopedNvramDevice device;
309 ScopedNvramSpace space(&device, kTestIndex1, 1);
310 }
311
TEST(NVRAMModuleTest,CreateLarge)312 TEST(NVRAMModuleTest, CreateLarge) {
313 SafeScopedNvramDevice device;
314 uint64_t max_space_size = 0;
315 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetMaxSpaceSizeInBytes(&max_space_size));
316 uint64_t available_size = 0;
317 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetAvailableSizeInBytes(&available_size));
318 ScopedNvramSpace space(&device, kTestIndex1,
319 std::min(max_space_size, available_size));
320 }
321
TEST(NVRAMModuleTest,CreateWithCustomControls)322 TEST(NVRAMModuleTest, CreateWithCustomControls) {
323 const std::vector<nvram_control_t> kControlList{
324 NV_CONTROL_BOOT_WRITE_LOCK, NV_CONTROL_READ_AUTHORIZATION,
325 NV_CONTROL_WRITE_EXTEND};
326 SafeScopedNvramDevice device;
327 ScopedNvramSpace space(&device, kTestIndex1, 32, kControlList);
328 std::vector<nvram_control_t> control_list;
329 ASSERT_EQ(NV_RESULT_SUCCESS,
330 device.GetSpaceControls(kTestIndex1, &control_list));
331 ASSERT_EQ(kControlList.size(), control_list.size());
332 EXPECT_TRUE(ContainsAll(control_list, kControlList));
333 EXPECT_TRUE(ContainsAll(kControlList, control_list));
334 }
335
TEST(NVRAMModuleTest,CreateWithAuthorization)336 TEST(NVRAMModuleTest, CreateWithAuthorization) {
337 SafeScopedNvramDevice device;
338 std::string password = "hunter2";
339 ScopedNvramSpace space(
340 &device, kTestIndex1, 32,
341 {NV_CONTROL_WRITE_AUTHORIZATION, NV_CONTROL_READ_AUTHORIZATION},
342 password);
343 std::string data = "test";
344 std::string bad_password = "*******";
345 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
346 device.WriteSpace(kTestIndex1, data, bad_password));
347 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(kTestIndex1, data, password));
348 }
349
TEST(NVRAMModuleTest,CreateAlreadyExists)350 TEST(NVRAMModuleTest, CreateAlreadyExists) {
351 SafeScopedNvramDevice device;
352 ScopedNvramSpace space(&device, kTestIndex1, 32);
353 EXPECT_EQ(NV_RESULT_SPACE_ALREADY_EXISTS,
354 device.CreateSpace(kTestIndex1, 32, {}, kNoAuth));
355 }
356
TEST(NVRAMModuleTest,Delete)357 TEST(NVRAMModuleTest, Delete) {
358 SafeScopedNvramDevice device;
359 {
360 ScopedNvramSpace space(&device, kTestIndex1, 32);
361 uint64_t size = 0;
362 EXPECT_EQ(NV_RESULT_SUCCESS, device.GetSpaceSize(kTestIndex1, &size));
363 }
364 // ScopedNvramSpace will call Delete when it falls out of scope. Now we can
365 // make sure that worked.
366 uint64_t size = 0;
367 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
368 device.GetSpaceSize(kTestIndex1, &size));
369 }
370
TEST(NVRAMModuleTest,WriteLock)371 TEST(NVRAMModuleTest, WriteLock) {
372 SafeScopedNvramDevice device;
373 uint32_t index;
374 ASSERT_TRUE(GetNextBurnSpace(&device, &index));
375 ASSERT_EQ(
376 NV_RESULT_SUCCESS,
377 device.CreateSpace(index, 32, {NV_CONTROL_BOOT_WRITE_LOCK}, kNoAuth));
378 int write_lock, read_lock;
379 EXPECT_EQ(NV_RESULT_SUCCESS,
380 device.IsSpaceLocked(index, &write_lock, &read_lock));
381 EXPECT_FALSE(write_lock);
382 EXPECT_FALSE(read_lock);
383 // It should be possible to delete if the space has not yet been locked.
384 ASSERT_EQ(NV_RESULT_SUCCESS, device.DeleteSpace(index, kNoAuth));
385 ASSERT_EQ(
386 NV_RESULT_SUCCESS,
387 device.CreateSpace(index, 32, {NV_CONTROL_BOOT_WRITE_LOCK}, kNoAuth));
388 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test", kNoAuth));
389 EXPECT_EQ(NV_RESULT_SUCCESS, device.EnableWriteLock(index, kNoAuth));
390 EXPECT_EQ(NV_RESULT_SUCCESS,
391 device.IsSpaceLocked(index, &write_lock, &read_lock));
392 EXPECT_TRUE(write_lock);
393 EXPECT_FALSE(read_lock);
394 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
395 device.WriteSpace(index, "test2", kNoAuth));
396 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED, device.DeleteSpace(index, kNoAuth));
397 std::string data;
398 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 4, kNoAuth, &data));
399 EXPECT_EQ("test", data);
400 }
401
TEST(NVRAMModuleTest,ReadLock)402 TEST(NVRAMModuleTest, ReadLock) {
403 uint32_t index = kTestIndex1;
404 SafeScopedNvramDevice device;
405 ScopedNvramSpace space(&device, index, 32, {NV_CONTROL_BOOT_READ_LOCK});
406 int write_lock, read_lock;
407 EXPECT_EQ(NV_RESULT_SUCCESS,
408 device.IsSpaceLocked(index, &write_lock, &read_lock));
409 EXPECT_FALSE(write_lock);
410 EXPECT_FALSE(read_lock);
411 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test", kNoAuth));
412 std::string data;
413 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 4, kNoAuth, &data));
414 EXPECT_EQ("test", data);
415 EXPECT_EQ(NV_RESULT_SUCCESS, device.EnableReadLock(index, kNoAuth));
416 EXPECT_EQ(NV_RESULT_SUCCESS,
417 device.IsSpaceLocked(index, &write_lock, &read_lock));
418 EXPECT_FALSE(write_lock);
419 EXPECT_TRUE(read_lock);
420 EXPECT_EQ(NV_RESULT_OPERATION_DISABLED,
421 device.ReadSpace(index, 4, kNoAuth, &data));
422 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test2", kNoAuth));
423 }
424
TEST(NVRAMModuleTest,WriteAuthorization)425 TEST(NVRAMModuleTest, WriteAuthorization) {
426 uint32_t index = kTestIndex1;
427 std::string password = "hunter2";
428 SafeScopedNvramDevice device;
429 ScopedNvramSpace space(&device, index, 32, {NV_CONTROL_WRITE_AUTHORIZATION},
430 password);
431 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test", password));
432 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
433 device.WriteSpace(index, "test2", kNoAuth));
434 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
435 device.WriteSpace(index, "test3", "bad_password"));
436 EXPECT_EQ(NV_RESULT_ACCESS_DENIED, device.DeleteSpace(index, kNoAuth));
437 EXPECT_EQ(NV_RESULT_ACCESS_DENIED, device.DeleteSpace(index, "bad"));
438 std::string data;
439 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 4, kNoAuth, &data));
440 EXPECT_EQ("test", data);
441 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 4, password, &data));
442 }
443
TEST(NVRAMModuleTest,ReadAuthorization)444 TEST(NVRAMModuleTest, ReadAuthorization) {
445 uint32_t index = kTestIndex1;
446 std::string password = "hunter2";
447 SafeScopedNvramDevice device;
448 ScopedNvramSpace space(&device, index, 32, {NV_CONTROL_READ_AUTHORIZATION},
449 password);
450 ASSERT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test", password));
451 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test2", kNoAuth));
452 std::string data;
453 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 4, password, &data));
454 EXPECT_EQ("test", data);
455 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
456 device.ReadSpace(index, 4, kNoAuth, &data));
457 EXPECT_EQ(NV_RESULT_ACCESS_DENIED,
458 device.ReadSpace(index, 4, "bad_password", &data));
459 }
460
TEST(NVRAMModuleTest,WriteLockAuthorization)461 TEST(NVRAMModuleTest, WriteLockAuthorization) {
462 SafeScopedNvramDevice device;
463 uint32_t index;
464 ASSERT_TRUE(GetNextBurnSpace(&device, &index));
465 ASSERT_EQ(NV_RESULT_SUCCESS,
466 device.CreateSpace(index, 32, {NV_CONTROL_BOOT_WRITE_LOCK,
467 NV_CONTROL_BOOT_READ_LOCK,
468 NV_CONTROL_WRITE_AUTHORIZATION},
469 kBurnSpaceAuth));
470 EXPECT_EQ(NV_RESULT_SUCCESS, device.EnableReadLock(index, kNoAuth));
471 EXPECT_EQ(NV_RESULT_ACCESS_DENIED, device.EnableWriteLock(index, kNoAuth));
472 EXPECT_EQ(NV_RESULT_ACCESS_DENIED, device.EnableWriteLock(index, "bad"));
473 EXPECT_EQ(NV_RESULT_SUCCESS, device.EnableWriteLock(index, kBurnSpaceAuth));
474 }
475
TEST(NVRAMModuleTest,ReadLockAuthorization)476 TEST(NVRAMModuleTest, ReadLockAuthorization) {
477 uint32_t index = kTestIndex1;
478 std::string password = "hunter2";
479 SafeScopedNvramDevice device;
480 ScopedNvramSpace space(&device, index, 32,
481 {NV_CONTROL_BOOT_WRITE_LOCK, NV_CONTROL_BOOT_READ_LOCK,
482 NV_CONTROL_READ_AUTHORIZATION},
483 password);
484 EXPECT_EQ(NV_RESULT_ACCESS_DENIED, device.EnableReadLock(index, kNoAuth));
485 EXPECT_EQ(NV_RESULT_ACCESS_DENIED, device.EnableReadLock(index, "bad"));
486 EXPECT_EQ(NV_RESULT_SUCCESS, device.EnableReadLock(index, password));
487 }
488
TEST(NVRAMModuleTest,WriteExtend)489 TEST(NVRAMModuleTest, WriteExtend) {
490 uint32_t index = kTestIndex1;
491 SafeScopedNvramDevice device;
492 ScopedNvramSpace space(&device, index, 32, {NV_CONTROL_WRITE_EXTEND});
493 ASSERT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test", kNoAuth));
494 std::string data;
495 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 32, kNoAuth, &data));
496 std::string hash1 = SHA256HashString(std::string(32, 0) + "test");
497 EXPECT_EQ(hash1, data);
498 EXPECT_EQ(NV_RESULT_SUCCESS, device.WriteSpace(index, "test2", kNoAuth));
499 EXPECT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 32, kNoAuth, &data));
500 std::string hash2 = SHA256HashString(hash1 + "test2");
501 EXPECT_EQ(hash2, data);
502 }
503
TEST(NVRAMModuleTest,WriteExtendTooShort)504 TEST(NVRAMModuleTest, WriteExtendTooShort) {
505 uint32_t index = kTestIndex1;
506 SafeScopedNvramDevice device;
507 // Only SHA-256 is supported. Try 20 which is SHA-1 output.
508 EXPECT_EQ(
509 NV_RESULT_INVALID_PARAMETER,
510 device.CreateSpace(index, 20, {NV_CONTROL_WRITE_EXTEND}, kNoAuth));
511 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
512 device.WriteSpace(index, "test", kNoAuth));
513 }
514
TEST(NVRAMModuleTest,WriteExtendTooLong)515 TEST(NVRAMModuleTest, WriteExtendTooLong) {
516 uint32_t index = kTestIndex1;
517 SafeScopedNvramDevice device;
518 uint64_t max_space_size = 0;
519 ASSERT_EQ(NV_RESULT_SUCCESS, device.GetMaxSpaceSizeInBytes(&max_space_size));
520 if (max_space_size > 32) {
521 // Only SHA-256 is supported. Try 64 which is SHA-512 output.
522 EXPECT_EQ(NV_RESULT_INVALID_PARAMETER,
523 device.CreateSpace(index, std::min<uint64_t>(max_space_size, 64),
524 {NV_CONTROL_WRITE_EXTEND}, kNoAuth));
525 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
526 device.WriteSpace(index, "test", kNoAuth));
527 }
528 }
529
TEST(NVRAMModuleTest,InitialValue)530 TEST(NVRAMModuleTest, InitialValue) {
531 uint32_t index = kTestIndex1;
532 SafeScopedNvramDevice device;
533 ScopedNvramSpace space(&device, index, 32);
534 std::string data;
535 ASSERT_EQ(NV_RESULT_SUCCESS, device.ReadSpace(index, 32, kNoAuth, &data));
536 EXPECT_EQ(std::string(32, 0), data);
537 }
538
TEST(NVRAMModuleTest,ReadWriteSpaceDoesNotExist)539 TEST(NVRAMModuleTest, ReadWriteSpaceDoesNotExist) {
540 uint32_t index = kTestIndexNeverExists;
541 SafeScopedNvramDevice device;
542 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
543 device.WriteSpace(index, "test", kNoAuth));
544 std::string data;
545 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
546 device.ReadSpace(index, 1, kNoAuth, &data));
547 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
548 device.EnableWriteLock(index, kNoAuth));
549 EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST,
550 device.EnableReadLock(index, kNoAuth));
551 }
552
553 } // namespace nvram
554