diff --git a/cryptfs.cpp b/cryptfs.cpp index 234899e..f500a15 100644 --- a/cryptfs.cpp +++ b/cryptfs.cpp @@ -72,6 +72,7 @@ extern "C" { #define DM_CRYPT_BUF_SIZE 4096 #define HASH_COUNT 2000 +#define KEY_LEN_BYTES 16 #define IV_LEN_BYTES 16 #define KEY_IN_FOOTER "footer" @@ -100,11 +101,11 @@ extern "C" { // EVP_DecryptUpdate() requires not just our key length, but up to // block length - 1 additional bytes for its work. We provide a buffer // size that will work for all possible ciphers. -#define DECRYPTED_MASTER_KEY_BUF_SIZE (MAX_KEY_LEN + EVP_MAX_BLOCK_LENGTH - 1) +#define DECRYPTED_MASTER_KEY_BUF_SIZE (KEY_LEN_BYTES + EVP_MAX_BLOCK_LENGTH - 1) static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr); -static unsigned char saved_master_key[MAX_KEY_LEN]; +static unsigned char saved_master_key[KEY_LEN_BYTES]; static char *saved_mount_point; static int master_key_saved = 0; static struct crypt_persist_data *persist_data = NULL; @@ -259,94 +260,6 @@ static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, u } } -namespace { - -struct CryptType; - -// Use to get the CryptType in use on this device. -const CryptType &get_crypt_type(); - -struct CryptType { - const char * name; - __le32 keysize; - - constexpr CryptType(const char *n, size_t size) : name(n), keysize(size) {} - - private: - friend const CryptType &get_crypt_type(); - static const CryptType &get_device_crypt_name(); -}; - -// We only want to parse this read-only property once. But we need to wait -// until the system is initialized before we can read it. So we use a static -// scoped within this function to get it only once. -const CryptType &get_crypt_type() { - static CryptType crypt_type = CryptType::get_device_crypt_name(); - return crypt_type; -} - -__le32 get_keysize() { - return get_crypt_type().keysize; -} - -const char *get_crypt_name() { - return get_crypt_type().name; -} - - - -constexpr CryptType default_crypt_type = CryptType("aes-cbc-essiv:sha256", 16); - -constexpr CryptType supported_crypt_types[] = { - default_crypt_type, - CryptType("speck128-xts-plain64", 32), - // Add new CryptTypes here. Order is not important. -}; - - -// ---------- START COMPILE-TIME SANITY CHECK BLOCK ------------------------- -// We confirm all supported_crypt_types have a small enough keysize. - -template -constexpr size_t array_length(T (&)[N]) { return N; } - -constexpr bool indexOutOfBoundsForCryptTypes(size_t index) { - return (index >= array_length(supported_crypt_types)); -} - -// Note in C++11 that constexpr functions can only have a single line. -// So our code is a bit convoluted (using recursion instead of a loop), -// but it's asserting at compile time that all of our key lengths are valid. -constexpr bool validateSupportedCryptTypes(size_t index) { - return indexOutOfBoundsForCryptTypes(index) || - ((supported_crypt_types[index].keysize <= MAX_KEY_LEN) && - validateSupportedCryptTypes(index + 1)); -} - -static_assert(validateSupportedCryptTypes(0), - "We have a CryptType with keysize > MAX_KEYSIZE"); -// ---------- END COMPILE-TIME SANITY CHECK BLOCK ------------------------- - - -// Don't call this directly, use get_crypt_type(), which caches this result. -const CryptType &CryptType::get_device_crypt_name() { - constexpr char CRYPT_TYPE_PROP[] = "ro.crypto.crypt_type_name"; - char paramstr[PROPERTY_VALUE_MAX]; - - property_get(CRYPT_TYPE_PROP, paramstr, default_crypt_type.name); - for (auto const &ctype : supported_crypt_types) { - if (strcmp(paramstr, ctype.name) == 0) { - return ctype; - } - } - ALOGE("Invalid name (%s) for %s. Defaulting to %s\n", paramstr, - CRYPT_TYPE_PROP, default_crypt_type.name); - return default_crypt_type; -} - -} // namespace - - /** * Gets the default device scrypt parameters for key derivation time tuning. * The parameters should lead to about one second derivation time for the @@ -938,7 +851,7 @@ static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, struct dm_ioctl *io; struct dm_target_spec *tgt; char *crypt_params; - // We can't assume the key is only get_keysize(). But we do know its limit + // We can't assume the key is only KEY_LEN_BYTES. But we do know its limit // due to the crypt_mnt_ftr struct. We need two ASCII characters to represent // each byte, and need space for the '\0' terminator. char master_key_ascii[sizeof(crypt_ftr->master_key) * 2 + 1]; @@ -1135,7 +1048,7 @@ static int pbkdf2(const char *passwd, const unsigned char *salt, /* Turn the password into a key and IV that can decrypt the master key */ return PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN, - HASH_COUNT, get_keysize() + IV_LEN_BYTES, + HASH_COUNT, KEY_LEN_BYTES + IV_LEN_BYTES, ikey) != 1; } @@ -1153,7 +1066,7 @@ static int scrypt(const char *passwd, const unsigned char *salt, /* Turn the password into a key and IV that can decrypt the master key */ crypto_scrypt((const uint8_t*)passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey, - get_keysize() + IV_LEN_BYTES); + KEY_LEN_BYTES + IV_LEN_BYTES); return 0; } @@ -1174,21 +1087,21 @@ static int scrypt_keymaster(const char *passwd, const unsigned char *salt, rc = crypto_scrypt((const uint8_t*)passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey, - get_keysize() + IV_LEN_BYTES); + KEY_LEN_BYTES + IV_LEN_BYTES); if (rc) { SLOGE("scrypt failed"); return -1; } - if (keymaster_sign_object(ftr, ikey, get_keysize() + IV_LEN_BYTES, + if (keymaster_sign_object(ftr, ikey, KEY_LEN_BYTES + IV_LEN_BYTES, &signature, &signature_size)) { SLOGE("Signing failed"); return -1; } rc = crypto_scrypt(signature, signature_size, salt, SALT_LEN, - N, r, p, ikey, get_keysize() + IV_LEN_BYTES); + N, r, p, ikey, KEY_LEN_BYTES + IV_LEN_BYTES); free(signature); if (rc) { @@ -1204,7 +1117,7 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt, unsigned char *encrypted_master_key, struct crypt_mnt_ftr *crypt_ftr) { - unsigned char ikey[MAX_KEY_LEN+IV_LEN_BYTES] = { 0 }; + unsigned char ikey[KEY_LEN_BYTES+IV_LEN_BYTES] = { 0 }; EVP_CIPHER_CTX e_ctx; int encrypted_len, final_len; int rc = 0; @@ -1239,7 +1152,7 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt, /* Initialize the decryption engine */ EVP_CIPHER_CTX_init(&e_ctx); - if (! EVP_EncryptInit_ex(&e_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+get_keysize())) { + if (! EVP_EncryptInit_ex(&e_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+KEY_LEN_BYTES)) { SLOGE("EVP_EncryptInit failed\n"); return -1; } @@ -1247,7 +1160,7 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt, /* Encrypt the master key */ if (! EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len, - decrypted_master_key, get_keysize())) { + decrypted_master_key, KEY_LEN_BYTES)) { SLOGE("EVP_EncryptUpdate failed\n"); return -1; } @@ -1256,7 +1169,7 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt, return -1; } - if (encrypted_len + final_len != static_cast(get_keysize())) { + if (encrypted_len + final_len != KEY_LEN_BYTES) { SLOGE("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len); return -1; } @@ -1270,7 +1183,7 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt, int r = 1 << crypt_ftr->r_factor; int p = 1 << crypt_ftr->p_factor; - rc = crypto_scrypt(ikey, get_keysize(), + rc = crypto_scrypt(ikey, KEY_LEN_BYTES, crypt_ftr->salt, sizeof(crypt_ftr->salt), N, r, p, crypt_ftr->scrypted_intermediate_key, sizeof(crypt_ftr->scrypted_intermediate_key)); @@ -1291,7 +1204,7 @@ static int decrypt_master_key_aux(const char *passwd, unsigned char *salt, unsigned char** intermediate_key, size_t* intermediate_key_size) { - unsigned char ikey[MAX_KEY_LEN+IV_LEN_BYTES] = { 0 }; + unsigned char ikey[KEY_LEN_BYTES+IV_LEN_BYTES] = { 0 }; EVP_CIPHER_CTX d_ctx; int decrypted_len, final_len; @@ -1304,29 +1217,29 @@ static int decrypt_master_key_aux(const char *passwd, unsigned char *salt, /* Initialize the decryption engine */ EVP_CIPHER_CTX_init(&d_ctx); - if (! EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+get_keysize())) { + if (! EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+KEY_LEN_BYTES)) { return -1; } EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */ /* Decrypt the master key */ if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len, - encrypted_master_key, get_keysize())) { + encrypted_master_key, KEY_LEN_BYTES)) { return -1; } if (! EVP_DecryptFinal_ex(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) { return -1; } - if (decrypted_len + final_len != static_cast(get_keysize())) { + if (decrypted_len + final_len != KEY_LEN_BYTES) { return -1; } /* Copy intermediate key if needed by params */ if (intermediate_key && intermediate_key_size) { - *intermediate_key = (unsigned char*) malloc(get_keysize()); + *intermediate_key = (unsigned char*) malloc(KEY_LEN_BYTES); if (*intermediate_key) { - memcpy(*intermediate_key, ikey, get_keysize()); - *intermediate_key_size = get_keysize(); + memcpy(*intermediate_key, ikey, KEY_LEN_BYTES); + *intermediate_key_size = KEY_LEN_BYTES; } } @@ -1372,7 +1285,7 @@ static int decrypt_master_key(const char *passwd, unsigned char *decrypted_maste static int create_encrypted_random_key(const char *passwd, unsigned char *master_key, unsigned char *salt, struct crypt_mnt_ftr *crypt_ftr) { int fd; - unsigned char key_buf[MAX_KEY_LEN]; + unsigned char key_buf[KEY_LEN_BYTES]; /* Get some random bits for a key */ fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC); @@ -1770,7 +1683,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, /* Also save a the master key so we can reencrypted the key * the key when we want to change the password on it. */ - memcpy(saved_master_key, decrypted_master_key, get_keysize()); + memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES); saved_mount_point = strdup(mount_point); master_key_saved = 1; SLOGD("%s(): Master key saved\n", __FUNCTION__); @@ -1845,7 +1758,7 @@ int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev, 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, get_crypt_name(), + strlcpy((char*) ext_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256", MAX_CRYPTO_TYPE_NAME_LEN); return create_crypto_blk_dev( @@ -1988,7 +1901,7 @@ int cryptfs_verify_passwd(const char *passwd) } /* Initialize a crypt_mnt_ftr structure. The keysize is - * defaulted to get_keysize(), and the filesystem size to 0. + * defaulted to 16 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. */ @@ -2001,7 +1914,7 @@ static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr) ftr->major_version = CURRENT_MAJOR_VERSION; ftr->minor_version = CURRENT_MINOR_VERSION; ftr->ftr_size = sizeof(struct crypt_mnt_ftr); - ftr->keysize = get_keysize(); + ftr->keysize = KEY_LEN_BYTES; switch (keymaster_check_compatibility()) { case 1: @@ -2253,7 +2166,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE; } crypt_ftr.crypt_type = crypt_type; - strlcpy((char *)crypt_ftr.crypto_type_name, get_crypt_name(), MAX_CRYPTO_TYPE_NAME_LEN); + strlcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256", MAX_CRYPTO_TYPE_NAME_LEN); /* Make an encrypted master key */ if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd, @@ -2264,8 +2177,8 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) { /* Replace scrypted intermediate key if we are preparing for a reboot */ if (onlyCreateHeader) { - unsigned char fake_master_key[MAX_KEY_LEN]; - unsigned char encrypted_fake_master_key[MAX_KEY_LEN]; + unsigned char fake_master_key[KEY_LEN_BYTES]; + unsigned char encrypted_fake_master_key[KEY_LEN_BYTES]; memset(fake_master_key, 0, sizeof(fake_master_key)); encrypt_master_key(passwd, crypt_ftr.salt, fake_master_key, encrypted_fake_master_key, &crypt_ftr);