123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /* Copyright (c) 2018, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include "fscrypt_ice.h"
- int fscrypt_using_hardware_encryption(const struct inode *inode)
- {
- struct fscrypt_info *ci = inode->i_crypt_info;
- return ci && is_private_mode(ci->ci_mode);
- }
- EXPORT_SYMBOL(fscrypt_using_hardware_encryption);
- /*
- * Retrieves encryption key from the inode
- */
- char *fscrypt_get_ice_encryption_key(const struct inode *inode)
- {
- struct fscrypt_info *ci = NULL;
- if (!inode)
- return NULL;
- ci = inode->i_crypt_info;
- if (!ci)
- return NULL;
- return &(ci->ci_raw_key[0]);
- }
- /*
- * Retrieves encryption salt from the inode
- */
- char *fscrypt_get_ice_encryption_salt(const struct inode *inode)
- {
- struct fscrypt_info *ci = NULL;
- if (!inode)
- return NULL;
- ci = inode->i_crypt_info;
- if (!ci)
- return NULL;
- return &(ci->ci_raw_key[fscrypt_get_ice_encryption_key_size(inode)]);
- }
- /*
- * returns true if the cipher mode in inode is AES XTS
- */
- int fscrypt_is_aes_xts_cipher(const struct inode *inode)
- {
- struct fscrypt_info *ci = inode->i_crypt_info;
- if (!ci)
- return 0;
- return (ci->ci_data_mode == FS_ENCRYPTION_MODE_PRIVATE);
- }
- /*
- * returns true if encryption info in both inodes is equal
- */
- bool fscrypt_is_ice_encryption_info_equal(const struct inode *inode1,
- const struct inode *inode2)
- {
- char *key1 = NULL;
- char *key2 = NULL;
- char *salt1 = NULL;
- char *salt2 = NULL;
- if (!inode1 || !inode2)
- return false;
- if (inode1 == inode2)
- return true;
- /* both do not belong to ice, so we don't care, they are equal for us */
- if (!fscrypt_should_be_processed_by_ice(inode1) &&
- !fscrypt_should_be_processed_by_ice(inode2))
- return true;
- /* one belongs to ice, the other does not -> not equal */
- if (fscrypt_should_be_processed_by_ice(inode1) ^
- fscrypt_should_be_processed_by_ice(inode2))
- return false;
- key1 = fscrypt_get_ice_encryption_key(inode1);
- key2 = fscrypt_get_ice_encryption_key(inode2);
- salt1 = fscrypt_get_ice_encryption_salt(inode1);
- salt2 = fscrypt_get_ice_encryption_salt(inode2);
- /* key and salt should not be null by this point */
- if (!key1 || !key2 || !salt1 || !salt2 ||
- (fscrypt_get_ice_encryption_key_size(inode1) !=
- fscrypt_get_ice_encryption_key_size(inode2)) ||
- (fscrypt_get_ice_encryption_salt_size(inode1) !=
- fscrypt_get_ice_encryption_salt_size(inode2)))
- return false;
- if ((memcmp(key1, key2,
- fscrypt_get_ice_encryption_key_size(inode1)) == 0) &&
- (memcmp(salt1, salt2,
- fscrypt_get_ice_encryption_salt_size(inode1)) == 0))
- return true;
- return false;
- }
- void fscrypt_set_ice_dun(const struct inode *inode, struct bio *bio, u64 dun)
- {
- if (fscrypt_should_be_processed_by_ice(inode))
- bio->bi_iter.bi_dun = dun;
- }
- EXPORT_SYMBOL(fscrypt_set_ice_dun);
- void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip)
- {
- #ifdef CONFIG_DM_DEFAULT_KEY
- bio->bi_crypt_skip = bi_crypt_skip;
- #endif
- }
- EXPORT_SYMBOL(fscrypt_set_ice_skip);
- /*
- * This function will be used for filesystem when deciding to merge bios.
- * Basic assumption is, if inline_encryption is set, single bio has to
- * guarantee consecutive LBAs as well as ino|pg->index.
- */
- bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted,
- int bi_crypt_skip)
- {
- if (!bio)
- return true;
- #ifdef CONFIG_DM_DEFAULT_KEY
- if (bi_crypt_skip != bio->bi_crypt_skip)
- return false;
- #endif
- /* if both of them are not encrypted, no further check is needed */
- if (!bio_dun(bio) && !bio_encrypted)
- return true;
- /* ICE allows only consecutive iv_key stream. */
- return bio_end_dun(bio) == dun;
- }
- EXPORT_SYMBOL(fscrypt_mergeable_bio);
|