3737#include <errno.h>
3838#include <conv.h>
3939#include <zlib.h>
40+ #include <openssl/evp.h>
4041#ifdef HAVE_UNISTD_H
4142#include <unistd.h>
4243#endif
@@ -2350,15 +2351,43 @@ static cl_error_t generate_key_aes(const char *const password, encryption_key_t
23502351 encryption_verifier_t * verifier )
23512352{
23522353 uint8_t * buffer = NULL ;
2354+ uint8_t * heapBuffer = NULL ;
2355+ uint8_t stackBuffer [128 ] = {0 };
23532356 size_t bufLen = 0 ;
2357+ size_t passwordLen = 0 ;
23542358 cl_error_t ret = CL_ERROR ;
23552359 uint32_t i = 0 ;
2360+ size_t j = 0 ;
23562361 uint8_t sha1 [sizeof (uint32_t ) + SHA1_HASH_SIZE + sizeof (uint32_t )] = {0 };
23572362 uint8_t * sha1Dst = & (sha1 [sizeof (uint32_t )]);
23582363 uint8_t buf1 [64 ];
23592364 uint8_t buf2 [64 ];
23602365 uint8_t doubleSha [SHA1_HASH_SIZE * 2 ];
2361- uint32_t tmp = 0 ;
2366+ uint32_t tmp = 0 ;
2367+ EVP_MD_CTX * sha1_ctx = NULL ;
2368+
2369+ #if OPENSSL_VERSION_MAJOR >= 3
2370+ OSSL_LIB_CTX * ossl_ctx = NULL ;
2371+ EVP_MD * sha1_md = NULL ;
2372+ #else
2373+ const EVP_MD * sha1_md = NULL ;
2374+ #endif
2375+
2376+ #define SHA1_HASH_WITH_CTX (data , data_len , out ) \
2377+ do { \
2378+ if (!EVP_DigestInit_ex(sha1_ctx, sha1_md, NULL) || \
2379+ !EVP_DigestUpdate(sha1_ctx, (data), (data_len)) || \
2380+ !EVP_DigestFinal_ex(sha1_ctx, (out), NULL)) { \
2381+ cli_errmsg("ole2: SHA1 hash computation failed in generate_key_aes.\n"); \
2382+ goto done; \
2383+ } \
2384+ } while (0)
2385+
2386+ if (NULL == password || NULL == key || NULL == verifier ) {
2387+ cli_errmsg ("ole2: Invalid arguments to generate_key_aes\n" );
2388+ ret = CL_ENULLARG ;
2389+ goto done ;
2390+ }
23622391
23632392 if (!key_length_valid_aes_bits (key -> key_length_bits )) {
23642393 cli_errmsg ("ole2: Invalid key length '0x%x'\n" , key -> key_length_bits / 8 );
@@ -2367,15 +2396,56 @@ static cl_error_t generate_key_aes(const char *const password, encryption_key_t
23672396
23682397 memset (key -> key , 0 , key -> key_length_bits / 8 );
23692398
2370- bufLen = verifier -> salt_size + (strlen (password ) * 2 );
2399+ passwordLen = strlen (password );
2400+ if (passwordLen > ((SIZE_MAX - verifier -> salt_size ) / 2 )) {
2401+ cli_errmsg ("ole2: Password length overflow\n" );
2402+ ret = CL_EARG ;
2403+ goto done ;
2404+ }
2405+ bufLen = verifier -> salt_size + (passwordLen * 2 );
2406+
2407+ if (bufLen <= sizeof (stackBuffer )) {
2408+ buffer = stackBuffer ;
2409+ } else {
2410+ heapBuffer = calloc (bufLen , 1 );
2411+ if (NULL == heapBuffer ) {
2412+ cli_errmsg ("ole2: calloc failed\n" );
2413+ ret = CL_EMEM ;
2414+ goto done ;
2415+ }
2416+ buffer = heapBuffer ;
2417+ }
2418+
2419+ #if OPENSSL_VERSION_MAJOR >= 3
2420+ ossl_ctx = OSSL_LIB_CTX_new ();
2421+ if (NULL == ossl_ctx ) {
2422+ cli_errmsg ("ole2: Failed to create OpenSSL library context\n" );
2423+ ret = CL_EMEM ;
2424+ goto done ;
2425+ }
2426+ sha1_md = EVP_MD_fetch (ossl_ctx , "SHA1" , "-fips" );
2427+ #else
2428+ sha1_md = EVP_get_digestbyname ("sha1" );
2429+ #endif
2430+ if (NULL == sha1_md ) {
2431+ cli_errmsg ("ole2: Failed to initialize SHA1 digest\n" );
2432+ ret = CL_EARG ;
2433+ goto done ;
2434+ }
23712435
2372- buffer = calloc ( bufLen , 1 );
2373- if (NULL == buffer ) {
2374- cli_errmsg ("ole2: calloc failed \n" );
2436+ sha1_ctx = EVP_MD_CTX_new ( );
2437+ if (NULL == sha1_ctx ) {
2438+ cli_errmsg ("ole2: Failed to allocate SHA1 context \n" );
23752439 ret = CL_EMEM ;
23762440 goto done ;
23772441 }
23782442
2443+ #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
2444+ if (OPENSSL_VERSION_NUMBER < 0x30000000L ) {
2445+ EVP_MD_CTX_set_flags (sha1_ctx , EVP_MD_CTX_FLAG_NON_FIPS_ALLOW );
2446+ }
2447+ #endif
2448+
23792449 tmp = verifier -> salt_size ;
23802450 if (verifier -> salt_size > sizeof (verifier -> salt )) {
23812451 cli_dbgmsg ("ole2: Invalid salt length '0x%x'\n" , verifier -> salt_size );
@@ -2384,37 +2454,37 @@ static cl_error_t generate_key_aes(const char *const password, encryption_key_t
23842454 memcpy (buffer , verifier -> salt , tmp );
23852455
23862456 /*Convert to UTF16-LE*/
2387- for (i = 0 ; i < ( uint32_t ) strlen ( password ); i ++ ) {
2388- buffer [verifier -> salt_size + (i * 2 )] = password [i ];
2457+ for (j = 0 ; j < passwordLen ; j ++ ) {
2458+ buffer [verifier -> salt_size + (j * 2 )] = ( uint8_t ) password [j ];
23892459 }
23902460
2391- ( void ) cl_sha1 ( buffer , bufLen , sha1Dst , NULL );
2461+ SHA1_HASH_WITH_CTX ( buffer , bufLen , sha1Dst );
23922462
23932463 for (i = 0 ; i < GENERATE_KEY_AES_ITERATIONS ; i ++ ) {
23942464 uint32_t eye = ole2_endian_convert_32 (i );
23952465
23962466 memcpy (sha1 , & eye , sizeof (eye ));
2397- ( void ) cl_sha1 ( sha1 , SHA1_HASH_SIZE + sizeof (uint32_t ), sha1Dst , NULL );
2467+ SHA1_HASH_WITH_CTX ( sha1 , SHA1_HASH_SIZE + sizeof (uint32_t ), sha1Dst );
23982468 }
23992469
24002470 memset (& (sha1Dst [SHA1_HASH_SIZE ]), 0 , sizeof (uint32_t ));
24012471
2402- ( void ) cl_sha1 ( sha1Dst , SHA1_HASH_SIZE + sizeof (uint32_t ), sha1Dst , NULL );
2472+ SHA1_HASH_WITH_CTX ( sha1Dst , SHA1_HASH_SIZE + sizeof (uint32_t ), sha1Dst );
24032473
24042474 memset (buf1 , 0x36 , sizeof (buf1 ));
24052475 for (i = 0 ; i < SHA1_HASH_SIZE ; i ++ ) {
24062476 buf1 [i ] = buf1 [i ] ^ sha1Dst [i ];
24072477 }
24082478
24092479 // now sha1 buf1
2410- ( void ) cl_sha1 ( buf1 , sizeof (buf1 ), doubleSha , NULL );
2480+ SHA1_HASH_WITH_CTX ( buf1 , sizeof (buf1 ), doubleSha );
24112481
24122482 memset (buf2 , 0x5c , sizeof (buf2 ));
24132483 for (i = 0 ; i < SHA1_HASH_SIZE ; i ++ ) {
24142484 buf2 [i ] = buf2 [i ] ^ sha1Dst [i ];
24152485 }
24162486
2417- ( void ) cl_sha1 ( buf2 , sizeof (buf2 ), & (doubleSha [SHA1_HASH_SIZE ]), NULL );
2487+ SHA1_HASH_WITH_CTX ( buf2 , sizeof (buf2 ), & (doubleSha [SHA1_HASH_SIZE ]));
24182488
24192489 tmp = key -> key_length_bits / 8 ;
24202490 if (tmp > sizeof (key -> key )) {
@@ -2424,8 +2494,22 @@ static cl_error_t generate_key_aes(const char *const password, encryption_key_t
24242494
24252495 memcpy (key -> key , doubleSha , tmp );
24262496 ret = CL_SUCCESS ;
2497+
24272498done :
2428- CLI_FREE_AND_SET_NULL (buffer );
2499+ #undef SHA1_HASH_WITH_CTX
2500+
2501+ CLI_FREE_AND_SET_NULL (heapBuffer );
2502+ if (NULL != sha1_ctx ) {
2503+ EVP_MD_CTX_free (sha1_ctx );
2504+ }
2505+ #if OPENSSL_VERSION_MAJOR >= 3
2506+ if (NULL != sha1_md ) {
2507+ EVP_MD_free (sha1_md );
2508+ }
2509+ if (NULL != ossl_ctx ) {
2510+ OSSL_LIB_CTX_free (ossl_ctx );
2511+ }
2512+ #endif
24292513
24302514 return ret ;
24312515}
@@ -2556,8 +2640,9 @@ static bool initialize_encryption_key(
25562640 encryption_key_t * encryptionKey ,
25572641 encryption_status_t * pEncryptionStatus )
25582642{
2559- bool bRet = false;
2560- size_t idx = 0 ;
2643+ bool bRet = false;
2644+ size_t idx = 0 ;
2645+ size_t csp_name_max_u16 = 0 ;
25612646 encryption_key_t key ;
25622647 bool bAES = false;
25632648
@@ -2697,21 +2782,20 @@ static bool initialize_encryption_key(
26972782 goto done ;
26982783 }
26992784
2700- while (true) {
2701- // Check if we've gone past the end of the buffer without finding the end of the CSPName string.
2702- if ((idx + 1 ) * sizeof (uint16_t ) > remainingBytes ) {
2703- cli_dbgmsg ("ole2: CSPName is missing null terminator before end of buffer.\n" );
2704- goto done ;
2705- }
2706- // Check if we've found the end of the CSPName string.
2785+ csp_name_max_u16 = remainingBytes / sizeof (* encryptionInfo_CSPName );
2786+
2787+ for (idx = 0 ; idx < csp_name_max_u16 ; idx ++ ) {
27072788 if (encryptionInfo_CSPName [idx ] == 0 ) {
27082789 break ;
27092790 }
2710- // Found another character in the CSPName string, keep going.
2711- idx ++ ;
27122791 }
27132792
2714- CSPName_length = (idx + 1 ) * sizeof (uint16_t );
2793+ if (idx == csp_name_max_u16 ) {
2794+ cli_dbgmsg ("ole2: CSPName is missing null terminator before end of buffer.\n" );
2795+ goto done ;
2796+ }
2797+
2798+ CSPName_length = (idx + 1 ) * sizeof (* encryptionInfo_CSPName );
27152799
27162800 encryptionVerifierPtr = (uint8_t * )encryptionInfo_CSPName + CSPName_length ;
27172801 remainingBytes -= CSPName_length ;
@@ -2720,6 +2804,7 @@ static bool initialize_encryption_key(
27202804 cli_dbgmsg ("ole2: No encryption_verifier_t\n" );
27212805 goto done ;
27222806 }
2807+
27232808 copy_encryption_verifier (& encryptionVerifier , encryptionVerifierPtr );
27242809
27252810 key .key_length_bits = encryptionInfo .encryptionInfo .keySize ;
@@ -2741,6 +2826,7 @@ static bool initialize_encryption_key(
27412826 memcpy (encryptionKey , & key , sizeof (encryption_key_t ));
27422827 bRet = true;
27432828 pEncryptionStatus -> encryption_type = VELVET_SWEATSHOP_ENCRYPTION ;
2829+
27442830done :
27452831
27462832 if (pEncryptionStatus -> encryption_type ) {
0 commit comments