void
decrypt_file (const gchar *input_file_path, const gchar *pwd)
{
    GError *err = NULL;

    goffset file_size = get_file_size (input_file_path);
    if (file_size == -1) {
        return;
    }
    if (file_size < (goffset) (sizeof (Metadata) + SHA512_DIGEST_SIZE)) {
        g_printerr ("The selected file is not encrypted.\n");
        return;
    }

    GFile *in_file = g_file_new_for_path (input_file_path);
    GFileInputStream *in_stream = g_file_read (in_file, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    gchar *output_file_path;
    if (!g_str_has_suffix (input_file_path, ".enc")) {
        g_printerr ("The selected file may not be encrypted\n");
        output_file_path = g_strconcat (input_file_path, ".decrypted", NULL);
    }
    else {
        output_file_path = g_strndup (input_file_path, (gsize) g_utf8_strlen (input_file_path, -1) - 4); // remove .enc
    }
    GFile *out_file = g_file_new_for_path (output_file_path);
    GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    Metadata *header_metadata = g_new0 (Metadata, 1);
    CryptoKeys *decryption_keys = g_new0 (CryptoKeys, 1);

    gssize rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), header_metadata, sizeof (Metadata), NULL, &err);
    if (rw_len == -1) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    guchar *original_hmac = g_malloc (SHA512_DIGEST_SIZE);
    if (!g_seekable_seek (G_SEEKABLE (in_stream), file_size - SHA512_DIGEST_SIZE, G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }
    rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), original_hmac, SHA512_DIGEST_SIZE, NULL, &err);
    if (rw_len == -1) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    if (!g_seekable_seek (G_SEEKABLE (in_stream), 0, G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }
    GFile *file_encrypted_data = get_g_file_with_encrypted_data (in_stream, file_size);
    if (file_encrypted_data == NULL) {
        // TODO
        return;
    }

    if (!setup_keys (pwd, gcry_cipher_get_algo_keylen (header_metadata->algo), header_metadata, decryption_keys)) {
        g_printerr ("Error during key derivation or during memory allocation\n");
        //TODO
        return;
    }

    if (!compare_hmac (decryption_keys->hmac_key, original_hmac, file_encrypted_data)) {
        g_printerr ("HMAC differs from the one stored inside the file.\nEither the password is wrong or the file has been corrupted.\n");
        // TODO
        return;
    }

    decrypt (header_metadata, decryption_keys, file_encrypted_data, file_size - sizeof (Metadata) - SHA512_DIGEST_SIZE, out_stream);

    g_unlink (g_file_get_path (file_encrypted_data));
    // TODO remove encrypted file? Give option to the user

    multiple_unref (5, (gpointer) &file_encrypted_data,
                    (gpointer) &in_stream,
                    (gpointer) &out_stream,
                    (gpointer) &in_file,
                    (gpointer) &out_file);

    multiple_gcry_free (3, (gpointer) &decryption_keys->crypto_key,
                        (gpointer) &decryption_keys->derived_key,
                        (gpointer) &decryption_keys->hmac_key);

    multiple_free (4, (gpointer) &header_metadata,
                   (gpointer) &output_file_path,
                   (gpointer) &original_hmac,
                   (gpointer) &decryption_keys);
}
gpointer
encrypt_file (const gchar *input_file_path, const gchar *pwd, const gchar *algo, const gchar *algo_mode)
{
    Metadata *header_metadata = g_new0 (Metadata, 1);
    CryptoKeys *encryption_keys = g_new0 (CryptoKeys, 1);

    set_algo_and_mode (header_metadata, algo, algo_mode);
    gsize algo_key_len = gcry_cipher_get_algo_keylen (header_metadata->algo);
    gsize algo_blk_len = gcry_cipher_get_algo_blklen (header_metadata->algo);

    header_metadata->iv_size = algo_blk_len;  // iv must be the same size as the block size

    gcry_create_nonce (header_metadata->iv, header_metadata->iv_size);
    gcry_create_nonce (header_metadata->salt, KDF_SALT_SIZE);

    if (!setup_keys (pwd, algo_key_len, header_metadata, encryption_keys)) {
        multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata);
        return g_strdup ("Couldn't setup the encryption keys, exiting...");
    }

    goffset filesize = get_file_size (input_file_path);

    GError *err = NULL;

    GFile *in_file = g_file_new_for_path (input_file_path);
    GFileInputStream *in_stream = g_file_read (in_file, NULL, &err);
    if (err != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata);
        g_object_unref (in_file);

        return g_strdup (err->message);
    }

    gchar *output_file_path = g_strconcat (input_file_path, ".enc", NULL);
    GFile *out_file = g_file_new_for_path (output_file_path);
    GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err);
    if (err != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path);
        multiple_unref (3, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream);
        g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);

        return g_strdup (err->message);
    }

    gcry_cipher_hd_t hd;
    gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0);
    gcry_cipher_setkey (hd, encryption_keys->crypto_key, algo_key_len);

    gint64 number_of_blocks;
    gint number_of_padding_bytes;
    gchar *ret_msg;
    if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) {
        set_number_of_blocks_and_padding_bytes (filesize, algo_blk_len, &number_of_blocks, &number_of_padding_bytes);
        gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size);
        ret_msg = encrypt_using_cbc_mode (header_metadata, &hd, number_of_blocks, number_of_padding_bytes, algo_blk_len, in_stream, out_stream);
    }
    else {
        gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size);
        ret_msg = encrypt_using_ctr_mode (header_metadata, &hd, filesize, in_stream, out_stream);
    }
    if (ret_msg != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path);
        multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                        (gpointer) &out_stream);
        g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
        g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

        return g_strdup (ret_msg);

    }

    gcry_cipher_close (hd);

    guchar *hmac = calculate_hmac (output_file_path, encryption_keys->hmac_key, NULL);
    gssize written_bytes = g_output_stream_write (G_OUTPUT_STREAM (out_stream), hmac, SHA512_DIGEST_SIZE, NULL, &err);
    if (written_bytes == -1) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (4, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path,
                       (gpointer) &hmac);
        multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                        (gpointer) &out_stream);
        g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

        return g_strdup (err->message);
    }

    g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
    g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

    multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                        (gpointer) &encryption_keys->hmac_key);

    multiple_free (4, (gpointer) &output_file_path, (gpointer) &encryption_keys, (gpointer) &header_metadata,
                   (gpointer) &hmac);

    multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                    (gpointer) &out_stream);

    return NULL;
}
Exemple #3
0
void GameManager::init()
{
#ifdef CHOWDREN_USER_PROFILER
    user_log.open("log.txt", "w");
#endif

#ifdef CHOWDREN_USE_PROFILER
    PROFILE_SET_DAMPING(0.0);
#endif
    frame = &static_frames;

#ifdef CHOWDREN_IS_DEMO
    idle_timer_started = false;
    global_time = show_build_timer = reset_timer = manual_reset_timer = 0.0;
#endif

#ifdef CHOWDREN_USE_JOYTOKEY
    simulate_count = 0;
    axis_moved = false;
    last_axis = -1;
    deadzone = 0.4f;
    pad_selected = false;
    pad_disconnected = false;
    for (int i = 0; i < CHOWDREN_BUTTON_MAX-1; i++)
        key_mappings[i] = -1;
    for (int i = 0; i < CHOWDREN_AXIS_MAX-1; i++) {
        axis_pos_mappings[i] = -1;
        axis_neg_mappings[i] = -1;
        axis_values[i] = 0;
    }
#endif
    platform_init();
    media.init();
    set_window(false);

    // application setup
    preload_images();
    reset_globals();
    setup_keys(this);

    // setup random generator from start
    cross_srand((unsigned int)platform_get_global_time());

    fps_limit.start();
    set_framerate(FRAMERATE);

    int start_frame = 0;
#if defined(CHOWDREN_IS_AVGN)
    start_frame = 0;
#elif defined(CHOWDREN_IS_HFA)
    start_frame = 0;
#elif defined(CHOWDREN_IS_FP)
    player_died = false;
    lives = 3;
    start_frame = 0;
    // values->set(1, 2);
    // values->set(12, 2);
#elif defined(CHOWDREN_IS_NAH)
    platform_set_scale_type(2);
    // start_frame = 3;
    // set_local("fre");
    // values->set(13, 25);
    // strings->set(23, "OBJETS");
    // strings->set(9, "-fre");
#else
    start_frame = 0;
#endif

#ifdef NDEBUG
    set_frame(0);
#else
    set_frame(start_frame);
#endif
}