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