⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpeckey.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpECKey.c,v 1.17 2002/10/24 00:22:00 ajivsov Exp $
____________________________________________________________________________*/
#include "pgpSDKBuildFlags.h"

/* This entire module is dependent on EC being enabled */
#if PGP_EC

#include "pgpConfig.h"
#include <string.h>
#include <stddef.h>

#include "pgpDebug.h"
#include "pgpKeyMisc.h"
#include "pgpECKey.h"
#include "bn.h"
#include "ec.h"
#include "pgpCFBPriv.h"
#include "pgpSymmetricCipherPriv.h"
#include "pgpHashPriv.h"
#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpPubKey.h"
#include "pgpRandomX9_17.h"
#include "pgpStr2Key.h"
#include "pgpContext.h"
#include "pgpEnv.h"
#include "pgpEndianConversion.h"
#include "pgpFIPSPriv.h"



#define ASSERTEC(alg) pgpAssert( \
			      (ALGMASK(alg))==kPGPPublicKeyAlgorithm_ECEncrypt || \
			      (ALGMASK(alg))==kPGPPublicKeyAlgorithm_ECSign)
#define ASSERTECSIG(alg) \
		pgpAssert((ALGMASK(alg))==kPGPPublicKeyAlgorithm_ECSign)
#define ASSERTECENC(alg) \
		pgpAssert((ALGMASK(alg))==kPGPPublicKeyAlgorithm_ECEncrypt)


/* Size of encryption mask buffer - big enough to hold 256 bit keys */
#define MASKBUF_SIZE	40

/* Defines for ecScalars and BigNums */
#define SECURE		1
#define INSECURE	0


/* A structure to hold a public key */
typedef struct ECpub
{
	ecContextRef	ec;			/* Context */
	ecPointRef		y;			/* Public point */
	ecPointRef		g;			/* Generator */
	ecScalarRef		order;		/* Order of generator */
	PGPUInt32		cofactor;	/* # curve points / order */
	DEBUG_STRUCT_CONSTRUCTOR( ECpub )
} ECpub;

/* A structure to hold a secret key */
typedef struct ECsec
{
	ecContextRef	ec;			/* Context */
	ecPointRef		y;			/* Public point */
	ecPointRef		g;			/* Generator */
	ecScalarRef		order;		/* Order of generator */
	PGPUInt32		cofactor;	/* # curve points / order */
	ecScalarRef		x;			/* Private exponent */
	DEBUG_STRUCT_CONSTRUCTOR( ECsec )
} ECsec ;




/* A PGPSecKey's priv points to this, an ECsec plus the encrypted form... */
/* This struct is always allocated using PGPNewSecureData */
typedef struct ECsecPlus
{
	PGPContextRef	context;
	
	ECsec			s;
	PGPByte *		cryptkey;
	PGPSize			ckalloc;
	PGPSize			cklen;
	int				locked;
	DEBUG_STRUCT_CONSTRUCTOR( ECsecPlus )
} ECsecPlus ;



/** Predefined curves **/

#define BITSIZE1	163
#define NAME1		"sect163r2"
#define COFACTOR1	2
static PGPUInt32 nistb1[] = {
 0x4a3205fd, 0x512f7874, 0x1481eb10, 0xb8c953ca, 0x0a601907, 0x02
};
static PGPByte nistg1[] = {
    0x03, 0x03, 0xF0, 0xEB, 0xA1, 0x62,
	0x86, 0xA2, 0xD5, 0x7E, 0xA0, 0x99, 0x11, 0x68,
	0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E, 0x36
};
static PGPByte nisto1[] = {
    0x04, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, 0xFE,
	0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C, 0x33
};

#define BITSIZE2	283
#define NAME2		"sect283r1"
#define COFACTOR2	2
static PGPUInt32 nistb2[] = {
	0x3B79A2F5,
	0xF6263E31, 0xA581485A, 0x45309FA2, 0xCA97FD76,
	0x19A0303F, 0xA5A4AF8A, 0xC8B8596D, 0x027B680A
};
static PGPByte nistg2[] = {
    0x03, 0x05, 0xF9, 0x39, 0x25,
	0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, 0x4F, 0x8C,
	0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8,
	0x55, 0x7E, 0xAC, 0x9C, 0x80, 0xE2, 0xE1, 0x98,
	0xF8, 0xCD, 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53
};
static PGPByte nisto2[] = {
    0x03, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90,
	0x39, 0x96, 0x60, 0xFC, 0x93, 0x8A, 0x90, 0x16,
	0x5B, 0x04, 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07
};


