1 /*############################################################################
2 # Copyright 2016-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
17 /*!
18 * \file
19 * \brief Intel Intel(R) EPID 1.1 Verifier context implementation.
20 */
21
22 #include "epid/verifier/1.1/src/context.h"
23 #include "epid/common/src/endian_convert.h"
24 #include "epid/common/src/memory.h"
25 #include "epid/verifier/1.1/api.h"
26
27 /// Handle SDK Error with Break
28 #define BREAK_ON_EPID_ERROR(ret) \
29 \
30 if (kEpidNoErr != (ret)) { \
31 break; \
32 }
33
34 /// create Verifier precomp of the Epid11VerifierCtx
35 static EpidStatus DoPrecomputation(Epid11VerifierCtx* ctx);
36
37 /// Read Verifier precomp
38 static EpidStatus ReadPrecomputation(Epid11VerifierPrecomp const* precomp_str,
39 Epid11VerifierCtx* ctx);
40
41 /// Internal function to prove if group based revocation list is valid
Epid11IsGroupRlValid(Epid11GroupRl const * group_rl,size_t grp_rl_size)42 static bool Epid11IsGroupRlValid(Epid11GroupRl const* group_rl,
43 size_t grp_rl_size) {
44 const size_t kMinGroupRlSize = sizeof(Epid11GroupRl) - sizeof(Epid11GroupId);
45 size_t input_grp_rl_size = 0;
46
47 if (!group_rl) {
48 return false;
49 }
50 if (grp_rl_size < kMinGroupRlSize) {
51 return false;
52 }
53 if (ntohl(group_rl->n3) >
54 (SIZE_MAX - kMinGroupRlSize) / sizeof(Epid11GroupId)) {
55 return false;
56 }
57 input_grp_rl_size =
58 kMinGroupRlSize + (ntohl(group_rl->n3) * sizeof(Epid11GroupId));
59 if (input_grp_rl_size != grp_rl_size) {
60 return false;
61 }
62 return true;
63 }
64 /// Internal function to prove if signature based revocation list is valid
Epid11IsSigRlValid(Epid11GroupId const * gid,Epid11SigRl const * sig_rl,size_t sig_rl_size)65 bool Epid11IsSigRlValid(Epid11GroupId const* gid, Epid11SigRl const* sig_rl,
66 size_t sig_rl_size) {
67 const size_t kMinSigRlSize = sizeof(Epid11SigRl) - sizeof(Epid11SigRlEntry);
68 size_t input_sig_rl_size = 0;
69 if (!gid || !sig_rl || kMinSigRlSize > sig_rl_size) {
70 return false;
71 }
72 if (ntohl(sig_rl->n2) > (SIZE_MAX - kMinSigRlSize) / sizeof(sig_rl->bk[0])) {
73 return false;
74 }
75 // sanity check of intput SigRl size
76 input_sig_rl_size = kMinSigRlSize + ntohl(sig_rl->n2) * sizeof(sig_rl->bk[0]);
77 if (input_sig_rl_size != sig_rl_size) {
78 return false;
79 }
80 // verify that gid given and gid in SigRl match
81 if (0 != memcmp(gid, &sig_rl->gid, sizeof(*gid))) {
82 return false;
83 }
84 return true;
85 }
86 /// Internal function to verify if Intel(R) EPID 1.1 private key based
87 /// revocation list is valid
IsEpid11PrivRlValid(Epid11GroupId const * gid,Epid11PrivRl const * priv_rl,size_t priv_rl_size)88 static bool IsEpid11PrivRlValid(Epid11GroupId const* gid,
89 Epid11PrivRl const* priv_rl,
90 size_t priv_rl_size) {
91 const size_t kMinPrivRlSize = sizeof(Epid11PrivRl) - sizeof(FpElemStr);
92 size_t input_priv_rl_size = 0;
93
94 if (!gid || !priv_rl || kMinPrivRlSize > priv_rl_size) {
95 return false;
96 }
97 if (ntohl(priv_rl->n1) >
98 (SIZE_MAX - kMinPrivRlSize) / sizeof(priv_rl->f[0])) {
99 return false;
100 }
101 // sanity check of input Epid11PrivRl size
102 input_priv_rl_size =
103 kMinPrivRlSize + ntohl(priv_rl->n1) * sizeof(priv_rl->f[0]);
104 if (input_priv_rl_size != priv_rl_size) {
105 return false;
106 }
107 // verify that gid given and gid in Epid11PrivRl match
108 if (0 != memcmp(gid, &priv_rl->gid, sizeof(*gid))) {
109 return false;
110 }
111 return true;
112 }
113
Epid11VerifierCreate(Epid11GroupPubKey const * pub_key,Epid11VerifierPrecomp const * precomp,Epid11VerifierCtx ** ctx)114 EpidStatus Epid11VerifierCreate(Epid11GroupPubKey const* pub_key,
115 Epid11VerifierPrecomp const* precomp,
116 Epid11VerifierCtx** ctx) {
117 EpidStatus result = kEpidErr;
118 Epid11VerifierCtx* verifier_ctx = NULL;
119 if (!pub_key || !ctx) {
120 return kEpidBadArgErr;
121 }
122 do {
123 // Allocate memory for VerifierCtx
124 verifier_ctx = SAFE_ALLOC(sizeof(Epid11VerifierCtx));
125 if (!verifier_ctx) {
126 result = kEpidMemAllocErr;
127 break;
128 }
129
130 // Internal representation of Epid11Params
131 result = CreateEpid11Params(&verifier_ctx->epid11_params);
132 BREAK_ON_EPID_ERROR(result);
133 // Internal representation of Group Pub Key
134 result = CreateEpid11GroupPubKey(pub_key, verifier_ctx->epid11_params->G1,
135 verifier_ctx->epid11_params->G2,
136 &verifier_ctx->pub_key);
137 BREAK_ON_EPID_ERROR(result);
138 // Store group public key strings for later use
139 result =
140 SetKeySpecificEpid11CommitValues(pub_key, &verifier_ctx->commit_values);
141 if (kEpidNoErr != result) {
142 break;
143 }
144 // Allocate verifier_ctx->e12
145 result = NewFfElement(verifier_ctx->epid11_params->GT, &verifier_ctx->e12);
146 BREAK_ON_EPID_ERROR(result);
147 // Allocate verifier_ctx->e22
148 result = NewFfElement(verifier_ctx->epid11_params->GT, &verifier_ctx->e22);
149 BREAK_ON_EPID_ERROR(result);
150 // Allocate verifier_ctx->e2w
151 result = NewFfElement(verifier_ctx->epid11_params->GT, &verifier_ctx->e2w);
152 BREAK_ON_EPID_ERROR(result);
153 // precomputation
154 if (precomp != NULL) {
155 result = ReadPrecomputation(precomp, verifier_ctx);
156 } else {
157 result = DoPrecomputation(verifier_ctx);
158 }
159 BREAK_ON_EPID_ERROR(result);
160 verifier_ctx->sig_rl = NULL;
161 verifier_ctx->group_rl = NULL;
162 verifier_ctx->priv_rl = NULL;
163 *ctx = verifier_ctx;
164 result = kEpidNoErr;
165 } while (0);
166
167 if (kEpidNoErr != result && verifier_ctx) {
168 DeleteFfElement(&verifier_ctx->e2w);
169 DeleteFfElement(&verifier_ctx->e22);
170 DeleteFfElement(&verifier_ctx->e12);
171 DeleteEpid11GroupPubKey(&verifier_ctx->pub_key);
172 DeleteEpid11Params(&verifier_ctx->epid11_params);
173 SAFE_FREE(verifier_ctx);
174 }
175 return result;
176 }
177
Epid11VerifierDelete(Epid11VerifierCtx ** ctx)178 void Epid11VerifierDelete(Epid11VerifierCtx** ctx) {
179 if (ctx && *ctx) {
180 DeleteFfElement(&(*ctx)->e2w);
181 DeleteFfElement(&(*ctx)->e22);
182 DeleteFfElement(&(*ctx)->e12);
183 DeleteEpid11GroupPubKey(&(*ctx)->pub_key);
184 DeleteEpid11Params(&(*ctx)->epid11_params);
185 (*ctx)->priv_rl = NULL;
186 (*ctx)->sig_rl = NULL;
187 (*ctx)->group_rl = NULL;
188 DeleteEcPoint(&(*ctx)->basename_hash);
189 SAFE_FREE((*ctx)->basename);
190 (*ctx)->basename_len = 0;
191 SAFE_FREE(*ctx);
192 }
193 }
194
Epid11VerifierWritePrecomp(Epid11VerifierCtx const * ctx,Epid11VerifierPrecomp * precomp)195 EpidStatus Epid11VerifierWritePrecomp(Epid11VerifierCtx const* ctx,
196 Epid11VerifierPrecomp* precomp) {
197 EpidStatus result = kEpidErr;
198 FfElement* e12 = NULL; // an element in GT
199 FfElement* e22 = NULL; // an element in GT
200 FfElement* e2w = NULL; // an element in GT
201 FiniteField* GT = NULL; // Finite field GT(Fq6)
202 if (!ctx || !ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->epid11_params ||
203 !(ctx->epid11_params->GT) || !ctx->pub_key || !precomp) {
204 return kEpidBadArgErr;
205 }
206 e12 = ctx->e12;
207 e22 = ctx->e22;
208 e2w = ctx->e2w;
209 GT = ctx->epid11_params->GT;
210
211 precomp->gid = ctx->pub_key->gid;
212 result = WriteFfElement(GT, e12, &(precomp->e12), sizeof(precomp->e12));
213 if (kEpidNoErr != result) {
214 return result;
215 }
216 result = WriteFfElement(GT, e22, &(precomp->e22), sizeof(precomp->e22));
217 if (kEpidNoErr != result) {
218 return result;
219 }
220 result = WriteFfElement(GT, e2w, &(precomp->e2w), sizeof(precomp->e2w));
221 if (kEpidNoErr != result) {
222 return result;
223 }
224 return result;
225 }
226
Epid11VerifierSetPrivRl(Epid11VerifierCtx * ctx,Epid11PrivRl const * priv_rl,size_t priv_rl_size)227 EpidStatus Epid11VerifierSetPrivRl(Epid11VerifierCtx* ctx,
228 Epid11PrivRl const* priv_rl,
229 size_t priv_rl_size) {
230 if (!ctx || !priv_rl || !ctx->pub_key) {
231 return kEpidBadArgErr;
232 }
233 if (!IsEpid11PrivRlValid(&ctx->pub_key->gid, priv_rl, priv_rl_size)) {
234 return kEpidBadArgErr;
235 }
236 // Do not set an older version of Epid11PrivRl
237 if (ctx->priv_rl) {
238 unsigned int current_ver = 0;
239 unsigned int incoming_ver = 0;
240 current_ver = ntohl(ctx->priv_rl->version);
241 incoming_ver = ntohl(priv_rl->version);
242 if (current_ver >= incoming_ver) {
243 return kEpidBadArgErr;
244 }
245 }
246 ctx->priv_rl = priv_rl;
247 return kEpidNoErr;
248 }
249
Epid11VerifierSetSigRl(Epid11VerifierCtx * ctx,Epid11SigRl const * sig_rl,size_t sig_rl_size)250 EpidStatus Epid11VerifierSetSigRl(Epid11VerifierCtx* ctx,
251 Epid11SigRl const* sig_rl,
252 size_t sig_rl_size) {
253 if (!ctx || !sig_rl || !ctx->pub_key) {
254 return kEpidBadArgErr;
255 }
256 // Do not set an older version of sig rl
257 if (ctx->sig_rl) {
258 unsigned int current_ver = 0;
259 unsigned int incoming_ver = 0;
260 current_ver = ntohl(ctx->sig_rl->version);
261 incoming_ver = ntohl(sig_rl->version);
262 if (current_ver >= incoming_ver) {
263 return kEpidBadArgErr;
264 }
265 }
266 if (!Epid11IsSigRlValid(&ctx->pub_key->gid, sig_rl, sig_rl_size)) {
267 return kEpidBadArgErr;
268 }
269 ctx->sig_rl = sig_rl;
270
271 return kEpidNoErr;
272 }
273
Epid11VerifierSetGroupRl(Epid11VerifierCtx * ctx,Epid11GroupRl const * grp_rl,size_t grp_rl_size)274 EpidStatus Epid11VerifierSetGroupRl(Epid11VerifierCtx* ctx,
275 Epid11GroupRl const* grp_rl,
276 size_t grp_rl_size) {
277 if (!ctx || !grp_rl || !ctx->pub_key) {
278 return kEpidBadArgErr;
279 }
280 if (!Epid11IsGroupRlValid(grp_rl, grp_rl_size)) {
281 return kEpidBadArgErr;
282 }
283 // Do not set an older version of group rl
284 if (ctx->group_rl) {
285 unsigned int current_ver = 0;
286 unsigned int incoming_ver = 0;
287 current_ver = ntohl(ctx->group_rl->version);
288 incoming_ver = ntohl(grp_rl->version);
289 if (current_ver >= incoming_ver) {
290 return kEpidBadArgErr;
291 }
292 }
293 ctx->group_rl = grp_rl;
294
295 return kEpidNoErr;
296 }
297
Epid11VerifierSetBasename(Epid11VerifierCtx * ctx,void const * basename,size_t basename_len)298 EpidStatus Epid11VerifierSetBasename(Epid11VerifierCtx* ctx,
299 void const* basename,
300 size_t basename_len) {
301 EpidStatus result = kEpidErr;
302 EcPoint* basename_hash = NULL;
303 uint8_t* basename_buffer = NULL;
304
305 if (!ctx || !ctx->epid11_params || !ctx->epid11_params->G3) {
306 return kEpidBadArgErr;
307 }
308 if (!basename && basename_len > 0) {
309 return kEpidBadArgErr;
310 }
311
312 if (!basename) {
313 ctx->basename_len = 0;
314 DeleteEcPoint(&ctx->basename_hash);
315 SAFE_FREE(ctx->basename);
316 return kEpidNoErr;
317 }
318
319 do {
320 EcGroup* G3 = ctx->epid11_params->G3;
321 result = NewEcPoint(G3, &basename_hash);
322 if (kEpidNoErr != result) {
323 break;
324 }
325
326 result = Epid11EcHash(G3, basename, basename_len, basename_hash);
327 if (kEpidNoErr != result) {
328 break;
329 }
330
331 if (basename_len > 0) {
332 basename_buffer = SAFE_ALLOC(basename_len);
333 if (!basename_buffer) {
334 result = kEpidMemAllocErr;
335 break;
336 }
337 }
338
339 ctx->basename_len = basename_len;
340
341 if (basename_len > 0) {
342 // memcpy is used to copy variable length basename
343 if (0 != memcpy_S(basename_buffer, ctx->basename_len, basename,
344 basename_len)) {
345 result = kEpidErr;
346 break;
347 }
348 }
349 DeleteEcPoint(&ctx->basename_hash);
350 SAFE_FREE(ctx->basename);
351 ctx->basename = basename_buffer;
352 ctx->basename_hash = basename_hash;
353
354 result = kEpidNoErr;
355 } while (0);
356
357 if (kEpidNoErr != result) {
358 DeleteEcPoint(&basename_hash);
359 SAFE_FREE(basename_buffer);
360 }
361 return result;
362 }
363
DoPrecomputation(Epid11VerifierCtx * ctx)364 static EpidStatus DoPrecomputation(Epid11VerifierCtx* ctx) {
365 EpidStatus result = kEpidErr;
366 FfElement* e12 = NULL;
367 FfElement* e22 = NULL;
368 FfElement* e2w = NULL;
369 Epid11Params_* params = NULL;
370 Epid11GroupPubKey_* pub_key = NULL;
371 Epid11PairingState* ps_ctx = NULL;
372 if (!ctx) {
373 return kEpidBadArgErr;
374 }
375 if (!ctx->epid11_params || !ctx->epid11_params->GT ||
376 !ctx->epid11_params->pairing_state || !ctx->pub_key || !ctx->e12 ||
377 !ctx->e22 || !ctx->e2w) {
378 return kEpidBadArgErr;
379 }
380 pub_key = ctx->pub_key;
381 params = ctx->epid11_params;
382 e12 = ctx->e12;
383 e22 = ctx->e22;
384 e2w = ctx->e2w;
385 ps_ctx = params->pairing_state;
386 // do precomputation
387 // 1. The verifier computes e12 = pairing(h1, g2).
388 result = Epid11Pairing(ps_ctx, pub_key->h1, params->g2, e12);
389 if (kEpidNoErr != result) {
390 return result;
391 }
392 // 2. The verifier computes e22 = pairing(h2, g2).
393 result = Epid11Pairing(ps_ctx, pub_key->h2, params->g2, e22);
394 if (kEpidNoErr != result) {
395 return result;
396 }
397 // 3. The verifier computes e2w = pairing(h2, w).
398 result = Epid11Pairing(ps_ctx, pub_key->h2, pub_key->w, e2w);
399 if (kEpidNoErr != result) {
400 return result;
401 }
402 return kEpidNoErr;
403 }
ReadPrecomputation(Epid11VerifierPrecomp const * precomp_str,Epid11VerifierCtx * ctx)404 static EpidStatus ReadPrecomputation(Epid11VerifierPrecomp const* precomp_str,
405 Epid11VerifierCtx* ctx) {
406 EpidStatus result = kEpidErr;
407 FfElement* e12 = NULL;
408 FfElement* e22 = NULL;
409 FfElement* e2w = NULL;
410 FiniteField* GT = NULL;
411 Epid11Params_* params = NULL;
412 unsigned int current_gid = 0;
413 unsigned int incoming_gid = 0;
414 if (!ctx) {
415 return kEpidBadArgErr;
416 }
417 if (!ctx->epid11_params || !ctx->epid11_params->GT || !ctx->e12 ||
418 !ctx->e22 || !ctx->e2w) {
419 return kEpidBadArgErr;
420 }
421
422 if (!ctx->pub_key || !precomp_str) return kEpidBadArgErr;
423
424 current_gid = ntohl(ctx->pub_key->gid);
425 incoming_gid = ntohl(precomp_str->gid);
426
427 if (current_gid != incoming_gid) {
428 return kEpidBadArgErr;
429 }
430
431 params = ctx->epid11_params;
432 GT = params->GT;
433 e12 = ctx->e12;
434 e22 = ctx->e22;
435 e2w = ctx->e2w;
436
437 result = ReadFfElement(GT, &precomp_str->e12, sizeof(precomp_str->e12), e12);
438 if (kEpidNoErr != result) {
439 return result;
440 }
441 result = ReadFfElement(GT, &precomp_str->e22, sizeof(precomp_str->e22), e22);
442 if (kEpidNoErr != result) {
443 return result;
444 }
445 result = ReadFfElement(GT, &precomp_str->e2w, sizeof(precomp_str->e2w), e2w);
446 if (kEpidNoErr != result) {
447 return result;
448 }
449 return kEpidNoErr;
450 }
451