@@ -961,6 +961,234 @@ static int test_encrypt_simple_coverage(void) {
961961 return 0 ;
962962}
963963
964+ // Test parameter validation in key functions
965+ static int test_encrypt_parameter_validation (void ) {
966+ #ifdef BFC_WITH_SODIUM
967+ bfc_encrypt_key_t key ;
968+ uint8_t salt [BFC_ENC_SALT_SIZE ] = {0 };
969+
970+ // Test NULL password in bfc_encrypt_key_from_password
971+ int result = bfc_encrypt_key_from_password (NULL , 10 , salt , & key );
972+ assert (result == BFC_E_INVAL );
973+
974+ // Test NULL key in bfc_encrypt_key_from_password
975+ result = bfc_encrypt_key_from_password ("password" , 8 , salt , NULL );
976+ assert (result == BFC_E_INVAL );
977+
978+ // Test NULL key in bfc_encrypt_key_from_bytes
979+ uint8_t raw_key [BFC_ENC_KEY_SIZE ] = {0 };
980+ result = bfc_encrypt_key_from_bytes (raw_key , NULL );
981+ assert (result == BFC_E_INVAL );
982+
983+ // Test NULL raw_key in bfc_encrypt_key_from_bytes
984+ result = bfc_encrypt_key_from_bytes (NULL , & key );
985+ assert (result == BFC_E_INVAL );
986+
987+ // Test NULL salt in bfc_encrypt_generate_salt
988+ result = bfc_encrypt_generate_salt (NULL );
989+ assert (result == BFC_E_INVAL );
990+ #endif
991+ return 0 ;
992+ }
993+
994+ // Test encryption data function parameter validation
995+ static int test_encrypt_data_parameter_validation (void ) {
996+ #ifdef BFC_WITH_SODIUM
997+ bfc_encrypt_key_t key ;
998+ const char * password = "testpass" ;
999+ uint8_t salt [BFC_ENC_SALT_SIZE ] = {0 };
1000+ int result = bfc_encrypt_key_from_password (password , strlen (password ), salt , & key );
1001+ assert (result == BFC_OK );
1002+
1003+ const char * test_data = "test" ;
1004+ const char * path = "test/path" ;
1005+
1006+ // Test NULL key in bfc_encrypt_data
1007+ bfc_encrypt_result_t enc_result =
1008+ bfc_encrypt_data (NULL , test_data , strlen (test_data ), path , strlen (path ));
1009+ assert (enc_result .error == BFC_E_INVAL );
1010+ assert (enc_result .data == NULL );
1011+
1012+ // Test NULL input in bfc_encrypt_data
1013+ enc_result = bfc_encrypt_data (& key , NULL , 10 , path , strlen (path ));
1014+ assert (enc_result .error == BFC_E_INVAL );
1015+ assert (enc_result .data == NULL );
1016+
1017+ // Test zero input_size in bfc_encrypt_data - this should actually succeed
1018+ enc_result = bfc_encrypt_data (& key , test_data , 0 , path , strlen (path ));
1019+ assert (enc_result .error == BFC_OK ); // Zero-length encryption is allowed
1020+ free (enc_result .data );
1021+
1022+ // Test similar for decrypt function
1023+ bfc_decrypt_result_t dec_result =
1024+ bfc_decrypt_data (NULL , test_data , strlen (test_data ), path , strlen (path ), 100 );
1025+ assert (dec_result .error == BFC_E_INVAL );
1026+ assert (dec_result .data == NULL );
1027+
1028+ dec_result = bfc_decrypt_data (& key , NULL , 10 , path , strlen (path ), 100 );
1029+ assert (dec_result .error == BFC_E_INVAL );
1030+ assert (dec_result .data == NULL );
1031+
1032+ // Test zero input_size in bfc_decrypt_data - this might also be allowed
1033+ dec_result = bfc_decrypt_data (& key , test_data , 0 , path , strlen (path ), 100 );
1034+ // Don't assert specific error - it depends on implementation
1035+
1036+ bfc_encrypt_key_clear (& key );
1037+ #endif
1038+ return 0 ;
1039+ }
1040+
1041+ // Test encryption context parameter validation
1042+ static int test_encrypt_context_parameter_validation (void ) {
1043+ #ifdef BFC_WITH_SODIUM
1044+ bfc_encrypt_key_t key ;
1045+ const char * password = "testpass" ;
1046+ uint8_t salt [BFC_ENC_SALT_SIZE ] = {0 };
1047+ int result = bfc_encrypt_key_from_password (password , strlen (password ), salt , & key );
1048+ assert (result == BFC_OK );
1049+
1050+ const char * path = "test/path" ;
1051+
1052+ // Test NULL key in bfc_encrypt_ctx_create
1053+ bfc_encrypt_ctx_t * ctx = bfc_encrypt_ctx_create (NULL , path , strlen (path ));
1054+ assert (ctx == NULL );
1055+
1056+ bfc_encrypt_key_clear (& key );
1057+ #endif
1058+ return 0 ;
1059+ }
1060+
1061+ // Test context utility functions
1062+ static int test_encrypt_context_utilities (void ) {
1063+ #ifdef BFC_WITH_SODIUM
1064+ bfc_encrypt_key_t key ;
1065+ const char * password = "testpass" ;
1066+ uint8_t salt [BFC_ENC_SALT_SIZE ] = {0 };
1067+ int result = bfc_encrypt_key_from_password (password , strlen (password ), salt , & key );
1068+ assert (result == BFC_OK );
1069+
1070+ const char * path = "test/path" ;
1071+
1072+ // Test creating context with valid parameters
1073+ bfc_encrypt_ctx_t * ctx = bfc_encrypt_ctx_create (& key , path , strlen (path ));
1074+ assert (ctx != NULL );
1075+
1076+ // Test getting nonce from context
1077+ uint8_t nonce [BFC_ENC_NONCE_SIZE ];
1078+ result = bfc_encrypt_ctx_get_nonce (ctx , nonce );
1079+ // This might fail if not initialized, which is expected
1080+
1081+ // Test destroying context
1082+ bfc_encrypt_ctx_destroy (ctx );
1083+
1084+ // Test destroying NULL context (should not crash)
1085+ bfc_encrypt_ctx_destroy (NULL );
1086+
1087+ bfc_encrypt_key_clear (& key );
1088+ #endif
1089+ return 0 ;
1090+ }
1091+
1092+ // Test cryptographic edge cases
1093+ static int test_encrypt_crypto_edge_cases (void ) {
1094+ #ifdef BFC_WITH_SODIUM
1095+ bfc_encrypt_key_t key ;
1096+ const char * password = "testpass" ;
1097+ uint8_t salt [BFC_ENC_SALT_SIZE ] = {0 };
1098+ int result = bfc_encrypt_key_from_password (password , strlen (password ), salt , & key );
1099+ assert (result == BFC_OK );
1100+
1101+ // Test encryption with empty associated data
1102+ const char * test_data = "test data" ;
1103+ bfc_encrypt_result_t enc_result = bfc_encrypt_data (& key , test_data , strlen (test_data ), NULL , 0 );
1104+ assert (enc_result .error == BFC_OK );
1105+ assert (enc_result .data != NULL );
1106+
1107+ // Test decryption with empty associated data
1108+ bfc_decrypt_result_t dec_result = bfc_decrypt_data (
1109+ & key , enc_result .data , enc_result .encrypted_size , NULL , 0 , strlen (test_data ));
1110+ assert (dec_result .error == BFC_OK );
1111+ assert (dec_result .decrypted_size == strlen (test_data ));
1112+ assert (memcmp (dec_result .data , test_data , strlen (test_data )) == 0 );
1113+
1114+ free (enc_result .data );
1115+ free (dec_result .data );
1116+
1117+ // Test with very long associated data
1118+ char long_path [1000 ];
1119+ memset (long_path , 'A' , sizeof (long_path ) - 1 );
1120+ long_path [sizeof (long_path ) - 1 ] = '\0' ;
1121+
1122+ enc_result = bfc_encrypt_data (& key , test_data , strlen (test_data ), long_path , strlen (long_path ));
1123+ assert (enc_result .error == BFC_OK );
1124+ assert (enc_result .data != NULL );
1125+
1126+ dec_result = bfc_decrypt_data (& key , enc_result .data , enc_result .encrypted_size , long_path ,
1127+ strlen (long_path ), strlen (test_data ));
1128+ assert (dec_result .error == BFC_OK );
1129+ assert (dec_result .decrypted_size == strlen (test_data ));
1130+ assert (memcmp (dec_result .data , test_data , strlen (test_data )) == 0 );
1131+
1132+ free (enc_result .data );
1133+ free (dec_result .data );
1134+
1135+ bfc_encrypt_key_clear (& key );
1136+ #endif
1137+ return 0 ;
1138+ }
1139+
1140+ // Test corrupted ciphertext handling
1141+ static int test_encrypt_corruption_handling (void ) {
1142+ #ifdef BFC_WITH_SODIUM
1143+ bfc_encrypt_key_t key ;
1144+ const char * password = "testpass" ;
1145+ uint8_t salt [BFC_ENC_SALT_SIZE ] = {0 };
1146+ int result = bfc_encrypt_key_from_password (password , strlen (password ), salt , & key );
1147+ assert (result == BFC_OK );
1148+
1149+ const char * test_data = "test data for corruption test" ;
1150+ const char * path = "test/file/path" ;
1151+
1152+ // First encrypt normally
1153+ bfc_encrypt_result_t enc_result =
1154+ bfc_encrypt_data (& key , test_data , strlen (test_data ), path , strlen (path ));
1155+ assert (enc_result .error == BFC_OK );
1156+ assert (enc_result .data != NULL );
1157+
1158+ // Test with corrupted ciphertext - flip a bit in the middle
1159+ if (enc_result .encrypted_size > 32 ) {
1160+ uint8_t * corrupted = malloc (enc_result .encrypted_size );
1161+ memcpy (corrupted , enc_result .data , enc_result .encrypted_size );
1162+ corrupted [enc_result .encrypted_size / 2 ] ^= 0x01 ; // Flip a bit
1163+
1164+ bfc_decrypt_result_t dec_result = bfc_decrypt_data (& key , corrupted , enc_result .encrypted_size ,
1165+ path , strlen (path ), strlen (test_data ));
1166+ assert (dec_result .error != BFC_OK ); // Should fail authentication
1167+ assert (dec_result .data == NULL );
1168+
1169+ free (corrupted );
1170+ }
1171+
1172+ // Test with wrong path (different associated data)
1173+ bfc_decrypt_result_t dec_result = bfc_decrypt_data (
1174+ & key , enc_result .data , enc_result .encrypted_size , "wrong/path" , 10 , strlen (test_data ));
1175+ assert (dec_result .error != BFC_OK ); // Should fail authentication
1176+ assert (dec_result .data == NULL );
1177+
1178+ // Test with truncated ciphertext
1179+ if (enc_result .encrypted_size > 16 ) {
1180+ dec_result = bfc_decrypt_data (& key , enc_result .data , enc_result .encrypted_size - 10 , path ,
1181+ strlen (path ), strlen (test_data ));
1182+ assert (dec_result .error != BFC_OK ); // Should fail
1183+ assert (dec_result .data == NULL );
1184+ }
1185+
1186+ free (enc_result .data );
1187+ bfc_encrypt_key_clear (& key );
1188+ #endif
1189+ return 0 ;
1190+ }
1191+
9641192int test_encrypt (void ) {
9651193 int result = 0 ;
9661194
@@ -979,6 +1207,12 @@ int test_encrypt(void) {
9791207 result += test_additional_encryption_coverage ();
9801208 result += test_encryption_key_edge_cases ();
9811209 result += test_encrypt_simple_coverage ();
1210+ result += test_encrypt_parameter_validation ();
1211+ result += test_encrypt_data_parameter_validation ();
1212+ result += test_encrypt_context_parameter_validation ();
1213+ result += test_encrypt_context_utilities ();
1214+ result += test_encrypt_crypto_edge_cases ();
1215+ result += test_encrypt_corruption_handling ();
9821216
9831217 return result ;
9841218}
0 commit comments