sign-test.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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 Sign unit tests.
  17. /*! \file */
  18. #include <climits>
  19. #include "gtest/gtest.h"
  20. #include "epid/common-testhelper/epid2params_wrapper-testhelper.h"
  21. #include "epid/common-testhelper/epid_params-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/common/src/hashsize.h"
  27. #include "epid/common/src/memory.h"
  28. #include "epid/member/tpm2/commit.h"
  29. #include "epid/member/tpm2/load_external.h"
  30. #include "epid/member/tpm2/sign.h"
  31. }
  32. namespace {
  33. //////////////////////////////////////////////////////////////////////////
  34. // Tpm2Sign Tests
  35. // Verify signature computed by TPM ECDAA scheme:
  36. // sign_k ?= digest mod p
  37. // point^sign_s ?= random_exp * private_exp^sign_k
  38. bool IsSignatureValid(void const* digest, size_t digest_len,
  39. FfElement const* sign_k, FfElement const* sign_s,
  40. EcPoint const* point, EcPoint const* private_exp,
  41. EcPoint const* random_exp, HashAlg hash_alg) {
  42. (void)hash_alg;
  43. Epid20Params params;
  44. BigNumObj digest_bn(digest_len);
  45. THROW_ON_EPIDERR(ReadBigNum(digest, digest_len, digest_bn));
  46. FfElementObj t(&params.fp);
  47. THROW_ON_EPIDERR(InitFfElementFromBn(params.fp, digest_bn, t));
  48. FpElemStr t_str, sign_k_str;
  49. THROW_ON_EPIDERR(WriteFfElement(params.fp, t, &t_str, sizeof(t_str)));
  50. THROW_ON_EPIDERR(
  51. WriteFfElement(params.fp, sign_k, &sign_k_str, sizeof(sign_k_str)));
  52. if (!(t_str == sign_k_str)) return false;
  53. BigNumStr exp;
  54. // v1 = p2^s
  55. EcPointObj v1(&params.G1);
  56. THROW_ON_EPIDERR(WriteFfElement(params.fp, sign_s, &exp, sizeof(exp)));
  57. THROW_ON_EPIDERR(EcExp(params.G1, point, &exp, v1));
  58. // v2 = k^sign_k
  59. EcPointObj v2(&params.G1);
  60. THROW_ON_EPIDERR(WriteFfElement(params.fp, sign_k, &exp, sizeof(exp)));
  61. THROW_ON_EPIDERR(EcExp(params.G1, private_exp, &exp, v2));
  62. // v2 = l * k^digest
  63. THROW_ON_EPIDERR(EcMul(params.G1, random_exp, v2, v2));
  64. // v1 ?= v2
  65. G1ElemStr v1_str, v2_str;
  66. THROW_ON_EPIDERR(WriteEcPoint(params.G1, v1, &v1_str, sizeof(v1_str)));
  67. THROW_ON_EPIDERR(WriteEcPoint(params.G1, v2, &v2_str, sizeof(v2_str)));
  68. return v1_str == v2_str;
  69. }
  70. TEST_F(EpidTpm2Test, SignProducesValidSignature) {
  71. Epid20Params params;
  72. // create TPM context
  73. Prng my_prng;
  74. Epid2ParamsObj epid2params;
  75. FpElemStr f = this->kMemberFValue;
  76. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &f, epid2params);
  77. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  78. // load f value
  79. EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f));
  80. // commit(P1=p2, P2=p2) => k = p2^f, l = p2^r, e = p2^r
  81. FfElementObj y2(&params.fq, this->kY2Sha256Str);
  82. EcPointObj p2(&params.G1, kP2Sha256Str);
  83. EcPointObj p2_exp_f(&params.G1, kP2Sha256ExpF);
  84. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  85. uint16_t counter = 0;
  86. EXPECT_EQ(kEpidNoErr,
  87. Tpm2Commit(tpm, p2, this->kS2Sha256.data(), this->kS2Sha256.size(),
  88. y2, k, l, e, &counter));
  89. // sign(digest) => sign_k = sign_k, sign_s = r + c * f,
  90. // where c = H(sign_k||digest)
  91. FfElementObj sign_k(&params.fp), sign_s(&params.fp);
  92. EXPECT_EQ(kEpidNoErr,
  93. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  94. counter, sign_k, sign_s));
  95. EXPECT_TRUE(IsSignatureValid(this->kDigestSha256, sizeof(this->kDigestSha256),
  96. sign_k, sign_s, p2, k, l, kSha256));
  97. }
  98. TEST_F(EpidTpm2Test, SignProducesValidSignatureTwoTimes) {
  99. Epid20Params params;
  100. // create TPM context
  101. Prng my_prng;
  102. Epid2ParamsObj epid2params;
  103. FpElemStr f = this->kMemberFValue;
  104. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &f, epid2params);
  105. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  106. // load f value
  107. EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f));
  108. // commit(P1=p2, P2=p2) => k = p2^f, l = p2^r, e = p2^r
  109. FfElementObj y2(&params.fq, this->kY2Sha256Str);
  110. EcPointObj p2(&params.G1, kP2Sha256Str);
  111. EcPointObj p2_exp_f(&params.G1, kP2Sha256ExpF);
  112. EcPointObj k1(&params.G1), l1(&params.G1), e1(&params.G1);
  113. EcPointObj k2(&params.G1), l2(&params.G1), e2(&params.G1);
  114. uint16_t ctr1 = 0, ctr2 = 0;
  115. EXPECT_EQ(kEpidNoErr,
  116. Tpm2Commit(tpm, p2, this->kS2Sha256.data(), this->kS2Sha256.size(),
  117. y2, k1, l1, e1, &ctr1));
  118. EXPECT_EQ(kEpidNoErr,
  119. Tpm2Commit(tpm, p2, this->kS2Sha256.data(), this->kS2Sha256.size(),
  120. y2, k2, l2, e2, &ctr2));
  121. // sign(digest) => sign_k = sign_k, sign_s = r + c * f,
  122. // where c = H(sign_k||digest)
  123. FfElementObj sign_k1(&params.fp), sign_s1(&params.fp);
  124. FfElementObj sign_k2(&params.fp), sign_s2(&params.fp);
  125. EXPECT_EQ(kEpidNoErr,
  126. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  127. ctr1, sign_k1, sign_s1));
  128. EXPECT_EQ(kEpidNoErr,
  129. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  130. ctr2, sign_k2, sign_s2));
  131. EXPECT_TRUE(IsSignatureValid(this->kDigestSha256, sizeof(this->kDigestSha256),
  132. sign_k1, sign_s1, p2, k1, l1, kSha256));
  133. EXPECT_TRUE(IsSignatureValid(this->kDigestSha256, sizeof(this->kDigestSha256),
  134. sign_k2, sign_s2, p2, k2, l2, kSha256));
  135. }
  136. TEST_F(EpidTpm2Test, SignFailsGivenNullParameters) {
  137. Epid20Params params;
  138. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  139. FfElementObj sig_k(&params.fp), sig_s(&params.fp);
  140. uint16_t counter = 0;
  141. Prng my_prng;
  142. Epid2ParamsObj epid2params;
  143. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
  144. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  145. THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
  146. THROW_ON_EPIDERR(
  147. Tpm2Commit(tpm, nullptr, nullptr, 0, nullptr, k, l, e, &counter));
  148. EXPECT_EQ(kEpidBadArgErr,
  149. Tpm2Sign(nullptr, this->kDigestSha256, sizeof(this->kDigestSha256),
  150. counter, sig_k, sig_s));
  151. EXPECT_EQ(kEpidBadArgErr, Tpm2Sign(tpm, nullptr, sizeof(this->kDigestSha256),
  152. counter, sig_k, sig_s));
  153. EXPECT_EQ(kEpidBadArgErr,
  154. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  155. counter, sig_k, nullptr));
  156. }
  157. TEST_F(EpidTpm2Test, SignFailsGivenInvalidDigestLen) {
  158. Epid20Params params;
  159. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  160. FfElementObj sig_k(&params.fp), sig_s(&params.fp);
  161. uint16_t counter = 0;
  162. Prng my_prng;
  163. Epid2ParamsObj epid2params;
  164. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
  165. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  166. THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
  167. THROW_ON_EPIDERR(
  168. Tpm2Commit(tpm, nullptr, nullptr, 0, nullptr, k, l, e, &counter));
  169. uint8_t digest[EPID_SHA256_DIGEST_BITSIZE / CHAR_BIT + 1] = {0};
  170. EXPECT_EQ(kEpidBadArgErr, Tpm2Sign(tpm, digest, 0, counter, sig_k, sig_s));
  171. EXPECT_EQ(kEpidBadArgErr,
  172. Tpm2Sign(tpm, digest, EPID_SHA256_DIGEST_BITSIZE / CHAR_BIT + 1,
  173. counter, sig_k, sig_s));
  174. EXPECT_EQ(kEpidBadArgErr,
  175. Tpm2Sign(tpm, digest, EPID_SHA256_DIGEST_BITSIZE / CHAR_BIT - 1,
  176. counter, sig_k, sig_s));
  177. }
  178. TEST_F(EpidTpm2Test, SignFailsGivenUnrecognizedCounter) {
  179. Epid20Params params;
  180. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  181. FfElementObj sig_k(&params.fp), sig_s(&params.fp);
  182. uint16_t counter = 0;
  183. uint16_t zero = 0;
  184. uint16_t one = 1;
  185. uint16_t minus_one = (uint16_t)-1;
  186. Prng my_prng;
  187. Epid2ParamsObj epid2params;
  188. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
  189. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  190. THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
  191. EXPECT_EQ(kEpidBadArgErr,
  192. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  193. zero, sig_k, sig_s));
  194. EXPECT_EQ(kEpidBadArgErr,
  195. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256), one,
  196. sig_k, sig_s));
  197. EXPECT_EQ(kEpidBadArgErr,
  198. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  199. minus_one, sig_k, sig_s));
  200. THROW_ON_EPIDERR(
  201. Tpm2Commit(tpm, nullptr, nullptr, 0, nullptr, k, l, e, &counter));
  202. uint16_t counter_plus_1 = counter + 1;
  203. EXPECT_EQ(kEpidBadArgErr,
  204. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  205. counter_plus_1, sig_k, sig_s));
  206. THROW_ON_EPIDERR(Tpm2ReleaseCounter(tpm, counter));
  207. }
  208. TEST_F(EpidTpm2Test, SignFailsGivenPreviouslyUsedCounter) {
  209. Epid20Params params;
  210. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  211. FfElementObj sig_k(&params.fp), sig_s(&params.fp);
  212. uint16_t counter = 0;
  213. Prng my_prng;
  214. Epid2ParamsObj epid2params;
  215. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
  216. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  217. THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
  218. THROW_ON_EPIDERR(
  219. Tpm2Commit(tpm, nullptr, nullptr, 0, nullptr, k, l, e, &counter));
  220. EXPECT_EQ(kEpidNoErr,
  221. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  222. counter, sig_k, sig_s));
  223. EXPECT_EQ(kEpidBadArgErr,
  224. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  225. counter, sig_k, sig_s));
  226. }
  227. TEST_F(EpidTpm2Test, SignFailsIfKeyNotSet) {
  228. Epid20Params params;
  229. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  230. FfElementObj sig_k(&params.fp), sig_s(&params.fp);
  231. uint16_t counter = 0;
  232. Prng my_prng;
  233. Epid2ParamsObj epid2params;
  234. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, nullptr, epid2params);
  235. EXPECT_EQ(kEpidBadArgErr,
  236. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  237. counter, sig_k, sig_s));
  238. }
  239. //////////////////////////////////////////////////////////////////////////
  240. // Tpm2ReleaseCounter Tests
  241. TEST_F(EpidTpm2Test, ReleaseCounterFailsGivenNullPtr) {
  242. // create TPM context
  243. Prng my_prng;
  244. Epid2ParamsObj epid2params;
  245. FpElemStr f = this->kMemberFValue;
  246. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &f, epid2params);
  247. uint16_t ctr = 0;
  248. EXPECT_EQ(kEpidBadArgErr, Tpm2ReleaseCounter(nullptr, ctr));
  249. }
  250. TEST_F(EpidTpm2Test, ReleaseCounterSuccessfullyReleasesCounter) {
  251. Epid20Params params;
  252. // create TPM context
  253. Prng my_prng;
  254. Epid2ParamsObj epid2params;
  255. FpElemStr f = this->kMemberFValue;
  256. Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &f, epid2params);
  257. THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
  258. // load f value
  259. EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f));
  260. // commit(P1=p2, P2=p2) => k = p2^f, l = p2^r, e = p2^r
  261. FfElementObj y2(&params.fq, this->kY2Sha256Str);
  262. EcPointObj p2(&params.G1, kP2Sha256Str);
  263. EcPointObj p2_exp_f(&params.G1, kP2Sha256ExpF);
  264. EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
  265. uint16_t counter = 0;
  266. EXPECT_EQ(kEpidNoErr,
  267. Tpm2Commit(tpm, p2, this->kS2Sha256.data(), this->kS2Sha256.size(),
  268. y2, k, l, e, &counter));
  269. EXPECT_EQ(kEpidNoErr, Tpm2ReleaseCounter(tpm, counter));
  270. // sign(digest) => sign_k = sign_k, sign_s = r + c * f,
  271. // where c = H(sign_k||digest)
  272. FfElementObj sign_k(&params.fp), sign_s(&params.fp);
  273. EXPECT_EQ(kEpidBadArgErr,
  274. Tpm2Sign(tpm, this->kDigestSha256, sizeof(this->kDigestSha256),
  275. counter, sign_k, sign_s));
  276. }
  277. } // namespace