static void test_generate_key_simple (void) { int i; gboolean ret; guchar *key; for (i = 0; i < N_GENERATION_TESTS; ++i) { if (!all_generation_tests[i].result_simple) continue; ret = egg_symkey_generate_simple (all_generation_tests[i].cipher_algo, all_generation_tests[i].hash_algo, all_generation_tests[i].password, -1, (guchar*)all_generation_tests[i].salt, 8, all_generation_tests[i].iterations, &key, NULL); g_assert (ret && "key generation failed"); ret = (memcmp (key, all_generation_tests[i].result_simple, gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0); g_assert (ret && "invalid simple key generated"); } }
guchar * egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password, gssize n_password, GBytes *data, gsize *n_decrypted) { gcry_cipher_hd_t ch; guchar *key = NULL; guchar *iv = NULL; int gcry, ivlen; int algo = 0; int mode = 0; guchar *decrypted; if (!parse_dekinfo (dekinfo, &algo, &mode, &iv)) return FALSE; ivlen = gcry_cipher_get_algo_blklen (algo); /* We assume the iv is at least as long as at 8 byte salt */ g_return_val_if_fail (ivlen >= 8, FALSE); /* IV is already set from the DEK info */ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, n_password, iv, 8, 1, &key, NULL)) { g_free (iv); return NULL; } gcry = gcry_cipher_open (&ch, algo, mode, 0); g_return_val_if_fail (!gcry, NULL); gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo)); g_return_val_if_fail (!gcry, NULL); egg_secure_free (key); /* 16 = 128 bits */ gcry = gcry_cipher_setiv (ch, iv, ivlen); g_return_val_if_fail (!gcry, NULL); g_free (iv); /* Allocate output area */ *n_decrypted = g_bytes_get_size (data); decrypted = egg_secure_alloc (*n_decrypted); gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted, g_bytes_get_data (data, NULL), g_bytes_get_size (data)); if (gcry) { egg_secure_free (decrypted); g_return_val_if_reached (NULL); } gcry_cipher_close (ch); return decrypted; }
static gboolean decrypt_buffer (EggBuffer *buffer, GkmSecret *master, guchar salt[8], int iterations) { const gchar *password = NULL; gcry_cipher_hd_t cih; gcry_error_t gerr; guchar *key, *iv; gsize n_password = 0; size_t pos; g_assert (buffer->len % 16 == 0); g_assert (16 == gcry_cipher_get_algo_blklen (GCRY_CIPHER_AES128)); g_assert (16 == gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES128)); /* No password is set, try an null password */ if (master == NULL) { password = NULL; n_password = 0; } else { password = gkm_secret_get_password (master, &n_password); } if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256, password, n_password, salt, 8, iterations, &key, &iv)) return FALSE; gerr = gcry_cipher_open (&cih, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0); if (gerr) { g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gerr)); egg_secure_free (key); g_free (iv); return FALSE; } /* 16 = 128 bits */ gerr = gcry_cipher_setkey (cih, key, 16); g_return_val_if_fail (!gerr, FALSE); egg_secure_free (key); /* 16 = 128 bits */ gerr = gcry_cipher_setiv (cih, iv, 16); g_return_val_if_fail (!gerr, FALSE); g_free (iv); for (pos = 0; pos < buffer->len; pos += 16) { /* In place encryption */ gerr = gcry_cipher_decrypt (cih, buffer->buf + pos, 16, NULL, 0); g_return_val_if_fail (!gerr, FALSE); } gcry_cipher_close (cih); return TRUE; }
gboolean egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password, gssize n_password, const guchar *data, gsize n_data, guchar **encrypted, gsize *n_encrypted) { gsize n_overflow, n_batch, n_padding; gcry_cipher_hd_t ch; guchar *key = NULL; guchar *iv = NULL; guchar *padded = NULL; int gcry, ivlen; int algo = 0; int mode = 0; if (!parse_dekinfo (dekinfo, &algo, &mode, &iv)) g_return_val_if_reached (FALSE); ivlen = gcry_cipher_get_algo_blklen (algo); /* We assume the iv is at least as long as at 8 byte salt */ g_return_val_if_fail (ivlen >= 8, FALSE); /* IV is already set from the DEK info */ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, n_password, iv, 8, 1, &key, NULL)) g_return_val_if_reached (FALSE); gcry = gcry_cipher_open (&ch, algo, mode, 0); g_return_val_if_fail (!gcry, FALSE); gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo)); g_return_val_if_fail (!gcry, FALSE); egg_secure_free (key); /* 16 = 128 bits */ gcry = gcry_cipher_setiv (ch, iv, ivlen); g_return_val_if_fail (!gcry, FALSE); g_free (iv); /* Allocate output area */ n_overflow = (n_data % ivlen); n_padding = n_overflow ? (ivlen - n_overflow) : 0; n_batch = n_data - n_overflow; *n_encrypted = n_data + n_padding; *encrypted = g_malloc0 (*n_encrypted); g_assert (*n_encrypted % ivlen == 0); g_assert (*n_encrypted >= n_data); g_assert (*n_encrypted == n_batch + n_overflow + n_padding); /* Encrypt everything but the last bit */ gcry = gcry_cipher_encrypt (ch, *encrypted, n_batch, (void*)data, n_batch); if (gcry) { g_free (*encrypted); g_return_val_if_reached (FALSE); } /* Encrypt the padded block */ if (n_overflow) { padded = egg_secure_alloc (ivlen); memset (padded, 0, ivlen); memcpy (padded, data + n_batch, n_overflow); gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen); egg_secure_free (padded); if (gcry) { g_free (*encrypted); g_return_val_if_reached (FALSE); } } gcry_cipher_close (ch); return TRUE; }