• 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 Epid11NrVerify implementation.
20 */
21 #include "epid/common/math/hash.h"
22 #include "epid/common/src/endian_convert.h"
23 #include "epid/common/src/memory.h"
24 #include "epid/verifier/1.1/api.h"
25 #include "epid/verifier/1.1/src/context.h"
26 #include "ext/ipp/include/ippcp.h"
27 /// Handle SDK Error with Break
28 #define BREAK_ON_EPID_ERROR(ret) \
29   if (kEpidNoErr != (ret)) {     \
30     break;                       \
31   }
32 /// Count of elements in array
33 #define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
34 #pragma pack(1)
35 /// Storage for values to create commitment in NrVerify algorithm
36 typedef struct Epid11NrVerifyCommitValues {
37   BigNumStr p_tick;        //!< A large prime (256-bit)
38   Epid11G3ElemStr g3;      //!< Generator of G3 (512-bit)
39   Epid11G3ElemStr B;       //!< (element of G3): part of basic signature Sigma0
40   Epid11G3ElemStr K;       //!< (element of G3): part of basic signature Sigma0
41   Epid11G3ElemStr B_tick;  //!< (element of G3): one entry in SigRL
42   Epid11G3ElemStr K_tick;  //!< (element of G3): one entry in SigRL
43   Epid11G3ElemStr T;       //!< element of G3
44   Epid11G3ElemStr R1;      //!< element of G3
45   Epid11G3ElemStr R2;      //!< element of G3
46   uint32_t msg_len;        //!< length of the message
47   uint8_t msg[1];          //!< message
48 } Epid11NrVerifyCommitValues;
49 #pragma pack()
50 
Epid11NrVerify(Epid11VerifierCtx const * ctx,Epid11BasicSignature const * sig,void const * msg,size_t msg_len,Epid11SigRlEntry const * sigrl_entry,Epid11NrProof const * proof)51 EpidStatus Epid11NrVerify(Epid11VerifierCtx const* ctx,
52                           Epid11BasicSignature const* sig, void const* msg,
53                           size_t msg_len, Epid11SigRlEntry const* sigrl_entry,
54                           Epid11NrProof const* proof) {
55   size_t const cv_header_len =
56       sizeof(Epid11NrVerifyCommitValues) - sizeof(uint8_t);
57   Epid11NrVerifyCommitValues* commit_values = NULL;
58   size_t const commit_len = sizeof(Epid11NrVerifyCommitValues) + msg_len - 1;
59   EpidStatus res = kEpidErr;
60   // Epid11 G3 elements
61   EcPoint* T = NULL;
62   EcPoint* R1 = NULL;
63   EcPoint* R2 = NULL;
64 
65   EcPoint* K = NULL;
66   EcPoint* B = NULL;
67   EcPoint* K_tick = NULL;
68   EcPoint* B_tick = NULL;
69 
70   // Big integers
71   BigNum* smu = NULL;
72   BigNum* snu = NULL;
73   BigNum* nc_tick_bn = NULL;
74   Sha256Digest commit_hash;
75 
76   if (!ctx || !sig || !proof || !sigrl_entry) {
77     return kEpidBadArgErr;
78   }
79   if (!msg && (0 != msg_len)) {
80     return kEpidBadArgErr;
81   }
82   if (msg_len > (UINT_MAX - cv_header_len)) {
83     return kEpidBadArgErr;
84   }
85   if (!ctx->epid11_params) {
86     return kEpidBadArgErr;
87   }
88   do {
89     bool cmp_result = false;
90     // handy shorthands:
91     EcGroup* G3 = ctx->epid11_params->G3;
92     BigNum* p_tick_bn = ctx->epid11_params->p_tick;
93 
94     if (!G3 || !p_tick_bn) {
95       res = kEpidBadArgErr;
96       BREAK_ON_EPID_ERROR(res);
97     }
98 
99     commit_values = SAFE_ALLOC(commit_len);
100     if (commit_values == NULL) {
101       res = kEpidMemAllocErr;
102       break;
103     }
104     // 1. We use the following variables T, R1, R2 (elements of G3), and c, smu,
105     // snu, nc (big integers).
106     res = NewEcPoint(G3, &T);
107     BREAK_ON_EPID_ERROR(res);
108     res = NewEcPoint(G3, &R1);
109     BREAK_ON_EPID_ERROR(res);
110     res = NewEcPoint(G3, &R2);
111     BREAK_ON_EPID_ERROR(res);
112 
113     res = NewEcPoint(G3, &K);
114     BREAK_ON_EPID_ERROR(res);
115     res = NewEcPoint(G3, &B);
116     BREAK_ON_EPID_ERROR(res);
117     res = NewEcPoint(G3, &K_tick);
118     BREAK_ON_EPID_ERROR(res);
119     res = NewEcPoint(G3, &B_tick);
120     BREAK_ON_EPID_ERROR(res);
121 
122     res = NewBigNum(sizeof(proof->smu), &smu);
123     BREAK_ON_EPID_ERROR(res);
124     res = NewBigNum(sizeof(proof->smu), &snu);
125     BREAK_ON_EPID_ERROR(res);
126 
127     res = NewBigNum(sizeof(FpElemStr), &nc_tick_bn);
128     BREAK_ON_EPID_ERROR(res);
129 
130     // 2. The verifier verifies that G3.inGroup(T) = true.
131     res = ReadEcPoint(G3, &(proof->T), sizeof(proof->T), T);
132     if (kEpidNoErr != res) {
133       res = kEpidBadArgErr;
134       break;
135     }
136 
137     // 3. The verifier verifies that G3.isIdentity(T) = false.
138     res = EcIsIdentity(G3, T, &(cmp_result));
139     BREAK_ON_EPID_ERROR(res);
140     if (cmp_result) {
141       res = kEpidBadArgErr;
142       break;
143     }
144 
145     // 4. The verifier verifies that smu, snu in [0, p'-1].
146     res = WriteBigNum(ctx->epid11_params->p_tick, sizeof(commit_values->p_tick),
147                       &commit_values->p_tick);
148     BREAK_ON_EPID_ERROR(res);
149     if (memcmp(&proof->smu, &commit_values->p_tick, sizeof(FpElemStr)) >= 0 ||
150         memcmp(&proof->snu, &commit_values->p_tick, sizeof(FpElemStr)) >= 0) {
151       res = kEpidBadArgErr;
152       break;
153     }
154     // 5. The verifier computes nc = (- c) mod p'.
155     res = ReadBigNum(&(proof->c), sizeof(proof->c), nc_tick_bn);
156     BREAK_ON_EPID_ERROR(res);
157     res = BigNumMod(nc_tick_bn, p_tick_bn, nc_tick_bn);
158     BREAK_ON_EPID_ERROR(res);
159     // (-c) mod p'  ==  p' - (c mod p')
160     res = BigNumSub(p_tick_bn, nc_tick_bn, nc_tick_bn);
161     BREAK_ON_EPID_ERROR(res);
162 
163     // 6. The verifier computes R1 = G3.multiExp(K, smu, B, snu).
164     res = ReadEcPoint(G3, &(sig->K), sizeof(sig->K), K);
165     if (kEpidNoErr != res) {
166       res = kEpidBadArgErr;
167       break;
168     }
169     res = ReadEcPoint(G3, &(sig->B), sizeof(sig->B), B);
170     if (kEpidNoErr != res) {
171       res = kEpidBadArgErr;
172       break;
173     }
174     res = ReadBigNum(&(proof->smu), sizeof(proof->smu), smu);
175     BREAK_ON_EPID_ERROR(res);
176     res = ReadBigNum(&(proof->snu), sizeof(proof->snu), snu);
177     BREAK_ON_EPID_ERROR(res);
178     {
179       EcPoint const* points[2];
180       BigNum const* exponents[2];
181       points[0] = K;
182       points[1] = B;
183       exponents[0] = smu;
184       exponents[1] = snu;
185       res = EcMultiExpBn(G3, points, exponents, COUNT_OF(points), R1);
186       BREAK_ON_EPID_ERROR(res);
187     }
188     // 7. The verifier computes R2 = G3.multiExp(K', smu, B', snu, T, nc).
189     res = ReadEcPoint(G3, &(sigrl_entry->k), sizeof(sigrl_entry->k), K_tick);
190     if (kEpidNoErr != res) {
191       res = kEpidBadArgErr;
192       break;
193     }
194     res = ReadEcPoint(G3, &(sigrl_entry->b), sizeof(sigrl_entry->b), B_tick);
195     if (kEpidNoErr != res) {
196       res = kEpidBadArgErr;
197       break;
198     }
199     {
200       EcPoint const* points[3];
201       BigNum const* exponents[3];
202       points[0] = K_tick;
203       points[1] = B_tick;
204       points[2] = T;
205       exponents[0] = smu;
206       exponents[1] = snu;
207       exponents[2] = nc_tick_bn;
208       res = EcMultiExpBn(G3, points, exponents, COUNT_OF(points), R2);
209       BREAK_ON_EPID_ERROR(res);
210     }
211     // 8. The verifier verifies c = Hash(p' || g3 || B || K || B' || K' || T ||
212     // R1 || R2 || mSize || m).
213     if (msg) {
214       // Memory copy is used to copy a message of variable length
215       if (0 != memcpy_S(&commit_values->msg[0], msg_len, msg, msg_len)) {
216         res = kEpidBadArgErr;
217         break;
218       }
219     }
220     commit_values->g3 = ctx->commit_values.g3;
221     commit_values->B = sig->B;
222     commit_values->K = sig->K;
223     commit_values->B_tick = sigrl_entry->b;
224     commit_values->K_tick = sigrl_entry->k;
225     commit_values->T = proof->T;
226     commit_values->msg_len = ntohl(msg_len);
227     res = WriteEcPoint(G3, R1, &commit_values->R1, sizeof(commit_values->R1));
228     BREAK_ON_EPID_ERROR(res);
229     res = WriteEcPoint(G3, R2, &commit_values->R2, sizeof(commit_values->R2));
230     BREAK_ON_EPID_ERROR(res);
231     res = Sha256MessageDigest(commit_values, commit_len, &commit_hash);
232     if (0 != memcmp(&proof->c, &commit_hash, sizeof(proof->c))) {
233       res = kEpidBadArgErr;
234       break;
235     }
236   } while (0);
237   SAFE_FREE(commit_values);
238   DeleteEcPoint(&T);
239   DeleteEcPoint(&R1);
240   DeleteEcPoint(&R2);
241 
242   DeleteEcPoint(&K);
243   DeleteEcPoint(&B);
244   DeleteEcPoint(&K_tick);
245   DeleteEcPoint(&B_tick);
246 
247   DeleteBigNum(&smu);
248   DeleteBigNum(&snu);
249 
250   DeleteBigNum(&nc_tick_bn);
251 
252   return res;
253 }
254