blob: 797e8f64f93502ebe01244da5b8d4f4aa2a715a8 [file] [log] [blame]
/*############################################################################
# Copyright 1999-2018 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.
############################################################################*/
/*
//
// Purpose:
// Cryptography Primitive.
// EC over GF(p^m) Shared Secret (Diffie-Hellman wo/w cofactor)
//
// Contents:
// ippsGFpECSharedSecretDH()
// ippsGFpECSharedSecretDHC()
//
//
*/
#include "owndefs.h"
#include "owncp.h"
#include "pcpgfpecstuff.h"
/*F*
// Name: ippsGFpECSharedSecretDHC
//
// Purpose: Compute Shared Secret (Diffie-Hellman)
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pEC
// NULL == pPrivateA
// NULL == pPublicB
// NULL == pShare
//
// ippStsContextMatchErr illegal pEC->idCtx
// illegal pPrivateA->idCtx
// illegal pPublicB->idCtx
// illegal pShare->idCtx
//
// ippStsRangeErr not enough room for share key
//
// ippStsShareKeyErr (infinity) => z
//
// ippStsNoErr no errors
//
// Parameters:
// pPrivateA pointer to own private key
// pPublicB pointer to alien public key
// pShare pointer to the shared secret value
// pEC pointer to the EC context
//
*F*/
IPPFUN(IppStatus, ippsGFpECSharedSecretDH,(const IppsBigNumState* pPrivateA, const IppsGFpECPoint* pPublicB,
IppsBigNumState* pShare,
IppsGFpECState* pEC, Ipp8u* pScratchBuffer))
{
IppsGFpState* pGF;
gsModEngine* pGFE;
/* EC context and buffer */
IPP_BAD_PTR2_RET(pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET(!ECP_TEST_ID(pEC), ippStsContextMatchErr);
pGF = ECP_GFP(pEC);
pGFE = GFP_PMA(pGF);
/* test private (own) key */
IPP_BAD_PTR1_RET(pPrivateA);
pPrivateA = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPrivateA, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pPrivateA), ippStsContextMatchErr);
/* test public (other party) key */
IPP_BAD_PTR1_RET(pPublicB);
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPublicB), ippStsContextMatchErr );
/* test share secret value */
IPP_BAD_PTR1_RET(pShare);
pShare = (IppsBigNumState*)( IPP_ALIGNED_PTR(pShare, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pShare), ippStsContextMatchErr);
IPP_BADARG_RET((BN_ROOM(pShare)<GFP_FELEN(pGFE)), ippStsRangeErr);
{
int elmLen = GFP_FELEN(pGFE);
IppsGFpElement elm;
IppsGFpECPoint T;
int finite_point;
/* T = [privateA]pPublicB */
cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC);
gfec_MulPoint(&T, pPublicB, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), pEC, pScratchBuffer);
/* share = T.x */
cpGFpElementConstruct(&elm, cpGFpGetPool(1, pGFE), elmLen);
finite_point = gfec_GetPoint(GFPE_DATA(&elm), NULL, &T, pEC);
if(finite_point) {
BNU_CHUNK_T* pShareData = BN_NUMBER(pShare);
int nsShare = BN_ROOM(pShare);
/* share = decode(T.x) */
GFP_METHOD(pGFE)->decode(pShareData, GFPE_DATA(&elm), pGFE);
cpGFpElementPadd(pShareData+elmLen, nsShare-elmLen, 0);
BN_SIGN(pShare) = ippBigNumPOS;
FIX_BNU(pShareData, nsShare);
BN_SIZE(pShare) = nsShare;
}
cpGFpReleasePool(1, pGFE);
cpEcGFpReleasePool(1, pEC);
return finite_point? ippStsNoErr : ippStsShareKeyErr;
}
}
/*F*
// Name: ippsGFpECSharedSecretDHC
//
// Purpose: Compute Shared Secret (Diffie-Hellman with cofactor)
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pEC
// NULL == pPrivateA
// NULL == pPublicB
// NULL == pShare
//
// ippStsContextMatchErr illegal pEC->idCtx
// illegal pPrivateA->idCtx
// illegal pPublicB->idCtx
// illegal pShare->idCtx
//
// ippStsRangeErr not enough room for share key
//
// ippStsShareKeyErr (infinity) => z
//
// ippStsNoErr no errors
//
// Parameters:
// pPrivateA pointer to own private key
// pPublicB pointer to alien public key
// pShare pointer to the shared secret value
// pEC pointer to the EC context
//
*F*/
IPPFUN(IppStatus, ippsGFpECSharedSecretDHC,(const IppsBigNumState* pPrivateA, const IppsGFpECPoint* pPublicB,
IppsBigNumState* pShare,
IppsGFpECState* pEC, Ipp8u* pScratchBuffer))
{
IppsGFpState* pGF;
gsModEngine* pGFE;
/* EC context and buffer */
IPP_BAD_PTR2_RET(pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET(!ECP_TEST_ID(pEC), ippStsContextMatchErr);
pGF = ECP_GFP(pEC);
pGFE = GFP_PMA(pGF);
/* test private (own) key */
IPP_BAD_PTR1_RET(pPrivateA);
pPrivateA = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPrivateA, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pPrivateA), ippStsContextMatchErr);
/* test public (other party) key */
IPP_BAD_PTR1_RET(pPublicB);
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPublicB), ippStsContextMatchErr );
/* test share key */
IPP_BAD_PTR1_RET(pShare);
pShare = (IppsBigNumState*)( IPP_ALIGNED_PTR(pShare, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pShare), ippStsContextMatchErr);
IPP_BADARG_RET((BN_ROOM(pShare)<GFP_FELEN(pGFE)), ippStsRangeErr);
{
int elmLen = GFP_FELEN(pGFE);
IppsGFpElement elm;
IppsGFpECPoint T;
int finite_point;
gsModEngine* montR = ECP_MONT_R(pEC);
int nsR = MOD_LEN(montR);
/* compute factored secret F = coFactor*privateA */
BNU_CHUNK_T* F = cpGFpGetPool(1, pGFE);
cpMontEnc_BNU_EX(F, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), montR);
cpMontMul_BNU_EX(F, F, nsR, ECP_COFACTOR(pEC), 1, montR);
/* T = [F]pPublicB */
cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC);
FIX_BNU(F, nsR);
gfec_MulPoint(&T, pPublicB, F, nsR, pEC, pScratchBuffer);
/* share = T.x */
cpGFpElementConstruct(&elm, F, elmLen);
finite_point = gfec_GetPoint(GFPE_DATA(&elm), NULL, &T, pEC);
if(finite_point) {
BNU_CHUNK_T* pShareData = BN_NUMBER(pShare);
int nsShare = BN_ROOM(pShare);
/* share = decode(T.x) */
GFP_METHOD(pGFE)->decode(pShareData, GFPE_DATA(&elm), pGFE);
cpGFpElementPadd(pShareData+elmLen, nsShare-elmLen, 0);
BN_SIGN(pShare) = ippBigNumPOS;
FIX_BNU(pShareData, nsShare);
BN_SIZE(pShare) = nsShare;
}
cpGFpReleasePool(1, pGFE);
cpEcGFpReleasePool(1, pEC);
return finite_point? ippStsNoErr : ippStsShareKeyErr;
}
}