cryptfs: Require ext disk crypt to match code
Our external partitions have no crypto header/footer, so we
only get the keysize and key. Our code has been implicitly
assuming that this keysize off of disk matches the crypto
type we have in our code (and thus matches the keysize our
code is using as well). We now make this assumption
explicit, and check for this and no longer allow external
code to pass a keysize in to cryptfs.
Bug: 73079191
Test: Compiled and tested in combination with other CLs.
Change-Id: I1a1996187e1aaad6f103982652b1bcdfd5be33ce
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 8c66e01..62eb9a7 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -282,6 +282,14 @@
ftr->p_factor = pf;
}
+uint32_t cryptfs_get_keysize() {
+ return DEFAULT_KEY_LEN_BYTES;
+}
+
+const char *cryptfs_get_crypto_name() {
+ return "aes-cbc-essiv:sha256";
+}
+
static unsigned int get_fs_size(char *dev)
{
int fd, block_size;
@@ -1749,22 +1757,18 @@
/*
* Called by vold when it's asked to mount an encrypted external
* storage volume. The incoming partition has no crypto header/footer,
- * as any metadata is been stored in a separate, small partition.
+ * as any metadata is been stored in a separate, small partition. We
+ * assume it must be using our same crypt type and keysize.
*
* out_crypto_blkdev must be MAXPATHLEN.
*/
int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
- const unsigned char* key, int keysize, char* out_crypto_blkdev) {
+ const unsigned char* key, char* out_crypto_blkdev) {
int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
SLOGE("Failed to open %s: %s", real_blkdev, strerror(errno));
return -1;
}
- if (keysize > MAX_KEY_LEN) {
- SLOGE("ext_volume keysize (%d) larger than max (%d)\n", keysize,
- MAX_KEY_LEN);
- return -1;
- }
unsigned long nr_sec = 0;
get_blkdev_size(fd, &nr_sec);
@@ -1778,8 +1782,8 @@
struct crypt_mnt_ftr ext_crypt_ftr;
memset(&ext_crypt_ftr, 0, sizeof(ext_crypt_ftr));
ext_crypt_ftr.fs_size = nr_sec;
- ext_crypt_ftr.keysize = keysize;
- strlcpy((char*) ext_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256",
+ ext_crypt_ftr.keysize = cryptfs_get_keysize();
+ strlcpy((char*) ext_crypt_ftr.crypto_type_name, cryptfs_get_crypto_name(),
MAX_CRYPTO_TYPE_NAME_LEN);
return create_crypto_blk_dev(
@@ -1922,7 +1926,7 @@
}
/* Initialize a crypt_mnt_ftr structure. The keysize is
- * defaulted to DEFAULT_KEY_LEN_BYTES bytes, and the filesystem size to 0.
+ * defaulted to cryptfs_get_keysize() bytes, and the filesystem size to 0.
* Presumably, at a minimum, the caller will update the
* filesystem size and crypto_type_name after calling this function.
*/
@@ -1935,7 +1939,7 @@
ftr->major_version = CURRENT_MAJOR_VERSION;
ftr->minor_version = CURRENT_MINOR_VERSION;
ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
- ftr->keysize = DEFAULT_KEY_LEN_BYTES;
+ ftr->keysize = cryptfs_get_keysize();
switch (keymaster_check_compatibility()) {
case 1:
@@ -2190,7 +2194,7 @@
crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
}
crypt_ftr.crypt_type = crypt_type;
- strlcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256", MAX_CRYPTO_TYPE_NAME_LEN);
+ strlcpy((char *)crypt_ftr.crypto_type_name, cryptfs_get_crypto_name(), MAX_CRYPTO_TYPE_NAME_LEN);
/* Make an encrypted master key */
if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd,
diff --git a/cryptfs.h b/cryptfs.h
index bf4b405..d6c7dc5 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -30,6 +30,7 @@
*/
#include <stdbool.h>
+#include <stdint.h>
#include <cutils/properties.h>
/* The current cryptfs version */
@@ -235,7 +236,7 @@
int cryptfs_changepw(int type, const char* newpw);
int cryptfs_enable_default(int no_ui);
int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev, const unsigned char* key,
- int keysize, char* out_crypto_blkdev);
+ char* out_crypto_blkdev);
int cryptfs_revert_ext_volume(const char* label);
int cryptfs_getfield(const char* fieldname, char* value, int len);
int cryptfs_setfield(const char* fieldname, const char* value);
@@ -245,4 +246,7 @@
void cryptfs_clear_password(void);
int cryptfs_isConvertibleToFBE(void);
+uint32_t cryptfs_get_keysize();
+const char* cryptfs_get_crypto_name();
+
#endif /* ANDROID_VOLD_CRYPTFS_H */
diff --git a/model/Disk.cpp b/model/Disk.cpp
index becf8b7..9fcf5e1 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -30,6 +30,8 @@
#include <android-base/parseint.h>
#include <ext4_utils/ext4_crypt.h>
+#include "cryptfs.h"
+
#include <vector>
#include <fcntl.h>
#include <inttypes.h>
@@ -480,7 +482,7 @@
}
std::string keyRaw;
- if (ReadRandomBytes(16, keyRaw) != OK) {
+ if (ReadRandomBytes(cryptfs_get_keysize(), keyRaw) != OK) {
LOG(ERROR) << "Failed to generate key";
return -EIO;
}
diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp
index 48d041b..cf21577 100644
--- a/model/PrivateVolume.cpp
+++ b/model/PrivateVolume.cpp
@@ -65,6 +65,11 @@
if (CreateDeviceNode(mRawDevPath, mRawDevice)) {
return -EIO;
}
+ if (mKeyRaw.size() != cryptfs_get_keysize()) {
+ PLOG(ERROR) << getId() << " Raw keysize " << mKeyRaw.size() <<
+ " does not match crypt keysize " << cryptfs_get_keysize();
+ return -EIO;
+ }
// Recover from stale vold by tearing down any old mappings
cryptfs_revert_ext_volume(getId().c_str());
@@ -74,7 +79,7 @@
unsigned char* key = (unsigned char*) mKeyRaw.data();
char crypto_blkdev[MAXPATHLEN];
int res = cryptfs_setup_ext_volume(getId().c_str(), mRawDevPath.c_str(),
- key, mKeyRaw.size(), crypto_blkdev);
+ key, crypto_blkdev);
mDmDevPath = crypto_blkdev;
if (res != 0) {
PLOG(ERROR) << getId() << " failed to setup cryptfs";