summaryrefslogtreecommitdiff
path: root/fs/ecryptfs/events.c
diff options
context:
space:
mode:
authorGilad Broner <gbroner@codeaurora.org>2016-01-11 14:07:26 +0200
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-25 16:04:06 -0700
commitf50a4a1dc7a0196eb94bfaa18abb95dd387fee1e (patch)
tree46e88594582b5b69030c0eb224eca30a53f81da5 /fs/ecryptfs/events.c
parent53db8d989d8f077a5c8b2e41370449004b1c9199 (diff)
eCryptfs: fixed bug in cipher handling
Cipher was sometimes not treated properly, causing valid requests belonging to eCryptfs to be treated as regular. Change-Id: Iabfb93cc4c9e9e167901043482eb99613ed70343 Signed-off-by: Andrey Markovytch <andreym@codeaurora.org> Signed-off-by: Gilad Broner <gbroner@codeaurora.org>
Diffstat (limited to 'fs/ecryptfs/events.c')
-rw-r--r--fs/ecryptfs/events.c92
1 files changed, 62 insertions, 30 deletions
diff --git a/fs/ecryptfs/events.c b/fs/ecryptfs/events.c
index 043ea39c4901..12e26c683cf6 100644
--- a/fs/ecryptfs/events.c
+++ b/fs/ecryptfs/events.c
@@ -1,6 +1,6 @@
/**
* 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 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(crypt_stat);
+}
+
+/**
+ * Given mount_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_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(cipher);
+ return get_events()->get_salt_key_size_cb(crypt_stat);
}
+