@@ -8672,20 +8672,8 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
86728672}
86738673
86748674
8675- /* Compute the shared key from the private key and peer's public key.
8676- *
8677- * Return code compliant with OpenSSL.
8678- * OpenSSL returns 0 when number of bits in p are smaller than minimum
8679- * supported.
8680- *
8681- * @param [out] key Buffer to place shared key.
8682- * @param [in] otherPub Peer's public key.
8683- * @param [in] dh DH key containing private key.
8684- * @return -1 on error.
8685- * @return Size of shared secret in bytes on success.
8686- */
8687- int wolfSSL_DH_compute_key (unsigned char * key , const WOLFSSL_BIGNUM * otherPub ,
8688- WOLFSSL_DH * dh )
8675+ static int _DH_compute_key (unsigned char * key , const WOLFSSL_BIGNUM * otherPub ,
8676+ WOLFSSL_DH * dh , int ct )
86898677{
86908678 int ret = 0 ;
86918679 word32 keySz = 0 ;
@@ -8773,10 +8761,39 @@ int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
87738761
87748762 PRIVATE_KEY_UNLOCK ();
87758763 /* Calculate shared secret from private and public keys. */
8776- if ((ret == 0 ) && (wc_DhAgree ((DhKey * )dh -> internal , key , & keySz , priv ,
8777- (word32 )privSz , pub , (word32 )pubSz ) < 0 )) {
8778- WOLFSSL_ERROR_MSG ("wc_DhAgree failed" );
8779- ret = WOLFSSL_FATAL_ERROR ;
8764+ if (ret == 0 ) {
8765+ word32 padded_keySz = keySz ;
8766+ #if (!defined(HAVE_FIPS ) || FIPS_VERSION_GE (7 ,0 )) && !defined(HAVE_SELFTEST )
8767+ if (ct ) {
8768+ if (wc_DhAgree_ct ((DhKey * )dh -> internal , key , & keySz , priv ,
8769+ (word32 )privSz , pub , (word32 )pubSz ) < 0 ) {
8770+ WOLFSSL_ERROR_MSG ("wc_DhAgree_ct failed" );
8771+ ret = WOLFSSL_FATAL_ERROR ;
8772+ }
8773+ }
8774+ else
8775+ #endif /* (!HAVE_FIPS || FIPS_VERSION_GE(7,0)) && !HAVE_SELFTEST */
8776+ {
8777+ if (wc_DhAgree ((DhKey * )dh -> internal , key , & keySz , priv ,
8778+ (word32 )privSz , pub , (word32 )pubSz ) < 0 ) {
8779+ WOLFSSL_ERROR_MSG ("wc_DhAgree failed" );
8780+ ret = WOLFSSL_FATAL_ERROR ;
8781+ }
8782+ }
8783+
8784+ if ((ret == 0 ) && ct ) {
8785+ /* Arrange for correct fixed-length, right-justified key, even if
8786+ * the crypto back end doesn't support it. With some crypto back
8787+ * ends this forgoes formal constant-timeness on the key agreement,
8788+ * but assured that wolfSSL_DH_compute_key_padded() functions
8789+ * correctly.
8790+ */
8791+ if (keySz < padded_keySz ) {
8792+ XMEMMOVE (key , key + (padded_keySz - keySz ),
8793+ padded_keySz - keySz );
8794+ XMEMSET (key , 0 , padded_keySz - keySz );
8795+ }
8796+ }
87808797 }
87818798 if (ret == 0 ) {
87828799 /* Return actual length. */
@@ -8800,6 +8817,45 @@ int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
88008817
88018818 return ret ;
88028819}
8820+
8821+ /* Compute the shared key from the private key and peer's public key.
8822+ *
8823+ * Return code compliant with OpenSSL.
8824+ * OpenSSL returns 0 when number of bits in p are smaller than minimum
8825+ * supported.
8826+ *
8827+ * @param [out] key Buffer to place shared key.
8828+ * @param [in] otherPub Peer's public key.
8829+ * @param [in] dh DH key containing private key.
8830+ * @return -1 on error.
8831+ * @return Size of shared secret in bytes on success.
8832+ */
8833+ int wolfSSL_DH_compute_key (unsigned char * key , const WOLFSSL_BIGNUM * otherPub ,
8834+ WOLFSSL_DH * dh )
8835+ {
8836+ return _DH_compute_key (key , otherPub , dh , 0 );
8837+ }
8838+
8839+ /* Compute the shared key from the private key and peer's public key as in
8840+ * wolfSSL_DH_compute_key, but using constant time processing, with an output
8841+ * key length fixed at the nominal DH key size. Leading zeros are retained.
8842+ *
8843+ * Return code compliant with OpenSSL.
8844+ * OpenSSL returns 0 when number of bits in p are smaller than minimum
8845+ * supported.
8846+ *
8847+ * @param [out] key Buffer to place shared key.
8848+ * @param [in] otherPub Peer's public key.
8849+ * @param [in] dh DH key containing private key.
8850+ * @return -1 on error.
8851+ * @return Size of shared secret in bytes on success.
8852+ */
8853+ int wolfSSL_DH_compute_key_padded (unsigned char * key ,
8854+ const WOLFSSL_BIGNUM * otherPub , WOLFSSL_DH * dh )
8855+ {
8856+ return _DH_compute_key (key , otherPub , dh , 1 );
8857+ }
8858+
88038859#endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) ||
88048860 * HAVE_FIPS_VERSION > 2 */
88058861
0 commit comments