123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- /*############################################################################
- # Copyright 2017 Intel Corporation
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- ############################################################################*/
- /// Sensitive pre-computed signature implementation
- /*! \file */
- #include <epid/member/api.h>
- #include <string.h>
- #include "epid/common/math/ecgroup.h"
- #include "epid/common/math/finitefield.h"
- #include "epid/common/src/endian_convert.h"
- #include "epid/common/src/epid2params.h"
- #include "epid/common/src/memory.h"
- #include "epid/common/src/stack.h"
- #include "epid/member/src/context.h"
- #include "epid/member/tpm2/commit.h"
- #include "epid/member/tpm2/context.h"
- #include "epid/member/tpm2/getrandom.h"
- #include "epid/member/tpm2/sign.h"
- /// Handle SDK Error with Break
- #define BREAK_ON_EPID_ERROR(ret) \
- if (kEpidNoErr != (ret)) { \
- break; \
- }
- /// Count of elements in array
- #define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
- static EpidStatus MemberComputePreSig(MemberCtx const* ctx,
- PreComputedSignature* precompsig);
- EpidStatus EpidAddPreSigs(MemberCtx* ctx, size_t number_presigs) {
- PreComputedSignature* new_presigs = NULL;
- size_t i = 0;
- if (!ctx || !ctx->presigs) return kEpidBadArgErr;
- if (0 == number_presigs) return kEpidNoErr;
- new_presigs =
- (PreComputedSignature*)StackPushN(ctx->presigs, number_presigs, NULL);
- if (!new_presigs) return kEpidMemAllocErr;
- for (i = 0; i < number_presigs; i++) {
- EpidStatus sts = MemberComputePreSig(ctx, &new_presigs[i]);
- if (kEpidNoErr != sts) {
- // roll back pre-computed-signature pool
- StackPopN(ctx->presigs, number_presigs, 0);
- return sts;
- }
- }
- return kEpidNoErr;
- }
- size_t EpidGetNumPreSigs(MemberCtx const* ctx) {
- return (ctx && ctx->presigs) ? StackGetSize(ctx->presigs) : (size_t)0;
- }
- EpidStatus MemberGetPreSig(MemberCtx* ctx, PreComputedSignature* presig) {
- if (!ctx || !presig) {
- return kEpidBadArgErr;
- }
- if (StackGetSize(ctx->presigs)) {
- // Use existing pre-computed signature
- if (!StackPopN(ctx->presigs, 1, presig)) {
- return kEpidErr;
- }
- return kEpidNoErr;
- }
- // generate a new pre-computed signature
- return MemberComputePreSig(ctx, presig);
- }
- /// Performs Pre-computation that can be used to speed up signing
- EpidStatus MemberComputePreSig(MemberCtx const* ctx,
- PreComputedSignature* precompsig) {
- EpidStatus sts = kEpidErr;
- EcPoint* B = NULL;
- EcPoint* k = NULL;
- EcPoint* t = NULL; // temporary, used for K, T, R1
- EcPoint* e = NULL;
- FfElement* R2 = NULL;
- FfElement* a = NULL;
- FfElement* rx = NULL; // reused for rf
- FfElement* rb = NULL; // reused for ra
- FfElement* t1 = NULL;
- FfElement* t2 = NULL;
- BigNumStr t1_str = {0};
- BigNumStr t2_str = {0};
- struct {
- uint32_t i;
- BigNumStr bsn;
- } p2x = {0};
- FfElement* p2y = NULL;
- if (!ctx || !precompsig || !ctx->epid2_params) {
- return kEpidBadArgErr;
- }
- do {
- // handy shorthands:
- Tpm2Ctx* tpm = ctx->tpm2_ctx;
- EcGroup* G1 = ctx->epid2_params->G1;
- FiniteField* GT = ctx->epid2_params->GT;
- FiniteField* Fp = ctx->epid2_params->Fp;
- FiniteField* Fq = ctx->epid2_params->Fq;
- EcPoint const* h2 = ctx->h2;
- EcPoint const* A = ctx->A;
- FfElement const* x = ctx->x;
- 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};
- // 1. The member expects the pre-computation is done (e12, e22, e2w,
- // ea2). Refer to Section 3.5 for the computation of these
- // values.
- sts = NewFfElement(Fq, &p2y);
- // 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.
- 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(Fp, &a);
- BREAK_ON_EPID_ERROR(sts);
- sts = NewFfElement(Fp, &rx);
- BREAK_ON_EPID_ERROR(sts);
- sts = NewFfElement(Fp, &rb);
- BREAK_ON_EPID_ERROR(sts);
- sts = NewFfElement(Fp, &t1);
- BREAK_ON_EPID_ERROR(sts);
- sts = NewFfElement(Fp, &t2);
- BREAK_ON_EPID_ERROR(sts);
- // 3. The member computes B = G1.getRandom().
- // 4.a. If bsn is not provided, the member chooses randomly an integer bsn
- // from [1, p-1].
- sts = Tpm2GetRandom(tpm, sizeof(p2x.bsn) * 8, &p2x.bsn);
- BREAK_ON_EPID_ERROR(sts);
- precompsig->rnd_bsn = p2x.bsn;
- // 4.b. The member computes (B, i2, y2) = G1.tpmHash(bsn).
- sts = EcHash(G1, (const void*)&p2x.bsn, sizeof(p2x.bsn), ctx->hash_alg, B,
- &p2x.i);
- BREAK_ON_EPID_ERROR(sts);
- p2x.i = htonl(p2x.i);
- sts = WriteEcPoint(G1, B, &precompsig->B, sizeof(precompsig->B));
- BREAK_ON_EPID_ERROR(sts);
- sts = ReadFfElement(Fq, &precompsig->B.y, sizeof(precompsig->B.y), p2y);
- BREAK_ON_EPID_ERROR(sts);
- // 4.c. (KTPM, LTPM, ETPM, counterTPM) = TPM2_Commit(P1=h1, (s2, y2) = (i1
- // || bsn, y2)), K = KTPM
- sts = Tpm2Commit(tpm, ctx->h1, &p2x, sizeof(p2x), p2y, k, t, e,
- &precompsig->rf_ctr);
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteEcPoint(G1, k, &precompsig->K, sizeof(precompsig->K));
- BREAK_ON_EPID_ERROR(sts);
- // 4.k. The member computes R1 = LTPM.
- sts = WriteEcPoint(G1, t, &precompsig->R1, sizeof(precompsig->R1));
- BREAK_ON_EPID_ERROR(sts);
- // 4.d. The member chooses randomly an integer a from [1, p-1].
- sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, a);
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteFfElement(Fp, a, &precompsig->a, sizeof(precompsig->a));
- BREAK_ON_EPID_ERROR(sts);
- // 4.e. The member computes T = G1.sscmExp(h2, a).
- sts = EcExp(G1, h2, (BigNumStr*)&precompsig->a, t);
- BREAK_ON_EPID_ERROR(sts);
- // 4.k. The member computes T = G1.mul(T, A).
- sts = EcMul(G1, t, A, t);
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteEcPoint(G1, t, &precompsig->T, sizeof(precompsig->T));
- BREAK_ON_EPID_ERROR(sts);
- // 4.h. The member chooses rx, ra, rb randomly from [1, p-1].
- // note : rb are reused as ra
- sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, rx);
- BREAK_ON_EPID_ERROR(sts);
- sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, rb);
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteFfElement(Fp, rx, &precompsig->rx, sizeof(precompsig->rx));
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteFfElement(Fp, rb, &precompsig->rb, sizeof(precompsig->rb));
- BREAK_ON_EPID_ERROR(sts);
- // 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);
- // 4.g. The member computes b = (a * x) mod p.
- sts = FfMul(Fp, a, x, a);
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteFfElement(Fp, a, &precompsig->b, sizeof(precompsig->b));
- BREAK_ON_EPID_ERROR(sts);
- // reusing rb as ra
- sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, rb);
- BREAK_ON_EPID_ERROR(sts);
- sts = WriteFfElement(Fp, rb, &precompsig->ra, sizeof(precompsig->ra));
- BREAK_ON_EPID_ERROR(sts);
- // 4.l.i e12rf = pairing(ETPM, g2)
- sts = Pairing(ps_ctx, e, ctx->epid2_params->g2, R2);
- BREAK_ON_EPID_ERROR(sts);
- // 4.l.ii. The member computes R2 = GT.sscmMultiExp(ea2, t1, e12rf, 1,
- // e22, t2, e2w, ra).
- 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*)&precompsig->ra;
- sts = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2);
- BREAK_ON_EPID_ERROR(sts);
- }
- sts = WriteFfElement(GT, R2, &precompsig->R2, sizeof(precompsig->R2));
- BREAK_ON_EPID_ERROR(sts);
- sts = kEpidNoErr;
- } while (0);
- if (sts != kEpidNoErr) {
- (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, precompsig->rf_ctr);
- }
- EpidZeroMemory(&t1_str, sizeof(t1_str));
- EpidZeroMemory(&t2_str, sizeof(t2_str));
- EpidZeroMemory(&p2x, sizeof(p2x));
- DeleteFfElement(&p2y);
- DeleteEcPoint(&B);
- DeleteEcPoint(&k);
- DeleteEcPoint(&t);
- DeleteEcPoint(&e);
- DeleteFfElement(&R2);
- DeleteFfElement(&a);
- DeleteFfElement(&rx);
- DeleteFfElement(&rb);
- DeleteFfElement(&t1);
- DeleteFfElement(&t2);
- return sts;
- }
|