• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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