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