@@ -1172,3 +1172,158 @@ int test_aes256_cts(void *data)
11721172
11731173#endif /* WP_HAVE_AESCTS */
11741174
1175+ #ifdef WP_HAVE_AESCBC
1176+
1177+ int test_aes256_cbc_multiple (void * data )
1178+ {
1179+ /* Test vector from libmemcached/libhashkit */
1180+ static const unsigned char key_data [] = {
1181+ 0x5f , 0x5f , 0x5f , 0x5f , 0x43 , 0x5f , 0x41 , 0x5f ,
1182+ 0x54 , 0x5f , 0x43 , 0x5f , 0x48 , 0x5f , 0x5f , 0x5f ,
1183+ 0x5f , 0x54 , 0x5f , 0x45 , 0x5f , 0x53 , 0x5f , 0x54 ,
1184+ 0x5f , 0x5f , 0x5f , 0x5f , 0x30 , 0x00 , 0x00 , 0x00
1185+ };
1186+
1187+ static const unsigned char plain_text [] = {
1188+ 0x72 , 0x65 , 0x70 , 0x6c , 0x61 , 0x63 , 0x65 , 0x64 ,
1189+ 0x20 , 0x76 , 0x61 , 0x6c , 0x75 , 0x65 , 0x2c , 0x20 ,
1190+ 0x74 , 0x68 , 0x69 , 0x63 , 0x68 , 0x20 , 0x69 , 0x73 ,
1191+ 0x20 , 0x6c , 0x6f , 0x6e , 0x67 , 0x65 , 0x72 , 0x20 ,
1192+ 0x74 , 0x68 , 0x61 , 0x6e , 0x20 , 0x41 , 0x45 , 0x53 ,
1193+ 0x5f , 0x42 , 0x4c , 0x4f , 0x43 , 0x4b , 0x5f , 0x53 ,
1194+ 0x49 , 0x5a , 0x45
1195+ };
1196+ static const int plain_text_len = sizeof (plain_text );
1197+
1198+ static const unsigned char aes_iv [] = {
1199+ 0x44 , 0x63 , 0xff , 0xd3 , 0x79 , 0xcf , 0x04 , 0x74 ,
1200+ 0x9e , 0x75 , 0xa2 , 0x71 , 0xa4 , 0x2c , 0xc7 , 0x0a
1201+ };
1202+
1203+ static const unsigned char ciphertext_exp [] = {
1204+ 0x75 , 0xdd , 0x24 , 0xf5 , 0xc1 , 0x5c , 0x34 , 0x65 ,
1205+ 0xaf , 0xd3 , 0xa9 , 0x82 , 0x74 , 0xe2 , 0xf3 , 0xa1 ,
1206+ 0x35 , 0x95 , 0x5a , 0x89 , 0x6f , 0x59 , 0xb9 , 0xa2 ,
1207+ 0x84 , 0xec , 0xa8 , 0x54 , 0x9f , 0xcc , 0x6d , 0xe3 ,
1208+ 0x99 , 0xfc , 0xf0 , 0xa3 , 0xc4 , 0x03 , 0xc3 , 0x56 ,
1209+ 0xec , 0x6d , 0x1c , 0xcd , 0xe1 , 0xc2 , 0x17 , 0xa0 ,
1210+ 0x51 , 0x0b , 0x00 , 0x87 , 0xde , 0x43 , 0x8a , 0xf6 ,
1211+ 0x1b , 0x03 , 0x2c , 0x7f , 0x68 , 0x67 , 0x11 , 0x72
1212+ };
1213+
1214+ (void )data ;
1215+ int err = 0 ;
1216+
1217+ EVP_CIPHER_CTX * ctx_enc = NULL ;
1218+ EVP_CIPHER_CTX * ctx_dec = NULL ;
1219+
1220+ if (err == 0 ) {
1221+ ctx_enc = EVP_CIPHER_CTX_new ();
1222+ ctx_dec = EVP_CIPHER_CTX_new ();
1223+ if (ctx_dec == NULL || ctx_enc == NULL ) {
1224+ PRINT_MSG ("EVP_CIPHER_CTX_new failed" );
1225+ err = 1 ;
1226+ }
1227+ else {
1228+ PRINT_MSG ("CTXs created" );
1229+ }
1230+ }
1231+
1232+ if (err == 0 ) {
1233+ if (EVP_EncryptInit_ex (ctx_enc , EVP_aes_256_cbc (), NULL , key_data , aes_iv ) != 1
1234+ || EVP_DecryptInit_ex (ctx_dec , EVP_aes_256_cbc (), NULL , key_data , aes_iv ) != 1 ) {
1235+ PRINT_MSG ("EVP_EncryptInit_ex or EVP_DecryptInit_ex failed" );
1236+ err = 1 ;
1237+ }
1238+ else {
1239+ PRINT_MSG ("EVP_EncryptInit_ex and EVP_DecryptInit_ex succeeded" );
1240+ }
1241+ }
1242+
1243+ /* Test that we can encrypt and decrypt multiple times without creating
1244+ * a new context. We should get the same result each time: same ciphertext
1245+ * when encrypting and same plaintext when decrypting. */
1246+ for (int i = 0 ; i < 8 ; i ++ ) {
1247+ int cipher_text_len = plain_text_len + EVP_CIPHER_CTX_block_size (ctx_enc );
1248+ int decrypted_text_len = 0 ;
1249+ int final_len = 0 ;
1250+ unsigned char * cipher_text = malloc (cipher_text_len );
1251+ unsigned char * decrypted_text = malloc (plain_text_len );
1252+
1253+ PRINT_MSG ("Test iteration: %d" , i );
1254+
1255+ if (cipher_text == NULL || decrypted_text == NULL ) {
1256+ PRINT_MSG ("Memory allocation failed" );
1257+ err = 1 ;
1258+ }
1259+
1260+ if (err == 0 ) {
1261+ if (EVP_EncryptInit_ex (ctx_enc , NULL , NULL , NULL , NULL ) != 1
1262+ || EVP_EncryptUpdate (ctx_enc , cipher_text , & cipher_text_len , plain_text , plain_text_len ) != 1
1263+ || EVP_EncryptFinal_ex (ctx_enc , cipher_text + cipher_text_len , & final_len ) != 1 ) {
1264+ PRINT_MSG ("Encrypt failed" );
1265+ err = 1 ;
1266+ }
1267+ else {
1268+ cipher_text_len += final_len ;
1269+ PRINT_BUFFER ("Plain text " , plain_text , plain_text_len );
1270+ PRINT_BUFFER ("Cipher text " , cipher_text , cipher_text_len );
1271+ }
1272+ }
1273+
1274+ if (err == 0 ) {
1275+ if (cipher_text_len != sizeof (ciphertext_exp )) {
1276+ PRINT_MSG ("Cipher text length does not match expected value" );
1277+ err = 1 ;
1278+ }
1279+ }
1280+
1281+ if (err == 0 ) {
1282+ if (memcmp (cipher_text , ciphertext_exp , sizeof (ciphertext_exp )) != 0 ) {
1283+ PRINT_MSG ("Cipher text does not match expected value" );
1284+ err = 1 ;
1285+ } else {
1286+ PRINT_MSG ("Cipher text matches expected value" );
1287+ }
1288+ }
1289+
1290+ if (err == 0 ) {
1291+ if (EVP_DecryptInit_ex (ctx_dec , NULL , NULL , NULL , NULL ) != 1
1292+ || EVP_DecryptUpdate (ctx_dec , decrypted_text , & decrypted_text_len , cipher_text , cipher_text_len ) != 1
1293+ || EVP_DecryptFinal_ex (ctx_dec , decrypted_text + decrypted_text_len , & final_len ) != 1 ) {
1294+ PRINT_MSG ("Decrypt failed" );
1295+ err = 1 ;
1296+ }
1297+ else {
1298+ decrypted_text_len += final_len ;
1299+ PRINT_BUFFER ("Decrypted text" , decrypted_text , decrypted_text_len );
1300+ }
1301+ }
1302+
1303+ if (err == 0 ) {
1304+ if (plain_text_len != decrypted_text_len ) {
1305+ PRINT_MSG ("Decrypted text length does not match original" );
1306+ err = 1 ;
1307+ }
1308+ }
1309+
1310+ if (err == 0 ) {
1311+ int res = memcmp (plain_text , decrypted_text , plain_text_len );
1312+ if (res != 0 ) {
1313+ PRINT_MSG ("Decrypted text does not match original" );
1314+ err = 1 ;
1315+ } else {
1316+ PRINT_MSG ("Cipher test passed successfully" );
1317+ }
1318+ }
1319+
1320+ free (cipher_text );
1321+ free (decrypted_text );
1322+ }
1323+
1324+ EVP_CIPHER_CTX_free (ctx_enc );
1325+ EVP_CIPHER_CTX_free (ctx_dec );
1326+
1327+ return err ;
1328+ }
1329+ #endif /* WP_HAVE_AESCBC */
0 commit comments