Home | History | Annotate | Download | only in src
      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
     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
     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
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 }
    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