int PSIWorker::sp_psi_get_data_hash()

in samplecode/psi/SMCClient/worker/Worker.cpp [625:729]


int PSIWorker::sp_psi_get_data_hash(Messages::MessagePsiHashData *data) {
    int ret = 0;

    if (this->hash_vector.size() <= 0) {
        //read file
        uint8_t * file_data = NULL;
        int file_size = 0;

        //No duplicate data by default
        file_size = ReadFileToBuffer(this->hash_path, &file_data);
        if (file_size <= 0) {
            return -1;
        }

        char * p = (char*)file_data;
        const char * s = p;
        char* n = (char*)p;
        for( ; p - s < file_size; p = n + 1) {
            n = strchr(p, '\n');
            if (n == NULL) {
                //only one line or last line
                n = p + strlen(p);
            } else {
                n[0] = '\0';
            }
            if (strlen(p) <= 0) {//ignore null line
                continue;
            }

            sample_sha256_hash_t report_data = {0};
            Sha256 sha256;
            sha256.update((uint8_t*)p, strlen(p));
            sha256.update((uint8_t*)this->psi_salt.c_str(), this->psi_salt.size());
            sha256.hash((sample_sha256_hash_t * )&report_data);

            string hash = ByteArrayToString(report_data, sizeof(sample_sha256_hash_t));

            this->hash_vector.push_back(hash);
            this->data_map[hash] = p;

            Log("[PSI] Init data: %s, hash: %s", p, ByteArrayToString((const uint8_t*)&report_data, sizeof(sample_sha256_hash_t)));
        }

        Log("[PSI] Init all data, size: %d", this->hash_vector.size());

        std::sort(this->hash_vector.begin(), this->hash_vector.end());
        this->hash_vector_cursor = 0;
    }

    if (this->hash_vector_cursor >= this->hash_vector.size()) {
        return -1;
    }

    int count = PSI_HASH_DATA_COUNT;

    if (this->hash_vector_cursor + PSI_HASH_DATA_COUNT > this->hash_vector.size()) {
        count = this->hash_vector.size() - this->hash_vector_cursor;
    }

    int payload_size = count * SAMPLE_SHA256_HASH_SIZE;
    uint8_t payload[payload_size] = {0};
    uint8_t enc_data[payload_size] = {0};

    for (int i = 0; i < count; i++) {
        uint8_t * arr = NULL;
        int size = HexStringToByteArray(this->hash_vector[this->hash_vector_cursor + i], &arr);
        if (size != sizeof(sample_sha256_hash_t)) {
            Log("[PSI] Get hash vector , something error: %d, %d, %s", size, sizeof(sample_sha256_hash_t), this->hash_vector[this->hash_vector_cursor + i]);
            return -1;
        }
        memcpy(payload + i*sizeof(sample_sha256_hash_t), arr, size);
    }

    this->hash_vector_cursor += count;

    uint8_t aes_gcm_iv[SAMPLE_SP_IV_SIZE] = {0};
    sample_aes_gcm_128bit_tag_t out_mac = {0};

    ret = sample_rijndael128GCM_encrypt(&g_sp_db.sk_key,
                                        payload,
                                        payload_size,
                                        enc_data,
                                        &aes_gcm_iv[0],
                                        SAMPLE_SP_IV_SIZE,
                                        NULL,
                                        0,
                                        &out_mac);

    if (ret == -1) {
        Log("sample_rijndael128GCM_encrypt failed");
        return -1;
    }

    int data_size = sizeof(uint32_t) + sizeof(sample_aes_gcm_128bit_tag_t) + payload_size;
    data->set_size(data_size);
    for (int i = 0; i < sizeof(sample_aes_gcm_128bit_tag_t); i++) {
        data->add_mac(out_mac[i]);
    }

    for (int i = 0; i < payload_size; i++) {
        data->add_data((uint32_t)enc_data[i]);
    }

    return 0;
}