diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp index dcdcd62..d200ca6 100644 --- a/Ext4Crypt.cpp +++ b/Ext4Crypt.cpp @@ -25,10 +25,14 @@ namespace { static_assert(key_length % 8 == 0, "Key length must be multiple of 8 bits"); + // How long do we store passwords for? + const int password_max_age_seconds = 60; + // How is device encrypted struct keys { std::string master_key; std::string password; + time_t expiry_time; }; std::map s_key_store; @@ -318,9 +322,12 @@ int e4crypt_check_passwd(const char* path, const char* password) } } + struct timespec now; + clock_gettime(CLOCK_BOOTTIME, &now); s_key_store[path] = keys{std::string(reinterpret_cast(master_key), sizeof(master_key)), - password}; + password, + now.tv_sec + password_max_age_seconds}; // Install password into global keyring // ext4enc:TODO Currently raw key is required to be of length @@ -403,24 +410,43 @@ int e4crypt_restart(const char* path) return 0; } +int e4crypt_get_password_type(const char* path) +{ + SLOGI("e4crypt_get_password_type"); + return GetPropsOrAltProps(path).GetChild(properties::key) + .Get(tag::crypt_type, CRYPT_TYPE_DEFAULT); +} + const char* e4crypt_get_password(const char* path) { SLOGI("e4crypt_get_password"); - // ext4enc:TODO scrub password after timeout auto i = s_key_store.find(path); if (i == s_key_store.end()) { return 0; - } else { - return i->second.password.c_str(); } + + struct timespec now; + clock_gettime(CLOCK_BOOTTIME, &now); + if (i->second.expiry_time < now.tv_sec) { + e4crypt_clear_password(path); + return 0; + } + + return i->second.password.c_str(); } -int e4crypt_get_password_type(const char* path) +void e4crypt_clear_password(const char* path) { - SLOGI("e4crypt_get_password_type"); - return GetPropsOrAltProps(path).GetChild(properties::key) - .Get(tag::crypt_type, CRYPT_TYPE_DEFAULT); + SLOGI("e4crypt_clear_password"); + + auto i = s_key_store.find(path); + if (i == s_key_store.end()) { + return; + } + + memset(&i->second.password[0], 0, i->second.password.size()); + i->second.password = std::string(); } int e4crypt_get_field(const char* path, const char* fieldname, diff --git a/Ext4Crypt.h b/Ext4Crypt.h index 68e0fb2..53a26a0 100644 --- a/Ext4Crypt.h +++ b/Ext4Crypt.h @@ -12,6 +12,7 @@ int e4crypt_crypto_complete(const char* path); int e4crypt_check_passwd(const char* path, const char* password); int e4crypt_get_password_type(const char* path); const char* e4crypt_get_password(const char* path); +void e4crypt_clear_password(const char* path); int e4crypt_restart(const char* path); int e4crypt_get_field(const char* path, const char* fieldname, char* value, size_t len); diff --git a/cryptfs.c b/cryptfs.c index 5598671..5422f52 100644 --- a/cryptfs.c +++ b/cryptfs.c @@ -3805,6 +3805,10 @@ const char* cryptfs_get_password() void cryptfs_clear_password() { + if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) { + e4crypt_clear_password(DATA_MNT_POINT); + } + if (password) { size_t len = strlen(password); memset(password, 0, len);