typedef struct ECcurve
{
	PGPUInt32		bitsize;
	const char		*name;
	PGPUInt32		cofactor;
	PGPUInt32		a;
	PGPUInt32		*b;
	PGPByte			*g;
	PGPByte			*order;
	DEBUG_STRUCT_CONSTRUCTOR( ECcurve )
} ECcurve ;

static ECcurve sCurves[] = {
	{ BITSIZE1, NAME1, COFACTOR1, 1, nistb1, nistg1, nisto1 },
	{ BITSIZE2, NAME2, COFACTOR2, 1, nistb2, nistg2, nisto2 }
};



/** Elliptic Curve / BigNum conversion functions **/


/* Convert an EC scalar into a BigNum */
	static PGPError
sScalartoBN( ecScalarRef ec, BigNum *bn, PGPMemoryMgrRef mgr,
			   PGPUInt32 scalarSize )
{
	PGPByte *buf;

	buf = PGPNewSecureData( mgr, scalarSize, 0 );
	if( buf == NULL )
		return kPGPError_OutOfMemory;
	if( ecScalarExtractBytes( ec, buf ) < 0
		|| bnInsertBigBytes( bn, buf, 0, scalarSize ) < 0 )
	{
		PGPFreeData( buf );
		return kPGPError_OutOfMemory;
	}
	PGPFreeData( buf );
	return kPGPError_NoErr;
}

/* Convert an EC point into a BigNum */
	static PGPError
sPointtoBN( ecPointRef ec, BigNum *bn, PGPMemoryMgrRef mgr,
			   PGPUInt32 pointSize )
{
	PGPByte *buf;

	buf = PGPNewSecureData( mgr, pointSize, 0 );
	if( buf == NULL )
		return kPGPError_OutOfMemory;
	if( ecPointCompress( ec ) < 0
		|| ecPointExtractBytes( ec, buf, 0 ) < 0
		|| bnInsertBigBytes( bn, buf, 0, pointSize ) < 0 )
	{
		PGPFreeData( buf );
		return kPGPError_OutOfMemory;
	}
	PGPFreeData( buf );
	return kPGPError_NoErr;
}

/* Convert an EC point's X coordinate into a BigNum */
	static PGPError
sPointXtoBN( ecPointRef ec, BigNum *bn, PGPMemoryMgrRef mgr,
			   PGPUInt32 coordSize )
{
	PGPByte *buf;

	buf = PGPNewSecureData( mgr, coordSize, 0 );
	if( buf == NULL )
		return kPGPError_OutOfMemory;
	if( ecPointExtractXYBytes( ec, buf, NULL, 0 ) < 0 ||
		bnInsertBigBytes( bn, buf, 0, coordSize ) < 0 )
	{
		PGPFreeData( buf );
		return kPGPError_OutOfMemory;
	}
	PGPFreeData( buf );
	return kPGPError_NoErr;
}

/* Convert a BigNum into an EC scalar */
	static PGPError
sBNtoScalar( BigNum *bn, ecScalarRef ec, PGPMemoryMgrRef mgr,
			   PGPUInt32 scalarSize )
{
	PGPByte *buf;

	buf = PGPNewSecureData( mgr, scalarSize, 0 );
	if( buf == NULL )
		return kPGPError_OutOfMemory;

	bnExtractBigBytes( bn, buf, 0, scalarSize );
	if( ecScalarInsertBytes( ec, buf, NULL ) < 0 )
	{
		PGPFreeData( buf );
		return kPGPError_OutOfMemory;
	}
	PGPFreeData( buf );
	return kPGPError_NoErr;
}

/* Convert a BigNum into an EC point */
	static PGPError
