Home | History | Annotate | Download | only in unittests
      1 /*############################################################################
      2 # Copyright 2017 Intel Corporation
      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 /// TPM non volatile memory API unit tests.
     17 /*! \file */
     18 #include <array>
     19 #include <cstring>
     20 #include "gtest/gtest.h"
     21 
     22 #include "epid/common-testhelper/epid2params_wrapper-testhelper.h"
     23 #include "epid/common-testhelper/errors-testhelper.h"
     24 #include "epid/common-testhelper/prng-testhelper.h"
     25 #include "epid/member/tpm2/unittests/tpm2-testhelper.h"
     26 
     27 extern "C" {
     28 #include "epid/member/tpm2/nv.h"
     29 }
     30 
     31 bool operator==(MembershipCredential const& lhs,
     32                 MembershipCredential const& rhs) {
     33   return 0 == std::memcmp(&lhs, &rhs, sizeof(lhs));
     34 }
     35 
     36 namespace {
     37 
     38 TEST(NvTest, CanStoreMembershipCredential) {
     39   // Demonstrate NV API usage
     40   Prng my_prng;
     41   Epid2ParamsObj epid2params;
     42   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
     43   uint32_t nv_index = 0x01000000;
     44 
     45   MembershipCredential const credential = {
     46       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     47        0x00, 0x00, 0x00, 0x01},  // group id
     48       {{{{0x46, 0xc9, 0x69, 0xee, 0xf4, 0x68, 0xe1, 0x5f, 0xac, 0xbf, 0xdd,
     49           0x77, 0xeb, 0x4c, 0xaf, 0x8a, 0x87, 0x68, 0x3f, 0x4e, 0xda, 0xf2,
     50           0x96, 0xec, 0x57, 0x08, 0x90, 0xe8, 0x19, 0x62, 0x54, 0xdb}}},
     51        {{{0x1e, 0x52, 0x23, 0x16, 0x91, 0xe4, 0xa8, 0x1d, 0x9a, 0x1b, 0x8a,
     52           0xad, 0x0a, 0xcf, 0x36, 0x4f, 0xae, 0x43, 0xde, 0x62, 0xff, 0xa6,
     53           0x4b, 0xa8, 0x16, 0x24, 0x98, 0x80, 0x82, 0x80, 0x37, 0x77}}}},  // A
     54       {{{0x0a, 0x30, 0xae, 0x43, 0xa1, 0xe0, 0xd7, 0xdf, 0x10, 0x5e, 0xaf,
     55          0xd8, 0x5a, 0x61, 0x10, 0x86, 0xd0, 0x9d, 0xb9, 0xe4, 0x46, 0xdd,
     56          0xb7, 0x1b, 0x00, 0x14, 0x7c, 0x6b, 0x13, 0x72, 0xc3, 0x77}}}  // x
     57   };
     58   MembershipCredential data = {0};
     59 
     60   // probe is nv_index is defined
     61   if (kEpidNoErr != Tpm2NvRead(tpm, nv_index, sizeof(data), 0, &data)) {
     62     EXPECT_EQ(kEpidNoErr,
     63               Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
     64   }
     65   // write
     66   EXPECT_EQ(kEpidNoErr,
     67             Tpm2NvWrite(tpm, nv_index, sizeof(credential), 0, &credential));
     68 
     69   // read
     70   EXPECT_EQ(kEpidNoErr, Tpm2NvRead(tpm, nv_index, sizeof(data), 0, &data));
     71   EXPECT_EQ(credential, data);
     72   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
     73 }
     74 
     75 TEST(NvTest, CanUseOffset) {
     76   Prng my_prng;
     77   Epid2ParamsObj epid2params;
     78   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
     79   uint32_t nv_index = 0x01000000;
     80 
     81   std::array<uint8_t, 3> const data1_src = {1, 2, 3};
     82   std::array<uint8_t, 5> const data2_src = {4, 5, 6, 7, 8};
     83   std::array<uint8_t, 3> data1_dst = {0};
     84   std::array<uint8_t, 5> data2_dst = {0};
     85 
     86   THROW_ON_EPIDERR(
     87       Tpm2NvDefineSpace(tpm, nv_index, data1_src.size() + data2_src.size()));
     88 
     89   EXPECT_EQ(kEpidNoErr,
     90             Tpm2NvWrite(tpm, nv_index, data1_src.size(), 0, data1_src.data()));
     91   EXPECT_EQ(kEpidNoErr,
     92             Tpm2NvWrite(tpm, nv_index, data2_src.size(),
     93                         (uint16_t)data1_src.size(), data2_src.data()));
     94 
     95   EXPECT_EQ(kEpidNoErr,
     96             Tpm2NvRead(tpm, nv_index, data1_dst.size(), 0, data1_dst.data()));
     97   EXPECT_EQ(data1_src, data1_dst);
     98 
     99   EXPECT_EQ(kEpidNoErr,
    100             Tpm2NvRead(tpm, nv_index, data2_dst.size(),
    101                        (uint16_t)data1_dst.size(), data2_dst.data()));
    102   EXPECT_EQ(data2_src, data2_dst);
    103   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    104 }
    105 
    106 //////////////////////////////////////////////////////////////////////////
    107 // Tpm2NvDefineSpace Tests
    108 TEST(NvTest, NvDefineSpaceFailsGivenNullParameters) {
    109   uint32_t nv_index = 0x01000000;
    110   EXPECT_EQ(kEpidBadArgErr,
    111             Tpm2NvDefineSpace(nullptr, nv_index, sizeof(MembershipCredential)));
    112 }
    113 
    114 TEST(NvTest, NvDefineSpaceCanAllocateSpace) {
    115   Prng my_prng;
    116   Epid2ParamsObj epid2params;
    117   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    118   uint32_t nv_index = 0x01000000;
    119   EXPECT_EQ(kEpidNoErr,
    120             Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    121   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    122 }
    123 
    124 TEST(NvTest, NvDefineSpaceCatchReDefinition) {
    125   Prng my_prng;
    126   Epid2ParamsObj epid2params;
    127   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    128   uint32_t nv_index = 0x01000002;
    129   EXPECT_EQ(kEpidNoErr,
    130             Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    131   EXPECT_EQ(kEpidDuplicateErr,
    132             Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    133   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    134 }
    135 
    136 //////////////////////////////////////////////////////////////////////////
    137 // Tpm2NvUndefineSpace Tests
    138 TEST(NvTest, NvUndefineSpaceFailsGivenNullParameters) {
    139   uint32_t nv_index = 0x01000000;
    140   EXPECT_EQ(kEpidBadArgErr, Tpm2NvUndefineSpace(nullptr, nv_index));
    141 }
    142 
    143 TEST(NvTest, NvUndefineSpaceCanDeallocateSpace) {
    144   Prng my_prng;
    145   Epid2ParamsObj epid2params;
    146   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    147   uint32_t nv_index = 0x01000000;
    148   MembershipCredential data = {0};
    149   THROW_ON_EPIDERR(Tpm2NvDefineSpace(tpm, nv_index, sizeof(data)));
    150   EXPECT_EQ(kEpidNoErr, Tpm2NvUndefineSpace(tpm, nv_index));
    151   EXPECT_EQ(kEpidBadArgErr, Tpm2NvRead(tpm, nv_index, sizeof(data), 0, &data));
    152 }
    153 
    154 TEST(NvTest, NvUndefineSpaceCatchReDefinition) {
    155   Prng my_prng;
    156   Epid2ParamsObj epid2params;
    157   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    158   uint32_t nv_index = 0x01000000;
    159   MembershipCredential const data = {0};
    160   EXPECT_EQ(kEpidNoErr, Tpm2NvDefineSpace(tpm, nv_index, sizeof(data)));
    161   EXPECT_EQ(kEpidNoErr, Tpm2NvUndefineSpace(tpm, nv_index));
    162   EXPECT_EQ(kEpidBadArgErr, Tpm2NvUndefineSpace(tpm, nv_index));
    163 }
    164 
    165 //////////////////////////////////////////////////////////////////////////
    166 // Tpm2NvWrite Tests
    167 TEST(NvTest, NvWriteFailsGivenNullParameters) {
    168   Prng my_prng;
    169   Epid2ParamsObj epid2params;
    170   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    171   uint32_t nv_index = 0x01000000;
    172   THROW_ON_EPIDERR(
    173       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    174 
    175   MembershipCredential const data = {0};
    176   EXPECT_EQ(kEpidBadArgErr,
    177             Tpm2NvWrite(nullptr, nv_index, sizeof(data), 0, &data));
    178   EXPECT_EQ(kEpidBadArgErr,
    179             Tpm2NvWrite(tpm, nv_index, sizeof(data), 0, nullptr));
    180   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    181 }
    182 
    183 TEST(NvTest, NvWriteCanWrite) {
    184   Prng my_prng;
    185   Epid2ParamsObj epid2params;
    186   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    187   uint32_t nv_index = 0x01000000;
    188   THROW_ON_EPIDERR(
    189       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    190 
    191   MembershipCredential const data = {0};
    192   EXPECT_EQ(kEpidNoErr, Tpm2NvWrite(tpm, nv_index, sizeof(data), 0, &data));
    193   EXPECT_EQ(kEpidNoErr, Tpm2NvWrite(tpm, nv_index, sizeof(data) - 1, 1, &data));
    194   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    195 }
    196 
    197 TEST(NvTest, NvWriteFailsGivenOverflow) {
    198   Prng my_prng;
    199   Epid2ParamsObj epid2params;
    200   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    201   uint32_t nv_index = 0x01000000;
    202   THROW_ON_EPIDERR(
    203       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    204 
    205   MembershipCredential const data = {0};
    206   EXPECT_EQ(kEpidBadArgErr, Tpm2NvWrite(tpm, nv_index, sizeof(data), 1, &data));
    207   EXPECT_EQ(kEpidBadArgErr,
    208             Tpm2NvWrite(tpm, nv_index, sizeof(data) + 1, 1, &data));
    209   EXPECT_EQ(kEpidBadArgErr,
    210             Tpm2NvWrite(tpm, nv_index, 1, sizeof(MembershipCredential), &data));
    211   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    212 }
    213 
    214 TEST(NvTest, NvWriteFailsGivenInvalidLength) {
    215   Prng my_prng;
    216   Epid2ParamsObj epid2params;
    217   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    218   uint32_t nv_index = 0x01000000;
    219   THROW_ON_EPIDERR(
    220       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    221 
    222   MembershipCredential const data = {0};
    223   EXPECT_EQ(kEpidBadArgErr, Tpm2NvWrite(tpm, nv_index, 0, 0, &data));
    224   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    225 }
    226 
    227 TEST(NvTest, NvWriteFailsGivenIndexUndefined) {
    228   Prng my_prng;
    229   Epid2ParamsObj epid2params;
    230   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    231   uint32_t nv_index = 0x01000003;
    232 
    233   MembershipCredential const data = {0};
    234   EXPECT_EQ(kEpidBadArgErr, Tpm2NvWrite(tpm, nv_index, 1, 0, &data));
    235 }
    236 
    237 //////////////////////////////////////////////////////////////////////////
    238 // Tpm2NvRead Tests
    239 TEST(NvTest, NvReadFailsGivenNullParameters) {
    240   Prng my_prng;
    241   Epid2ParamsObj epid2params;
    242   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    243   uint32_t nv_index = 0x01000000;
    244   THROW_ON_EPIDERR(
    245       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    246 
    247   MembershipCredential data = {0};
    248   EXPECT_EQ(kEpidBadArgErr,
    249             Tpm2NvRead(nullptr, nv_index, sizeof(data), 0, &data));
    250   EXPECT_EQ(kEpidBadArgErr,
    251             Tpm2NvRead(tpm, nv_index, sizeof(data), 0, nullptr));
    252   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    253 }
    254 
    255 TEST(NvTest, NvReadCanRead) {
    256   Prng my_prng;
    257   Epid2ParamsObj epid2params;
    258   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    259   uint32_t nv_index = 0x01000000;
    260   std::vector<uint8_t> const data_src = {1, 2, 3, 4, 5, 6, 7, 8};
    261   std::vector<uint8_t> data_dst(data_src.size());
    262   THROW_ON_EPIDERR(Tpm2NvDefineSpace(tpm, nv_index, data_src.size()));
    263   THROW_ON_EPIDERR(
    264       Tpm2NvWrite(tpm, nv_index, data_src.size(), 0, data_src.data()));
    265 
    266   EXPECT_EQ(kEpidNoErr, Tpm2NvRead(tpm, nv_index, 3, 0, data_dst.data()));
    267   EXPECT_EQ(kEpidNoErr, Tpm2NvRead(tpm, nv_index, data_src.size() - 3, 3,
    268                                    data_dst.data() + 3));
    269   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    270   EXPECT_EQ(data_src, data_dst);
    271 }
    272 
    273 TEST(NvTest, NvReadFailIfWriteWasNotCalled) {
    274   Prng my_prng;
    275   Epid2ParamsObj epid2params;
    276   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    277   uint32_t nv_index = 0x01000000;
    278   THROW_ON_EPIDERR(
    279       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    280 
    281   MembershipCredential data = {0};
    282   EXPECT_EQ(kEpidBadArgErr, Tpm2NvRead(tpm, nv_index, sizeof(data), 0, &data));
    283   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    284 }
    285 
    286 TEST(NvTest, NvReadFailsGivenOverflow) {
    287   Prng my_prng;
    288   Epid2ParamsObj epid2params;
    289   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    290   uint32_t nv_index = 0x01000000;
    291   THROW_ON_EPIDERR(
    292       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    293 
    294   MembershipCredential data = {0};
    295   EXPECT_EQ(kEpidBadArgErr, Tpm2NvRead(tpm, nv_index, sizeof(data), 1, &data));
    296   EXPECT_EQ(kEpidBadArgErr,
    297             Tpm2NvRead(tpm, nv_index, sizeof(data) + 1, 0, &data));
    298   EXPECT_EQ(kEpidBadArgErr,
    299             Tpm2NvRead(tpm, nv_index, 1, sizeof(MembershipCredential), &data));
    300   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    301 }
    302 
    303 TEST(NvTest, NvReadFailsGivenInvalidLength) {
    304   Prng my_prng;
    305   Epid2ParamsObj epid2params;
    306   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    307   uint32_t nv_index = 0x01000000;
    308   THROW_ON_EPIDERR(
    309       Tpm2NvDefineSpace(tpm, nv_index, sizeof(MembershipCredential)));
    310 
    311   MembershipCredential data = {0};
    312   EXPECT_EQ(kEpidBadArgErr, Tpm2NvRead(tpm, nv_index, 0, 0, &data));
    313   THROW_ON_EPIDERR(Tpm2NvUndefineSpace(tpm, nv_index));
    314 }
    315 
    316 TEST(NvTest, NvReadFailsGivenIndexUndefined) {
    317   Prng my_prng;
    318   Epid2ParamsObj epid2params;
    319   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
    320   uint32_t nv_index = 0x01000003;
    321 
    322   MembershipCredential data = {0};
    323   EXPECT_EQ(kEpidBadArgErr, Tpm2NvRead(tpm, nv_index, 1, 0, &data));
    324 }
    325 
    326 }  // namespace
    327