int decrypt_record(char* ibuf, size_t ilen, char**obuf, size_t *olen){ int i; uint8_t keybuf[16]; uint8_t hmacbuf[32]; if (ilen < 48){ return 0; } calculate_hmac(hmac_key, ibuf, ilen - 32, hmacbuf); if (memcmp(hmacbuf, ibuf + ilen - 32, 32) != 0){ return 0; } *olen = ilen - 48; *obuf = GC_MALLOC_ATOMIC((*olen) + 1); memcpy(keybuf, ibuf, 16); for (i = 0; i < ilen - 48; i++){ if ((i % 16) == 0){ aes_encrypt(&aes, keybuf, keybuf); } (*obuf)[i] = ibuf[i + 16] ^ keybuf[i % 16]; } (*obuf)[*olen] = 0; return 1; }
void hash_record_id(char* type, char* id, uint8_t hash[32]){ size_t type_len = strlen(type); size_t id_len = strlen(id); char* buf = GC_MALLOC_ATOMIC(type_len + id_len + 1); memcpy(buf, type, type_len); memcpy(buf + type_len + 1, id, id_len); buf[type_len] = 0; calculate_hmac(recordid_key, buf, type_len + id_len + 1, hash); }
static gboolean compare_hmac (guchar *hmac_key, guchar *hmac, GFile *fl) { gchar *path = g_file_get_path (fl); if (calculate_hmac (path, hmac_key, hmac) == HMAC_MISMATCH) { return FALSE; } else { return TRUE; } }
void derive_key(char* passphrase, uint8_t salt[32], uint8_t key[32]){ int i; int j; uint8_t buf[32]; sha256_context sc; memcpy(key, salt, 32); for (i = 0; i < 4096; i++){ calculate_hmac(key, passphrase, strlen(passphrase), buf); for (j = 0; j < 32; j++){ key[j] ^= buf[j]; } } }
void encrypt_record(char* ibuf, size_t ilen, char**obuf, size_t *olen){ int i; uint8_t keybuf[16]; *obuf = GC_MALLOC_ATOMIC(ilen+48); *olen = ilen + 48; prng_get_bytes(keybuf, 16); memcpy(*obuf, keybuf, 16); for (i = 0; i < ilen; i++){ if ((i % 16) == 0){ aes_encrypt(&aes, keybuf, keybuf); } (*obuf)[i + 16] = ibuf[i] ^ keybuf[i % 16]; } calculate_hmac(hmac_key, *obuf, ilen + 16, *obuf + ilen + 16); }
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; }