📄 ctx_ecdsa.c
字号:
goto retreat;
}
printf( "sign( P8 )\n" ); // eZ
/* r = kG.x mod G.r */
CK( BN_mod( r, kg.x, gr, bnCtx ) );
/* k = ( k^-1 ) mod n */
CKPTR( BN_mod_inverse( k, k, gr, bnCtx ) );
/* s = k^-1 * ( d * r + e ) mod n */
CK( BN_mod_mul( s, d, r, gr, bnCtx ) );
CK( BN_mod_add( s, s, hash, gr, bnCtx ) );
CK( BN_mod_mul( s, s, k, gr, bnCtx ) );
if( bnStatusError( bnStatus ) )
{
status = getBnStatus( bnStatus );
break;
}
printf( "sign( P9 )\n" ); // eZ
/* If either r = 0 or s = 0, try again. See the earlier comment
about the real necessity of this check */
if( BN_is_zero( r ) || BN_is_zero( s ) )
continue;
}
BN_CTX_end( bnCtx );
if( cryptStatusError( status ) )
return( status );
/* Encode the result as a DL data block */
status = pkcInfo->encodeDLValuesFunction( eccParams->outParam,
eccParams->outLen, r, s,
eccParams->formatType );
if( !cryptStatusError( status ) )
{
eccParams->outLen = status;
status = CRYPT_OK; /* encodeDLValues() returns a byte count */
}
printf( "sign( P10 )\n" ); // eZ
return( status );
}
/* Signature check a single block of data */
static int sigCheck( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int noBytes )
{
PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
BN_CTX *bnCtx = pkcInfo->bnCTX;
DLP_PARAMS *eccParams = ( DLP_PARAMS * ) buffer;
BIGNUM *p = &pkcInfo->eccParam_p, *a = &pkcInfo->eccParam_a;
BIGNUM *b = &pkcInfo->eccParam_b, *gx = &pkcInfo->eccParam_gx;
BIGNUM *gy = &pkcInfo->eccParam_gy, *qx = &pkcInfo->eccParam_qx;
BIGNUM *qy = &pkcInfo->eccParam_qy, *gr = &pkcInfo->eccParam_r;
BIGNUM *u1 = &pkcInfo->tmp1, *u2 = &pkcInfo->tmp2;
BIGNUM *r = &pkcInfo->tmp3, *s = &pkcInfo->tmp4;
S_POINT u1g, u2q;
S_ECP_CTX ctx;
int bnStatus = BN_STATUS, status;
printf( "sigCheck\n" ); // eZ
assert( noBytes == sizeof( DLP_PARAMS ) );
assert( dlpParams->inParam1 != NULL );
assert( dlpParams->inParam2 != NULL );
assert( dlpParams->outParam == NULL && dlpParams->outLen == 0 );
BN_CTX_start( bnCtx );
// u1 = BN_CTX_get( bnCtx );
// u2 = BN_CTX_get( bnCtx );
// As before.
ctx.t1 = BN_CTX_get( bnCtx );
ctx.t2 = BN_CTX_get( bnCtx );
ctx.t3 = BN_CTX_get( bnCtx );
ctx.t4 = BN_CTX_get( bnCtx );
ctx.p1.x = BN_CTX_get( bnCtx );
ctx.p1.y = BN_CTX_get( bnCtx );
ctx.p2.x = BN_CTX_get( bnCtx );
ctx.p2.y = BN_CTX_get( bnCtx );
ctx.p3.x = BN_CTX_get( bnCtx );
ctx.p3.y = BN_CTX_get( bnCtx );
ctx.pkc=pkcInfo;
u1g.x = BN_CTX_get( bnCtx );
u1g.y = BN_CTX_get( bnCtx );
u2q.x = BN_CTX_get( bnCtx );
u2q.y = BN_CTX_get( bnCtx );
// r = BN_CTX_get( bnCtx );
// CKPTR( s = BN_CTX_get( bnCtx ) );
// if( bnStatusError( bnStatus ) )
// {
// status = getBnStatus( bnStatus );
// goto retreat;
// }
if( !ecp_init( &ctx, 0 ) )
{
BN_CTX_end( bnCtx );
return( CRYPT_ERROR_FAILED );
}
/* Decode the values from a DL data block and make sure that r and s are
valid, i.e. r, s = [1...gr-1] */
status = pkcInfo->decodeDLValuesFunction( eccParams->inParam2,
eccParams->inLen2, &r, &s,
eccParams->formatType );
if( cryptStatusError( status ) )
{
BN_CTX_end( bnCtx );
return( status );
}
if( BN_is_zero( r ) || BN_cmp( r, gr ) >= 0 || \
BN_cmp( s, gr ) >= 0 || BN_is_zero( s ) )
{
BN_CTX_end( bnCtx );
return( CRYPT_ERROR_BADDATA );
}
/* w = ( s^-1 ) mod G.r */
CKPTR( BN_mod_inverse( u2, s, gr, bnCtx ) );
/* u1 = ( hash * w ) mod G.r */
BN_bin2bn( ( BYTE * ) eccParams->inParam1, eccParams->inLen1, u1 );
CK( BN_mod_mul( u1, u1, u2, gr, bnCtx ) );
/* u2 = ( r * w ) mod G.r */
CK( BN_mod_mul( u2, r, u2, gr, bnCtx ) );
/* u1p = u1 * G */
CKPTR( BN_copy( u1g.x, gx ) );
CKPTR( BN_copy( u1g.y, gy ) );
if( bnStatusError( bnStatus ) )
{
BN_CTX_end( bnCtx );
return( getBnStatus( bnStatus ) );
}
if( !ecp_pt_smul_naf( &ctx, &u1g, u1 ) )
{
BN_CTX_end( bnCtx );
return( CRYPT_ERROR_FAILED );
}
/* u2Q = u2 * Q */
CKPTR( BN_copy( u2q.x, qx ) );
CKPTR( BN_copy( u2q.y, qy ) );
if( bnStatusError( bnStatus ) )
{
BN_CTX_end( bnCtx );
return( getBnStatus( bnStatus ) );
}
if( !ecp_pt_smul_naf( &ctx, &u2q, u2 ) )
{
BN_CTX_end( bnCtx );
return( CRYPT_ERROR_FAILED );
}
/* Point (x1, y1) = u1G + u2Q */
if( !ecp_pt_add( &ctx, &u1g, &u2q ) )
{
BN_CTX_end( bnCtx );
return( CRYPT_ERROR_FAILED );
}
/* Convert point (x1, y1) to an integer r':
r' = p((x1, y1)) mod n
= x1 mod n */
CK( BN_mod( u1, u1g.x, gr, bnCtx ) );
if( bnStatusError( bnStatus ) )
{
BN_CTX_end( bnCtx );
return( getBnStatus( bnStatus ) );
}
BN_CTX_end( bnCtx );
/* if r == r' signature is good */
return( BN_cmp( u1, r ) ? CRYPT_ERROR_SIGNATURE : CRYPT_OK );
}
/****************************************************************************
* *
* Key Management *
* *
****************************************************************************/
/* Load key components into an encryption context */
static int initKey( CONTEXT_INFO *contextInfoPtr, const void *key,
const int keyLength )
{
int status;
#ifndef USE_FIPS140
/* Load the key component from the external representation into the
internal bignums unless we're doing an internal load */
if( key != NULL )
{
PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
const CRYPT_PKCINFO_ECC *eccKey = ( CRYPT_PKCINFO_ECC * ) key;
contextInfoPtr->flags |= ( eccKey->isPublicKey ) ? \
CONTEXT_ISPUBLICKEY : CONTEXT_ISPRIVATEKEY;
status = extractBignum( &pkcInfo->eccParam_p, eccKey->p,
bitsToBytes( eccKey->pLen ),
ECCPARAM_MIN_P, ECCPARAM_MAX_P );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_a, eccKey->a,
bitsToBytes( eccKey->aLen ),
ECCPARAM_MIN_A, ECCPARAM_MAX_A );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_b, eccKey->b,
bitsToBytes( eccKey->bLen ),
ECCPARAM_MIN_B, ECCPARAM_MAX_B );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_gx, eccKey->gx,
bitsToBytes( eccKey->gxLen ),
ECCPARAM_MIN_GX, ECCPARAM_MAX_GX );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_gy, eccKey->gy,
bitsToBytes( eccKey->gyLen ),
ECCPARAM_MIN_GY, ECCPARAM_MAX_GY );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_r, eccKey->r,
bitsToBytes( eccKey->rLen ),
ECCPARAM_MIN_R, ECCPARAM_MAX_R );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_qx, eccKey->qx,
bitsToBytes( eccKey->qxLen ),
ECCPARAM_MIN_QX, ECCPARAM_MAX_QX );
if( cryptStatusOK( status ) )
status = extractBignum( &pkcInfo->eccParam_qy, eccKey->qy,
bitsToBytes( eccKey->qyLen ),
ECCPARAM_MIN_QY, ECCPARAM_MAX_QY );
if( cryptStatusOK( status ) && !eccKey->isPublicKey )
status = extractBignum( &pkcInfo->eccParam_d, eccKey->d,
bitsToBytes( eccKey->dLen ),
ECCPARAM_MIN_D, ECCPARAM_MAX_D );
contextInfoPtr->flags |= CONTEXT_PBO;
if( cryptStatusError( status ) )
return( status );
}
#endif /* USE_FIPS140 */
/* Complete the key checking and setup */
status = initECCkey( contextInfoPtr );
if( cryptStatusOK( status ) )
status = checkECCkey( contextInfoPtr );
if( cryptStatusOK( status ) )
status = contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr );
return( status );
}
/* Generate a key into an encryption context */
static int generateKey( CONTEXT_INFO *contextInfoPtr, const int keySizeBits )
{
int status;
status = generateECCkey( contextInfoPtr, keySizeBits );
if( cryptStatusOK( status ) &&
#ifndef USE_FIPS140
( contextInfoPtr->flags & CONTEXT_SIDECHANNELPROTECTION ) &&
#endif /* USE_FIPS140 */
!pairwiseConsistencyTest( contextInfoPtr ) )
{
assert( DEBUG_WARN );
status = CRYPT_ERROR_FAILED;
}
if( cryptStatusOK( status ) )
status = contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr );
return( status );
}
/****************************************************************************
* *
* Capability Access Routines *
* *
****************************************************************************/
static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
CRYPT_ALGO_ECDSA, bitsToBytes( 0 ), "ECDSA", 5,
MIN_PKCSIZE_ECC, bitsToBytes( 256 ), CRYPT_MAX_PKCSIZE_ECC,
selfTest, getDefaultInfo, NULL, NULL, initKey, generateKey,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, sign, sigCheck
};
const CAPABILITY_INFO *getECDSACapability( void )
{
return( &capabilityInfo );
}
#endif /* USE_ECC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -