nv-test.cc 12 KB

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