static int alice_function(void) { size_t input_length = current_length; themis_status_t themis_status; current_length = sizeof(shared_mem); themis_status = secure_comparator_proceed_compare(alice, shared_mem, input_length, shared_mem, ¤t_length); switch (themis_status) { case THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER: if (0 == current_length) { testsuite_fail_if(true, "secure_comparator_proceed_compare: invalid output length"); return TEST_STOP_ERROR; } return TEST_CONTINUE; case THEMIS_SUCCESS: if (current_length > 0) { testsuite_fail_if(true, "secure_comparator_proceed_compare: invalid output length"); return TEST_STOP_ERROR; } return TEST_STOP_SUCCESS; default: return TEST_STOP_ERROR; } }
const data_t& proceed(const std::vector<uint8_t>& data) { if (data.empty()) { throw themispp::exception_t( "Secure Comparator failed to proceed comparison: data must be non-empty"); } themis_status_t status = THEMIS_FAIL; size_t res_data_length = 0; status = secure_comparator_proceed_compare(comparator_, &data[0], data.size(), NULL, &res_data_length); if (THEMIS_BUFFER_TOO_SMALL != status) { throw themispp::exception_t("Secure Comparator failed to proceed comparison", status); } res_.resize(res_data_length); status = secure_comparator_proceed_compare(comparator_, &data[0], data.size(), &res_[0], &res_data_length); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != status && THEMIS_SUCCESS != status) { throw themispp::exception_t("Secure Comparator failed to proceed comparison", status); } return res_; }
static void corrupt_bob_step2(secure_comparator_t *bob, const void *input, size_t input_length, void *output, size_t *output_length) { /* Let's assume bob is malicious and uses zeroes instead of random numbers */ ge_p3 g2a; ge_p3 g3a; ge_p3 g2b; ge_p3 g3b; ge_frombytes_vartime(&g2a, (const unsigned char *)input); ge_frombytes_vartime(&g3a, ((const unsigned char *)input) + (3 * ED25519_GE_LENGTH)); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(bob, input, input_length, output, output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } memset(bob->rand2, 0, sizeof(bob->rand2)); memset(bob->rand3, 0, sizeof(bob->rand3)); ge_scalarmult_base(&g2b, bob->rand2); ge_scalarmult_base(&g3b, bob->rand3); ge_scalarmult_blinded(&(bob->g2), bob->rand2, &g2a); ge_scalarmult_blinded(&(bob->g3), bob->rand3, &g3a); memset(bob->rand, 0, sizeof(bob->rand)); ge_scalarmult_blinded(&(bob->P), bob->rand, &(bob->g3)); ge_double_scalarmult_vartime((ge_p2 *)&(bob->Q), bob->secret, &(bob->g2), bob->rand); ge_p2_to_p3(&(bob->Q), (const ge_p2 *)&(bob->Q)); ge_p3_tobytes((unsigned char *)output, &g2b); ed_sign(3, bob->rand2, ((unsigned char *)output) + ED25519_GE_LENGTH); ge_p3_tobytes(((unsigned char *)output) + (3 * ED25519_GE_LENGTH), &g3b); ed_sign(4, bob->rand3, ((unsigned char *)output) + (4 * ED25519_GE_LENGTH)); ge_p3_tobytes(((unsigned char *)output) + (6 * ED25519_GE_LENGTH), &(bob->P)); ge_p3_tobytes(((unsigned char *)output) + (7 * ED25519_GE_LENGTH), &(bob->Q)); ed_dbl_base_sign(5, bob->rand, bob->secret, &(bob->g2), &(bob->g3), ((unsigned char *)output) + (8 * ED25519_GE_LENGTH)); }
void secure_comparator_security_test(void) { const char alice_secret[] = "alice secret"; const char bob_secret[] = "bob secret"; size_t output_length = sizeof(shared_mem); secure_comparator_t alice, bob; if (THEMIS_SUCCESS != secure_comparator_init(&alice)) { testsuite_fail_if(true, "secure_comparator_init failed"); return; } if (THEMIS_SUCCESS != secure_comparator_init(&bob)) { testsuite_fail_if(true, "secure_comparator_init failed"); return; } if (THEMIS_SUCCESS != secure_comparator_append_secret(&alice, alice_secret, sizeof(alice_secret))) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); return; } if (THEMIS_SUCCESS != secure_comparator_append_secret(&bob, bob_secret, sizeof(bob_secret))) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); return; } current_length = sizeof(shared_mem); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_begin_compare(&alice, shared_mem, ¤t_length)) { testsuite_fail_if(true, "secure_comparator_begin_compare failed"); return; } corrupt_alice_step1(&alice, shared_mem); corrupt_bob_step2(&bob, shared_mem, current_length, shared_mem, &output_length); current_length = output_length; output_length = sizeof(shared_mem); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(&alice, shared_mem, current_length, shared_mem, &output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } current_length = output_length; output_length = sizeof(shared_mem); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(&bob, shared_mem, current_length, shared_mem, &output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } current_length = output_length; output_length = sizeof(shared_mem); if (THEMIS_SUCCESS != secure_comparator_proceed_compare(&alice, shared_mem, current_length, shared_mem, &output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } testsuite_fail_unless((THEMIS_SCOMPARE_NO_MATCH == secure_comparator_get_result(&alice)) && (THEMIS_SCOMPARE_NO_MATCH == secure_comparator_get_result(&bob)), "compare result no match"); }