Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e117d2aa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "eCryptfs: fixed bug in cipher handling"

parents 906563ee 5353c9a0
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -471,8 +471,6 @@ out:
static void init_ecryption_parameters(bool *hw_crypt, bool *cipher_supported,
				struct ecryptfs_crypt_stat *crypt_stat)
{
	unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];

	if (!hw_crypt || !cipher_supported)
		return;

@@ -481,9 +479,7 @@ static void init_ecryption_parameters(bool *hw_crypt, bool *cipher_supported,

	if (get_events() && get_events()->is_cipher_supported_cb) {
		*cipher_supported =
			get_events()->is_cipher_supported_cb(
				ecryptfs_get_full_cipher(crypt_stat->cipher,
				crypt_stat->cipher_mode, final, sizeof(final)));
			get_events()->is_cipher_supported_cb(crypt_stat);
		if (*cipher_supported) {

			/**
@@ -810,12 +806,8 @@ static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
static int ecryptfs_generate_new_salt(struct ecryptfs_crypt_stat *crypt_stat)
{
	size_t salt_size = 0;
	unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];

	salt_size = ecryptfs_get_salt_size_for_cipher(
			ecryptfs_get_full_cipher(crypt_stat->cipher,
						 crypt_stat->cipher_mode,
						 final, sizeof(final)));
	salt_size = ecryptfs_get_salt_size_for_cipher(crypt_stat);

	if (0 == salt_size)
		return 0;
+18 −2
Original line number Diff line number Diff line
@@ -119,9 +119,10 @@ void ecryptfs_dump_hex(char *data, int bytes)
		printk("\n");
}

void ecryptfs_dump_salt_hex(char *data, int key_size, char *cipher)
void ecryptfs_dump_salt_hex(char *data, int key_size,
		const struct ecryptfs_crypt_stat *crypt_stat)
{
	size_t salt_size = ecryptfs_get_salt_size_for_cipher(cipher);
	size_t salt_size = ecryptfs_get_salt_size_for_cipher(crypt_stat);

	if (0 == salt_size)
		return;
@@ -132,3 +133,18 @@ void ecryptfs_dump_salt_hex(char *data, int key_size, char *cipher)
	ecryptfs_printk(KERN_DEBUG, "Decrypted session salt key:\n");
	ecryptfs_dump_hex(data + key_size, salt_size);
}

void ecryptfs_dump_cipher(struct ecryptfs_crypt_stat *stat)
{
	if (!stat)
		return;

	if (stat->cipher)
		ecryptfs_printk(KERN_DEBUG,
				"ecryptfs cipher is %s\n", stat->cipher);

	if (stat->cipher_mode)
		ecryptfs_printk(KERN_DEBUG, "ecryptfs cipher mode is %s\n",
				stat->cipher_mode);

}
+12 −5
Original line number Diff line number Diff line
@@ -625,7 +625,10 @@ int ecryptfs_encrypt_and_encode_filename(
	const char *name, size_t name_size);
struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry);
void ecryptfs_dump_hex(char *data, int bytes);
void ecryptfs_dump_salt_hex(char *data, int key_size, char *cipher);
void ecryptfs_dump_salt_hex(char *data, int key_size,
		const struct ecryptfs_crypt_stat *crypt_stat);
extern void ecryptfs_dump_cipher(struct ecryptfs_crypt_stat *stat);

int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
			int sg_size);
int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat);
@@ -780,16 +783,20 @@ void ecryptfs_freepage(struct page *page);

struct ecryptfs_events *get_events(void);

size_t ecryptfs_get_salt_size_for_cipher(const char *cipher);
size_t ecryptfs_get_salt_size_for_cipher(
		const struct ecryptfs_crypt_stat *crypt_stat);

size_t ecryptfs_get_salt_size_for_cipher_mount(
		const struct ecryptfs_mount_crypt_stat *mount_crypt_stat);

size_t ecryptfs_get_key_size_to_enc_data(
		struct ecryptfs_crypt_stat *crypt_stat);
		const struct ecryptfs_crypt_stat *crypt_stat);

size_t ecryptfs_get_key_size_to_store_key(
		struct ecryptfs_crypt_stat *crypt_stat);
		const struct ecryptfs_crypt_stat *crypt_stat);

size_t ecryptfs_get_key_size_to_restore_key(size_t stored_key_size,
		const char *cipher);
		const struct ecryptfs_crypt_stat *crypt_stat);

bool ecryptfs_check_space_for_salt(const size_t key_size,
		const size_t salt_size);
+62 −30
Original line number Diff line number Diff line
/**
 * eCryptfs: Linux filesystem encryption layer
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -42,7 +42,7 @@ void ecryptfs_free_events(void)
 * The function returns a handle to be passed
 * to unregister function.
 */
int ecryptfs_register_to_events(struct ecryptfs_events *ops)
int ecryptfs_register_to_events(const struct ecryptfs_events *ops)
{
	int ret_value = 0;

@@ -115,7 +115,7 @@ out:
 * The caller must pass ecryptfs data, which was received in one
 * of the callback invocations.
 */
bool ecryptfs_is_page_in_metadata(void *data, pgoff_t offset)
bool ecryptfs_is_page_in_metadata(const void *data, pgoff_t offset)
{

	struct ecryptfs_crypt_stat *stat = NULL;
@@ -145,7 +145,7 @@ end:
 * Given two ecryptfs data, the function
 * decides whether they are equal.
 */
inline bool ecryptfs_is_data_equal(void *data1, void *data2)
inline bool ecryptfs_is_data_equal(const void *data1, const void *data2)
{
	/* pointer comparison*/
	return data1 == data2;
@@ -155,7 +155,7 @@ inline bool ecryptfs_is_data_equal(void *data1, void *data2)
 * Given ecryptfs data, the function
 * returns appropriate key size.
 */
size_t ecryptfs_get_key_size(void *data)
size_t ecryptfs_get_key_size(const void *data)
{

	struct ecryptfs_crypt_stat *stat = NULL;
@@ -173,49 +173,67 @@ size_t ecryptfs_get_key_size(void *data)
 *
 * !!! crypt_stat cipher name and mode must be initialized
 */
size_t ecryptfs_get_salt_size(void *data)
size_t ecryptfs_get_salt_size(const void *data)
{
	struct ecryptfs_crypt_stat *stat = NULL;
	unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];

	if (!data) {
		ecryptfs_printk(KERN_ERR,
				"ecryptfs_get_salt_size: invalid data parameter\n");
		return 0;
	}

	stat = (struct ecryptfs_crypt_stat *)data;
	return ecryptfs_get_salt_size_for_cipher(
			ecryptfs_get_full_cipher(stat->cipher,
						 stat->cipher_mode,
						 final, sizeof(final)));
	return ecryptfs_get_salt_size_for_cipher(data);

}

/**
 * Given ecryptfs data, the function
 * returns appropriate cipher.
 * Given ecryptfs data and cipher string, the function
 * returns true if provided cipher and the one in ecryptfs match.
 */
const unsigned char *ecryptfs_get_cipher(void *data)
bool ecryptfs_cipher_match(const void *data,
		const unsigned char *cipher, size_t cipher_size)
{
	unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
	const unsigned char *ecryptfs_cipher = NULL;
	struct ecryptfs_crypt_stat *stat = NULL;

	if (!data) {
	if (!data || !cipher) {
		ecryptfs_printk(KERN_ERR,
			"ecryptfs_get_cipher: invalid data parameter\n");
		return NULL;
		return false;
	}

	if (!cipher_size || cipher_size > sizeof(final)) {
		ecryptfs_printk(KERN_ERR,
				"ecryptfs_get_cipher: cipher_size\n");
		return false;
	}

	stat = (struct ecryptfs_crypt_stat *)data;
	return ecryptfs_get_full_cipher(stat->cipher, stat->cipher_mode,
	ecryptfs_cipher = ecryptfs_get_full_cipher(stat->cipher,
			stat->cipher_mode,
			final, sizeof(final));

	if (!ecryptfs_cipher) {
		ecryptfs_printk(KERN_ERR,
				"ecryptfs_get_cipher: internal error while parsing cipher\n");
		return false;
	}

	if (strcmp(ecryptfs_cipher, cipher)) {
		if (ecryptfs_verbosity > 0)
			ecryptfs_dump_cipher(stat);

		return false;
	}

	return true;
}

/**
 * Given ecryptfs data, the function
 * returns file encryption key.
 */
const unsigned char *ecryptfs_get_key(void *data)
const unsigned char *ecryptfs_get_key(const void *data)
{

	struct ecryptfs_crypt_stat *stat = NULL;
@@ -233,7 +251,7 @@ const unsigned char *ecryptfs_get_key(void *data)
 * Given ecryptfs data, the function
 * returns file encryption salt.
 */
const unsigned char *ecryptfs_get_salt(void *data)
const unsigned char *ecryptfs_get_salt(const void *data)
{
	struct ecryptfs_crypt_stat *stat = NULL;

@@ -279,7 +297,7 @@ bool ecryptfs_check_space_for_salt(const size_t key_size,
 * or for all other general purposes
 */
size_t ecryptfs_get_key_size_to_enc_data(
		struct ecryptfs_crypt_stat *crypt_stat)
		const struct ecryptfs_crypt_stat *crypt_stat)
{
	if (!crypt_stat)
		return 0;
@@ -299,7 +317,7 @@ size_t ecryptfs_get_key_size_to_enc_data(
 * !!! crypt_stat cipher name and mode must be initialized
 */
size_t ecryptfs_get_key_size_to_store_key(
		struct ecryptfs_crypt_stat *crypt_stat)
		const struct ecryptfs_crypt_stat *crypt_stat)
{
	size_t salt_size = 0;

@@ -329,14 +347,14 @@ size_t ecryptfs_get_key_size_to_store_key(
 * !!! crypt_stat cipher name and mode must be initialized
 */
size_t ecryptfs_get_key_size_to_restore_key(size_t stored_key_size,
		const char *cipher)
		const struct ecryptfs_crypt_stat *crypt_stat)
{
	size_t salt_size = 0;

	if (!cipher)
	if (!crypt_stat)
		return 0;

	salt_size = ecryptfs_get_salt_size_for_cipher(cipher);
	salt_size = ecryptfs_get_salt_size_for_cipher(crypt_stat);

	if (salt_size >= stored_key_size) {
		ecryptfs_printk(KERN_WARNING,
@@ -350,12 +368,26 @@ size_t ecryptfs_get_key_size_to_restore_key(size_t stored_key_size,
}

/**
 * Given cipher, the function returns appropriate salt size.
 * Given crypt_stat, the function returns appropriate salt size.
 */
size_t ecryptfs_get_salt_size_for_cipher(const char *cipher)
size_t ecryptfs_get_salt_size_for_cipher(
		const struct ecryptfs_crypt_stat *crypt_stat)
{
	if (!get_events() || !(get_events()->get_salt_key_size_cb))
		return 0;

	return get_events()->get_salt_key_size_cb(cipher);
	return get_events()->get_salt_key_size_cb(crypt_stat);
}

/**
 * Given mount_crypt_stat, the function returns appropriate salt size.
 */
size_t ecryptfs_get_salt_size_for_cipher_mount(
		const struct ecryptfs_mount_crypt_stat *crypt_stat)
{
	if (!get_events() || !(get_events()->get_salt_key_size_cb))
		return 0;

	return get_events()->get_salt_key_size_cb(crypt_stat);
}
+5 −12
Original line number Diff line number Diff line
@@ -1210,7 +1210,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
	memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
	       auth_tok->session_key.decrypted_key_size);
	crypt_stat->key_size = ecryptfs_get_key_size_to_restore_key(
			auth_tok->session_key.decrypted_key_size, full_cipher);
			auth_tok->session_key.decrypted_key_size, crypt_stat);

	ecryptfs_parse_full_cipher(full_cipher,
		crypt_stat->cipher, crypt_stat->cipher_mode);
@@ -1222,7 +1222,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
				  crypt_stat->key_size);

		ecryptfs_dump_salt_hex(crypt_stat->key, crypt_stat->key_size,
				full_cipher);
				crypt_stat);
	}
out:
	kfree(msg);
@@ -1495,7 +1495,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
		crypt_stat->key_size =
			ecryptfs_get_key_size_to_restore_key(
			(*new_auth_tok)->session_key.encrypted_key_size,
			full_cipher);
			crypt_stat);

	}
	rc = ecryptfs_init_crypt_ctx(crypt_stat);
@@ -1695,8 +1695,6 @@ static int
decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
					 struct ecryptfs_crypt_stat *crypt_stat)
{

	unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1];
	struct scatterlist dst_sg[2];
	struct scatterlist src_sg[2];
	struct mutex *tfm_mutex;
@@ -1776,9 +1774,7 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
		ecryptfs_dump_hex(crypt_stat->key,
				  crypt_stat->key_size);
		ecryptfs_dump_salt_hex(crypt_stat->key, crypt_stat->key_size,
				ecryptfs_get_full_cipher(crypt_stat->cipher,
					crypt_stat->cipher_mode,
					final, sizeof(final)));
				crypt_stat);
	}
out:
	return rc;
@@ -2347,10 +2343,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes,
	ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the key\n",
		crypt_stat->key_size);
	ecryptfs_printk(KERN_DEBUG, "Encrypting [%zd] bytes of the salt key\n",
		ecryptfs_get_salt_size_for_cipher(
			ecryptfs_get_full_cipher(crypt_stat->cipher,
				crypt_stat->cipher_mode,
				final, sizeof(final))));
		ecryptfs_get_salt_size_for_cipher(crypt_stat));
	rc = crypto_blkcipher_encrypt(&desc, dst_sg, src_sg,
				      (*key_rec).enc_key_size);
	mutex_unlock(tfm_mutex);
Loading