Is it just me or is there absolutely NO documentation on this? I have searched the manual over and over looking for some information. Heaven forbid there should be an actual piece of example code lying around somewhere

. Finally, I resorted to looking at the source code and found *something* that looks like what I need, but it appears that these are all internal functions and not listed in the main cryptlib.h header that I've used previously.
This is what I found listed below though I can't get the damn thing to include without errors to save my life
The following functions are located in lib_dh.c in case anyone knows anything about the cryptlib library.
I am going to *assume* the first step will be to call dhInitKey... Can't vouch for that though as I can't get everything to compile w/o linker errors.
BTW, I don't really care what library I'm using... Feel free to suggest another one that has Diffie Hellman (with better documentation) if you know of one. At this point, ANY suggestions will be appreciated.
int dhInitKey( CRYPT_INFO *cryptInfo, const void *key, const int keyLength );
int dhEncrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes );
int dhDecrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes );
/****************************************************************************
* *
* Diffie-Hellman Key Exchange Routines *
* *
****************************************************************************/
/* Perform phase 1 of Diffie-Hellman ("export"

*/
int dhEncrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
BN_CTX *bnCTX;
int status = CRYPT_OK;
UNUSED( noBytes );
/* Usually y is generated as a side-effect of the implicit generation of
the x value, so if y is already set we just return its value */
if( !BN_is_zero( cryptInfo->ctxPKC.dlpParam_y ) )
{
keyAgreeParams->publicValueLen = \
BN_bn2bin( cryptInfo->ctxPKC.dlpParam_y,
keyAgreeParams->publicValue );
return( CRYPT_OK );
}
if( ( bnCTX = BN_CTX_new() ) == NULL )
return( CRYPT_ERROR_MEMORY );
/* Export y = g^x mod p. There is no input data since x was set when the
DH values were loaded */
BN_mod_exp( cryptInfo->ctxPKC.dlpParam_y, cryptInfo->ctxPKC.dlpParam_g,
cryptInfo->ctxPKC.dlpParam_x, cryptInfo->ctxPKC.dlpParam_p,
bnCTX );
keyAgreeParams->publicValueLen = \
BN_bn2bin( cryptInfo->ctxPKC.dlpParam_y,
keyAgreeParams->publicValue );
BN_CTX_free( bnCTX );
return( ( status == -1 ) ? CRYPT_ERROR_FAILED : status );
}
/* Perform phase 2 of Diffie-Hellman ("import"

*/
int dhDecrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
BN_CTX *bnCTX;
BIGNUM *z;
const int length = bitsToBytes( cryptInfo->ctxPKC.keySizeBits );
int i, status = CRYPT_OK;
/* Make sure we're not being fed suspiciously short data quantities */
for( i = 0; i < length; i++ )
if( keyAgreeParams->publicValue[ i ] )
break;
if( length - i < 56 )
return( CRYPT_ERROR_BADDATA );
if( ( bnCTX = BN_CTX_new() ) == NULL )
return( CRYPT_ERROR_MEMORY );
/* The other parties y value will be stored with the key agreement info
rather than having been read in when we read the DH public key */
BN_bin2bn( keyAgreeParams->publicValue, keyAgreeParams->publicValueLen,
cryptInfo->ctxPKC.dhParam_yPrime );
/* Export z = y^x mod p. We need to use separate y and z values because
the bignum code can't handle modexp with the first two parameters the
same */
z = BN_new();
BN_mod_exp( z, cryptInfo->ctxPKC.dhParam_yPrime,
cryptInfo->ctxPKC.dlpParam_x, cryptInfo->ctxPKC.dlpParam_p,
bnCTX );
keyAgreeParams->wrappedKeyLen = BN_bn2bin( z, keyAgreeParams->wrappedKey );
BN_clear_free( z );
#if 0
y = BN_new();
BN_bin2bn( buffer, length, y );
zeroise( buffer, length ); /* Clear buffer while data is in bignum */
BN_mod_exp( y, y, cryptInfo->ctxPKC.dlpParam_x,
cryptInfo->ctxPKC.dlpParam_p, bnCTX );
length = BN_bn2bin( y, buffer );
BN_clear_free( y );
#endif
BN_CTX_free( bnCTX );
return( ( status == -1 ) ? CRYPT_ERROR_FAILED : status );
}
/****************************************************************************
* *
* Diffie-Hellman Key Management Routines *
* *
****************************************************************************/
/* Load DH public key components into an encryption context */
int dhInitKey( CRYPT_INFO *cryptInfo, const void *key, const int keyLength )
{
CRYPT_PKCINFO_DLP *dhKey = ( CRYPT_PKCINFO_DLP * ) key;
int status;
/* Load the key component from the external representation into the
internal BigNums unless we're doing an internal load */
if( keyLength != sizeof( PKCINFO_LOADINTERNAL ) )
{
cryptInfo->ctxPKC.isPublicKey = dhKey->isPublicKey;
BN_bin2bn( dhKey->p, bitsToBytes( dhKey->pLen ),
cryptInfo->ctxPKC.dlpParam_p );
BN_bin2bn( dhKey->g, bitsToBytes( dhKey->gLen ),
cryptInfo->ctxPKC.dlpParam_g );
BN_bin2bn( dhKey->q, bitsToBytes( dhKey->qLen ),
cryptInfo->ctxPKC.dlpParam_q );
BN_bin2bn( dhKey->y, bitsToBytes( dhKey->yLen ),
cryptInfo->ctxPKC.dlpParam_y );
if( !dhKey->isPublicKey )
BN_bin2bn( dhKey->x, bitsToBytes( dhKey->xLen ),
cryptInfo->ctxPKC.dlpParam_x );
else
{
/* If there's no x value present, generate one implicitly. This
is needed because all DH keys are effectively private keys */
status = generateDLPKey( cryptInfo, CRYPT_UNUSED, CRYPT_UNUSED,
FALSE );
if( cryptStatusError( status ) )
return( status );
}
}
/* Check the parameters and calculate the key ID */
status = checkDLParams( cryptInfo, TRUE );
if( cryptStatusError( status ) )
return( status );
cryptInfo->ctxPKC.keySizeBits = BN_num_bits( cryptInfo->ctxPKC.dlpParam_p );
return( calculateKeyID( cryptInfo ) );
}
/* Generate a Diffie-Hellman key into an encryption context */
int dhGenerateKey( CRYPT_INFO *cryptInfo, const int keySizeBits )
{
int status;
status = generateDLPKey( cryptInfo, keySizeBits, CRYPT_USE_DEFAULT,
TRUE );
if( cryptStatusError( status ) )
return( status );
return( calculateKeyID( cryptInfo ) );
}
Thanks,
--an extremely frustrated,
Clandestiny