コード例 #1
0
ファイル: check_privrl_entry.c プロジェクト: 01org/linux-sgx
EpidStatus EpidCheckPrivRlEntry(VerifierCtx const* ctx,
                                BasicSignature const* sig, FpElemStr const* f) {
  EpidStatus result = kEpidErr;
  EcPoint* b = NULL;
  EcPoint* k = NULL;
  EcPoint* t4 = NULL;
  EcGroup* G1 = NULL;
  FfElement* ff_elem = NULL;
  if (!ctx || !sig || !f) {
    return kEpidBadArgErr;
  }
  if (!ctx->epid2_params || !ctx->epid2_params->G1) {
    return kEpidBadArgErr;
  }
  do {
    // Section 4.1.2 Step 4.b For i = 0, ... , n1-1, the verifier computes t4
    // =G1.exp(B, f[i]) and verifies that G1.isEqual(t4, K) = false.
    bool compare_result = false;
    FiniteField* Fp = ctx->epid2_params->Fp;
    G1 = ctx->epid2_params->G1;
    result = NewFfElement(Fp, &ff_elem);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewEcPoint(G1, &b);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewEcPoint(G1, &k);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewEcPoint(G1, &t4);
    if (kEpidNoErr != result) {
      break;
    }
    // ReadFfElement checks that the value f is in the field
    result = ReadFfElement(Fp, (BigNumStr const*)f, sizeof(BigNumStr), ff_elem);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadEcPoint(G1, &sig->B, sizeof(sig->B), b);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadEcPoint(G1, &sig->K, sizeof(sig->K), k);
    if (kEpidNoErr != result) {
      break;
    }
    result = EcExp(G1, b, (BigNumStr const*)f, t4);
    if (kEpidNoErr != result) {
      break;
    }
    result = EcIsEqual(G1, t4, k, &compare_result);
    if (kEpidNoErr != result) {
      break;
    }
    // if t4 == k, sig revoked in PrivRl
    if (compare_result) {
      result = kEpidSigRevokedInPrivRl;
    } else {
      result = kEpidNoErr;
    }
  } while (0);
  DeleteFfElement(&ff_elem);
  DeleteEcPoint(&t4);
  DeleteEcPoint(&k);
  DeleteEcPoint(&b);
  return result;
}
コード例 #2
0
ファイル: request_join.c プロジェクト: axelexic/linux-sgx
EpidStatus EpidRequestJoin(GroupPubKey const* pub_key, IssuerNonce const* ni,
                           FpElemStr const* f, BitSupplier rnd_func,
                           void* rnd_param, HashAlg hash_alg,
                           JoinRequest* join_request) {
  EpidStatus sts;
  static const BigNumStr one = {
      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};
  BigNumStr r_str;
  JoinPCommitValues commit_values;
  Epid2Params_* params = NULL;
  FfElement* r_el = NULL;
  FfElement* f_el = NULL;
  FfElement* c_el = NULL;
  FfElement* cf_el = NULL;
  FfElement* s_el = NULL;
  EcPoint* f_pt = NULL;
  EcPoint* r_pt = NULL;
  EcPoint* h1_pt = NULL;

  if (!pub_key || !ni || !f || !rnd_func || !join_request) {
    return kEpidBadArgErr;
  }
  if (kSha256 != hash_alg && kSha384 != hash_alg && kSha512 != hash_alg) {
    return kEpidBadArgErr;
  }

  do {
    sts = CreateEpid2Params(&params);
    BREAK_ON_EPID_ERROR(sts);
    if (!params->Fp || !params->G1) {
      sts = kEpidBadArgErr;
      break;
    }
    sts = NewFfElement(params->Fp, &r_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(params->Fp, &f_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(params->Fp, &c_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(params->Fp, &cf_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(params->Fp, &s_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(params->G1, &f_pt);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(params->G1, &h1_pt);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(params->G1, &r_pt);
    BREAK_ON_EPID_ERROR(sts);

    sts = ReadFfElement(params->Fp, (uint8_t const*)f, sizeof(*f), f_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadEcPoint(params->G1, (uint8_t*)&pub_key->h1, sizeof(pub_key->h1),
                      h1_pt);
    BREAK_ON_EPID_ERROR(sts);

    // Step 1. The member chooses a random integer r from [1, p-1].
    sts = FfGetRandom(params->Fp, &one, rnd_func, rnd_param, r_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(params->Fp, r_el, (uint8_t*)&r_str, sizeof(r_str));

    // Step 2. The member computes F = G1.sscmExp(h1, f).
    sts = EcExp(params->G1, h1_pt, (BigNumStr const*)f, f_pt);
    BREAK_ON_EPID_ERROR(sts);

    // Step 3. The member computes R = G1.sscmExp(h1, r).
    sts = EcExp(params->G1, h1_pt, (BigNumStr const*)&r_str, r_pt);
    BREAK_ON_EPID_ERROR(sts);

    // Step 4. The member computes c = Fp.hash(p || g1 || g2 || h1 || h2 || w ||
    // F || R || NI). Refer to Section 7.1 for hash operation over a prime
    // field.
    sts = WriteBigNum(params->p, sizeof(commit_values.p),
                      (uint8_t*)&commit_values.p);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteEcPoint(params->G1, params->g1, (uint8_t*)&commit_values.g1,
                       sizeof(commit_values.g1));
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteEcPoint(params->G2, params->g2, (uint8_t*)&commit_values.g2,
                       sizeof(commit_values.g2));
    BREAK_ON_EPID_ERROR(sts);
    commit_values.h1 = pub_key->h1;
    commit_values.h2 = pub_key->h2;
    commit_values.w = pub_key->w;
    sts = WriteEcPoint(params->G1, f_pt, (uint8_t*)&commit_values.F,
                       sizeof(commit_values.F));
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteEcPoint(params->G1, r_pt, (uint8_t*)&commit_values.R,
                       sizeof(commit_values.R));
    BREAK_ON_EPID_ERROR(sts);
    commit_values.NI = *ni;
    sts = FfHash(params->Fp, (uint8_t*)&commit_values, sizeof(commit_values),
                 hash_alg, c_el);
    BREAK_ON_EPID_ERROR(sts);

    // Step 5. The member computes s = (r + c * f) mod p.
    sts = FfMul(params->Fp, c_el, f_el, cf_el);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(params->Fp, r_el, cf_el, s_el);
    BREAK_ON_EPID_ERROR(sts);

    // Step 6. The output join request is (F, c, s).
    sts = WriteFfElement(params->Fp, c_el, (uint8_t*)&join_request->c,
                         sizeof(join_request->c));
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(params->Fp, s_el, (uint8_t*)&join_request->s,
                         sizeof(join_request->s));
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteEcPoint(params->G1, f_pt, (uint8_t*)&join_request->F,
                       sizeof(join_request->F));
    BREAK_ON_EPID_ERROR(sts);

    sts = kEpidNoErr;
  } while (0);
  DeleteEcPoint(&h1_pt);
  DeleteEcPoint(&r_pt);
  DeleteEcPoint(&f_pt);
  DeleteFfElement(&s_el);
  DeleteFfElement(&cf_el);
  DeleteFfElement(&c_el);
  DeleteFfElement(&f_el);
  DeleteFfElement(&r_el);
  DeleteEpid2Params(&params);
  return sts;
}
コード例 #3
0
ファイル: presig.c プロジェクト: axelexic/linux-sgx
EpidStatus EpidComputePreSig(MemberCtx const* ctx,
                             PreComputedSignature* precompsig) {
  EpidStatus res = kEpidNotImpl;

  EcPoint* B = NULL;
  EcPoint* K = NULL;
  EcPoint* T = NULL;
  EcPoint* R1 = NULL;

  FfElement* R2 = NULL;

  FfElement* a = NULL;
  FfElement* b = NULL;
  FfElement* rx = NULL;
  FfElement* rf = NULL;
  FfElement* ra = NULL;
  FfElement* rb = NULL;
  FfElement* t1 = NULL;
  FfElement* t2 = NULL;
  FfElement* f = NULL;

  if (!ctx || !precompsig) return kEpidBadArgErr;
  if (!ctx->epid2_params || !ctx->pub_key || !ctx->priv_key)
    return kEpidBadArgErr;

  do {
    // handy shorthands:
    EcGroup* G1 = ctx->epid2_params->G1;
    FiniteField* GT = ctx->epid2_params->GT;
    FiniteField* Fp = ctx->epid2_params->Fp;
    EcPoint* h2 = ctx->pub_key->h2;
    EcPoint* A = ctx->priv_key->A;
    FfElement* x = ctx->priv_key->x;
    BigNumStr f_str = {0};
    BigNumStr a_str = {0};
    BigNumStr t1_str = {0};
    BigNumStr rf_str = {0};
    BigNumStr t2_str = {0};
    BigNumStr ra_str = {0};
    static const BigNumStr one = {
        {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};

    if (!G1 || !GT || !Fp || !h2 || !A || !x || !ctx->priv_key->f ||
        !ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->ea2) {
      res = kEpidBadArgErr;
      BREAK_ON_EPID_ERROR(res);
    }
    f = ctx->priv_key->f;
    // The following variables B, K, T, R1 (elements of G1), R2
    // (elements of GT), a, b, rx, rf, ra, rb, t1, t2 (256-bit
    // integers) are used.
    res = NewEcPoint(G1, &B);
    BREAK_ON_EPID_ERROR(res);
    res = NewEcPoint(G1, &K);
    BREAK_ON_EPID_ERROR(res);
    res = NewEcPoint(G1, &T);
    BREAK_ON_EPID_ERROR(res);
    res = NewEcPoint(G1, &R1);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(GT, &R2);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &a);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &b);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &rx);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &rf);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &ra);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &rb);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &t1);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &t2);
    BREAK_ON_EPID_ERROR(res);
    // 1. The member expects the pre-computation is done (e12, e22, e2w,
    //    ea2). Refer to Section 3.5 for the computation of these
    //    values.

    // 2. The member verifies gid in public key matches gid in private
    //    key.
    // 3. The member computes B = G1.getRandom().
    res = EcGetRandom(G1, ctx->rnd_func, ctx->rnd_param, B);
    BREAK_ON_EPID_ERROR(res);
    // 4. The member computes K = G1.sscmExp(B, f).
    res = WriteFfElement(Fp, f, &f_str, sizeof(f_str));
    BREAK_ON_EPID_ERROR(res);
    res = EcExp(G1, B, &f_str, K);
    BREAK_ON_EPID_ERROR(res);
    // 5. The member chooses randomly an integers a from [1, p-1].
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, a);
    BREAK_ON_EPID_ERROR(res);
    // 6. The member computes T = G1.sscmExp(h2, a).
    res = WriteFfElement(Fp, a, &a_str, sizeof(a_str));
    BREAK_ON_EPID_ERROR(res);
    res = EcExp(G1, h2, &a_str, T);
    BREAK_ON_EPID_ERROR(res);
    // 7. The member computes T = G1.mul(T, A).
    res = EcMul(G1, T, A, T);
    BREAK_ON_EPID_ERROR(res);
    // 8. The member computes b = (a * x) mod p.
    res = FfMul(Fp, a, x, b);
    BREAK_ON_EPID_ERROR(res);
    // 9. The member chooses rx, rf, ra, rb randomly from [1, p-1].
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rx);
    BREAK_ON_EPID_ERROR(res);
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rf);
    BREAK_ON_EPID_ERROR(res);
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, ra);
    BREAK_ON_EPID_ERROR(res);
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rb);
    BREAK_ON_EPID_ERROR(res);
    // 10. The member computes t1 = (- rx) mod p.
    res = FfNeg(Fp, rx, t1);
    BREAK_ON_EPID_ERROR(res);
    // 11. The member computes t2 = (rb - a * rx) mod p.
    res = FfMul(Fp, a, rx, t2);
    BREAK_ON_EPID_ERROR(res);
    res = FfNeg(Fp, t2, t2);
    BREAK_ON_EPID_ERROR(res);
    res = FfAdd(Fp, rb, t2, t2);
    BREAK_ON_EPID_ERROR(res);
    // 12. The member computes R1 = G1.sscmExp(B, rf).
    res = WriteFfElement(Fp, rf, &rf_str, sizeof(rf_str));
    BREAK_ON_EPID_ERROR(res);
    res = EcExp(G1, B, &rf_str, R1);
    BREAK_ON_EPID_ERROR(res);
    // 13. The member computes R2 = GT.sscmMultiExp(ea2, t1, e12, rf,
    //     e22, t2, e2w, ra).
    res = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, ra, &ra_str, sizeof(ra_str));
    BREAK_ON_EPID_ERROR(res);
    {
      FfElement const* points[4];
      BigNumStr const* exponents[4];
      points[0] = ctx->ea2;
      points[1] = ctx->e12;
      points[2] = ctx->e22;
      points[3] = ctx->e2w;
      exponents[0] = &t1_str;
      exponents[1] = &rf_str;
      exponents[2] = &t2_str;
      exponents[3] = &ra_str;
      res = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2);
      BREAK_ON_EPID_ERROR(res);
    }
    // 14. The member sets and outputs pre-sigma = (B, K, T, a, b, rx,
    //     rf, ra, rb, R1, R2).
    res = WriteEcPoint(G1, B, &precompsig->B, sizeof(precompsig->B));
    BREAK_ON_EPID_ERROR(res);
    res = WriteEcPoint(G1, K, &precompsig->K, sizeof(precompsig->K));
    BREAK_ON_EPID_ERROR(res);
    res = WriteEcPoint(G1, T, &precompsig->T, sizeof(precompsig->T));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, a, &precompsig->a, sizeof(precompsig->a));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, b, &precompsig->b, sizeof(precompsig->b));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, rx, &precompsig->rx, sizeof(precompsig->rx));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, rf, &precompsig->rf, sizeof(precompsig->rf));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, ra, &precompsig->ra, sizeof(precompsig->ra));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, rb, &precompsig->rb, sizeof(precompsig->rb));
    BREAK_ON_EPID_ERROR(res);
    res = WriteEcPoint(G1, R1, &precompsig->R1, sizeof(precompsig->R1));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(GT, R2, &precompsig->R2, sizeof(precompsig->R2));
    BREAK_ON_EPID_ERROR(res);
    // 15. The member stores pre-sigma in the secure storage of the
    //     member.
    res = kEpidNoErr;
  } while (0);

  f = NULL;
  DeleteEcPoint(&B);
  DeleteEcPoint(&K);
  DeleteEcPoint(&T);
  DeleteEcPoint(&R1);
  DeleteFfElement(&R2);
  DeleteFfElement(&a);
  DeleteFfElement(&b);
  DeleteFfElement(&rx);
  DeleteFfElement(&rf);
  DeleteFfElement(&ra);
  DeleteFfElement(&rb);
  DeleteFfElement(&t1);
  DeleteFfElement(&t2);

  return (res);
}
コード例 #4
0
ファイル: load_external.c プロジェクト: 01org/linux-sgx
EpidStatus Tpm2LoadExternal(Tpm2Ctx* ctx, FpElemStr const* f_str) {
  EpidStatus sts = kEpidErr;
  TPM_RC rc = TPM_RC_SUCCESS;
  EcPoint* pub = NULL;
  FfElement* f = NULL;
  TPMI_ALG_HASH tpm_hash_alg = TPM_ALG_NULL;

  if (!ctx || !ctx->epid2_params || !f_str) {
    return kEpidBadArgErr;
  }

  do {
    LoadExternal_In in = {0};
    LoadExternal_Out out;
    G1ElemStr pub_str = {0};
    TPMS_ECC_PARMS* ecc_details = &in.inPublic.publicArea.parameters.eccDetail;
    EcGroup* G1 = ctx->epid2_params->G1;
    EcPoint* g1 = ctx->epid2_params->g1;

    sts = NewFfElement(ctx->epid2_params->Fp, &f);
    BREAK_ON_EPID_ERROR(sts);
    // verify that f is valid
    sts = ReadFfElement(ctx->epid2_params->Fp, f_str, sizeof(*f_str), f);
    BREAK_ON_EPID_ERROR(sts);
    if (ctx->key_handle) {
      FlushContext_In in_fc;
      in_fc.flushHandle = ctx->key_handle;
      TSS_Execute(ctx->tss, NULL, (COMMAND_PARAMETERS*)&in_fc, NULL,
                  TPM_CC_FlushContext, TPM_RH_NULL, NULL, 0);
      if (rc != TPM_RC_SUCCESS) {
        print_tpm2_response_code("TPM2_FlushContext", rc);
      }
      ctx->key_handle = 0;
    }

    sts = NewEcPoint(G1, &pub);
    BREAK_ON_EPID_ERROR(sts);

    sts = EcExp(G1, g1, (BigNumStr const*)f_str, pub);
    BREAK_ON_EPID_ERROR(sts);

    sts = WriteEcPoint(G1, pub, &pub_str, sizeof(pub_str));
    BREAK_ON_EPID_ERROR(sts);

    tpm_hash_alg = EpidtoTpm2HashAlg(ctx->hash_alg);
    if (tpm_hash_alg == TPM_ALG_NULL) {
      sts = kEpidHashAlgorithmNotSupported;
      break;
    }

    in.hierarchy = TPM_RH_NULL;
    in.inPublic.size = sizeof(TPM2B_PUBLIC);
    in.inPublic.publicArea.type = TPM_ALG_ECC;
    in.inPublic.publicArea.nameAlg = tpm_hash_alg;
    in.inPublic.publicArea.objectAttributes.val =
        TPMA_OBJECT_NODA | TPMA_OBJECT_USERWITHAUTH | TPMA_OBJECT_SIGN;
    in.inPublic.publicArea.authPolicy.t.size = 0;

    ecc_details->symmetric.algorithm = TPM_ALG_NULL;
    ecc_details->scheme.scheme = TPM_ALG_ECDAA;
    ecc_details->scheme.details.ecdaa.hashAlg = tpm_hash_alg;
    ecc_details->scheme.details.ecdaa.count = 0;
    ecc_details->curveID = TPM_ECC_BN_P256;
    ecc_details->kdf.scheme = TPM_ALG_NULL;

    sts = ReadTpm2FfElement(&pub_str.x.data,
                            &in.inPublic.publicArea.unique.ecc.x);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadTpm2FfElement(&pub_str.y.data,
                            &in.inPublic.publicArea.unique.ecc.y);
    BREAK_ON_EPID_ERROR(sts);

    in.inPrivate.t.size = sizeof(in.inPrivate.t.sensitiveArea);
    in.inPrivate.t.sensitiveArea.sensitiveType = TPM_ALG_ECC;
    sts = ReadTpm2FfElement(&f_str->data,
                            &in.inPrivate.t.sensitiveArea.sensitive.ecc);
    BREAK_ON_EPID_ERROR(sts);

    rc = TSS_Execute(ctx->tss, (RESPONSE_PARAMETERS*)&out,
                     (COMMAND_PARAMETERS*)&in, NULL, TPM_CC_LoadExternal,
                     TPM_RH_NULL, NULL, 0);
    if (rc != TPM_RC_SUCCESS) {
      print_tpm2_response_code("TPM2_LoadExternal", rc);
      if (TPM_RC_BINDING == rc || TPM_RC_ECC_POINT == rc ||
          TPM_RC_KEY_SIZE == rc)
        sts = kEpidBadArgErr;
      else
        sts = kEpidErr;
      break;
    }

    ctx->key_handle = out.objectHandle;
  } while (0);

  DeleteEcPoint(&pub);
  DeleteFfElement(&f);

  return sts;
}