Пример #1
0
EpidStatus NewGT(FiniteField* Fq6, FiniteField** GT) {
  EpidStatus result = kEpidErr;
  FiniteField* Ff = NULL;
  FfElement* v = NULL;
  FfElement* neg_v = NULL;

  const Fq6ElemStr v_str = {
      {{{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
         {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}},
       {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}},
         {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}},
       {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
         {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}}}};

  if (!Fq6 || !GT) {
    return kEpidBadArgErr;
  }
  do {
    result = NewFfElement(Fq6, &v);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(Fq6, &neg_v);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq6, &v_str, sizeof(v_str), v);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfNeg(Fq6, v, neg_v);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFiniteFieldViaBinomalExtension(Fq6, neg_v, 2, &Ff);
    if (kEpidNoErr != result) {
      break;
    }
    *GT = Ff;
    result = kEpidNoErr;
  } while (0);

  DeleteFfElement(&v);
  DeleteFfElement(&neg_v);

  return result;
}
Пример #2
0
EpidStatus CreatePrivKey(PrivKey const* priv_key_str, EcGroup* G1,
                         FiniteField* Fp, PrivKey_** priv_key) {
  EpidStatus result = kEpidErr;
  PrivKey_* priv_key_ = NULL;

  // check parameters
  if (!priv_key_str || !G1 || !Fp || !priv_key) return kEpidBadArgErr;

  do {
    priv_key_ = SAFE_ALLOC(sizeof(*priv_key_));

    if (!priv_key_) {
      result = kEpidMemAllocErr;
      break;
    }

    result = NewEcPoint(G1, &priv_key_->A);
    if (kEpidNoErr != result) break;

    result = NewFfElement(Fp, &priv_key_->x);
    if (kEpidNoErr != result) break;

    result = NewFfElement(Fp, &priv_key_->f);
    if (kEpidNoErr != result) break;

    if (0 != memcpy_S(&priv_key_->gid, sizeof(priv_key_->gid),
                      &priv_key_str->gid, sizeof(priv_key_str->gid))) {
      result = kEpidBadArgErr;
      break;
    }

    result = ReadEcPoint(G1, &priv_key_str->A, sizeof(priv_key_str->A),
                         priv_key_->A);
    if (kEpidNoErr != result) break;

    result = ReadFfElement(Fp, &priv_key_str->x, sizeof(priv_key_str->x),
                           priv_key_->x);
    if (kEpidNoErr != result) break;

    result = ReadFfElement(Fp, &priv_key_str->f, sizeof(priv_key_str->f),
                           priv_key_->f);
    if (kEpidNoErr != result) break;

    *priv_key = priv_key_;
    result = kEpidNoErr;
  } while (0);

  if (kEpidNoErr != result) {
    DeletePrivKey(&priv_key_);
  }

  return (result);
}
Пример #3
0
EpidStatus Tpm2CreatePrimary(Tpm2Ctx* ctx, G1ElemStr* p_str) {
  EpidStatus sts = kEpidErr;
  FfElement* ff_elem;
  FpElemStr ff_elem_str;
  if (!ctx || !ctx->epid2_params) {
    return kEpidBadArgErr;
  }
  (void)p_str;
  do {
    const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
    FiniteField* Fp = ctx->epid2_params->Fp;
    sts = NewFfElement(Fp, &ff_elem);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, ff_elem);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, ff_elem, &ff_elem_str, sizeof(ff_elem_str));
    BREAK_ON_EPID_ERROR(sts);
  } while (0);
  DeleteFfElement(&ff_elem);
  if (kEpidNoErr == sts) {
    sts = Tpm2LoadExternal(ctx, &ff_elem_str);
  }
  return sts;
}
Пример #4
0
EpidStatus NewFq6(Epid2Params const* param, FiniteField* Fq2, FfElement* xi,
                  FiniteField** Fq6) {
  EpidStatus result = kEpidErr;
  FiniteField* Ff = NULL;
  FfElement* neg_xi = NULL;
  if (!param || !Fq2 || !Fq6) {
    return kEpidBadArgErr;
  }
  do {
    result = NewFfElement(Fq2, &neg_xi);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfNeg(Fq2, xi, neg_xi);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFiniteFieldViaBinomalExtension(Fq2, neg_xi, 3, &Ff);
    if (kEpidNoErr != result) {
      break;
    }
    *Fq6 = Ff;
    result = kEpidNoErr;
  } while (0);

  DeleteFfElement(&neg_xi);

  return result;
}
Пример #5
0
EpidStatus NewFq2(Epid2Params const* param, FiniteField* Fq,
                  FiniteField** Fq2) {
  EpidStatus result = kEpidErr;
  FiniteField* Ff = NULL;
  FfElement* beta = NULL;
  FfElement* neg_beta = NULL;
  if (!param || !Fq || !Fq2) {
    return kEpidBadArgErr;
  }
  do {
    result = NewFfElement(Fq, &beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(Fq, &neg_beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq, &param->beta, sizeof(param->beta), beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfNeg(Fq, beta, neg_beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFiniteFieldViaBinomalExtension(Fq, neg_beta, 2, &Ff);
    if (kEpidNoErr != result) {
      break;
    }
    *Fq2 = Ff;
    result = kEpidNoErr;
  } while (0);

  DeleteFfElement(&neg_beta);
  DeleteFfElement(&beta);

  return result;
}
Пример #6
0
EpidStatus EpidSignBasic(MemberCtx const* ctx, void const* msg, size_t msg_len,
                         void const* basename, size_t basename_len,
                         BasicSignature* sig, BigNumStr* rnd_bsn) {
  EpidStatus sts = kEpidErr;

  EcPoint* B = NULL;
  EcPoint* t = NULL;  // temp value in G1
  EcPoint* k = NULL;
  EcPoint* e = NULL;
  FfElement* R2 = NULL;
  FfElement* p2y = NULL;
  FfElement* t1 = NULL;
  FfElement* t2 = NULL;

  FfElement* a = NULL;
  FfElement* b = NULL;
  FfElement* rx = NULL;
  FfElement* ra = NULL;
  FfElement* rb = NULL;

  struct p2x_t {
    uint32_t i;
    uint8_t bsn[1];
  }* p2x = NULL;

  FfElement* t3 = NULL;  // temporary for multiplication
  FfElement* c = NULL;
  uint8_t* digest = NULL;

  PreComputedSignature curr_presig = {0};

  if (!ctx || !sig) {
    return kEpidBadArgErr;
  }
  if (!msg && (0 != msg_len)) {
    // if message is non-empty it must have both length and content
    return kEpidBadArgErr;
  }
  if (!basename && (0 != basename_len)) {
    // if basename is non-empty it must have both length and content
    return kEpidBadArgErr;
  }
  if (!ctx->epid2_params) {
    return kEpidBadArgErr;
  }

  do {
    FiniteField* Fp = ctx->epid2_params->Fp;
    SignCommitOutput commit_out = {0};
    FpElemStr c_str = {0};
    EcGroup* G1 = ctx->epid2_params->G1;
    FiniteField* GT = ctx->epid2_params->GT;

    FiniteField* Fq = ctx->epid2_params->Fq;
    PairingState* ps_ctx = ctx->epid2_params->pairing_state;
    const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
    BigNumStr t1_str = {0};
    BigNumStr t2_str = {0};
    size_t digest_size = 0;
    uint16_t* rf_ctr = (uint16_t*)&ctx->rf_ctr;
    FfElement const* x = ctx->x;

    if (basename) {
      if (!IsBasenameAllowed(ctx->allowed_basenames, basename, basename_len)) {
        sts = kEpidBadArgErr;
        BREAK_ON_EPID_ERROR(sts);
      }
    }

    sts = NewEcPoint(G1, &B);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(G1, &k);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(G1, &t);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(G1, &e);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(GT, &R2);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fq, &p2y);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &t1);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &t2);
    BREAK_ON_EPID_ERROR(sts);
    p2x = (struct p2x_t*)SAFE_ALLOC(sizeof(struct p2x_t) + basename_len - 1);
    if (!p2x) {
      sts = kEpidMemAllocErr;
      break;
    }

    sts = NewFfElement(Fp, &a);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &b);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &rx);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &ra);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &rb);
    BREAK_ON_EPID_ERROR(sts);

    sts = MemberGetPreSig((MemberCtx*)ctx, &curr_presig);
    BREAK_ON_EPID_ERROR(sts);

    // 3.  If the pre-computed signature pre-sigma exists, the member
    //     loads (B, K, T, a, b, rx, rf, ra, rb, R1, R2) from
    //     pre-sigma. Refer to Section 4.4 for the computation of
    //     these values.
    sts = ReadFfElement(Fp, &curr_presig.a, sizeof(curr_presig.a), a);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.b, sizeof(curr_presig.b), b);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.rx, sizeof(curr_presig.rx), rx);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.ra, sizeof(curr_presig.ra), ra);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.rb, sizeof(curr_presig.rb), rb);
    BREAK_ON_EPID_ERROR(sts);

    // If the basename is provided, use it, otherwise use presig B
    if (basename) {
      // 3.a. The member computes (B, i2, y2) = G1.tpmHash(bsn).
      sts = EcHash(G1, basename, basename_len, ctx->hash_alg, B, &p2x->i);
      BREAK_ON_EPID_ERROR(sts);
      p2x->i = htonl(p2x->i);
      sts = WriteEcPoint(G1, B, &commit_out.B, sizeof(commit_out.B));
      BREAK_ON_EPID_ERROR(sts);
      sts = ReadFfElement(Fq, &commit_out.B.y, sizeof(commit_out.B.y), p2y);
      BREAK_ON_EPID_ERROR(sts);

      // b.i. (KTPM, LTPM, ETPM, counterTPM) = TPM2_Commit(P1=h1,(s2, y2) = (i2
      // || bsn, y2)).
      // b.ii.K = KTPM.
      if (0 !=
          memcpy_S((void*)p2x->bsn, basename_len, basename, basename_len)) {
        sts = kEpidBadArgErr;
        break;
      }
      sts =
          Tpm2Commit(ctx->tpm2_ctx, ctx->h1, p2x, sizeof(p2x->i) + basename_len,
                     p2y, k, t, e, (uint16_t*)&ctx->rf_ctr);
      BREAK_ON_EPID_ERROR(sts);
      sts = WriteEcPoint(G1, k, &commit_out.K, sizeof(commit_out.K));
      BREAK_ON_EPID_ERROR(sts);
      // c.i. The member computes R1 = LTPM.
      sts = WriteEcPoint(G1, t, &commit_out.R1, sizeof(commit_out.R1));
      BREAK_ON_EPID_ERROR(sts);
      // c.ii. e12rf = pairing(ETPM, g2)
      sts = Pairing(ps_ctx, e, ctx->epid2_params->g2, R2);
      BREAK_ON_EPID_ERROR(sts);
      // c.iii. R2 = GT.sscmMultiExp(ea2, t1, e12rf, 1, e22, t2, e2w,ra).
      // 4.i. The member computes t1 = (- rx) mod p.
      sts = FfNeg(Fp, rx, t1);
      BREAK_ON_EPID_ERROR(sts);
      // 4.j. The member computes t2 = (rb - a * rx) mod p.
      sts = FfMul(Fp, a, rx, t2);
      BREAK_ON_EPID_ERROR(sts);
      sts = FfNeg(Fp, t2, t2);
      BREAK_ON_EPID_ERROR(sts);
      sts = FfAdd(Fp, rb, t2, t2);
      BREAK_ON_EPID_ERROR(sts);

      sts = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str));
      BREAK_ON_EPID_ERROR(sts);
      sts = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str));
      BREAK_ON_EPID_ERROR(sts);
      {
        FfElement const* points[4];
        BigNumStr const* exponents[4];
        points[0] = ctx->ea2;
        points[1] = R2;
        points[2] = ctx->e22;
        points[3] = ctx->e2w;
        exponents[0] = &t1_str;
        exponents[1] = &kOne;
        exponents[2] = &t2_str;
        exponents[3] = (BigNumStr*)&curr_presig.ra;
        sts = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2);
        BREAK_ON_EPID_ERROR(sts);
      }

      sts = WriteFfElement(GT, R2, &commit_out.R2, sizeof(commit_out.R2));
      BREAK_ON_EPID_ERROR(sts);
      // d. The member over-writes the counterTPM, B, K, R1 and R2 values.
    } else {
      if (!rnd_bsn) {
        sts = kEpidBadArgErr;
        break;
      }
      sts = ReadEcPoint(G1, &curr_presig.B, sizeof(curr_presig.B), B);
      BREAK_ON_EPID_ERROR(sts);
      commit_out.B = curr_presig.B;
      commit_out.K = curr_presig.K;
      commit_out.R1 = curr_presig.R1;
      ((MemberCtx*)ctx)->rf_ctr = curr_presig.rf_ctr;
      commit_out.R2 = curr_presig.R2;
      *rnd_bsn = curr_presig.rnd_bsn;
    }

    commit_out.T = curr_presig.T;

    sts = HashSignCommitment(Fp, ctx->hash_alg, &ctx->pub_key, &commit_out, msg,
                             msg_len, &c_str);
    BREAK_ON_EPID_ERROR(sts);

    digest_size = EpidGetHashSize(ctx->hash_alg);
    digest = (uint8_t*)SAFE_ALLOC(digest_size);
    if (!digest) {
      sts = kEpidNoMemErr;
      break;
    }
    memcpy_S(digest + digest_size - sizeof(c_str), sizeof(c_str), &c_str,
             sizeof(c_str));

    sts = NewFfElement(Fp, &t3);
    BREAK_ON_EPID_ERROR(sts);

    sts = NewFfElement(Fp, &c);
    BREAK_ON_EPID_ERROR(sts);

    sts = ReadFfElement(Fp, &c_str, sizeof(c_str), c);
    BREAK_ON_EPID_ERROR(sts);

    // 7.  The member computes sx = (rx + c * x) mod p.
    sts = FfMul(Fp, c, x, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(Fp, rx, t3, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sx, sizeof(sig->sx));
    BREAK_ON_EPID_ERROR(sts);

    // 8.  The member computes sf = (rf + c * f) mod p.
    sts = Tpm2Sign(ctx->tpm2_ctx, digest, digest_size, *rf_ctr, NULL, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sf, sizeof(sig->sf));
    BREAK_ON_EPID_ERROR(sts);

    // 9.  The member computes sa = (ra + c * a) mod p.
    sts = FfMul(Fp, c, a, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(Fp, ra, t3, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sa, sizeof(sig->sa));
    BREAK_ON_EPID_ERROR(sts);

    // 10. The member computes sb = (rb + c * b) mod p.
    sts = FfMul(Fp, c, b, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(Fp, rb, t3, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sb, sizeof(sig->sb));
    BREAK_ON_EPID_ERROR(sts);

    sig->B = commit_out.B;
    sig->K = commit_out.K;
    sig->T = commit_out.T;
    sig->c = c_str;

    sts = kEpidNoErr;
  } while (0);

  if (sts != kEpidNoErr) {
    (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, (uint16_t)ctx->rf_ctr);
    (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, curr_presig.rf_ctr);
  } else if (basename) {
    (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, curr_presig.rf_ctr);
  }

  EpidZeroMemory(&curr_presig, sizeof(curr_presig));

  DeleteEcPoint(&B);
  DeleteEcPoint(&k);
  DeleteEcPoint(&t);
  DeleteEcPoint(&e);
  DeleteFfElement(&R2);
  DeleteFfElement(&p2y);
  DeleteFfElement(&t1);
  DeleteFfElement(&t2);

  DeleteFfElement(&a);
  DeleteFfElement(&b);
  DeleteFfElement(&rx);
  DeleteFfElement(&ra);
  DeleteFfElement(&rb);

  SAFE_FREE(p2x);

  DeleteFfElement(&t3);
  DeleteFfElement(&c);
  SAFE_FREE(digest);

  return sts;
}
Пример #7
0
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;
}
Пример #8
0
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);
}
Пример #9
0
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;
}
Пример #10
0
// implements section 3.2.2 "Validation of Private Key" from
// Intel(R) EPID 2.0 Spec
bool EpidIsPrivKeyInGroup(GroupPubKey const* pub_key, PrivKey const* priv_key) {
  bool result;

  // Intel(R) EPID Parameters
  Epid2Params_* params = NULL;
  PairingState* ps = NULL;

  // private key
  EcPoint* a_pt = NULL;    // an element in G1
  FfElement* x_el = NULL;  // an integer between [1, p-1]
  FfElement* f_el = NULL;  // an integer between [1, p-1]

  // public key
  EcPoint* h1_pt = NULL;  // an element in G1
  EcPoint* h2_pt = NULL;  // an element in G1
  EcPoint* w_pt = NULL;   // an element in G2

  // local variables
  EcPoint* t1_pt = NULL;    // an element in G2
  EcPoint* t2_pt = NULL;    // an element in G1
  FfElement* t3_el = NULL;  // an element in GT
  FfElement* t4_el = NULL;  // an element in GT

  if (!pub_key || !priv_key) {
    return false;
  }

  do {
    EpidStatus sts;
    EcGroup* G1 = NULL;
    EcGroup* G2 = NULL;
    FiniteField* GT = NULL;
    FiniteField* Fp = NULL;
    BigNumStr t_str = {0};

    sts = CreateEpid2Params(&params);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    G1 = params->G1;
    G2 = params->G2;
    GT = params->GT;
    Fp = params->Fp;

    sts = WriteBigNum(params->t, sizeof(t_str), &t_str);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewPairingState(G1, G2, GT, &t_str, params->neg, &ps);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Load private key
    sts = NewEcPoint(G1, &a_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = ReadEcPoint(G1, &priv_key->A, sizeof(priv_key->A), a_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewFfElement(Fp, &x_el);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = ReadFfElement(Fp, &priv_key->x, sizeof(priv_key->x), x_el);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewFfElement(Fp, &f_el);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = ReadFfElement(Fp, &priv_key->f, sizeof(priv_key->f), f_el);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Load public key
    sts = NewEcPoint(G1, &h1_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = ReadEcPoint(G1, &pub_key->h1, sizeof(pub_key->h1), h1_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewEcPoint(G1, &h2_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = ReadEcPoint(G1, &pub_key->h2, sizeof(pub_key->h2), h2_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewEcPoint(G2, &w_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = ReadEcPoint(G2, &pub_key->w, sizeof(pub_key->w), w_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // local variables
    sts = NewEcPoint(G2, &t1_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewEcPoint(G1, &t2_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewFfElement(GT, &t3_el);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = NewFfElement(GT, &t4_el);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 1. The member verifies that the gid in the public key matches the
    //         gid in the private key.
    if (0 != memcmp(&pub_key->gid, &priv_key->gid, sizeof(priv_key->gid))) {
      result = false;
      break;
    }

    // Step 2. The member computes t1 = G2.sscmExp(g2, x).
    sts = EcSscmExp(G2, params->g2, (BigNumStr const*)&priv_key->x, t1_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 3. The member computes t1 = G2.mul(t1, w).
    sts = EcMul(G2, t1_pt, w_pt, t1_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 4. The member computes t3 = pairing(A, t1).
    sts = Pairing(ps, t3_el, a_pt, t1_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 5. The member computes t2 = G1.sscmExp(h1, f).
    sts = EcSscmExp(G1, h1_pt, (BigNumStr const*)&priv_key->f, t2_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 6. The member computes t2 = G1.mul(t2, g1).
    sts = EcMul(G1, t2_pt, params->g1, t2_pt);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 7. The member computes t4 = pairing(t2, g2).
    sts = WriteBigNum(params->t, sizeof(t_str), &t_str);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    sts = Pairing(ps, t4_el, t2_pt, params->g2);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }

    // Step 8. If GT.isEqual(t3, t4) = false, reports bad private key.
    sts = FfIsEqual(GT, t3_el, t4_el, &result);
    if (kEpidNoErr != sts) {
      result = false;
      break;
    }
  } while (0);

  // local variables
  DeleteFfElement(&t4_el);
  DeleteFfElement(&t3_el);
  DeleteEcPoint(&t2_pt);
  DeleteEcPoint(&t1_pt);

  // public key
  DeleteEcPoint(&w_pt);
  DeleteEcPoint(&h2_pt);
  DeleteEcPoint(&h1_pt);

  // private key
  DeleteFfElement(&f_el);
  DeleteFfElement(&x_el);
  DeleteEcPoint(&a_pt);

  // Intel(R) EPID Parameters
  DeletePairingState(&ps);
  DeleteEpid2Params(&params);

  return result;
}
Пример #11
0
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;
}
Пример #12
0
void PrintEcPoint(EcGroup const* g, EcPoint const* ec_point,
                  char const* var_name, PrintUtilFormat format) {
  FiniteField fp;
  FfElement* fp_x = NULL;
  FfElement* fp_y = NULL;
  uint8_t ec_point_str[sizeof(G2ElemStr)];
  if (!var_name) {
    var_name = "<no name>";
  }
  if (!ec_point || !g) {
    PRINT("%s (EcPoint):\n", var_name);
    MAKE_INDENT();
    PRINT("<null>\n");
    return;
  }
  if (!ec_point->ipp_ec_pt || !g->ipp_ec) {
    PRINT("%s (EcPoint):\n", var_name);
    MAKE_INDENT();
    PRINT("<invalid>\n");
    return;
  }
  do {
    IppStatus sts = ippStsNoErr;
    int ipp_half_strlen;
    // get finite field
    sts = ippsGFpECGet(g->ipp_ec, (const IppsGFpState**)&(fp.ipp_ff), 0, 0, 0,
                       0, 0, 0, 0, 0);
    if (ippStsNoErr != sts) {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }

    // create element X
    if (kEpidNoErr != NewFfElement(&fp, &fp_x)) {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }
    // create element Y
    if (kEpidNoErr != NewFfElement(&fp, &fp_y)) {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }

    ipp_half_strlen = fp_x->info.elementLen * sizeof(Ipp32u);

    // get elements from point
    sts = ippsGFpECGetPoint(ec_point->ipp_ec_pt, fp_x->ipp_ff_elem,
                            fp_y->ipp_ff_elem, g->ipp_ec);
    // check return codes
    if (ippStsNoErr != sts) {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }

    // get element X data
    sts = ippsGFpGetElementOctString(fp_x->ipp_ff_elem, (Ipp8u*)&ec_point_str,
                                     ipp_half_strlen, fp.ipp_ff);
    // check return codes
    if (ippStsNoErr != sts) {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }
    // get element Y data
    sts = ippsGFpGetElementOctString(fp_y->ipp_ff_elem,
                                     (Ipp8u*)&ec_point_str + ipp_half_strlen,
                                     ipp_half_strlen, fp.ipp_ff);
    // check return codes
    if (ippStsNoErr != sts) {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }

    if (2 * ipp_half_strlen == sizeof(G1ElemStr)) {
      PrintG1ElemStr((const G1ElemStr*)&ec_point_str, var_name, format);
    } else if (2 * ipp_half_strlen == sizeof(G2ElemStr)) {
      PrintG2ElemStr((const G2ElemStr*)&ec_point_str, var_name, format);
    } else {
      PRINT("%s (EcPoint):\n", var_name);
      MAKE_INDENT();
      PRINT("<invalid>\n");
      break;
    }
  } while (0);

  DeleteFfElement(&fp_x);
  DeleteFfElement(&fp_y);
}
Пример #13
0
EpidStatus EpidVerifierCreate(GroupPubKey const* pubkey,
                              VerifierPrecomp const* precomp,
                              VerifierCtx** ctx) {
  EpidStatus result = kEpidErr;
  VerifierCtx* verifier_ctx = NULL;
  if (!pubkey || !ctx) {
    return kEpidBadArgErr;
  }
  do {
    // Allocate memory for VerifierCtx
    verifier_ctx = SAFE_ALLOC(sizeof(VerifierCtx));
    if (!verifier_ctx) {
      result = kEpidMemAllocErr;
      break;
    }

    // set SHA512 as the default hash algorithm
    verifier_ctx->hash_alg = kSha512;

    // Internal representation of Epid2Params
    result = CreateEpid2Params(&verifier_ctx->epid2_params);
    if (kEpidNoErr != result) {
      break;
    }
    // Internal representation of Group Pub Key
    result = CreateGroupPubKey(pubkey, verifier_ctx->epid2_params->G1,
                               verifier_ctx->epid2_params->G2,
                               &verifier_ctx->pub_key);
    if (kEpidNoErr != result) {
      break;
    }
    // Store group public key strings for later use
    result = SetKeySpecificCommitValues(pubkey, &verifier_ctx->commit_values);
    if (kEpidNoErr != result) {
      break;
    }
    // Allocate verifier_ctx->e12
    result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e12);
    if (kEpidNoErr != result) {
      break;
    }
    // Allocate verifier_ctx->e22
    result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e22);
    if (kEpidNoErr != result) {
      break;
    }
    // Allocate verifier_ctx->e2w
    result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e2w);
    if (kEpidNoErr != result) {
      break;
    }
    // Allocate verifier_ctx->eg12
    result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->eg12);
    if (kEpidNoErr != result) {
      break;
    }
    // precomputation
    if (precomp != NULL) {
      result = ReadPrecomputation(precomp, verifier_ctx);
    } else {
      result = DoPrecomputation(verifier_ctx);
    }
    if (kEpidNoErr != result) {
      break;
    }
    verifier_ctx->sig_rl = NULL;
    verifier_ctx->group_rl = NULL;
    verifier_ctx->priv_rl = NULL;
    verifier_ctx->verifier_rl = NULL;
    *ctx = verifier_ctx;
    result = kEpidNoErr;
  } while (0);

  if (kEpidNoErr != result && verifier_ctx) {
    DeleteFfElement(&verifier_ctx->eg12);
    DeleteFfElement(&verifier_ctx->e2w);
    DeleteFfElement(&verifier_ctx->e22);
    DeleteFfElement(&verifier_ctx->e12);
    DeleteEpid2Params(&verifier_ctx->epid2_params);
    DeleteGroupPubKey(&verifier_ctx->pub_key);
    SAFE_FREE(verifier_ctx);
  }
  return result;
}
Пример #14
0
EpidStatus CreateEpid2Params(Epid2Params_** params) {
  EpidStatus result = kEpidErr;
  Epid2Params_* internal_param = NULL;
  BigNumStr t_str = {0};
  Epid2Params params_str = {
#include "epid/common/epid2params_ate.inc"
  };
  if (!params) {
    return kEpidBadArgErr;
  }
  do {
    internal_param = SAFE_ALLOC(sizeof(Epid2Params_));
    if (!internal_param) {
      result = kEpidMemAllocErr;
      break;
    }
    result = NewBigNum(sizeof(params_str.p), &internal_param->p);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadBigNum(&params_str.p, sizeof(params_str.p), internal_param->p);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewBigNum(sizeof(params_str.q), &internal_param->q);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadBigNum(&params_str.q, sizeof(params_str.q), internal_param->q);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewBigNum(sizeof(params_str.t), &internal_param->t);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadBigNum(&params_str.t, sizeof(params_str.t), internal_param->t);
    if (kEpidNoErr != result) {
      break;
    }
    internal_param->neg = (params_str.neg.data[0]) ? true : false;

    result = NewFp(&params_str, &internal_param->Fp);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFq(&params_str, &internal_param->Fq);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFq2(&params_str, internal_param->Fq, &internal_param->Fq2);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(internal_param->Fq2, &internal_param->xi);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(internal_param->Fq2, &params_str.xi,
                           sizeof(params_str.xi), internal_param->xi);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFq6(&params_str, internal_param->Fq2, internal_param->xi,
                    &internal_param->Fq6);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewGT(internal_param->Fq6, &internal_param->GT);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewG1(&params_str, internal_param->Fq, &internal_param->G1);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewEcPoint(internal_param->G1, &internal_param->g1);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadEcPoint(internal_param->G1, &params_str.g1,
                         sizeof(params_str.g1), internal_param->g1);
    if (kEpidNoErr != result) {
      break;
    }
    result =
        NewG2(&params_str, internal_param->p, internal_param->q,
              internal_param->Fq, internal_param->Fq2, &internal_param->G2);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewEcPoint(internal_param->G2, &internal_param->g2);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadEcPoint(internal_param->G2, &params_str.g2,
                         sizeof(params_str.g2), internal_param->g2);
    if (kEpidNoErr != result) {
      break;
    }
    result = WriteBigNum(internal_param->t, sizeof(t_str), &t_str);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewPairingState(internal_param->G1, internal_param->G2,
                             internal_param->GT, &t_str, internal_param->neg,
                             &internal_param->pairing_state);
    if (kEpidNoErr != result) {
      break;
    }
    *params = internal_param;
    result = kEpidNoErr;
  } while (0);
  if (kEpidNoErr != result && internal_param) {
    DeletePairingState(&internal_param->pairing_state);

    DeleteEcPoint(&internal_param->g2);
    DeleteEcPoint(&internal_param->g1);

    DeleteBigNum(&internal_param->p);
    DeleteBigNum(&internal_param->q);
    DeleteBigNum(&internal_param->t);

    DeleteFp(&internal_param->Fp);
    DeleteFq(&internal_param->Fq);
    DeleteFq2(&internal_param->Fq2);
    DeleteFq6(&internal_param->Fq6);
    DeleteGT(&internal_param->GT);

    DeleteG1(&internal_param->G1);
    DeleteG2(&internal_param->G2);

    SAFE_FREE(internal_param);
  }
  return result;
}
Пример #15
0
EpidStatus NewG2(Epid2Params const* param, BigNum* p, BigNum* q,
                 FiniteField* Fq, FiniteField* Fq2, EcGroup** G2) {
  EpidStatus result = kEpidErr;
  EcGroup* ec = NULL;
  FfElement* a = NULL;
  FfElement* b = NULL;
  FfElement* fq_param_b = NULL;
  FfElement* x = NULL;
  FfElement* y = NULL;
  BigNum* order = NULL;
  BigNum* cofactor = NULL;
  if (!param || !Fq || !Fq2 || !G2) {
    return kEpidBadArgErr;
  }
  do {
    //   2. Set xi = (xi0, xi1) an element of Fq2.
    //   3. Let b', xi' be a temporary variable in Fq2.
    //   4. Compute xi' = Fq2.inverse(xi).
    //   5. Compute b' = Fq2.mul(xi', b).
    result = NewFfElement(Fq2, &b);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq2, &param->xi, sizeof(param->xi), b);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfInv(Fq2, b, b);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(Fq, &fq_param_b);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq, &param->b, sizeof(param->b), fq_param_b);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfMul(Fq2, b, fq_param_b, b);  // ??? overflow fq2*fq
    if (kEpidNoErr != result) {
      break;
    }
    //   6. Set g2.x = (g2.x[0], g2.x[1]) an element of Fq2.
    //   7. Set g2.y = (g2.y[0], g2.y[1]) an element of Fq2.
    result = NewFfElement(Fq2, &x);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq2, &param->g2.x, sizeof(param->g2.x), x);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(Fq2, &y);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq2, &param->g2.y, sizeof(param->g2.y), y);
    if (kEpidNoErr != result) {
      break;
    }
    //   8. set h = 2q - p, aka cofactor
    result = NewBigNum(2 * sizeof(param->q), &cofactor);
    if (kEpidNoErr != result) {
      break;
    }
    result = BigNumAdd(q, q, cofactor);
    if (kEpidNoErr != result) {
      break;
    }
    result = BigNumSub(cofactor, p, cofactor);
    if (kEpidNoErr != result) {
      break;
    }
    //   9. set n = p * h, AKA order
    result = NewBigNum(2 * sizeof(param->q), &order);
    if (kEpidNoErr != result) {
      break;
    }
    result = BigNumMul(p, cofactor, order);
    if (kEpidNoErr != result) {
      break;
    }
    // set a to identity, NewFfElement does it by default
    result = NewFfElement(Fq2, &a);
    if (kEpidNoErr != result) {
      break;
    }
    //   10. Set G2 = E(Fq2).init(p, param(Fq2), n, h, 0, b', g2.x, g2.y)
    result = NewEcGroup(Fq2, a, b, x, y, order, cofactor, &ec);
    if (kEpidNoErr != result) {
      break;
    }
    *G2 = ec;
    result = kEpidNoErr;
  } while (0);

  DeleteBigNum(&cofactor);
  DeleteBigNum(&order);
  DeleteFfElement(&y);
  DeleteFfElement(&x);
  DeleteFfElement(&b);
  DeleteFfElement(&a);
  DeleteFfElement(&fq_param_b);

  return result;
}
Пример #16
0
EpidStatus NewG1(Epid2Params const* param, FiniteField* Fq, EcGroup** G1) {
  EpidStatus result = kEpidErr;
  EcGroup* ec = NULL;
  FfElement* fq_a = NULL;
  FfElement* fq_b = NULL;
  FfElement* g1_x = NULL;
  FfElement* g1_y = NULL;
  BigNum* order = NULL;
  BigNum* cofactor = NULL;
  // h = 1;
  const BigNumStr h1 = {
      {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}};

  if (!param || !Fq || !G1) {
    return kEpidBadArgErr;
  }
  do {
    // Create G1
    // G1 is an elliptic curve group E(Fq).It can be initialized as follows :
    //   1. Set G1 = E(Fq).init(p, q, n = p, h = 1, a = 0, b, g1.x, g1.y).
    // a = 0
    // NewFfelement is Identidy
    result = NewFfElement(Fq, &fq_a);
    if (kEpidNoErr != result) {
      break;
    }
    // b
    result = NewFfElement(Fq, &fq_b);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq, &param->b, sizeof(param->b), fq_b);
    if (kEpidNoErr != result) {
      break;
    }
    // g1.x
    result = NewFfElement(Fq, &g1_x);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq, &param->g1.x, sizeof(param->g1.x), g1_x);
    if (kEpidNoErr != result) {
      break;
    }
    // g1.y
    result = NewFfElement(Fq, &g1_y);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq, &param->g1.y, sizeof(param->g1.y), g1_y);
    if (kEpidNoErr != result) {
      break;
    }
    // order
    result = NewBigNum(sizeof(BigNumStr), &order);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadBigNum(&param->p, sizeof(param->p), order);
    if (kEpidNoErr != result) {
      break;
    }
    // cofactor
    result = NewBigNum(sizeof(BigNumStr), &cofactor);
    if (kEpidNoErr != result) {
      break;
    }

    result = ReadBigNum(&h1, sizeof(h1), cofactor);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewEcGroup(Fq, fq_a, fq_b, g1_x, g1_y, order, cofactor, &ec);
    if (kEpidNoErr != result) {
      break;
    }
    *G1 = ec;
    result = kEpidNoErr;
  } while (0);

  DeleteBigNum(&cofactor);
  DeleteBigNum(&order);
  DeleteFfElement(&g1_y);
  DeleteFfElement(&g1_x);
  DeleteFfElement(&fq_b);
  DeleteFfElement(&fq_a);

  return result;
}