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