@ -38,6 +38,7 @@
# include <cutils/android_reboot.h>
# include <ext4.h>
# include <linux/kdev_t.h>
# include <fs_mgr.h>
# include "cryptfs.h"
# define LOG_TAG "Cryptfs"
# include "cutils/android_reboot.h"
@ -53,7 +54,6 @@
# define KEY_LEN_BYTES 16
# define IV_LEN_BYTES 16
# define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
# define KEY_IN_FOOTER "footer"
# define EXT4_FS 1
@ -65,6 +65,8 @@ static unsigned char saved_master_key[KEY_LEN_BYTES];
static char * saved_data_blkdev ;
static char * saved_mount_point ;
static int master_key_saved = 0 ;
# define FSTAB_PREFIX " / fstab."
static char fstab_filename [ PROPERTY_VALUE_MAX + sizeof ( FSTAB_PREFIX ) ] ;
static void ioctl_init ( struct dm_ioctl * io , size_t dataSize , const char * name , unsigned flags )
{
@ -122,6 +124,19 @@ static unsigned int get_blkdev_size(int fd)
return nr_sec ;
}
/* Get and cache the name of the fstab file so we don't
* keep talking over the socket to the property service .
*/
static char * get_fstab_filename ( void )
{
if ( fstab_filename [ 0 ] = = 0 ) {
strcpy ( fstab_filename , FSTAB_PREFIX ) ;
property_get ( " ro.hardware " , fstab_filename + sizeof ( FSTAB_PREFIX ) - 1 , " " ) ;
}
return fstab_filename ;
}
/* key or salt can be NULL, in which case just skip writing that value. Useful to
* update the failed mount count but not change the key .
*/
@ -136,7 +151,7 @@ static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
char key_loc [ PROPERTY_VALUE_MAX ] ;
struct stat statbuf ;
property_get( KEY_LOC_PROP , key_loc , KEY_IN_FOOTER ) ;
fs_mgr_get_crypt_info( get_fstab_filename ( ) , key_loc , 0 , sizeof ( key_loc ) ) ;
if ( ! strcmp ( key_loc , KEY_IN_FOOTER ) ) {
fname = real_blk_name ;
@ -167,7 +182,7 @@ static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
return - 1 ;
}
} else {
SLOGE ( " Unexpected value for " KEY_LOC_PROP " \n " ) ;
SLOGE ( " Unexpected value for crypto key location \n " ) ;
return - 1 ; ;
}
@ -235,7 +250,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
char * fname ;
struct stat statbuf ;
property_get( KEY_LOC_PROP , key_loc , KEY_IN_FOOTER ) ;
fs_mgr_get_crypt_info( get_fstab_filename ( ) , key_loc , 0 , sizeof ( key_loc ) ) ;
if ( ! strcmp ( key_loc , KEY_IN_FOOTER ) ) {
fname = real_blk_name ;
@ -273,7 +288,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp
goto errout ;
}
} else {
SLOGE ( " Unexpected value for " KEY_LOC_PROP " \n " ) ;
SLOGE ( " Unexpected value for crypto key location \n " ) ;
return - 1 ; ;
}
@ -557,27 +572,6 @@ static int create_encrypted_random_key(char *passwd, unsigned char *master_key,
return encrypt_master_key ( passwd , salt , key_buf , master_key ) ;
}
static int get_orig_mount_parms ( char * mount_point , char * fs_type , char * real_blkdev ,
unsigned long * mnt_flags , char * fs_options )
{
char mount_point2 [ PROPERTY_VALUE_MAX ] ;
char fs_flags [ PROPERTY_VALUE_MAX ] ;
property_get ( " ro.crypto.fs_type " , fs_type , " " ) ;
property_get ( " ro.crypto.fs_real_blkdev " , real_blkdev , " " ) ;
property_get ( " ro.crypto.fs_mnt_point " , mount_point2 , " " ) ;
property_get ( " ro.crypto.fs_options " , fs_options , " " ) ;
property_get ( " ro.crypto.fs_flags " , fs_flags , " " ) ;
* mnt_flags = strtol ( fs_flags , 0 , 0 ) ;
if ( strcmp ( mount_point , mount_point2 ) ) {
/* Consistency check. These should match. If not, something odd happened. */
return - 1 ;
}
return 0 ;
}
static int wait_and_unmount ( char * mountpoint )
{
int i , rc ;
@ -692,26 +686,22 @@ int cryptfs_restart(void)
return - 1 ;
}
if ( ! get_orig_mount_parms ( DATA_MNT_POINT , fs_type , real_blkdev , & mnt_flags , fs_options ) ) {
SLOGD ( " Just got orig mount parms \n " ) ;
if ( ! ( rc = wait_and_unmount ( DATA_MNT_POINT ) ) ) {
/* If that succeeded, then mount the decrypted filesystem */
mount ( crypto_blkdev , DATA_MNT_POINT , fs_type , mnt_flags , fs_options ) ;
if ( ! ( rc = wait_and_unmount ( DATA_MNT_POINT ) ) ) {
/* If that succeeded, then mount the decrypted filesystem */
fs_mgr_do_mount ( get_fstab_filename ( ) , DATA_MNT_POINT , crypto_blkdev , 0 ) ;
property_set ( " vold.decrypt " , " trigger_load_persist_props " ) ;
/* Create necessary paths on /data */
if ( prep_data_fs ( ) ) {
return - 1 ;
}
property_set ( " vold.decrypt " , " trigger_load_persist_props " ) ;
/* Create necessary paths on /data */
if ( prep_data_fs ( ) ) {
return - 1 ;
}
/* startup service classes main and late_start */
property_set ( " vold.decrypt " , " trigger_restart_framework " ) ;
SLOGD ( " Just triggered restart_framework \n " ) ;
/* startup service classes main and late_start */
property_set ( " vold.decrypt " , " trigger_restart_framework " ) ;
SLOGD ( " Just triggered restart_framework \n " ) ;
/* Give it a few moments to get started */
sleep ( 1 ) ;
}
/* Give it a few moments to get started */
sleep ( 1 ) ;
}
if ( rc = = 0 ) {
@ -727,9 +717,6 @@ static int do_crypto_complete(char *mount_point)
unsigned char encrypted_master_key [ 32 ] ;
unsigned char salt [ SALT_LEN ] ;
char real_blkdev [ MAXPATHLEN ] ;
char fs_type [ PROPERTY_VALUE_MAX ] ;
char fs_options [ PROPERTY_VALUE_MAX ] ;
unsigned long mnt_flags ;
char encrypted_state [ PROPERTY_VALUE_MAX ] ;
char key_loc [ PROPERTY_VALUE_MAX ] ;
@ -739,13 +726,11 @@ static int do_crypto_complete(char *mount_point)
return 1 ;
}
if ( get_orig_mount_parms ( mount_point , fs_type , real_blkdev , & mnt_flags , fs_options ) ) {
SLOGE ( " Error reading original mount parms for mount point %s \n " , mount_point ) ;
return - 1 ;
}
fs_mgr_get_crypt_info ( get_fstab_filename ( ) , 0 , real_blkdev , sizeof ( real_blkdev ) ) ;
if ( get_crypt_ftr_and_key ( real_blkdev , & crypt_ftr , encrypted_master_key , salt ) ) {
property_get ( KEY_LOC_PROP , key_loc , KEY_IN_FOOTER ) ;
fs_mgr_get_crypt_info ( get_fstab_filename ( ) , key_loc , 0 , sizeof ( key_loc ) ) ;
/*
* Only report this error if key_loc is a file and it exists .
* If the device was never encrypted , and / data is not mountable for
@ -780,10 +765,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label)
unsigned char salt [ SALT_LEN ] ;
char crypto_blkdev [ MAXPATHLEN ] ;
char real_blkdev [ MAXPATHLEN ] ;
char fs_type [ PROPERTY_VALUE_MAX ] ;
char fs_options [ PROPERTY_VALUE_MAX ] ;
char tmp_mount_point [ 64 ] ;
unsigned long mnt_flags ;
unsigned int orig_failed_decrypt_count ;
char encrypted_state [ PROPERTY_VALUE_MAX ] ;
int rc ;
@ -794,10 +776,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label)
return - 1 ;
}
if ( get_orig_mount_parms ( mount_point , fs_type , real_blkdev , & mnt_flags , fs_options ) ) {
SLOGE ( " Error reading original mount parms for mount point %s \n " , mount_point ) ;
return - 1 ;
}
fs_mgr_get_crypt_info ( get_fstab_filename ( ) , 0 , real_blkdev , sizeof ( real_blkdev ) ) ;
if ( get_crypt_ftr_and_key ( real_blkdev , & crypt_ftr , encrypted_master_key , salt ) ) {
SLOGE ( " Error getting crypt footer and key \n " ) ;
@ -826,7 +805,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label)
*/
sprintf ( tmp_mount_point , " %s/tmp_mnt " , mount_point ) ;
mkdir ( tmp_mount_point , 0755 ) ;
if ( mount( crypto_blkdev , tmp_mount_point , " ext4 " , MS_RDONLY , " " ) ) {
if ( fs_mgr_do_ mount( get_fstab_filename ( ) , DATA_MNT_POINT , crypto_blkdev , tmp_mount_point )) {
SLOGE ( " Error temp mounting decrypted block device \n " ) ;
delete_crypto_blk_dev ( label ) ;
crypt_ftr . failed_decrypt_count + + ;
@ -938,9 +917,6 @@ int cryptfs_verify_passwd(char *passwd)
unsigned char encrypted_master_key [ 32 ] , decrypted_master_key [ 32 ] ;
unsigned char salt [ SALT_LEN ] ;
char real_blkdev [ MAXPATHLEN ] ;
char fs_type [ PROPERTY_VALUE_MAX ] ;
char fs_options [ PROPERTY_VALUE_MAX ] ;
unsigned long mnt_flags ;
char encrypted_state [ PROPERTY_VALUE_MAX ] ;
int rc ;
@ -960,10 +936,7 @@ int cryptfs_verify_passwd(char *passwd)
return - 1 ;
}
if ( get_orig_mount_parms ( saved_mount_point , fs_type , real_blkdev , & mnt_flags , fs_options ) ) {
SLOGE ( " Error reading original mount parms for mount point %s \n " , saved_mount_point ) ;
return - 1 ;
}
fs_mgr_get_crypt_info ( get_fstab_filename ( ) , 0 , real_blkdev , sizeof ( real_blkdev ) ) ;
if ( get_crypt_ftr_and_key ( real_blkdev , & crypt_ftr , encrypted_master_key , salt ) ) {
SLOGE ( " Error getting crypt footer and key \n " ) ;
@ -1143,9 +1116,7 @@ int cryptfs_enable(char *howarg, char *passwd)
{
int how = 0 ;
char crypto_blkdev [ MAXPATHLEN ] , real_blkdev [ MAXPATHLEN ] , sd_crypto_blkdev [ MAXPATHLEN ] ;
char fs_type [ PROPERTY_VALUE_MAX ] , fs_options [ PROPERTY_VALUE_MAX ] ,
mount_point [ PROPERTY_VALUE_MAX ] ;
unsigned long mnt_flags , nr_sec ;
unsigned long nr_sec ;
unsigned char master_key [ KEY_LEN_BYTES ] , decrypted_master_key [ KEY_LEN_BYTES ] ;
unsigned char salt [ SALT_LEN ] ;
int rc = - 1 , fd , i , ret ;
@ -1167,7 +1138,7 @@ int cryptfs_enable(char *howarg, char *passwd)
goto error_unencrypted ;
}
property_get( KEY_LOC_PROP , key_loc , KEY_IN_FOOTER ) ;
fs_mgr_get_crypt_info( get_fstab_filename ( ) , key_loc , 0 , sizeof ( key_loc ) ) ;
if ( ! strcmp ( howarg , " wipe " ) ) {
how = CRYPTO_ENABLE_WIPE ;
@ -1178,7 +1149,7 @@ int cryptfs_enable(char *howarg, char *passwd)
goto error_unencrypted ;
}
get_orig_mount_parms( mount_point , fs_type , real_blkdev , & mnt_flags , fs_options ) ;
fs_mgr_get_crypt_info( get_fstab_filename ( ) , 0 , real_blkdev , sizeof ( real_blkdev ) ) ;
/* Get the size of the real block device */
fd = open ( real_blkdev , O_RDONLY ) ;
@ -1267,9 +1238,7 @@ int cryptfs_enable(char *howarg, char *passwd)
* / data , set a property saying we ' re doing inplace encryption ,
* and restart the framework .
*/
property_get ( " ro.crypto.tmpfs_options " , tmpfs_options , " " ) ;
if ( mount ( " tmpfs " , DATA_MNT_POINT , " tmpfs " , MS_NOATIME | MS_NOSUID | MS_NODEV ,
tmpfs_options ) < 0 ) {
if ( fs_mgr_do_tmpfs_mount ( DATA_MNT_POINT ) ) {
goto error_shutting_down ;
}
/* Tells the framework that inplace encryption is starting */
@ -1456,7 +1425,7 @@ int cryptfs_changepw(char *newpw)
return - 1 ;
}
property_get( " ro.crypto.fs_real_blkdev " , real_blkdev , " " ) ;
fs_mgr_get_crypt_info( get_fstab_filename ( ) , 0 , real_blkdev , sizeof ( real_blkdev ) ) ;
if ( strlen ( real_blkdev ) = = 0 ) {
SLOGE ( " Can't find real blkdev " ) ;
return - 1 ;