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