blob: 9ed5b46795e21ab9226d577a8a311548f5402da7 [file] [log] [blame]
// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <gtest/gtest.h>
#include "tpm_message.h"
#include "tpm_constants.h"
namespace trunks {
// Tests individual value push and pop functions.
TEST(TpmMessageTest, PushPopValue) {
TpmMessage message;
const std::vector<uint8_t>* data = message.GetDataForTest();
ASSERT_EQ(1, message.PushBackUint8(0x80));
ASSERT_EQ(data->size() , 1);
ASSERT_EQ(data->at(0), 0x80);
uint8_t u8;
ASSERT_EQ(1, message.PopFrontUint8(&u8));
ASSERT_EQ(data->size(), 0);
ASSERT_EQ(u8, 0x80);
ASSERT_EQ(1, message.PushBackInt8(-1));
ASSERT_EQ(data->size(), 1);
ASSERT_EQ(data->at(0), 0xFF);
int8_t i8;
ASSERT_EQ(1, message.PopFrontInt8(&i8));
ASSERT_EQ(data->size(), 0);
ASSERT_EQ(i8, -1);
ASSERT_EQ(2, message.PushBackUint16(0x1234));
ASSERT_EQ(data->size(), 2);
ASSERT_EQ(data->at(0), 0x12);
ASSERT_EQ(data->at(1), 0x34);
uint16_t u16;
ASSERT_EQ(2, message.PopFrontUint16(&u16));
ASSERT_EQ(data->size(), 0);
ASSERT_EQ(u16, 0x1234);
ASSERT_EQ(4, message.PushBackUint32(0x12345678));
ASSERT_EQ(data->size(), 4);
ASSERT_EQ(data->at(0), 0x12);
ASSERT_EQ(data->at(1), 0x34);
ASSERT_EQ(data->at(2), 0x56);
ASSERT_EQ(data->at(3), 0x78);
uint32_t u32;
ASSERT_EQ(4, message.PopFrontUint32(&u32));
ASSERT_EQ(data->size(), 0);
ASSERT_EQ(u32, 0x12345678);
ASSERT_EQ(8, message.PushBackUint64(0x1234567890ABCDEF));
ASSERT_EQ(data->size(), 8);
ASSERT_EQ(data->at(0), 0x12);
ASSERT_EQ(data->at(1), 0x34);
ASSERT_EQ(data->at(2), 0x56);
ASSERT_EQ(data->at(3), 0x78);
ASSERT_EQ(data->at(4), 0x90);
ASSERT_EQ(data->at(5), 0xAB);
ASSERT_EQ(data->at(6), 0xCD);
ASSERT_EQ(data->at(7), 0xEF);
uint64_t u64;
ASSERT_EQ(8, message.PopFrontUint64(&u64));
ASSERT_EQ(data->size(), 0);
ASSERT_EQ(u64, 0x1234567890ABCDEF);
// Tests that trying to read more results in an error.
ASSERT_EQ(0, message.PopFrontUint8(&u8));
ASSERT_EQ(0, message.PopFrontInt8(&i8));
ASSERT_EQ(0, message.PopFrontUint16(&u16));
ASSERT_EQ(0, message.PopFrontUint32(&u32));
ASSERT_EQ(0, message.PopFrontUint64(&u64));
}
// Tests array push and pop functions.
TEST(TpmMessageTest, PushPopArray) {
TpmMessage message;
const std::vector<uint8_t>* data = message.GetDataForTest();
std::vector<uint8_t> au8;
au8.push_back(0x80);
au8.push_back(0x80);
ASSERT_EQ(6, message.PushBackArrayUint8(au8));
ASSERT_EQ(6, data->size());
ASSERT_EQ(0, data->at(0));
ASSERT_EQ(0, data->at(1));
ASSERT_EQ(0, data->at(2));
ASSERT_EQ(0x02, data->at(3));
ASSERT_EQ(0x80, data->at(4));
ASSERT_EQ(0x80, data->at(5));
au8.clear();
ASSERT_EQ(0, au8.size());
ASSERT_EQ(6, message.PopFrontArrayUint8(&au8));
ASSERT_EQ(2, au8.size());
ASSERT_EQ(0x80, au8.at(0));
ASSERT_EQ(0x80, au8.at(1));
std::vector<int8_t> ai8;
ai8.push_back(-1);
ai8.push_back(-1);
ASSERT_EQ(6, message.PushBackArrayInt8(ai8));
ASSERT_EQ(6, data->size());
ASSERT_EQ(0, data->at(0));
ASSERT_EQ(0, data->at(1));
ASSERT_EQ(0, data->at(2));
ASSERT_EQ(0x02, data->at(3));
ASSERT_EQ(0xFF, data->at(4));
ASSERT_EQ(0xFF, data->at(5));
ai8.clear();
ASSERT_EQ(0, ai8.size());
ASSERT_EQ(6, message.PopFrontArrayInt8(&ai8));
ASSERT_EQ(2, ai8.size());
ASSERT_EQ(-1, ai8.at(0));
ASSERT_EQ(-1, ai8.at(1));
std::vector<uint16_t> au16;
au16.push_back(0x1234);
au16.push_back(0x1234);
ASSERT_EQ(8, message.PushBackArrayUint16(au16));
ASSERT_EQ(8, data->size());
ASSERT_EQ(0, data->at(0));
ASSERT_EQ(0, data->at(1));
ASSERT_EQ(0, data->at(2));
ASSERT_EQ(0x02, data->at(3));
ASSERT_EQ(0x12, data->at(4));
ASSERT_EQ(0x34, data->at(5));
ASSERT_EQ(0x12, data->at(6));
ASSERT_EQ(0x34, data->at(7));
au16.clear();
ASSERT_EQ(0, au16.size());
ASSERT_EQ(8, message.PopFrontArrayUint16(&au16));
ASSERT_EQ(2, au16.size());
ASSERT_EQ(0x1234, au16.at(0));
ASSERT_EQ(0x1234, au16.at(1));
std::vector<uint32_t> au32;
au32.push_back(0x12345678);
au32.push_back(0x12345678);
ASSERT_EQ(12, message.PushBackArrayUint32(au32));
ASSERT_EQ(12, data->size());
ASSERT_EQ(0, data->at(0));
ASSERT_EQ(0, data->at(1));
ASSERT_EQ(0, data->at(2));
ASSERT_EQ(0x02, data->at(3));
ASSERT_EQ(0x12, data->at(4));
ASSERT_EQ(0x34, data->at(5));
ASSERT_EQ(0x56, data->at(6));
ASSERT_EQ(0x78, data->at(7));
ASSERT_EQ(0x12, data->at(8));
ASSERT_EQ(0x34, data->at(9));
ASSERT_EQ(0x56, data->at(10));
ASSERT_EQ(0x78, data->at(11));
au32.clear();
ASSERT_EQ(0, au32.size());
ASSERT_EQ(12, message.PopFrontArrayUint32(&au32));
ASSERT_EQ(2, au32.size());
ASSERT_EQ(0x12345678, au32.at(0));
ASSERT_EQ(0x12345678, au32.at(1));
std::vector<uint64_t> au64;
au64.push_back(0x1234567890ABCDEF);
au64.push_back(0x1234567890ABCDEF);
ASSERT_EQ(20, message.PushBackArrayUint64(au64));
ASSERT_EQ(20, data->size());
ASSERT_EQ(0, data->at(0));
ASSERT_EQ(0, data->at(1));
ASSERT_EQ(0, data->at(2));
ASSERT_EQ(0x02, data->at(3));
ASSERT_EQ(0x12, data->at(4));
ASSERT_EQ(0x34, data->at(5));
ASSERT_EQ(0x56, data->at(6));
ASSERT_EQ(0x78, data->at(7));
ASSERT_EQ(0x90, data->at(8));
ASSERT_EQ(0xAB, data->at(9));
ASSERT_EQ(0xCD, data->at(10));
ASSERT_EQ(0xEF, data->at(11));
ASSERT_EQ(0x12, data->at(12));
ASSERT_EQ(0x34, data->at(13));
ASSERT_EQ(0x56, data->at(14));
ASSERT_EQ(0x78, data->at(15));
ASSERT_EQ(0x90, data->at(16));
ASSERT_EQ(0xAB, data->at(17));
ASSERT_EQ(0xCD, data->at(18));
ASSERT_EQ(0xEF, data->at(19));
au64.clear();
ASSERT_EQ(0, au64.size());
ASSERT_EQ(20, message.PopFrontArrayUint64(&au64));
ASSERT_EQ(2, au64.size());
ASSERT_EQ(0x1234567890ABCDEF, au64.at(0));
ASSERT_EQ(0x1234567890ABCDEF, au64.at(1));
// Tests that trying to read more results in an error.
ASSERT_EQ(0, message.PopFrontArrayUint8(&au8));
ASSERT_EQ(0, message.PopFrontArrayInt8(&ai8));
ASSERT_EQ(0, message.PopFrontArrayUint16(&au16));
ASSERT_EQ(0, message.PopFrontArrayUint32(&au32));
ASSERT_EQ(0, message.PopFrontArrayUint64(&au64));
}
// Tests packet formatting.
TEST(TpmMessageTest, DataFormatting) {
TpmMessage message;
uint8_t buffer[kTpmPacketSize];
uint8_t buffer_test_data[] = { 0x12, 0x34,
0x00, 0x00, 0x00, 0x0C,
0x56, 0x78, 0x90, 0xAB,
0x80, 0x80 };
memcpy(buffer, buffer_test_data, 12);
message.ImportPacketData(buffer, 12);
uint16_t tag;
uint32_t code;
uint16_t value;
message.GetHeader(&tag, &code);
ASSERT_EQ(0x1234, tag);
ASSERT_EQ(0x567890AB, code);
ASSERT_EQ(2, message.PopFrontUint16(&value));
ASSERT_EQ(0x8080, value);
ASSERT_EQ(0, message.GetDataForTest()->size());
memset(buffer, 0, 12);
message.Clear();
message.GetHeader(&tag, &code);
ASSERT_EQ(0, tag);
ASSERT_EQ(0, code);
ASSERT_EQ(0, message.GetDataForTest()->size());
message.SetHeader(0x90AB, 0x12345678);
message.PushBackUint16(0xEFEF);
uint32_t size;
message.ExportPacketData(buffer, &size);
ASSERT_EQ(12, size);
ASSERT_EQ(0x90, buffer[0]);
ASSERT_EQ(0xAB, buffer[1]);
ASSERT_EQ(0x00, buffer[2]);
ASSERT_EQ(0x00, buffer[3]);
ASSERT_EQ(0x00, buffer[4]);
ASSERT_EQ(0x0C, buffer[5]);
ASSERT_EQ(0x12, buffer[6]);
ASSERT_EQ(0x34, buffer[7]);
ASSERT_EQ(0x56, buffer[8]);
ASSERT_EQ(0x78, buffer[9]);
ASSERT_EQ(0xEF, buffer[10]);
ASSERT_EQ(0xEF, buffer[11]);
}
} // namespace trunks