sBNtoPoint( BigNum *bn, ecPointRef ec, PGPMemoryMgrRef mgr,
			   PGPUInt32 pointSize )
{
	PGPByte *buf;

	buf = PGPNewSecureData( mgr, pointSize, 0 );
	if( buf == NULL )
		return kPGPError_OutOfMemory;

	bnExtractBigBytes( bn, buf, 0, pointSize );
	if( ecPointInsertBytes( ec, buf, 0 ) < 0 )
	{
		PGPFreeData( buf );
		return kPGPError_OutOfMemory;
	}
	PGPFreeData( buf );
	return kPGPError_NoErr;
}


/** Search for known curves **/

	static PGPInt32
sCurveIndexFromBitsize( PGPUInt32 bitsize )
{
	PGPUInt32 i;

	for( i=0; i<sizeof(sCurves)/sizeof(sCurves[0]); ++i )
	{
		if( sCurves[i].bitsize == bitsize )
			return (PGPInt32)i;
	}
	return -1;
}

	static PGPInt32
sCurveIndexFromScalarsize( PGPUInt32 scalarsize )
{
	PGPUInt32 i;

	for( i=0; i<sizeof(sCurves)/sizeof(sCurves[0]); ++i )
	{
		if( (sCurves[i].bitsize+7)/8 == scalarsize )
			return (PGPInt32)i;
	}
	return -1;
}

	static PGPInt32
sCurveIndexFromName( const char * name, PGPSize namelen )
{
	PGPUInt32 i;

	for( i=0; i<sizeof(sCurves)/sizeof(sCurves[0]); ++i )
	{
		if( strlen( sCurves[i].name ) == namelen
			&& strncmp( sCurves[i].name, name, namelen ) == 0 )
			return (PGPInt32)i;
	}
	return -1;
}

/* Special entry point used by keyring parsing code to get bitsize */
	PGPInt32
pgpECurveBitsFromName( const char * name, PGPSize namelen )
{
	PGPUInt32 i;

	for( i=0; i<sizeof(sCurves)/sizeof(sCurves[0]); ++i )
	{
		if( strlen( sCurves[i].name ) == namelen
			&& strncmp( sCurves[i].name, name, namelen ) == 0 )
			return sCurves[i].bitsize;
	}
	return -1;
}


/* Create mask buffer for EC encrypt/decrypt from shared secret curve
 * point and hash algorithm.  Use algorithm MGF1 from IEEE P1363.
 */
static PGPError
sFillEncryptMaskBuf( PGPContextRef context, ecPointRef ec,
					 PGPSize coordSize, PGPHashAlgorithm hashalg,
					 PGPByte *hashbuf, PGPSize hashbuflen )
{
	PGPHashContextRef	hc;
	PGPSize				hashsize;
	PGPUInt32			counter;
	PGPByte				counterbuf[4];
	void				*hbuf = NULL;
	void				*xbuf = NULL;
	PGPUInt32			off;
	PGPMemoryMgrRef		mgr = PGPPeekContextMemoryMgr( context );
	PGPError			err = kPGPError_NoErr;

	err = PGPNewHashContext( context, hashalg, &hc );
	pgpAssert( IsntPGPError( err ) );

	PGPGetHashSize( hc, &hashsize );

	/* Get X coordinate as shared secret */
	xbuf = PGPNewSecureData( mgr, coordSize, 0 );
	if( IsNull( xbuf ) ) {
		err = kPGPError_OutOfMemory;
		goto error;
	}
	if( ecPointExtractXYBytes( ec, xbuf, NULL, 0 ) < 0 ) {
		err = kPGPError_BadParams;
		goto error;
	}

	hbuf = PGPNewSecureData( mgr, hashsize, 0 );
	if( IsNull( hbuf ) ) {
		err = kPGPError_OutOfMemory;
		goto error;
	}

	counter = 0;
	for( off = 0; off < hashbuflen; off += hashsize )
	{
		PGPUInt32ToEndian( counter++, kPGPBigEndian, counterbuf );
		PGPContinueHash( hc, counterbuf, sizeof(counterbuf) );
		PGPContinueHash( hc, xbuf, coordSize );
		PGPFinalizeHash( hc, hbuf );
		pgpCopyMemory( hbuf, hashbuf+off, pgpMin(hashsize,hashbuflen-off) );
	}

 error:
	if( IsntNull( hbuf ) )
		PGPFreeData( hbuf );
	if( IsntNull( xbuf ) )
		PGPFreeData( xbuf );
	PGPFreeHashContext( hc );

	return err;
}



