blob: d85bcb8ea1ba9fcac3eb149eb3fbd0d7ae1152a9 [file] [log] [blame]
/* Copyright (c) 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
* 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 "ext4_ice.h"
#include "ext4_crypto.h"
/*
* Retrieves encryption key from the inode
*/
char *ext4_get_ice_encryption_key(const struct inode *inode)
{
struct ext4_crypt_info *ci = NULL;
if (!inode)
return NULL;
ci = ext4_encryption_info((struct inode *)inode);
if (!ci)
return NULL;
return &(ci->ci_raw_key[0]);
}
/*
* Retrieves encryption salt from the inode
*/
char *ext4_get_ice_encryption_salt(const struct inode *inode)
{
struct ext4_crypt_info *ci = NULL;
if (!inode)
return NULL;
ci = ext4_encryption_info((struct inode *)inode);
if (!ci)
return NULL;
return &(ci->ci_raw_key[ext4_get_ice_encryption_key_size(inode)]);
}
/*
* returns true if the cipher mode in inode is AES XTS
*/
int ext4_is_aes_xts_cipher(const struct inode *inode)
{
struct ext4_crypt_info *ci = NULL;
ci = ext4_encryption_info((struct inode *)inode);
if (!ci)
return 0;
return (ci->ci_data_mode == EXT4_ENCRYPTION_MODE_PRIVATE);
}
/*
* returns true if encryption info in both inodes is equal
*/
int ext4_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 0;
if (inode1 == inode2)
return 1;
/* both do not belong to ice, so we don't care, they are equal for us */
if (!ext4_should_be_processed_by_ice(inode1) &&
!ext4_should_be_processed_by_ice(inode2))
return 1;
/* one belongs to ice, the other does not -> not equal */
if (ext4_should_be_processed_by_ice(inode1) ^
ext4_should_be_processed_by_ice(inode2))
return 0;
key1 = ext4_get_ice_encryption_key(inode1);
key2 = ext4_get_ice_encryption_key(inode2);
salt1 = ext4_get_ice_encryption_salt(inode1);
salt2 = ext4_get_ice_encryption_salt(inode2);
/* key and salt should not be null by this point */
if (!key1 || !key2 || !salt1 || !salt2 ||
(ext4_get_ice_encryption_key_size(inode1) !=
ext4_get_ice_encryption_key_size(inode2)) ||
(ext4_get_ice_encryption_salt_size(inode1) !=
ext4_get_ice_encryption_salt_size(inode2)))
return 0;
return ((memcmp(key1, key2,
ext4_get_ice_encryption_key_size(inode1)) == 0) &&
(memcmp(salt1, salt2,
ext4_get_ice_encryption_salt_size(inode1)) == 0));
}