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(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
42 EcPointObj p1(¶ms.G1, this->kP1Str);
43 FfElementObj y2(¶ms.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(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
79 EcPointObj p1(¶ms.G1, this->kP1Str);
80 FfElementObj y2(¶ms.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(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
100 EcPointObj p1(¶ms.G1, this->kP1Str);
101 FfElementObj y2(¶ms.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(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
117 EcPointObj p1(¶ms.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(¶ms.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(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
138 G1ElemStr infinity_str = {0};
139 EcPointObj infinity(¶ms.G1, infinity_str);
140 FfElementObj y2(¶ms.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(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
160 FfElementObj y2(¶ms.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(¶ms.fq, this->kY2Sha256Str);
190 EcPointObj p2(¶ms.G1, kP2Sha256Str);
191 EcPointObj p2_exp_f(¶ms.G1, kP2Sha256ExpF);
192
193 EcPointObj k(¶ms.G1), l(¶ms.G1), e(¶ms.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(¶ms.G1, this->kP1Str);
218 EcPointObj e(¶ms.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(¶ms.G1), k(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
237 FfElementObj y(¶ms.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(¶ms.G1), k(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
268 FfElementObj y(¶ms.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(¶ms.G1), k(¶ms.G1), l(¶ms.G1), e(¶ms.G1);
298 FfElementObj y(¶ms.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