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