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 24namespace nvram { 25 26namespace { 27 28template <typename Message> 29void 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 37TEST(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 48TEST(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 86TEST(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 117TEST(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 130TEST(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 147TEST(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 177TEST(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 201TEST(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 214TEST(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 225TEST(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 238TEST(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 267TEST(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 280TEST(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 304TEST(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 325TEST(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 349TEST(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 362TEST(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 386TEST(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 399TEST(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