/* Write a bignum as a fixed-length value, needed by SSH */ CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ static int writeFixedBignum( INOUT STREAM *stream, const BIGNUM *bignum, IN_LENGTH_SHORT_MIN( 20 ) const int fixedSize ) { BYTE buffer[ CRYPT_MAX_PKCSIZE + 8 ]; int bnLength, noZeroes, i, status; assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( isReadPtr( bignum, sizeof( BIGNUM ) ) ); REQUIRES( fixedSize >= 20 && fixedSize <= CRYPT_MAX_PKCSIZE ); /* Extract the bignum data and get its length */ status = exportBignum( buffer, CRYPT_MAX_PKCSIZE, &bnLength, bignum ); ENSURES( cryptStatusOK( status ) ); noZeroes = fixedSize - bnLength; REQUIRES( noZeroes >= 0 && noZeroes < fixedSize ); /* Write the leading zeroes followed by the bignum value */ for( i = 0; i < noZeroes; i++ ) sputc( stream, 0 ); status = swrite( stream, buffer, bnLength ); zeroise( buffer, CRYPT_MAX_PKCSIZE ); return( status ); } #endif /* USE_SSH */ /****************************************************************************
{ PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC; KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer; int status; assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); assert( isWritePtr( keyAgreeParams, sizeof( KEYAGREE_PARAMS ) ) ); REQUIRES( noBytes == sizeof( KEYAGREE_PARAMS ) ); REQUIRES( !BN_is_zero( &pkcInfo->dlpParam_y ) ); /* y is generated either at keygen time for static DH or as a side-effect of the implicit generation of the x value for ephemeral DH, so all we have to do is copy it to the output */ status = exportBignum( keyAgreeParams->publicValue, CRYPT_MAX_PKCSIZE, &keyAgreeParams->publicValueLen, &pkcInfo->dlpParam_y ); if( cryptStatusError( status ) ) return( status ); /* Perform side-channel attack checks if necessary */ if( ( contextInfoPtr->flags & CONTEXT_FLAG_SIDECHANNELPROTECTION ) && \ cryptStatusError( calculateBignumChecksum( pkcInfo, CRYPT_ALGO_DH ) ) ) { return( CRYPT_ERROR_FAILED ); } return( CRYPT_OK ); } /* Perform phase 2 of Diffie-Hellman ("import") */