📄 pgpikeec.c
字号:
static PGPError sInitGroup9( PGPMemoryMgrRef memoryMgr,
PGPECContextRef *c283, PGPECPointRef *G,
unsigned *cofactor, PGPECScalarRef *orderG )
{
PGPError ret;
PGPECPointRef p;
PGPECCreate2mContext( memoryMgr, 283, kPGPECMemoryMedium, c283 );
PGPECPointCreate( *c283, G );
PGPECSetEC2mParamAInt( *c283, 0 );
PGPECSetEC2mParamBInt( *c283, 1 ); /* Koblitz curve */
*cofactor = 4;
PGPECPointInsertBytes( *G, (const void*)ec_9_G_283, 0 );
ret = PGPECPointDecompress( *G );
if( IsPGPError(ret) )
return ret;
/* decompressed OK */
PGPECPointPrefBasis( *G );
/* Check consistency of public parameters */
/* first, generator must be a valid EC point */
if( !PGPECPointIsConsistent( *G ) ) {
PGPECPointSetZero( *G );
return kPGPError_ImproperInitialization;
}
PGPECPointCreate( *c283, &p );
/* just initialized point is not a zero point */
pgpAssert( !PGPECPointIsZero(p) );
/* second, listed order must satisfy its properties */
PGPECScalarCreate( *c283, orderG, FALSE );
PGPECScalarInsertBytes( *orderG, ec_9_G_283_order, NULL );
ret = PGPECPointMul( *G, *orderG, FALSE, p );
if( IsntPGPError(ret) && !PGPECPointIsZero(p) )
ret = kPGPError_ImproperInitialization;
PGPECPointFree( p );
if( IsPGPError(ret) )
PGPECPointSetZero( *G );
return ret;
}
static PGPError sInitGroup10( PGPMemoryMgrRef memoryMgr,
PGPECContextRef *c409, PGPECPointRef *G,
unsigned *cofactor, PGPECScalarRef *orderG )
{
PGPError ret;
PGPECPointRef p;
PGPECCreate2mContext( memoryMgr, 409, kPGPECMemoryMedium, c409 );
PGPECPointCreate( *c409, G );
PGPECSetEC2mParamAInt( *c409, 1 );
PGPECSetEC2mParamB( *c409, ec_10_b_409 );
*cofactor = 2;
PGPECPointInsertBytes( *G, (const void*)ec_10_G_409, 0 );
ret = PGPECPointDecompress( *G );
if( IsPGPError(ret) )
return ret;
/* decompressed OK */
PGPECPointPrefBasis( *G );
/* Check consistency of public parameters */
/* first, generator must be a valid EC point */
if( !PGPECPointIsConsistent( *G ) )
{
PGPECPointSetZero( *G );
return kPGPError_ImproperInitialization;
}
PGPECPointCreate( *c409, &p );
/* just initialized point is not a zero point */
pgpAssert( !PGPECPointIsZero(p) );
/* second, listed order must satisfy its properties */
PGPECScalarCreate( *c409, orderG, FALSE );
PGPECScalarInsertBytes( *orderG, ec_10_G_409_order, NULL );
ret = PGPECPointMul( *G, *orderG, FALSE, p );
if( IsntPGPError(ret) && !PGPECPointIsZero(p) )
ret = kPGPError_ImproperInitialization;
PGPECPointFree( p );
if( IsPGPError(ret) )
PGPECPointSetZero( *G );
return ret;
}
static PGPError sInitGroup11( PGPMemoryMgrRef memoryMgr,
PGPECContextRef *c409, PGPECPointRef *G,
unsigned *cofactor, PGPECScalarRef *orderG )
{
PGPError ret;
PGPECPointRef p;
PGPECCreate2mContext( memoryMgr, 409, kPGPECMemoryMedium, c409 );
PGPECPointCreate( *c409, G );
PGPECSetEC2mParamAInt( *c409, 0 );
PGPECSetEC2mParamBInt( *c409, 1 ); /* Koblitz curve */
*cofactor = 4;
PGPECPointInsertBytes( *G, (const void*)ec_11_G_409, 0 );
ret = PGPECPointDecompress( *G );
if( IsPGPError(ret) )
return ret;
/* decompressed OK */
PGPECPointPrefBasis( *G );
/* Check consistency of public parameters */
/* first, generator must be a valid EC point */
if( !PGPECPointIsConsistent( *G ) ) {
PGPECPointSetZero( *G );
return kPGPError_ImproperInitialization;
}
PGPECPointCreate( *c409, &p );
/* just initialized point is not a zero point */
pgpAssert( !PGPECPointIsZero(p) );
/* second, listed order must satisfy its properties */
PGPECScalarCreate( *c409, orderG, FALSE );
PGPECScalarInsertBytes( *orderG, ec_11_G_409_order, NULL );
ret = PGPECPointMul( *G, *orderG, FALSE, p );
if( IsntPGPError(ret) && !PGPECPointIsZero(p) )
ret = kPGPError_ImproperInitialization;
PGPECPointFree( p );
if( IsPGPError(ret) )
PGPECPointSetZero( *G );
return ret;
}
PGPError pgpECIKEGetBufferSize( pgpECIKEContextRef c,
PGPSize *xSize, PGPSize *ySize, PGPSize *xySize )
{
PGPError ret;
pgpECIKEContextPriv *cc = (pgpECIKEContextPriv *)c;
ret = PGPECGetBufferSize( cc->c, xySize, xSize, NULL, ySize );
return ret;
}
PGPError pgpECIKE_DH1( pgpECIKEContextRef c,
const PGPByte *Xsecret,
PGPByte *Ypublic )
{
pgpECIKEContextPriv *cc = (pgpECIKEContextPriv *)c;
PGPError ret;
PGPECScalarInsertBytes( cc->secretX, Xsecret, cc->orderG );
ret = PGPECPointMul( cc->G, cc->secretX, FALSE, cc->myY );
if( IsntPGPError(ret) )
ret = PGPECPointCompress( cc->myY );
if( IsntPGPError(ret) )
ret = PGPECPointExtractBytes( cc->myY, Ypublic, 0 );
return ret;
}
PGPError pgpECIKE_import_Y( pgpECIKEContextRef c,
const PGPByte *Ypublic )
{
pgpECIKEContextPriv *cc = (pgpECIKEContextPriv *)c;
PGPError ret;
ret = PGPECPointInsertBytes( cc->hisY, Ypublic, 0 );
if( IsntPGPError(ret) )
ret = PGPECPointDecompress( cc->hisY );
if( IsntPGPError(ret) && !PGPECPointIsConsistent( cc->hisY ) )
return kPGPError_CorruptData; /* point is inconsistent */
/* security checks: */
if( PGPECPointIsZero(cc->hisY) )
ret = kPGPError_BadParams;
#if 0
/* Perform (expensive) check of the base point order only if we use
standard DH (not a DH with cofactor multiplication).
We may want to make it configuarable later */
ret = PGPECPointMul( cc->hisY, cc->orderG, FALSE, cc->out );
if( !PGPECPointIsZero(cc->out) )
ret = kPGPError_BadParams;
#endif
return ret;
}
/* get x*cofactor*y*G */
PGPError pgpECIKE_DH2( pgpECIKEContextRef c, PGPByte *out_secret )
{
pgpECIKEContextPriv *cc = (pgpECIKEContextPriv *)c;
PGPError ret;
int cofactor;
pgpAssert( PGPECPointIsConsistent( cc->hisY ) );
ret = PGPECPointMul( cc->hisY, cc->secretX, FALSE, cc->out );
/* account for cofactor */
if( IsntPGPError(ret) ) {
pgpAssert( cc->cofactor == 2 || cc->cofactor == 4 ); /* simplyfying... */
cofactor = cc->cofactor;
while( (cofactor-=2) >= 0 ) {
/* double the y*G */
ret = PGPECPointAdd( cc->out, cc->out, cc->out );
if( IsPGPError(ret) || PGPECPointIsZero(cc->out) ) {
ret = kPGPError_BadParams;
break;
}
}
}
if( IsntPGPError(ret) )
ret = PGPECPointExtractXYBytes( cc->out, out_secret, NULL, 0 );
return ret;
}
PGPError pgpECIKEInitContext( PGPMemoryMgrRef memoryMgr,
PGPUInt32 group, pgpECIKEContextRef *c )
{
pgpECIKEContextPriv *cc;
PGPECContextRef c1;
PGPECPointRef p1;
PGPError ret;
unsigned cofactor;
PGPECScalarRef orderG;
switch( group ) {
case 6:
ret = sInitGroup6( memoryMgr, &c1, &p1, &cofactor, &orderG );
break;
case 7:
ret = sInitGroup7( memoryMgr, &c1, &p1, &cofactor, &orderG );
break;
case 8:
ret = sInitGroup8( memoryMgr, &c1, &p1, &cofactor, &orderG );
break;
case 9:
ret = sInitGroup9( memoryMgr, &c1, &p1, &cofactor, &orderG );
break;
case 10:
ret = sInitGroup10( memoryMgr, &c1, &p1, &cofactor, &orderG );
break;
case 11:
ret = sInitGroup11( memoryMgr, &c1, &p1, &cofactor, &orderG );
break;
default:
return kPGPError_BadParams;
}
if( IsPGPError(ret) )
return ret;
cc = PGPNewData( memoryMgr, sizeof(pgpECIKEContextPriv), kPGPMemoryMgrFlags_Clear );
if( cc==NULL )
return kPGPError_OutOfMemory;
cc->c = c1;
cc->G = p1;
cc->cofactor = cofactor;
cc->orderG = orderG;
PGPECPointCreate( cc->c, &cc->myY );
PGPECPointCreate( cc->c, &cc->hisY );
PGPECPointCreate( cc->c, &cc->out );
PGPECScalarCreate( cc->c, &cc->secretX, TRUE /*isSecure*/ );
*c = (pgpECIKEContextRef)cc;
return ret;
}
PGPError pgpECIKEFreeContext( pgpECIKEContextRef c ) {
pgpECIKEContextPriv *pc = (pgpECIKEContextPriv*)c;
PGPECPointFree( pc->G );
PGPECPointFree( pc->myY );
PGPECPointFree( pc->hisY );
PGPECPointFree( pc->out );
PGPECScalarFree( pc->secretX );
PGPECScalarFree( pc->orderG );
PGPECFreeContext( pc->c );
PGPFreeData( c );
return kPGPError_NoErr;
}
#ifdef EC_TEST
void testEcIkeKe() {
pgpECIKEContextRef c1; /*peer 1*/
pgpECIKEContextRef c2; /*peer 2*/
unsigned xSize, expYSize, expXYSize;
int group = 11;
unsigned char *randBuf1;
unsigned char *pub1;
unsigned char *secret1_out;
unsigned char *randBuf2;
unsigned char *pub2;
unsigned char *secret2_out;
unsigned i;
i = pgpECIKEInitContext( NULL, group, &c1 );
printf( "pgpECIKEInitContext returned %d\n", i );
i = pgpECIKEInitContext( NULL, group, &c2 );
printf( "pgpECIKEInitContext returned %d\n", i );
if( i )
return;
pgpECIKEGetBufferSize( c1, &xSize, &expYSize, &expXYSize );
/* Align arrays for RISC systems */
xSize = (xSize & ~(sizeof(int)-1)) + sizeof(int);
expXYSize = (expXYSize & ~(sizeof(int)-1)) + sizeof(int); /* take only x from the xyG */
expYSize = (expYSize & ~(sizeof(int)-1)) + sizeof(int);
randBuf1 = calloc( ( xSize + expYSize + expXYSize) * 2, 1 );
pub1 = (unsigned char*)randBuf1 + xSize; /* expYSize size */
secret1_out = pub1 + expYSize; /* expXYSize size */
randBuf2 = secret1_out + expXYSize; /* xSize */
pub2 = (unsigned char*)randBuf2 + xSize; /* expYSize */
secret2_out = pub2 + expYSize; /* expXYSize size */
for( i=0; i<xSize-2; i+=2 ) {
*(unsigned short*)((unsigned char *)randBuf1+i) = rand();
}
for( i=0; i<xSize-2; i+=2 ) {
*(unsigned short*)((unsigned char *)randBuf2+i) = rand();
}
printf("Startup initialization for group %d completed\n", group);
pgpECIKE_DH1( c1, randBuf1, pub1 );
/* ... send pub1 to peer 2 */
printf(">");
pgpECIKE_DH1( c2, randBuf2, pub2 );
/* ... send pub2 to peer 1 */
printf("<");
pgpECIKE_import_Y( c1, pub2 );
pgpECIKE_DH2( c1, secret1_out );
printf(".");
pgpECIKE_import_Y( c2, pub1 );
pgpECIKE_DH2( c2, secret2_out );
printf(".");
/* Compare shared secret */
if( memcmp( secret1_out, secret2_out, expXYSize )!=0 )
printf( ">>> DH test failed!!!\a\n" );
else
printf("\nDone\n");
pgpECIKEFreeContext( c1 );
pgpECIKEFreeContext( c2 );
free( randBuf1 );
}
#endif /* EC_TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -