예제 #1
0
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");
	}
}
예제 #2
0
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;
}
예제 #3
0
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;
}