@@ -2058,44 +2058,19 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
20582058#endif
20592059
20602060#ifdef WOLFSSL_HAVE_SP_DH
2061+ if (0
20612062#ifndef WOLFSSL_SP_NO_2048
2062- if (mp_count_bits (& key -> p ) == 2048 ) {
2063- if (mp_init (y ) != MP_OKAY )
2064- ret = MP_INIT_E ;
2065-
2066- if (ret == 0 ) {
2067- SAVE_VECTOR_REGISTERS (ret = _svr_ret ;);
2068-
2069- if (ret == 0 && mp_read_unsigned_bin (y , otherPub , pubSz ) != MP_OKAY )
2070- ret = MP_READ_E ;
2071-
2072- if (ret == 0 )
2073- ret = sp_DhExp_2048 (y , priv , privSz , & key -> p , agree , agreeSz );
2074-
2075- mp_clear (y );
2076-
2077- RESTORE_VECTOR_REGISTERS ();
2078- }
2079-
2080- /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */
2081- if ((ret == 0 ) &&
2082- ((* agreeSz == 0 ) || ((* agreeSz == 1 ) && (agree [0 ] == 1 ))))
2083- {
2084- ret = MP_VAL ;
2085- }
2086-
2087- #if defined(WOLFSSL_SMALL_STACK ) && !defined(WOLFSSL_NO_MALLOC )
2088- #if !defined(WOLFSSL_SP_MATH )
2089- XFREE (z , key -> heap , DYNAMIC_TYPE_DH );
2090- XFREE (x , key -> heap , DYNAMIC_TYPE_DH );
2091- #endif
2092- XFREE (y , key -> heap , DYNAMIC_TYPE_DH );
2093- #endif
2094- return ret ;
2095- }
2063+ || mp_count_bits (& key -> p ) == 2048
20962064#endif
20972065#ifndef WOLFSSL_SP_NO_3072
2098- if (mp_count_bits (& key -> p ) == 3072 ) {
2066+ || mp_count_bits (& key -> p ) == 3072
2067+ #endif
2068+ #ifdef WOLFSSL_SP_4096
2069+ || mp_count_bits (& key -> p ) == 4096
2070+ #endif
2071+ ) {
2072+ int i = (int )* agreeSz - 1 ;
2073+
20992074 if (mp_init (y ) != MP_OKAY )
21002075 ret = MP_INIT_E ;
21012076
@@ -2105,8 +2080,26 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
21052080 if (ret == 0 && mp_read_unsigned_bin (y , otherPub , pubSz ) != MP_OKAY )
21062081 ret = MP_READ_E ;
21072082
2108- if (ret == 0 )
2109- ret = sp_DhExp_3072 (y , priv , privSz , & key -> p , agree , agreeSz );
2083+ if (ret == 0 ) {
2084+ #ifndef WOLFSSL_SP_NO_2048
2085+ if (mp_count_bits (& key -> p ) == 2048 ) {
2086+ ret = sp_DhExp_2048 (y , priv , privSz , & key -> p , agree ,
2087+ agreeSz );
2088+ }
2089+ #endif
2090+ #ifndef WOLFSSL_SP_NO_3072
2091+ if (mp_count_bits (& key -> p ) == 3072 ) {
2092+ ret = sp_DhExp_3072 (y , priv , privSz , & key -> p , agree ,
2093+ agreeSz );
2094+ }
2095+ #endif
2096+ #ifdef WOLFSSL_SP_4096
2097+ if (mp_count_bits (& key -> p ) == 4096 ) {
2098+ ret = sp_DhExp_4096 (y , priv , privSz , & key -> p , agree ,
2099+ agreeSz );
2100+ }
2101+ #endif
2102+ }
21102103
21112104 mp_clear (y );
21122105
@@ -2120,40 +2113,16 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
21202113 ret = MP_VAL ;
21212114 }
21222115
2123- #if defined(WOLFSSL_SMALL_STACK ) && !defined(WOLFSSL_NO_MALLOC )
2124- #if !defined(WOLFSSL_SP_MATH )
2125- XFREE (z , key -> heap , DYNAMIC_TYPE_DH );
2126- XFREE (x , key -> heap , DYNAMIC_TYPE_DH );
2127- #endif
2128- XFREE (y , key -> heap , DYNAMIC_TYPE_DH );
2129- #endif
2130- return ret ;
2131- }
2132- #endif
2133- #ifdef WOLFSSL_SP_4096
2134- if (mp_count_bits (& key -> p ) == 4096 ) {
2135- if (mp_init (y ) != MP_OKAY )
2136- ret = MP_INIT_E ;
2137-
2138- if (ret == 0 ) {
2139- SAVE_VECTOR_REGISTERS (ret = _svr_ret ;);
2140-
2141- if (ret == 0 && mp_read_unsigned_bin (y , otherPub , pubSz ) != MP_OKAY )
2142- ret = MP_READ_E ;
2143-
2144- if (ret == 0 )
2145- ret = sp_DhExp_4096 (y , priv , privSz , & key -> p , agree , agreeSz );
2146-
2147- mp_clear (y );
2148-
2149- RESTORE_VECTOR_REGISTERS ();
2150- }
2116+ if ((ret == 0 ) && ct ) {
2117+ word16 mask = 0xff ;
2118+ sword16 o = (sword16 )(* agreeSz - 1 );
21512119
2152- /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */
2153- if ((ret == 0 ) &&
2154- ((* agreeSz == 0 ) || ((* agreeSz == 1 ) && (agree [0 ] == 1 ))))
2155- {
2156- ret = MP_VAL ;
2120+ * agreeSz = (word32 )(i + 1 );
2121+ for (; i >= 0 ; i -- ) {
2122+ agree [i ] = agree [o ] & (byte )mask ;
2123+ mask = ctMask16LT (0 , (int )o );
2124+ o = (sword16 )(o + (sword16 )mask );
2125+ }
21572126 }
21582127
21592128 #if defined(WOLFSSL_SMALL_STACK ) && !defined(WOLFSSL_NO_MALLOC )
@@ -2166,16 +2135,8 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
21662135 return ret ;
21672136 }
21682137#endif
2169- #endif
21702138
21712139#if !defined(WOLFSSL_SP_MATH )
2172- if (ct ) {
2173- /* for the constant-time variant, we will probably use more bits in x for
2174- * the modexp than we read from the private key, and those extra bits need
2175- * to be zeroed.
2176- */
2177- XMEMSET (x , 0 , sizeof * x );
2178- }
21792140 if (mp_init_multi (x , y , z , 0 , 0 , 0 ) != MP_OKAY ) {
21802141 #if defined(WOLFSSL_SMALL_STACK ) && !defined(WOLFSSL_NO_MALLOC )
21812142 XFREE (z , key -> heap , DYNAMIC_TYPE_DH );
@@ -2184,6 +2145,14 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
21842145 #endif
21852146 return MP_INIT_E ;
21862147 }
2148+ #if defined(WOLFSSL_SP_MATH_ALL )
2149+ if (ct ) {
2150+ /* TFM and Integer implementations keep high words zero.
2151+ * SP math implementation needs all words set to zero as it doesn't
2152+ * ensure unused words are zero. */
2153+ mp_forcezero (x );
2154+ }
2155+ #endif
21872156
21882157 SAVE_VECTOR_REGISTERS (ret = _svr_ret ;);
21892158
@@ -2198,12 +2167,24 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
21982167 ret = MP_READ_E ;
21992168
22002169 if (ret == 0 ) {
2201- if (ct )
2202- ret = mp_exptmod_ex (y , x ,
2203- ((int )* agreeSz + DIGIT_BIT - 1 ) / DIGIT_BIT ,
2170+ if (ct ) {
2171+ int bits ;
2172+
2173+ /* x is mod q but if q not available, use p (> q). */
2174+ if (mp_iszero (& key -> q ) == MP_NO ) {
2175+ bits = mp_count_bits (& key -> q );
2176+ }
2177+ else {
2178+ bits = mp_count_bits (& key -> p );
2179+ }
2180+ /* Exponentiate to the maximum words of a valid x to ensure a
2181+ * constant time operation. */
2182+ ret = mp_exptmod_ex (y , x , (bits + DIGIT_BIT - 1 ) / DIGIT_BIT ,
22042183 & key -> p , z );
2205- else
2184+ }
2185+ else {
22062186 ret = mp_exptmod (y , x , & key -> p , z );
2187+ }
22072188 if (ret != MP_OKAY )
22082189 ret = MP_EXPTMOD_E ;
22092190 }
@@ -2219,6 +2200,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
22192200
22202201 if (ret == 0 ) {
22212202 if (ct ) {
2203+ /* Put the secret into a buffer in constant time. */
22222204 ret = mp_to_unsigned_bin_len_ct (z , agree , (int )* agreeSz );
22232205 }
22242206 else {
@@ -2316,7 +2298,8 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
23162298#else
23172299#if defined(WOLFSSL_ASYNC_CRYPT ) && defined(WC_ASYNC_ENABLE_DH )
23182300 if (key -> asyncDev .marker == WOLFSSL_ASYNC_MARKER_DH ) {
2319- ret = wc_DhAgree_Async (key , agree , agreeSz , priv , privSz , otherPub , pubSz );
2301+ ret = wc_DhAgree_Async (key , agree , agreeSz , priv , privSz , otherPub ,
2302+ pubSz );
23202303 }
23212304 else
23222305#endif
@@ -2332,56 +2315,21 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
23322315int wc_DhAgree_ct (DhKey * key , byte * agree , word32 * agreeSz , const byte * priv ,
23332316 word32 privSz , const byte * otherPub , word32 pubSz )
23342317{
2335- int ret ;
23362318 word32 requested_agreeSz ;
2337- #ifndef WOLFSSL_NO_MALLOC
2338- byte * agree_buffer = NULL ;
2339- #else
2340- byte agree_buffer [DH_MAX_SIZE / 8 ];
2341- #endif
23422319
23432320 if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
23442321 otherPub == NULL ) {
23452322 return BAD_FUNC_ARG ;
23462323 }
23472324
2348- requested_agreeSz = * agreeSz ;
2349-
2350- #ifndef WOLFSSL_NO_MALLOC
2351- agree_buffer = (byte * )XMALLOC (requested_agreeSz , key -> heap ,
2352- DYNAMIC_TYPE_DH );
2353- if (agree_buffer == NULL )
2354- return MEMORY_E ;
2355- #endif
2356-
2357- XMEMSET (agree_buffer , 0 , requested_agreeSz );
2358-
2359- ret = wc_DhAgree_Sync (key , agree_buffer , agreeSz , priv , privSz , otherPub ,
2360- pubSz , 1 );
2361-
2362- if (ret == 0 ) {
2363- /* Arrange for correct fixed-length, right-justified key, even if the
2364- * crypto back end doesn't support it. This assures that the key is
2365- * unconditionally agreed correctly. With some crypto back ends,
2366- * e.g. heapmath, there are no provisions for actual constant time, but
2367- * with others the key computation and clamping is constant time, and
2368- * the unclamping here is also constant time.
2369- */
2370- byte * agree_src = agree_buffer + * agreeSz - 1 ,
2371- * agree_dst = agree + requested_agreeSz - 1 ;
2372- while (agree_dst >= agree ) {
2373- word32 mask = (agree_src >= agree_buffer ) - 1U ;
2374- agree_src += (mask & requested_agreeSz );
2375- * agree_dst -- = * agree_src -- ;
2376- }
2377- * agreeSz = requested_agreeSz ;
2325+ requested_agreeSz = (word32 )mp_unsigned_bin_size (& key -> p );
2326+ if (requested_agreeSz > * agreeSz ) {
2327+ return BUFFER_E ;
23782328 }
2329+ * agreeSz = requested_agreeSz ;
23792330
2380- #ifndef WOLFSSL_NO_MALLOC
2381- XFREE (agree_buffer , key -> heap , DYNAMIC_TYPE_DH );
2382- #endif
2383-
2384- return ret ;
2331+ return wc_DhAgree_Sync (key , agree , agreeSz , priv , privSz , otherPub , pubSz ,
2332+ 1 );
23852333}
23862334
23872335#ifdef WOLFSSL_DH_EXTRA
0 commit comments