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 <stdlib.h>
18 #include <string.h>
19 
20 #include <gtest/gtest.h>
21 
22 #include <nvram/messages/nvram_messages.h>
23 
24 namespace nvram {
25 
26 namespace {
27 
28 template <typename Message>
EncodeAndDecode(const Message & in,Message * out)29 void EncodeAndDecode(const Message& in, Message* out) {
30   Blob blob;
31   ASSERT_TRUE(Encode(in, &blob));
32   ASSERT_TRUE(Decode(blob.data(), blob.size(), out));
33 }
34 
35 }  // namespace
36 
TEST(NvramMessagesTest,GetInfoRequest)37 TEST(NvramMessagesTest, GetInfoRequest) {
38   Request request;
39   request.payload.Activate<COMMAND_GET_INFO>();
40 
41   Request decoded;
42   EncodeAndDecode(request, &decoded);
43 
44   EXPECT_EQ(COMMAND_GET_INFO, decoded.payload.which());
45   EXPECT_TRUE(decoded.payload.get<COMMAND_GET_INFO>());
46 }
47 
TEST(NvramMessagesTest,GetInfoResponse)48 TEST(NvramMessagesTest, GetInfoResponse) {
49   Response response;
50   response.result = NV_RESULT_SUCCESS;
51   response.payload.Activate<COMMAND_GET_INFO>();
52 
53   GetInfoResponse& response_payload =
54       response.payload.Activate<COMMAND_GET_INFO>();
55   response_payload.total_size = 32768;
56   response_payload.available_size = 4096;
57   response_payload.max_space_size = 512;
58   response_payload.max_spaces = 32;
59   ASSERT_TRUE(response_payload.space_list.Append(0x1234));
60   ASSERT_TRUE(response_payload.space_list.Append(0xffffffff));
61   ASSERT_TRUE(response_payload.space_list.Append(0x32));
62   ASSERT_TRUE(response_payload.space_list.Append(0x0));
63   ASSERT_TRUE(response_payload.space_list.Append(0x1));
64 
65   Response decoded;
66   EncodeAndDecode(response, &decoded);
67 
68   EXPECT_EQ(NV_RESULT_SUCCESS, response.result);
69   EXPECT_EQ(COMMAND_GET_INFO, decoded.payload.which());
70   const GetInfoResponse* decoded_payload =
71       decoded.payload.get<COMMAND_GET_INFO>();
72   ASSERT_TRUE(decoded_payload);
73 
74   EXPECT_EQ(32768ULL, decoded_payload->total_size);
75   EXPECT_EQ(4096ULL, decoded_payload->available_size);
76   EXPECT_EQ(512ULL, decoded_payload->max_space_size);
77   EXPECT_EQ(32U, decoded_payload->max_spaces);
78   ASSERT_EQ(5U, decoded_payload->space_list.size());
79   EXPECT_EQ(0x1234U, decoded_payload->space_list[0]);
80   EXPECT_EQ(0xffffffffU, decoded_payload->space_list[1]);
81   EXPECT_EQ(0x32U, decoded_payload->space_list[2]);
82   EXPECT_EQ(0x0U, decoded_payload->space_list[3]);
83   EXPECT_EQ(0x1U, decoded_payload->space_list[4]);
84 }
85 
TEST(NvramMessagesTest,CreateSpaceRequest)86 TEST(NvramMessagesTest, CreateSpaceRequest) {
87   Request request;
88   CreateSpaceRequest& request_payload =
89       request.payload.Activate<COMMAND_CREATE_SPACE>();
90   request_payload.index = 0x12345678;
91   request_payload.size = 8;
92   ASSERT_TRUE(request_payload.controls.Append(NV_CONTROL_BOOT_WRITE_LOCK));
93   ASSERT_TRUE(request_payload.controls.Append(NV_CONTROL_WRITE_EXTEND));
94   const uint8_t kAuthValue[] = {1, 2, 3, 4, 5};
95   ASSERT_TRUE(request_payload.authorization_value.Assign(kAuthValue,
96                                                          sizeof(kAuthValue)));
97 
98   Request decoded;
99   EncodeAndDecode(request, &decoded);
100 
101   EXPECT_EQ(COMMAND_CREATE_SPACE, decoded.payload.which());
102   const CreateSpaceRequest* decoded_payload =
103       decoded.payload.get<COMMAND_CREATE_SPACE>();
104   ASSERT_TRUE(decoded_payload);
105 
106   EXPECT_EQ(0x12345678U, decoded_payload->index);
107   EXPECT_EQ(8ULL, decoded_payload->size);
108   ASSERT_EQ(2UL, decoded_payload->controls.size());
109   EXPECT_EQ(NV_CONTROL_BOOT_WRITE_LOCK, decoded_payload->controls[0]);
110   EXPECT_EQ(NV_CONTROL_WRITE_EXTEND, decoded_payload->controls[1]);
111   const Blob& decoded_auth_value = decoded_payload->authorization_value;
112   ASSERT_EQ(sizeof(kAuthValue), decoded_auth_value.size());
113   EXPECT_EQ(0,
114             memcmp(kAuthValue, decoded_auth_value.data(), sizeof(kAuthValue)));
115 }
116 
TEST(NvramMessagesTest,CreateSpaceResponse)117 TEST(NvramMessagesTest, CreateSpaceResponse) {
118   Response response;
119   response.result = NV_RESULT_SPACE_ALREADY_EXISTS;
120   response.payload.Activate<COMMAND_CREATE_SPACE>();
121 
122   Response decoded;
123   EncodeAndDecode(response, &decoded);
124 
125   EXPECT_EQ(NV_RESULT_SPACE_ALREADY_EXISTS, response.result);
126   EXPECT_EQ(COMMAND_CREATE_SPACE, decoded.payload.which());
127   EXPECT_TRUE(decoded.payload.get<COMMAND_CREATE_SPACE>());
128 }
129 
TEST(NvramMessagesTest,GetSpaceInfoRequest)130 TEST(NvramMessagesTest, GetSpaceInfoRequest) {
131   Request request;
132   GetSpaceInfoRequest& request_payload =
133       request.payload.Activate<COMMAND_GET_SPACE_INFO>();
134   request_payload.index = 0x1234;
135 
136   Request decoded;
137   EncodeAndDecode(request, &decoded);
138 
139   EXPECT_EQ(COMMAND_GET_SPACE_INFO, decoded.payload.which());
140   const GetSpaceInfoRequest* decoded_payload =
141       decoded.payload.get<COMMAND_GET_SPACE_INFO>();
142   ASSERT_TRUE(decoded_payload);
143 
144   EXPECT_EQ(0x1234U, decoded_payload->index);
145 }
146 
TEST(NvramMessagesTest,GetSpaceInfoResponse)147 TEST(NvramMessagesTest, GetSpaceInfoResponse) {
148   Response response;
149   response.result = NV_RESULT_SPACE_DOES_NOT_EXIST;
150   GetSpaceInfoResponse& response_payload =
151       response.payload.Activate<COMMAND_GET_SPACE_INFO>();
152   response_payload.size = 256;
153   ASSERT_TRUE(response_payload.controls.Append(NV_CONTROL_BOOT_WRITE_LOCK));
154   ASSERT_TRUE(response_payload.controls.Append(NV_CONTROL_BOOT_READ_LOCK));
155   ASSERT_TRUE(response_payload.controls.Append(NV_CONTROL_WRITE_EXTEND));
156   response_payload.read_locked = false;
157   response_payload.write_locked = true;
158 
159   Response decoded;
160   EncodeAndDecode(response, &decoded);
161 
162   EXPECT_EQ(NV_RESULT_SPACE_DOES_NOT_EXIST, response.result);
163   EXPECT_EQ(COMMAND_GET_SPACE_INFO, decoded.payload.which());
164   const GetSpaceInfoResponse* decoded_payload =
165       decoded.payload.get<COMMAND_GET_SPACE_INFO>();
166   ASSERT_TRUE(decoded_payload);
167 
168   EXPECT_EQ(256ULL, decoded_payload->size);
169   ASSERT_EQ(3U, decoded_payload->controls.size());
170   EXPECT_EQ(NV_CONTROL_BOOT_WRITE_LOCK, decoded_payload->controls[0]);
171   EXPECT_EQ(NV_CONTROL_BOOT_READ_LOCK, decoded_payload->controls[1]);
172   EXPECT_EQ(NV_CONTROL_WRITE_EXTEND, decoded_payload->controls[2]);
173   EXPECT_FALSE(decoded_payload->read_locked);
174   EXPECT_TRUE(decoded_payload->write_locked);
175 }
176 
TEST(NvramMessagesTest,DeleteSpaceRequest)177 TEST(NvramMessagesTest, DeleteSpaceRequest) {
178   Request request;
179   DeleteSpaceRequest& request_payload =
180       request.payload.Activate<COMMAND_DELETE_SPACE>();
181   request_payload.index = 0x1234;
182   const uint8_t kAuthValue[] = {1, 2, 3};
183   ASSERT_TRUE(request_payload.authorization_value.Assign(kAuthValue,
184                                                          sizeof(kAuthValue)));
185 
186   Request decoded;
187   EncodeAndDecode(request, &decoded);
188 
189   EXPECT_EQ(COMMAND_DELETE_SPACE, decoded.payload.which());
190   const DeleteSpaceRequest* decoded_payload =
191       decoded.payload.get<COMMAND_DELETE_SPACE>();
192   ASSERT_TRUE(decoded_payload);
193 
194   EXPECT_EQ(0x1234U, decoded_payload->index);
195   const Blob& decoded_auth_value = decoded_payload->authorization_value;
196   ASSERT_EQ(sizeof(kAuthValue), decoded_auth_value.size());
197   EXPECT_EQ(0,
198             memcmp(kAuthValue, decoded_auth_value.data(), sizeof(kAuthValue)));
199 }
200 
TEST(NvramMessagesTest,DeleteSpaceResponse)201 TEST(NvramMessagesTest, DeleteSpaceResponse) {
202   Response response;
203   response.result = NV_RESULT_ACCESS_DENIED;
204   response.payload.Activate<COMMAND_DELETE_SPACE>();
205 
206   Response decoded;
207   EncodeAndDecode(response, &decoded);
208 
209   EXPECT_EQ(NV_RESULT_ACCESS_DENIED, response.result);
210   EXPECT_EQ(COMMAND_DELETE_SPACE, decoded.payload.which());
211   EXPECT_TRUE(decoded.payload.get<COMMAND_DELETE_SPACE>());
212 }
213 
TEST(NvramMessagesTest,DisableCreateRequest)214 TEST(NvramMessagesTest, DisableCreateRequest) {
215   Request request;
216   request.payload.Activate<COMMAND_DISABLE_CREATE>();
217 
218   Request decoded;
219   EncodeAndDecode(request, &decoded);
220 
221   EXPECT_EQ(COMMAND_DISABLE_CREATE, decoded.payload.which());
222   EXPECT_TRUE(decoded.payload.get<COMMAND_DISABLE_CREATE>());
223 }
224 
TEST(NvramMessagesTest,DisableCreateResponse)225 TEST(NvramMessagesTest, DisableCreateResponse) {
226   Response response;
227   response.result = NV_RESULT_INTERNAL_ERROR;
228   response.payload.Activate<COMMAND_DISABLE_CREATE>();
229 
230   Response decoded;
231   EncodeAndDecode(response, &decoded);
232 
233   EXPECT_EQ(NV_RESULT_INTERNAL_ERROR, response.result);
234   EXPECT_EQ(COMMAND_DISABLE_CREATE, decoded.payload.which());
235   EXPECT_TRUE(decoded.payload.get<COMMAND_DISABLE_CREATE>());
236 }
237 
TEST(NvramMessagesTest,WriteSpaceRequest)238 TEST(NvramMessagesTest, WriteSpaceRequest) {
239   Request request;
240   WriteSpaceRequest& request_payload =
241       request.payload.Activate<COMMAND_WRITE_SPACE>();
242   request_payload.index = 0x1234;
243   const uint8_t kData[] = {17, 29, 33};
244   ASSERT_TRUE(request_payload.buffer.Assign(kData, sizeof(kData)));
245   const uint8_t kAuthValue[] = {1, 2, 3};
246   ASSERT_TRUE(request_payload.authorization_value.Assign(kAuthValue,
247                                                          sizeof(kAuthValue)));
248 
249   Request decoded;
250   EncodeAndDecode(request, &decoded);
251 
252   EXPECT_EQ(COMMAND_WRITE_SPACE, decoded.payload.which());
253   const WriteSpaceRequest* decoded_payload =
254       decoded.payload.get<COMMAND_WRITE_SPACE>();
255   ASSERT_TRUE(decoded_payload);
256 
257   EXPECT_EQ(0x1234U, decoded_payload->index);
258   const Blob& decoded_buffer = decoded_payload->buffer;
259   ASSERT_EQ(sizeof(kData), decoded_buffer.size());
260   EXPECT_EQ(0, memcmp(kData, decoded_buffer.data(), sizeof(kData)));
261   const Blob& decoded_auth_value = decoded_payload->authorization_value;
262   ASSERT_EQ(sizeof(kAuthValue), decoded_auth_value.size());
263   EXPECT_EQ(0,
264             memcmp(kAuthValue, decoded_auth_value.data(), sizeof(kAuthValue)));
265 }
266 
TEST(NvramMessagesTest,WriteSpaceResponse)267 TEST(NvramMessagesTest, WriteSpaceResponse) {
268   Response response;
269   response.result = NV_RESULT_OPERATION_DISABLED;
270   response.payload.Activate<COMMAND_WRITE_SPACE>();
271 
272   Response decoded;
273   EncodeAndDecode(response, &decoded);
274 
275   EXPECT_EQ(NV_RESULT_OPERATION_DISABLED, response.result);
276   EXPECT_EQ(COMMAND_WRITE_SPACE, decoded.payload.which());
277   EXPECT_TRUE(decoded.payload.get<COMMAND_WRITE_SPACE>());
278 }
279 
TEST(NvramMessagesTest,ReadSpaceRequest)280 TEST(NvramMessagesTest, ReadSpaceRequest) {
281   Request request;
282   ReadSpaceRequest& request_payload =
283       request.payload.Activate<COMMAND_READ_SPACE>();
284   request_payload.index = 0x1234;
285   const uint8_t kAuthValue[] = {1, 2, 3};
286   ASSERT_TRUE(request_payload.authorization_value.Assign(kAuthValue,
287                                                          sizeof(kAuthValue)));
288 
289   Request decoded;
290   EncodeAndDecode(request, &decoded);
291 
292   EXPECT_EQ(COMMAND_READ_SPACE, decoded.payload.which());
293   const ReadSpaceRequest* decoded_payload =
294       decoded.payload.get<COMMAND_READ_SPACE>();
295   ASSERT_TRUE(decoded_payload);
296 
297   EXPECT_EQ(0x1234U, decoded_payload->index);
298   const Blob& decoded_auth_value = decoded_payload->authorization_value;
299   ASSERT_EQ(sizeof(kAuthValue), decoded_auth_value.size());
300   EXPECT_EQ(0,
301             memcmp(kAuthValue, decoded_auth_value.data(), sizeof(kAuthValue)));
302 }
303 
TEST(NvramMessagesTest,ReadSpaceResponse)304 TEST(NvramMessagesTest, ReadSpaceResponse) {
305   Response response;
306   response.result = NV_RESULT_SUCCESS;
307   ReadSpaceResponse& response_payload =
308       response.payload.Activate<COMMAND_READ_SPACE>();
309   const uint8_t kData[] = {48, 0, 32, 1, 255};
310   ASSERT_TRUE(response_payload.buffer.Assign(kData, sizeof(kData)));
311 
312   Response decoded;
313   EncodeAndDecode(response, &decoded);
314 
315   EXPECT_EQ(NV_RESULT_SUCCESS, response.result);
316   EXPECT_EQ(COMMAND_READ_SPACE, decoded.payload.which());
317   const ReadSpaceResponse* decoded_payload =
318       decoded.payload.get<COMMAND_READ_SPACE>();
319   ASSERT_TRUE(decoded_payload);
320   const Blob& decoded_buffer = decoded_payload->buffer;
321   ASSERT_EQ(sizeof(kData), decoded_buffer.size());
322   EXPECT_EQ(0, memcmp(kData, decoded_buffer.data(), sizeof(kData)));
323 }
324 
TEST(NvramMessagesTest,LockSpaceWriteRequest)325 TEST(NvramMessagesTest, LockSpaceWriteRequest) {
326   Request request;
327   LockSpaceWriteRequest& request_payload =
328       request.payload.Activate<COMMAND_LOCK_SPACE_WRITE>();
329   request_payload.index = 0x1234;
330   const uint8_t kAuthValue[] = {1, 2, 3};
331   ASSERT_TRUE(request_payload.authorization_value.Assign(kAuthValue,
332                                                          sizeof(kAuthValue)));
333 
334   Request decoded;
335   EncodeAndDecode(request, &decoded);
336 
337   EXPECT_EQ(COMMAND_LOCK_SPACE_WRITE, decoded.payload.which());
338   const LockSpaceWriteRequest* decoded_payload =
339       decoded.payload.get<COMMAND_LOCK_SPACE_WRITE>();
340   ASSERT_TRUE(decoded_payload);
341 
342   EXPECT_EQ(0x1234U, decoded_payload->index);
343   const Blob& decoded_auth_value = decoded_payload->authorization_value;
344   ASSERT_EQ(sizeof(kAuthValue), decoded_auth_value.size());
345   EXPECT_EQ(0,
346             memcmp(kAuthValue, decoded_auth_value.data(), sizeof(kAuthValue)));
347 }
348 
TEST(NvramMessagesTest,LockSpaceWriteResponse)349 TEST(NvramMessagesTest, LockSpaceWriteResponse) {
350   Response response;
351   response.result = NV_RESULT_SUCCESS;
352   response.payload.Activate<COMMAND_LOCK_SPACE_WRITE>();
353 
354   Response decoded;
355   EncodeAndDecode(response, &decoded);
356 
357   EXPECT_EQ(NV_RESULT_SUCCESS, response.result);
358   EXPECT_EQ(COMMAND_LOCK_SPACE_WRITE, decoded.payload.which());
359   EXPECT_TRUE(decoded.payload.get<COMMAND_LOCK_SPACE_WRITE>());
360 }
361 
TEST(NvramMessagesTest,LockSpaceReadRequest)362 TEST(NvramMessagesTest, LockSpaceReadRequest) {
363   Request request;
364   LockSpaceReadRequest& request_payload =
365       request.payload.Activate<COMMAND_LOCK_SPACE_READ>();
366   request_payload.index = 0x1234;
367   const uint8_t kAuthValue[] = {1, 2, 3};
368   ASSERT_TRUE(request_payload.authorization_value.Assign(kAuthValue,
369                                                          sizeof(kAuthValue)));
370 
371   Request decoded;
372   EncodeAndDecode(request, &decoded);
373 
374   EXPECT_EQ(COMMAND_LOCK_SPACE_READ, decoded.payload.which());
375   const LockSpaceReadRequest* decoded_payload =
376       decoded.payload.get<COMMAND_LOCK_SPACE_READ>();
377   ASSERT_TRUE(decoded_payload);
378 
379   EXPECT_EQ(0x1234U, decoded_payload->index);
380   const Blob& decoded_auth_value = decoded_payload->authorization_value;
381   ASSERT_EQ(sizeof(kAuthValue), decoded_auth_value.size());
382   EXPECT_EQ(0,
383             memcmp(kAuthValue, decoded_auth_value.data(), sizeof(kAuthValue)));
384 }
385 
TEST(NvramMessagesTest,LockSpaceReadResponse)386 TEST(NvramMessagesTest, LockSpaceReadResponse) {
387   Response response;
388   response.result = NV_RESULT_SUCCESS;
389   response.payload.Activate<COMMAND_LOCK_SPACE_READ>();
390 
391   Response decoded;
392   EncodeAndDecode(response, &decoded);
393 
394   EXPECT_EQ(NV_RESULT_SUCCESS, response.result);
395   EXPECT_EQ(COMMAND_LOCK_SPACE_READ, decoded.payload.which());
396   EXPECT_TRUE(decoded.payload.get<COMMAND_LOCK_SPACE_READ>());
397 }
398 
TEST(NvramMessagesTest,GarbageDecode)399 TEST(NvramMessagesTest, GarbageDecode) {
400   srand(0);
401   uint8_t random_data[1024];
402   for (size_t i = 0; i < sizeof(random_data); ++i) {
403     random_data[i] = rand() & 0xff;
404   }
405 
406   // Feed the data to the decoder. The test succeeds if we don't crash.
407   for (size_t pos = 0; pos < sizeof(random_data); ++pos) {
408     for (size_t end = pos; end < sizeof(random_data); ++end) {
409       Request request;
410       Decode(random_data + pos, end - pos, &request);
411 
412       Response response;
413       Decode(random_data + pos, end - pos, &response);
414     }
415   }
416 }
417 
418 }  // namespace nvram
419