• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// Tpm2Commit unit tests.
17 /*! \file */
18 
19 #include "gtest/gtest.h"
20 
21 #include "epid/common-testhelper/ecpoint_wrapper-testhelper.h"
22 #include "epid/common-testhelper/epid2params_wrapper-testhelper.h"
23 #include "epid/common-testhelper/epid_params-testhelper.h"
24 #include "epid/common-testhelper/errors-testhelper.h"
25 #include "epid/common-testhelper/ffelement_wrapper-testhelper.h"
26 #include "epid/common-testhelper/prng-testhelper.h"
27 #include "epid/member/tpm2/unittests/tpm2-testhelper.h"
28 
29 extern "C" {
30 #include "epid/common/src/endian_convert.h"
31 #include "epid/member/tpm2/commit.h"
32 #include "epid/member/tpm2/context.h"
33 #include "epid/member/tpm2/load_external.h"
34 #include "epid/member/tpm2/sign.h"
35 }
36 
37 namespace {
38 
TEST_F(EpidTpm2Test,CommitFailsGivenNullParameters)39 TEST_F(EpidTpm2Test, CommitFailsGivenNullParameters) {
40   Epid20Params params;
41   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
42   EcPointObj p1(&params.G1, this->kP1Str);
43   FfElementObj y2(&params.fq, this->kY2Sha256Str);
44   uint16_t counter = 0;
45 
46   Prng my_prng;
47   Epid2ParamsObj epid2params;
48   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
49   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
50   THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
51 
52   EXPECT_EQ(kEpidBadArgErr,
53             Tpm2Commit(nullptr, p1, this->kS2Sha256.data(),
54                        this->kS2Sha256.size(), y2, k, l, e, &counter));
55   EXPECT_EQ(kEpidBadArgErr, Tpm2Commit(tpm, p1, nullptr, this->kS2Sha256.size(),
56                                        y2, k, l, e, &counter));
57   // Testing step a of the "C.2.3 Tpm2Commit()"
58   EXPECT_EQ(kEpidBadArgErr,
59             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
60                        nullptr, k, l, e, &counter));
61   // Testing step a of the "C.2.3 Tpm2Commit()"
62   EXPECT_EQ(kEpidBadArgErr,
63             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
64                        y2, nullptr, l, e, &counter));
65   EXPECT_EQ(kEpidBadArgErr,
66             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
67                        y2, k, nullptr, e, &counter));
68   EXPECT_EQ(kEpidBadArgErr,
69             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
70                        y2, k, l, nullptr, &counter));
71   EXPECT_EQ(kEpidBadArgErr,
72             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
73                        y2, k, l, e, nullptr));
74 }
75 
TEST_F(EpidTpm2Test,CommitFailsGivenInvalidLength)76 TEST_F(EpidTpm2Test, CommitFailsGivenInvalidLength) {
77   Epid20Params params;
78   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
79   EcPointObj p1(&params.G1, this->kP1Str);
80   FfElementObj y2(&params.fq, this->kY2Sha256Str);
81   uint16_t counter = 0;
82 
83   Prng my_prng;
84   Epid2ParamsObj epid2params;
85   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
86   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
87   THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
88 
89   EXPECT_EQ(kEpidBadArgErr, Tpm2Commit(tpm, p1, this->kS2Sha256.data(), 0, y2,
90                                        k, l, e, &counter));
91   EXPECT_EQ(kEpidBadArgErr,
92             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), sizeof(uint16_t) - 1,
93                        y2, k, l, e, &counter));
94 }
95 
TEST_F(EpidTpm2Test,CommitFailsGivenPrivateKeyDoesNotExists)96 TEST_F(EpidTpm2Test, CommitFailsGivenPrivateKeyDoesNotExists) {
97   // Testing step d of the "C.2.3 Tpm2Commit()"
98   Epid20Params params;
99   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
100   EcPointObj p1(&params.G1, this->kP1Str);
101   FfElementObj y2(&params.fq, this->kY2Sha256Str);
102   uint16_t counter = 0;
103 
104   Prng my_prng;
105   Epid2ParamsObj epid2params;
106   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, NULL, epid2params);
107 
108   EXPECT_EQ(kEpidBadArgErr,
109             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
110                        y2, k, l, e, &counter));
111 }
112 
TEST_F(EpidTpm2Test,CommitFailsGivenS2y2NotOnCurve)113 TEST_F(EpidTpm2Test, CommitFailsGivenS2y2NotOnCurve) {
114   // Testing step d of the "C.2.3 Tpm2Commit()"
115   Epid20Params params;
116   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
117   EcPointObj p1(&params.G1, this->kP1Str);
118   FqElemStr invalid_kY2Sha256Str = this->kY2Sha256Str;
119   invalid_kY2Sha256Str.data.data[31]++;  // make point not belong to the group
120   FfElementObj invalid_y2(&params.fq, invalid_kY2Sha256Str);
121   uint16_t counter = 0;
122 
123   Prng my_prng;
124   Epid2ParamsObj epid2params;
125   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
126   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
127   THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
128 
129   EXPECT_EQ(kEpidBadArgErr,
130             Tpm2Commit(tpm, p1, this->kS2Sha256.data(), this->kS2Sha256.size(),
131                        invalid_y2, k, l, e, &counter));
132 }
133 
TEST_F(EpidTpm2Test,CommitFailsIfResultIsAtInfinity)134 TEST_F(EpidTpm2Test, CommitFailsIfResultIsAtInfinity) {
135   // Testing step l of the "C.2.3 Tpm2Commit()"
136   Epid20Params params;
137   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
138   G1ElemStr infinity_str = {0};
139   EcPointObj infinity(&params.G1, infinity_str);
140   FfElementObj y2(&params.fq, this->kY2Sha256Str);
141   uint16_t counter = 0;
142 
143   Prng my_prng;
144   Epid2ParamsObj epid2params;
145   Tpm2CtxObj tpm(&Prng::Generate, &my_prng, &this->kMemberFValue, epid2params);
146   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
147   THROW_ON_EPIDERR(Tpm2LoadExternal(tpm, &this->kMemberFValue));
148 
149   EXPECT_EQ(kEpidBadArgErr,
150             Tpm2Commit(tpm, infinity, this->kS2Sha256.data(),
151                        this->kS2Sha256.size(), y2, k, l, e, &counter));
152 }
153 
TEST_F(EpidTpm2Test,CommitCanUseKeyLoadedByLoadExternal)154 TEST_F(EpidTpm2Test, CommitCanUseKeyLoadedByLoadExternal) {
155   Prng prng;
156   Epid2ParamsObj epid2params;
157   Epid20Params params;
158   FpElemStr f_str = this->kMemberFValue;
159   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
160   FfElementObj y2(&params.fq, this->kY2Sha256Str);
161   uint16_t counter = 0;
162   Tpm2CtxObj tpm(&Prng::Generate, &prng, &f_str, epid2params);
163   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
164   EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f_str));
165 
166   EXPECT_EQ(kEpidNoErr,
167             Tpm2Commit(tpm, nullptr, this->kS2Sha256.data(),
168                        this->kS2Sha256.size(), y2, k, l, e, &counter));
169   THROW_ON_EPIDERR(Tpm2ReleaseCounter(tpm, counter));
170 
171   // k = (x2, y2) ^ f, where x2 = Hash(s2)
172   G1ElemStr k_str;
173   THROW_ON_EPIDERR(WriteEcPoint(params.G1, k, &k_str, sizeof(k_str)));
174   EXPECT_EQ(this->kP2Sha256ExpF, k_str);
175 }
176 
TEST_F(EpidTpm2Test,CommitReturnsSameLEForSameP1P2)177 TEST_F(EpidTpm2Test, CommitReturnsSameLEForSameP1P2) {
178   Prng prng;
179   Epid2ParamsObj epid2params;
180   Epid20Params params;
181   FpElemStr f_str = this->kMemberFValue;
182   // create TPM context
183   Tpm2CtxObj tpm(&Prng::Generate, &prng, &f_str, epid2params);
184   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
185   // load f value
186   EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f_str));
187 
188   // commit(P1=p2, P2=p2) => k = p2^f, l = p2^r, e = p2^r
189   FfElementObj y2(&params.fq, this->kY2Sha256Str);
190   EcPointObj p2(&params.G1, kP2Sha256Str);
191   EcPointObj p2_exp_f(&params.G1, kP2Sha256ExpF);
192 
193   EcPointObj k(&params.G1), l(&params.G1), e(&params.G1);
194   uint16_t counter = 0;
195   EXPECT_EQ(kEpidNoErr,
196             Tpm2Commit(tpm, p2, this->kS2Sha256.data(), this->kS2Sha256.size(),
197                        y2, k, l, e, &counter));
198   THROW_ON_EPIDERR(Tpm2ReleaseCounter(tpm, counter));
199 
200   G1ElemStr l_str, e_str;
201   THROW_ON_EPIDERR(WriteEcPoint(params.G1, l, &l_str, sizeof(l_str)));
202   THROW_ON_EPIDERR(WriteEcPoint(params.G1, e, &e_str, sizeof(e_str)));
203   EXPECT_EQ(l_str, e_str);
204 }
205 
TEST_F(EpidTpm2Test,CommitCanBeUsedTwice)206 TEST_F(EpidTpm2Test, CommitCanBeUsedTwice) {
207   Prng prng;
208   Epid2ParamsObj epid2params;
209   Epid20Params params;
210   FpElemStr f_str = this->kMemberFValue;
211   // create TPM context
212   Tpm2CtxObj tpm(&Prng::Generate, &prng, &f_str, epid2params);
213   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, kSha256));
214   // load f value
215   EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f_str));
216 
217   EcPointObj p1(&params.G1, this->kP1Str);
218   EcPointObj e(&params.G1);
219   uint16_t ctr1 = 0, ctr2 = 0;
220 
221   EXPECT_EQ(kEpidNoErr, Tpm2Commit(tpm, p1, nullptr, 0, nullptr, nullptr,
222                                    nullptr, e, &ctr1));
223 
224   EXPECT_EQ(kEpidNoErr, Tpm2Commit(tpm, p1, nullptr, 0, nullptr, nullptr,
225                                    nullptr, e, &ctr2));
226   THROW_ON_EPIDERR(Tpm2ReleaseCounter(tpm, ctr1));
227   THROW_ON_EPIDERR(Tpm2ReleaseCounter(tpm, ctr2));
228 }
TEST_F(EpidTpm2Test,CommitCanUseHashFromEcHashSha256)229 TEST_F(EpidTpm2Test, CommitCanUseHashFromEcHashSha256) {
230   HashAlg halg = kSha256;
231   Prng prng;
232   Epid2ParamsObj epid2params;
233   FpElemStr f_str = this->kMemberFValue;
234   Tpm2CtxObj tpm(&Prng::Generate, &prng, &f_str, epid2params);
235   Epid20Params params;
236   EcPointObj R(&params.G1), k(&params.G1), l(&params.G1), e(&params.G1);
237   FfElementObj y(&params.fq);
238   uint32_t i = 0;
239   uint16_t counter = 0;
240   G1ElemStr R_str = {0};
241   std::vector<uint8_t> bsn = {'b', 's', 'n', '0'};
242   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, halg));
243   EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f_str));
244 
245   EXPECT_EQ(kEpidNoErr,
246             EcHash(epid2params.G1(), bsn.data(), bsn.size(), halg, R, &i));
247   i = ntohl(i);
248   THROW_ON_EPIDERR(WriteEcPoint(epid2params.G1(), R, &R_str, sizeof(R_str)));
249   THROW_ON_EPIDERR(
250       ReadFfElement(params.fq.get(), &R_str.y, sizeof(R_str.y), y));
251 
252   std::vector<uint8_t> digest((uint8_t*)&i, (uint8_t*)&i + sizeof(i));
253   digest.reserve(digest.size() + bsn.size());
254   digest.insert(digest.end(), bsn.begin(), bsn.end());
255   EXPECT_EQ(kEpidNoErr, Tpm2Commit(tpm, nullptr, digest.data(), digest.size(),
256                                    y, k, l, e, &counter));
257   Tpm2ReleaseCounter(tpm, counter);
258 }
259 #ifndef TPM_TSS
TEST_F(EpidTpm2Test,CommitCanUseHashFromEcHashSha384)260 TEST_F(EpidTpm2Test, CommitCanUseHashFromEcHashSha384) {
261   HashAlg halg = kSha384;
262   Prng prng;
263   Epid2ParamsObj epid2params;
264   FpElemStr f_str = this->kMemberFValue;
265   Tpm2CtxObj tpm(&Prng::Generate, &prng, &f_str, epid2params);
266   Epid20Params params;
267   EcPointObj R(&params.G1), k(&params.G1), l(&params.G1), e(&params.G1);
268   FfElementObj y(&params.fq);
269   uint32_t i = 0;
270   uint16_t counter = 0;
271   G1ElemStr R_str = {0};
272   std::vector<uint8_t> bsn = {'b', 's', 'n', '0'};
273   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, halg));
274   EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f_str));
275 
276   EXPECT_EQ(kEpidNoErr,
277             EcHash(epid2params.G1(), bsn.data(), bsn.size(), halg, R, &i));
278   i = ntohl(i);
279   THROW_ON_EPIDERR(WriteEcPoint(epid2params.G1(), R, &R_str, sizeof(R_str)));
280   THROW_ON_EPIDERR(
281       ReadFfElement(params.fq.get(), &R_str.y, sizeof(R_str.y), y));
282 
283   std::vector<uint8_t> digest((uint8_t*)&i, (uint8_t*)&i + sizeof(i));
284   digest.reserve(digest.size() + bsn.size());
285   digest.insert(digest.end(), bsn.begin(), bsn.end());
286   EXPECT_EQ(kEpidNoErr, Tpm2Commit(tpm, nullptr, digest.data(), digest.size(),
287                                    y, k, l, e, &counter));
288   Tpm2ReleaseCounter(tpm, counter);
289 }
TEST_F(EpidTpm2Test,CommitCanUseHashFromEcHashSha512)290 TEST_F(EpidTpm2Test, CommitCanUseHashFromEcHashSha512) {
291   HashAlg halg = kSha512;
292   Prng prng;
293   Epid2ParamsObj epid2params;
294   FpElemStr f_str = this->kMemberFValue;
295   Tpm2CtxObj tpm(&Prng::Generate, &prng, &f_str, epid2params);
296   Epid20Params params;
297   EcPointObj R(&params.G1), k(&params.G1), l(&params.G1), e(&params.G1);
298   FfElementObj y(&params.fq);
299   uint32_t i = 0;
300   uint16_t counter = 0;
301   G1ElemStr R_str = {0};
302   std::vector<uint8_t> bsn = {'b', 's', 'n', '0'};
303   THROW_ON_EPIDERR(Tpm2SetHashAlg(tpm, halg));
304   EXPECT_EQ(kEpidNoErr, Tpm2LoadExternal(tpm, &f_str));
305 
306   EXPECT_EQ(kEpidNoErr,
307             EcHash(epid2params.G1(), bsn.data(), bsn.size(), halg, R, &i));
308   i = ntohl(i);
309   THROW_ON_EPIDERR(WriteEcPoint(epid2params.G1(), R, &R_str, sizeof(R_str)));
310   THROW_ON_EPIDERR(
311       ReadFfElement(params.fq.get(), &R_str.y, sizeof(R_str.y), y));
312 
313   std::vector<uint8_t> digest((uint8_t*)&i, (uint8_t*)&i + sizeof(i));
314   digest.reserve(digest.size() + bsn.size());
315   digest.insert(digest.end(), bsn.begin(), bsn.end());
316   EXPECT_EQ(kEpidNoErr, Tpm2Commit(tpm, nullptr, digest.data(), digest.size(),
317                                    y, k, l, e, &counter));
318   Tpm2ReleaseCounter(tpm, counter);
319 }
320 #endif  // TPM_TSS
321 }  // namespace
322