/** Public key functions **/

static void
ecPubDestroy(PGPPubKey *pubkey)
{
	ECpub *pub = (ECpub *)pubkey->priv;
	PGPContextRef	context;

	pgpAssertAddrValid( pubkey, PGPPubKey );
	context	= pubkey->context;

	ASSERTEC(pubkey->pkAlg);
	
	ecPointFree( pub->y );
	ecPointFree( pub->g );
	ecScalarFree( pub->order );
	ecFreeContext( pub->ec );
	pgpClearMemory( pub,  sizeof(pub));
	pgpContextMemFree( context, pub);
	pgpClearMemory( pubkey,  sizeof(pubkey));
	pgpContextMemFree(context, pubkey);
}

/* Return the largest possible PGPESK size for a given key */
static PGPSize
ecPubMaxesk(PGPPubKey const *pubkey, PGPPublicKeyMessageFormat format)
{
	ECpub const *pub = (ECpub *)pubkey->priv;
	PGPUInt32 pointSize;

	ASSERTECENC(pubkey->pkAlg);

	ecGetBufferSize( pub->ec, NULL, NULL, NULL, &pointSize );

	if (format == kPGPPublicKeyMessageFormat_PGP)
		return 1 + 2 + pointSize + 2 + MASKBUF_SIZE;
	else if (format == kPGPPublicKeyMessageFormat_PKCS1 ||
			 format == kPGPPublicKeyMessageFormat_IKE)
		return 1 + pointSize + MASKBUF_SIZE;
	else if (format == kPGPPublicKeyMessageFormat_X509) {
		/* SEQUENCE, length, INT, INT */
		PGPUInt32 len;
		len = pgpBnX509LenLen(pointSize+1) + 1 + pointSize+1 +
			pgpBnX509LenLen(MASKBUF_SIZE+1) + 1 + MASKBUF_SIZE+1;
		return 1 + 1 + pgpBnX509LenLen(len) + len;
	}
	pgpAssert(0);
	return 0;
}

/* Return the largest possible input size for ecEncrypt */
static PGPSize
ecPubMaxdecrypted(PGPPubKey const *pubkey, PGPPublicKeyMessageFormat format)
{
	(void) format;
	ASSERTECENC(pubkey->pkAlg);

	return MASKBUF_SIZE - 3;
}

/* Return the largest possible signature input to ecVerify */
static PGPSize
ecPubMaxsig(PGPPubKey const *pubkey, PGPPublicKeyMessageFormat format)
{
	ECpub const *pub = (ECpub *)pubkey->priv;
	PGPUInt32 scalarSize;

	ASSERTECSIG(pubkey->pkAlg);

	ecGetBufferSize( pub->ec, NULL, &scalarSize, NULL, NULL );
	if (format == kPGPPublicKeyMessageFormat_PGP)
		return 2*( 2 + scalarSize );
	else if (format == kPGPPublicKeyMessageFormat_PKCS1 ||
			 format == kPGPPublicKeyMessageFormat_IKE)
		return 2 * scalarSize;
	else if (format == kPGPPublicKeyMessageFormat_X509) {
		/* SEQUENCE, length, INT, INT */
		PGPUInt32 len;
		len = 2*(pgpBnX509LenLen(scalarSize+1) + 1 + scalarSize+1);
		return 1 + pgpBnX509LenLen(len) + len;
	}
	pgpAssert(0);
	return 0;
}

/*
 * Set keyid
 */
static void
ecPubSetKeyID(PGPPubKey *pubkey, PGPByte *keyid)
{
	pgpCopyMemory(keyid, pubkey->keyID, sizeof(pubkey->keyID));
}


static int
ecPubParams(PGPPubKey const *pubkey,
	BigNum *x1, BigNum *x2, BigNum *x3, BigNum *x4, BigNum *x5, BigNum *x6,
	BigNum *x7, BigNum *x8)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -