Home | History | Annotate | Download | only in src
      1 /*############################################################################
      2   # Copyright 2016 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 NrVerfy implementation.
     20  */
     21 
     22 #include "epid/common/src/memory.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 #pragma pack(1)
     33 /// Storage for values to create commitment in NrVerify algorithm
     34 typedef struct NrVerifyCommitValues {
     35   BigNumStr p;     //!< A large prime (256-bit)
     36   G1ElemStr g1;    //!< Generator of G1 (512-bit)
     37   G1ElemStr b;     //!< (element of G1): part of basic signature Sigma0
     38   G1ElemStr k;     //!< (element of G1): part of basic signature Sigma0
     39   G1ElemStr bp;    //!< (element of G1): one entry in SigRL
     40   G1ElemStr kp;    //!< (element of G1): one entry in SigRL
     41   G1ElemStr t;     //!< element of G1
     42   G1ElemStr r1;    //!< element of G1
     43   G1ElemStr r2;    //!< element of G1
     44   uint8_t msg[1];  //!< message
     45 } NrVerifyCommitValues;
     46 #pragma pack()
     47 
     48 EpidStatus EpidNrVerify(VerifierCtx const* ctx, BasicSignature const* sig,
     49                         void const* msg, size_t msg_len,
     50                         SigRlEntry const* sigrl_entry, NrProof const* proof) {
     51   size_t const cv_header_len = sizeof(NrVerifyCommitValues) - sizeof(uint8_t);
     52   EpidStatus sts = kEpidErr;
     53   NrVerifyCommitValues* commit_values = NULL;
     54   size_t const commit_len = sizeof(*commit_values) + msg_len - 1;
     55   EcPoint* t_pt = NULL;
     56   EcPoint* k_pt = NULL;
     57   EcPoint* b_pt = NULL;
     58   EcPoint* kp_pt = NULL;
     59   EcPoint* bp_pt = NULL;
     60   EcPoint* r1_pt = NULL;
     61   EcPoint* r2_pt = NULL;
     62   FfElement* c_el = NULL;
     63   FfElement* nc_el = NULL;
     64   FfElement* smu_el = NULL;
     65   FfElement* snu_el = NULL;
     66   FfElement* commit_hash = NULL;
     67   if (!ctx || !sig || !proof || !sigrl_entry) {
     68     return kEpidBadArgErr;
     69   }
     70   if (!msg && (0 != msg_len)) {
     71     return kEpidBadArgErr;
     72   }
     73   if (msg_len > (SIZE_MAX - cv_header_len)) {
     74     return kEpidBadArgErr;
     75   }
     76   if (!ctx->epid2_params || !ctx->epid2_params->G1 || !ctx->epid2_params->Fp) {
     77     return kEpidBadArgErr;
     78   }
     79   do {
     80     EcGroup* G1 = ctx->epid2_params->G1;
     81     FiniteField* Fp = ctx->epid2_params->Fp;
     82     G1ElemStr const* b = &sig->B;
     83     G1ElemStr const* k = &sig->K;
     84     G1ElemStr const* bp = &sigrl_entry->b;
     85     G1ElemStr const* kp = &sigrl_entry->k;
     86     EcPoint const* r1p[2];
     87     FpElemStr const* r1b[2];
     88     EcPoint const* r2p[3];
     89     FpElemStr const* r2b[3];
     90     FpElemStr nc_str;
     91     bool t_is_identity;
     92     bool c_is_equal;
     93 
     94     commit_values = SAFE_ALLOC(commit_len);
     95     if (commit_values == NULL) {
     96       sts = kEpidMemAllocErr;
     97       break;
     98     }
     99 
    100     // allocate local memory
    101     sts = NewEcPoint(G1, &t_pt);
    102     BREAK_ON_EPID_ERROR(sts);
    103     sts = NewEcPoint(G1, &k_pt);
    104     BREAK_ON_EPID_ERROR(sts);
    105     sts = NewEcPoint(G1, &b_pt);
    106     BREAK_ON_EPID_ERROR(sts);
    107     sts = NewEcPoint(G1, &kp_pt);
    108     BREAK_ON_EPID_ERROR(sts);
    109     sts = NewEcPoint(G1, &bp_pt);
    110     BREAK_ON_EPID_ERROR(sts);
    111     sts = NewEcPoint(G1, &r1_pt);
    112     BREAK_ON_EPID_ERROR(sts);
    113     sts = NewEcPoint(G1, &r2_pt);
    114     BREAK_ON_EPID_ERROR(sts);
    115     sts = NewFfElement(Fp, &c_el);
    116     BREAK_ON_EPID_ERROR(sts);
    117     sts = NewFfElement(Fp, &nc_el);
    118     BREAK_ON_EPID_ERROR(sts);
    119     sts = NewFfElement(Fp, &smu_el);
    120     BREAK_ON_EPID_ERROR(sts);
    121     sts = NewFfElement(Fp, &snu_el);
    122     BREAK_ON_EPID_ERROR(sts);
    123     sts = NewFfElement(Fp, &commit_hash);
    124     BREAK_ON_EPID_ERROR(sts);
    125 
    126     // 1. The verifier verifies that G1.inGroup(T) = true.
    127     sts = ReadEcPoint(G1, &proof->T, sizeof(proof->T), t_pt);
    128     if (kEpidNoErr != sts) {
    129       sts = kEpidBadArgErr;
    130       break;
    131     }
    132 
    133     // 2. The verifier verifies that G1.isIdentity(T) = false.
    134     sts = EcIsIdentity(G1, t_pt, &t_is_identity);
    135     BREAK_ON_EPID_ERROR(sts);
    136     if (t_is_identity) {
    137       sts = kEpidBadArgErr;
    138       break;
    139     }
    140 
    141     // 3. The verifier verifies that c, smu, snu in [0, p-1].
    142     sts = ReadFfElement(Fp, &proof->c, sizeof(proof->c), c_el);
    143     BREAK_ON_EPID_ERROR(sts);
    144     sts = ReadFfElement(Fp, &proof->smu, sizeof(proof->smu), smu_el);
    145     BREAK_ON_EPID_ERROR(sts);
    146     sts = ReadFfElement(Fp, &proof->snu, sizeof(proof->snu), snu_el);
    147     BREAK_ON_EPID_ERROR(sts);
    148 
    149     // 4. The verifier computes nc = (- c) mod p.
    150     sts = FfNeg(Fp, c_el, nc_el);
    151     BREAK_ON_EPID_ERROR(sts);
    152 
    153     sts = WriteFfElement(Fp, nc_el, &nc_str, sizeof(nc_str));
    154     BREAK_ON_EPID_ERROR(sts);
    155 
    156     // 5. The verifier computes R1 = G1.multiExp(K, smu, B, snu).
    157     sts = ReadEcPoint(G1, k, sizeof(*k), k_pt);
    158     if (kEpidNoErr != sts) {
    159       sts = kEpidBadArgErr;
    160       break;
    161     }
    162     sts = ReadEcPoint(G1, b, sizeof(*b), b_pt);
    163     if (kEpidNoErr != sts) {
    164       sts = kEpidBadArgErr;
    165       break;
    166     }
    167     r1p[0] = k_pt;
    168     r1p[1] = b_pt;
    169     r1b[0] = &proof->smu;
    170     r1b[1] = &proof->snu;
    171     sts = EcMultiExp(G1, r1p, (const BigNumStr**)r1b, 2, r1_pt);
    172     BREAK_ON_EPID_ERROR(sts);
    173 
    174     // 6. The verifier computes R2 = G1.multiExp(K', smu, B', snu, T, nc).
    175     sts = ReadEcPoint(G1, kp, sizeof(*kp), kp_pt);
    176     if (kEpidNoErr != sts) {
    177       sts = kEpidBadArgErr;
    178       break;
    179     }
    180     sts = ReadEcPoint(G1, bp, sizeof(*bp), bp_pt);
    181     if (kEpidNoErr != sts) {
    182       sts = kEpidBadArgErr;
    183       break;
    184     }
    185     r2p[0] = kp_pt;
    186     r2p[1] = bp_pt;
    187     r2p[2] = t_pt;
    188     r2b[0] = &proof->smu;
    189     r2b[1] = &proof->snu;
    190     r2b[2] = &nc_str;
    191     sts = EcMultiExp(G1, r2p, (const BigNumStr**)r2b, 3, r2_pt);
    192     BREAK_ON_EPID_ERROR(sts);
    193 
    194     // 7. The verifier verifies c = Fp.hash(p || g1 || B || K ||
    195     //    B' || K' || T || R1 || R2 || m).
    196     //    Refer to Section 7.1 for hash operation over a prime field.
    197 
    198     // commit_values is allocated such that there are msg_len bytes available
    199     // starting at commit_values->msg
    200     if (msg) {
    201       // Memory copy is used to copy a message of variable length
    202       if (0 != memcpy_S(&commit_values->msg[0], msg_len, msg, msg_len)) {
    203         sts = kEpidBadArgErr;
    204         break;
    205       }
    206     }
    207     commit_values->p = ctx->commit_values.p;
    208     commit_values->g1 = ctx->commit_values.g1;
    209     commit_values->b = sig->B;
    210     commit_values->k = sig->K;
    211     commit_values->bp = sigrl_entry->b;
    212     commit_values->kp = sigrl_entry->k;
    213     commit_values->t = proof->T;
    214     sts =
    215         WriteEcPoint(G1, r1_pt, &commit_values->r1, sizeof(commit_values->r1));
    216     BREAK_ON_EPID_ERROR(sts);
    217     sts =
    218         WriteEcPoint(G1, r2_pt, &commit_values->r2, sizeof(commit_values->r2));
    219     BREAK_ON_EPID_ERROR(sts);
    220     sts = FfHash(Fp, commit_values, commit_len, ctx->hash_alg, commit_hash);
    221     BREAK_ON_EPID_ERROR(sts);
    222     sts = FfIsEqual(Fp, c_el, commit_hash, &c_is_equal);
    223     BREAK_ON_EPID_ERROR(sts);
    224     if (!c_is_equal) {
    225       sts = kEpidBadArgErr;
    226       break;
    227     }
    228     sts = kEpidNoErr;
    229   } while (0);
    230   SAFE_FREE(commit_values);
    231   DeleteFfElement(&commit_hash);
    232   DeleteFfElement(&snu_el);
    233   DeleteFfElement(&smu_el);
    234   DeleteFfElement(&nc_el);
    235   DeleteFfElement(&c_el);
    236   DeleteEcPoint(&r2_pt);
    237   DeleteEcPoint(&r1_pt);
    238   DeleteEcPoint(&bp_pt);
    239   DeleteEcPoint(&kp_pt);
    240   DeleteEcPoint(&b_pt);
    241   DeleteEcPoint(&k_pt);
    242   DeleteEcPoint(&t_pt);
    243   return sts;
    244 }
    245