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 Verify implementation.
     20  */
     21 #include <string.h>
     22 #include "epid/common/src/endian_convert.h"
     23 #include "epid/verifier/api.h"
     24 #include "epid/verifier/src/context.h"
     25 
     26 /// Handle SDK Error with Break
     27 #define BREAK_ON_EPID_ERROR(ret) \
     28   if (kEpidNoErr != (ret)) {     \
     29     break;                       \
     30   }
     31 
     32 static size_t EpidGetSignatureRlCount(EpidSignature const* sig) {
     33   if (!sig)
     34     return 0;
     35   else
     36     return ntohl(sig->n2);
     37 }
     38 
     39 static size_t EpidGetGroupRlCount(GroupRl const* rl) {
     40   if (!rl)
     41     return 0;
     42   else
     43     return ntohl(rl->n3);
     44 }
     45 
     46 static size_t EpidGetPrivRlCount(PrivRl const* rl) {
     47   if (!rl)
     48     return 0;
     49   else
     50     return ntohl(rl->n1);
     51 }
     52 
     53 static size_t EpidGetSigRlCount(SigRl const* rl) {
     54   if (!rl)
     55     return 0;
     56   else
     57     return ntohl(rl->n2);
     58 }
     59 
     60 static size_t EpidGetVerifierRlCount(VerifierRl const* rl) {
     61   if (!rl)
     62     return 0;
     63   else
     64     return ntohl(rl->n4);
     65 }
     66 
     67 // implements section 4.1.2 "Verify algorithm" from Intel(R) EPID 2.0 Spec
     68 EpidStatus EpidVerify(VerifierCtx const* ctx, EpidSignature const* sig,
     69                       size_t sig_len, void const* msg, size_t msg_len) {
     70   // Step 1. Setup
     71   size_t const sig_header_len = (sizeof(EpidSignature) - sizeof(NrProof));
     72   EpidStatus sts = kEpidErr;
     73   size_t rl_count = 0;
     74   size_t i;
     75   if (!ctx || !sig) {
     76     return kEpidBadArgErr;
     77   }
     78   if (!msg && (0 != msg_len)) {
     79     // if message is non-empty it must have both length and content
     80     return kEpidBadArgErr;
     81   }
     82   if (!ctx->epid2_params || !ctx->pub_key) {
     83     return kEpidBadArgErr;
     84   }
     85   if (sig_len < sig_header_len) {
     86     return kEpidBadArgErr;
     87   }
     88   rl_count = EpidGetSignatureRlCount(sig);
     89   if (rl_count > (SIZE_MAX - sig_header_len) / sizeof(sig->sigma[0]) ||
     90       (rl_count * sizeof(sig->sigma[0])) + sig_header_len != sig_len) {
     91     return kEpidBadArgErr;
     92   }
     93   // Step 2. The verifier verifies the basic signature Sigma0 as follows:
     94   sts = EpidVerifyBasicSig(ctx, &sig->sigma0, msg, msg_len);
     95   if (sts != kEpidNoErr) {
     96     // p. If any of the above verifications fails, the verifier aborts and
     97     // outputs 1
     98     return kEpidSigInvalid;
     99   }
    100 
    101   // Step 3. If GroupRL is provided,
    102   if (ctx->group_rl) {
    103     // a. The verifier verifies that gid does not match any entry in GroupRL.
    104     size_t grouprl_count = EpidGetGroupRlCount(ctx->group_rl);
    105     for (i = 0; i < grouprl_count; ++i) {
    106       if (0 == memcmp(&ctx->pub_key->gid, &ctx->group_rl->gid[i],
    107                       sizeof(ctx->pub_key->gid))) {
    108         // b. If gid matches an entry in GroupRL, aborts and returns 2.
    109         return kEpidSigRevokedInGroupRl;
    110       }
    111     }
    112   }
    113 
    114   // Step  4. If PrivRL is provided,
    115   if (ctx->priv_rl) {
    116     size_t privrl_count = EpidGetPrivRlCount(ctx->priv_rl);
    117     // a. The verifier verifies that gid in the public key and in PrivRL match.
    118     // If mismatch, abort and return "operation failed".
    119     if (0 != memcmp(&ctx->pub_key->gid, &ctx->priv_rl->gid,
    120                     sizeof(ctx->pub_key->gid))) {
    121       return kEpidBadArgErr;
    122     }
    123     // b. For i = 0, ..., n1-1, the verifier computes t4 =G1.exp(B, f[i]) and
    124     // verifies that G1.isEqual(t4, K) = false. A faster private-key revocation
    125     // check algorithm is provided in Section 4.5.
    126     for (i = 0; i < privrl_count; ++i) {
    127       sts = EpidCheckPrivRlEntry(ctx, &sig->sigma0, &ctx->priv_rl->f[i]);
    128       if (sts != kEpidNoErr) {
    129         // c. If the above step fails, the verifier aborts and output 3.
    130         return kEpidSigRevokedInPrivRl;
    131       }
    132     }
    133   }
    134 
    135   // Step 5. If SigRL is provided,
    136   if (ctx->sig_rl) {
    137     size_t sigrl_count = EpidGetSigRlCount(ctx->sig_rl);
    138     // a. The verifier verifies that gid in the public key and in SigRL match.
    139     // If mismatch, abort and return "operation failed".
    140     if (0 != memcmp(&ctx->pub_key->gid, &ctx->sig_rl->gid,
    141                     sizeof(ctx->pub_key->gid))) {
    142       return kEpidBadArgErr;
    143     }
    144 
    145     // b. The verifier verifies that RLver in Sigma and in SigRL match. If
    146     // mismatch, abort and output "operation failed".
    147     if (0 != memcmp(&ctx->sig_rl->version, &sig->rl_ver,
    148                     sizeof(ctx->sig_rl->version))) {
    149       return kEpidErr;
    150     }
    151 
    152     // c. The verifier verifies that n2 in Sigma and in SigRL match. If
    153     // mismatch, abort and output "operation failed".
    154     if (sigrl_count != rl_count) {
    155       return kEpidBadArgErr;
    156     }
    157 
    158     // d. For i = 0, ..., n2-1, the verifier verifies nrVerify(B, K, B[i],
    159     // K[i], Sigma[i]) = true. The details of nrVerify() will be given in the
    160     // next subsection.
    161     for (i = 0; i < sigrl_count; ++i) {
    162       sts = EpidNrVerify(ctx, &sig->sigma0, msg, msg_len, &ctx->sig_rl->bk[i],
    163                          &sig->sigma[i]);
    164       if (sts != kEpidNoErr) {
    165         // e. If the above step fails, the verifier aborts and output 4.
    166         return kEpidSigRevokedInSigRl;
    167       }
    168     }
    169   }
    170 
    171   // Step 6. If VerifierRL is provided,
    172   if (ctx->verifier_rl) {
    173     // a. The verifier verifies that gid in the public key and in VerifierRL
    174     // match. If mismatch, abort and return "operation failed".
    175     if (0 != memcmp(&ctx->pub_key->gid, &ctx->verifier_rl->gid,
    176                     sizeof(ctx->pub_key->gid))) {
    177       return kEpidBadArgErr;
    178     }
    179 
    180     // b. The verifier verifies that B in the signature and in VerifierRL
    181     // match. If mismatch, go to step 7.
    182     if (0 ==
    183         memcmp(&ctx->verifier_rl->B, &sig->sigma0.B, sizeof(sig->sigma0.B))) {
    184       size_t verifierrl_count = EpidGetVerifierRlCount(ctx->verifier_rl);
    185       // c. For i = 0, ..., n4-1, the verifier verifies that K != K[i].
    186       for (i = 0; i < verifierrl_count; ++i) {
    187         if (0 == memcmp(&ctx->verifier_rl->K[i], &sig->sigma0.K,
    188                         sizeof(sig->sigma0.K))) {
    189           // d. If the above step fails, the verifier aborts and output 5.
    190           return kEpidSigRevokedInVerifierRl;
    191         }
    192       }
    193     }
    194   }
    195 
    196   // Step 7. If all the above verifications succeed, the verifier outputs 0.
    197   return kEpidSigValid;
    198 }
    199