18f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall/* 28f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * Copyright (C) 2010 The Android Open Source Project 38f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * 48f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * Licensed under the Apache License, Version 2.0 (the "License"); 58f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * you may not use this file except in compliance with the License. 68f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * You may obtain a copy of the License at 78f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * 88f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * http://www.apache.org/licenses/LICENSE-2.0 98f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * 108f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * Unless required by applicable law or agreed to in writing, software 118f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * distributed under the License is distributed on an "AS IS" BASIS, 128f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * See the License for the specific language governing permissions and 148f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * limitations under the License. 158f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 168f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 178f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall/* TO DO: 188f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * 1. Perhaps keep several copies of the encrypted key, in case something 198f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * goes horribly wrong? 208f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * 218f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 228f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 238f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <sys/types.h> 24e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall#include <sys/wait.h> 258f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <sys/stat.h> 26f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence#include <ctype.h> 278f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <fcntl.h> 287373716c6d65ca328de11c994c60f698a9ef6290Elliott Hughes#include <inttypes.h> 298f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <unistd.h> 308f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <stdio.h> 318f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <sys/ioctl.h> 328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <linux/dm-ioctl.h> 338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <libgen.h> 348f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <stdlib.h> 358f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <sys/param.h> 368f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <string.h> 378f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <sys/mount.h> 388f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <openssl/evp.h> 3941405bb3e5cdde0782bfcf7065b88ce1bb253c3cAdam Langley#include <openssl/sha.h> 408f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include <errno.h> 415a95ddbacfe4ec74b6b90dd7a9bc76d27b173758Tao Bao#include <ext4_utils/ext4.h> 425a95ddbacfe4ec74b6b90dd7a9bc76d27b173758Tao Bao#include <ext4_utils/ext4_utils.h> 4329d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall#include <linux/kdev_t.h> 44e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall#include <fs_mgr.h> 459c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence#include <time.h> 4685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu#include <math.h> 47df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep#include <selinux/selinux.h> 488f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include "cryptfs.h" 49df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep#include "secontext.h" 508f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#define LOG_TAG "Cryptfs" 518f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include "cutils/log.h" 528f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include "cutils/properties.h" 53adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall#include "cutils/android_reboot.h" 545d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall#include "hardware_legacy/power.h" 55e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall#include <logwrap/logwrap.h> 5663c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley#include "ScryptParameters.h" 5729d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall#include "VolumeManager.h" 589caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall#include "VoldUtil.h" 59731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence#include "Ext4Crypt.h" 60e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg#include "f2fs_sparseblock.h" 6187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence#include "CheckBattery.h" 623f14fe45a3e7bc0d12ba26d20a36d355a10f623ejessica_yu#include "Process.h" 63015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis#include "Keymaster.h" 644375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang#include "android-base/properties.h" 651fb5966fbb4e05d15cb10ff371137b4ef9dff584Yabin Cui#include <bootloader_message/bootloader_message.h> 664375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wangextern "C" { 674375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang#include <crypto_scrypt.h> 684375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang} 693e971277db0d87652af5622c989233e7159ab909Mark Salyzyn 705eecc449cc75771cc0c6eb0ad936117d16704b83Mark Salyzyn#define UNUSED __attribute__((unused)) 715eecc449cc75771cc0c6eb0ad936117d16704b83Mark Salyzyn 728f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#define DM_CRYPT_BUF_SIZE 4096 738f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 7470a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks#define HASH_COUNT 2000 7570a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks#define KEY_LEN_BYTES 16 7670a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks#define IV_LEN_BYTES 16 7770a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks 7829d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall#define KEY_IN_FOOTER "footer" 7929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 803bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence#define DEFAULT_PASSWORD "default_password" 81f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 823d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence#define CRYPTO_BLOCK_DEVICE "userdata" 833d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 843d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence#define BREADCRUMB_FILE "/data/misc/vold/convert_fde" 853d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 8629d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall#define EXT4_FS 1 8762c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall#define F2FS_FS 2 8829d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 89e919efea94b178ed214ed2e78ef0d008727d62abKen Sumrall#define TABLE_LOAD_RETRIES 10 90e919efea94b178ed214ed2e78ef0d008727d62abKen Sumrall 9147ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden#define RSA_KEY_SIZE 2048 9247ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden#define RSA_KEY_SIZE_BYTES (RSA_KEY_SIZE / 8) 9347ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden#define RSA_EXPONENT 0x10001 94da6e899f4e1429add2ef023e0cc6b0fcca42c945Shawn Willden#define KEYMASTER_CRYPTFS_RATE_LIMIT 1 // Maximum one try per second 9569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 968e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence#define RETRY_MOUNT_ATTEMPTS 10 978e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence#define RETRY_MOUNT_DELAY_SECONDS 1 988e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence 9970a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parksstatic unsigned char saved_master_key[KEY_LEN_BYTES]; 1003ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrallstatic char *saved_mount_point; 10170a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parksstatic int master_key_saved = 0; 102160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic struct crypt_persist_data *persist_data = NULL; 10356ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall 10469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence/* Should we use keymaster? */ 10569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int keymaster_check_compatibility() 10669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence{ 107015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis return keymaster_compatibility_cryptfs_scrypt(); 10869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence} 10969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 11069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence/* Create a new keymaster key and store it in this footer */ 11169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int keymaster_create_key(struct crypt_mnt_ftr *ftr) 11269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence{ 1133d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (ftr->keymaster_blob_size) { 1143d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SLOGI("Already have key"); 1153d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence return 0; 1163d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 1173d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 118015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis int rc = keymaster_create_key_for_cryptfs_scrypt(RSA_KEY_SIZE, RSA_EXPONENT, 119015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob, KEYMASTER_BLOB_SIZE, 120015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis &ftr->keymaster_blob_size); 121015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis if (rc) { 122015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis if (ftr->keymaster_blob_size > KEYMASTER_BLOB_SIZE) { 123015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis SLOGE("Keymaster key blob to large)"); 124015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis ftr->keymaster_blob_size = 0; 125cfc5202147a1f72a61415266f0d4097544ce8b89Alex Klyubin } 126015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis SLOGE("Failed to generate keypair"); 127015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis return -1; 128cfc5202147a1f72a61415266f0d4097544ce8b89Alex Klyubin } 129015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis return 0; 13069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence} 13169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 132e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden/* This signs the given object using the keymaster key. */ 133e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willdenstatic int keymaster_sign_object(struct crypt_mnt_ftr *ftr, 13447ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden const unsigned char *object, 13547ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden const size_t object_size, 13647ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden unsigned char **signature, 13747ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden size_t *signature_size) 13847ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden{ 13947ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden unsigned char to_sign[RSA_KEY_SIZE_BYTES]; 140e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden size_t to_sign_size = sizeof(to_sign); 14147ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden memset(to_sign, 0, RSA_KEY_SIZE_BYTES); 14247ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden 143e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // To sign a message with RSA, the message must satisfy two 144e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // constraints: 145e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // 146e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // 1. The message, when interpreted as a big-endian numeric value, must 147e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // be strictly less than the public modulus of the RSA key. Note 148e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // that because the most significant bit of the public modulus is 149e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit 150e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // key), an n-bit message with most significant bit 0 always 151e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // satisfies this requirement. 152e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // 153e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // 2. The message must have the same length in bits as the public 154e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // modulus of the RSA key. This requirement isn't mathematically 155e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // necessary, but is necessary to ensure consistency in 156e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // implementations. 157e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden switch (ftr->kdf_type) { 158e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden case KDF_SCRYPT_KEYMASTER: 159e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // This ensures the most significant byte of the signed message 160e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // is zero. We could have zero-padded to the left instead, but 161e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // this approach is slightly more robust against changes in 162e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden // object size. However, it's still broken (but not unusably 163da6e899f4e1429add2ef023e0cc6b0fcca42c945Shawn Willden // so) because we really should be using a proper deterministic 164da6e899f4e1429add2ef023e0cc6b0fcca42c945Shawn Willden // RSA padding function, such as PKCS1. 1654375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang memcpy(to_sign + 1, object, std::min((size_t)RSA_KEY_SIZE_BYTES - 1, object_size)); 166e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden SLOGI("Signing safely-padded object"); 167e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden break; 168e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden default: 169e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden SLOGE("Unknown KDF type %d", ftr->kdf_type); 170015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis return -1; 171da6e899f4e1429add2ef023e0cc6b0fcca42c945Shawn Willden } 172015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis return keymaster_sign_object_for_cryptfs_scrypt(ftr->keymaster_blob, ftr->keymaster_blob_size, 173015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign, to_sign_size, signature, signature_size); 17447ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden} 17547ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden 176399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence/* Store password when userdata is successfully decrypted and mounted. 177399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * Cleared by cryptfs_clear_password 178399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * 179399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * To avoid a double prompt at boot, we need to store the CryptKeeper 180399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * password and pass it to KeyGuard, which uses it to unlock KeyStore. 181399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * Since the entire framework is torn down and rebuilt after encryption, 182399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * we have to use a daemon or similar to store the password. Since vold 183399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * is secured against IPC except from system processes, it seems a reasonable 184399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * place to store this. 185399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * 186399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * password should be cleared once it has been used. 187399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * 188399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence * password is aged out after password_max_age_seconds seconds. 189684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence */ 190399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrencestatic char* password = 0; 191399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrencestatic int password_expiry_time = 0; 192399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrencestatic const int password_max_age_seconds = 60; 193684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence 19456ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrallextern struct fstab *fstab; 1958ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 19687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrenceenum RebootType {reboot, recovery, shutdown}; 19787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrencestatic void cryptfs_reboot(enum RebootType rt) 198adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall{ 19987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence switch(rt) { 20087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence case reboot: 20187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence property_set(ANDROID_RB_PROPERTY, "reboot"); 20287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence break; 20387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 20487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence case recovery: 20587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence property_set(ANDROID_RB_PROPERTY, "reboot,recovery"); 20687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence break; 20787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 20887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence case shutdown: 20987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence property_set(ANDROID_RB_PROPERTY, "shutdown"); 21087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence break; 211adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall } 21287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 213adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall sleep(20); 214adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall 215adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall /* Shouldn't get here, reboot should happen before sleep times out */ 216adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall return; 217adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall} 218adfba3626e76c1931649634275d241b226cd1b9aKen Sumrall 2198f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallstatic void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags) 2208f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 2218f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall memset(io, 0, dataSize); 2228f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io->data_size = dataSize; 2238f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io->data_start = sizeof(struct dm_ioctl); 2248f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io->version[0] = 4; 2258f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io->version[1] = 0; 2268f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io->version[2] = 0; 2278f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io->flags = flags; 2288f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (name) { 2295e6b9141c11ebfd809acb69c7c672c6612334359Marek Pola strlcpy(io->name, name, sizeof(io->name)); 2308f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 2318f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 2328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 233c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root/** 234c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root * Gets the default device scrypt parameters for key derivation time tuning. 235c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root * The parameters should lead to about one second derivation time for the 236c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root * given device. 237c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root */ 238c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Rootstatic void get_device_scrypt_params(struct crypt_mnt_ftr *ftr) { 239c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root char paramstr[PROPERTY_VALUE_MAX]; 24063c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley int Nf, rf, pf; 241c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 24263c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS); 24363c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley if (!parse_scrypt_parameters(paramstr, &Nf, &rf, &pf)) { 24463c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley SLOGW("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr); 24563c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley parse_scrypt_parameters(SCRYPT_DEFAULTS, &Nf, &rf, &pf); 246c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root } 24763c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley ftr->N_factor = Nf; 24863c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley ftr->r_factor = rf; 24963c18d3ba9179ee0e678564e12aa845d9a6c3ec8Paul Crowley ftr->p_factor = pf; 250c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root} 251c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 2523ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrallstatic unsigned int get_fs_size(char *dev) 2533ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall{ 2543ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall int fd, block_size; 2553ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall struct ext4_super_block sb; 2563ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall off64_t len; 2573ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 258ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ((fd = open(dev, O_RDONLY|O_CLOEXEC)) < 0) { 2593ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall SLOGE("Cannot open device to get filesystem size "); 2603ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return 0; 2613ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } 2623ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 2633ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall if (lseek64(fd, 1024, SEEK_SET) < 0) { 2643ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall SLOGE("Cannot seek to superblock"); 2653ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return 0; 2663ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } 2673ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 2683ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { 2693ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall SLOGE("Cannot read superblock"); 2703ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return 0; 2713ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } 2723ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 2733ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall close(fd); 2743ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 275e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (le32_to_cpu(sb.s_magic) != EXT4_SUPER_MAGIC) { 276e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg SLOGE("Not a valid ext4 superblock"); 277e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return 0; 278e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2793ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall block_size = 1024 << sb.s_log_block_size; 2803ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* compute length in bytes */ 2813ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size; 2823ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 2833ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* return length in sectors */ 2843ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return (unsigned int) (len / 512); 2853ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall} 2863ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 287160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic int get_crypt_ftr_info(char **metadata_fname, off64_t *off) 2888f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 289160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall static int cached_data = 0; 290160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall static off64_t cached_off = 0; 291160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall static char cached_metadata_fname[PROPERTY_VALUE_MAX] = ""; 2928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int fd; 29329d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall char key_loc[PROPERTY_VALUE_MAX]; 294160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char real_blkdev[PROPERTY_VALUE_MAX]; 295160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int rc = -1; 2968f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 297160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!cached_data) { 298160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc)); 2998f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 300160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!strcmp(key_loc, KEY_IN_FOOTER)) { 301ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (fd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) { 302160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot open real block device %s\n", real_blkdev); 303160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 304160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3058f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 30614eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa unsigned long nr_sec = 0; 30714eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa get_blkdev_size(fd, &nr_sec); 30814eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa if (nr_sec != 0) { 309160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* If it's an encrypted Android partition, the last 16 Kbytes contain the 310160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * encryption info footer and key, and plenty of bytes to spare for future 311160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * growth. 312160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall */ 313160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname)); 314160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; 315160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall cached_data = 1; 316160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } else { 317160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot get size of block device %s\n", real_blkdev); 318160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 319160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall close(fd); 320160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } else { 321160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname)); 322160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall cached_off = 0; 323160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall cached_data = 1; 32429d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 325160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3268f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 327160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (cached_data) { 328160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (metadata_fname) { 329160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall *metadata_fname = cached_metadata_fname; 33029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 331160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (off) { 332160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall *off = cached_off; 33329d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 334160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall rc = 0; 3358f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 3368f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 337160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return rc; 338160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 3398f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 3403d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence/* Set sha256 checksum in structure */ 3413d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrencestatic void set_ftr_sha(struct crypt_mnt_ftr *crypt_ftr) 3423d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence{ 3433d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SHA256_CTX c; 3443d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SHA256_Init(&c); 3453d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence memset(crypt_ftr->sha256, 0, sizeof(crypt_ftr->sha256)); 3463d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SHA256_Update(&c, crypt_ftr, sizeof(*crypt_ftr)); 3473d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SHA256_Final(crypt_ftr->sha256, &c); 3483d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence} 3493d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 350160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall/* key or salt can be NULL, in which case just skip writing that value. Useful to 351160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * update the failed mount count but not change the key. 352160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall */ 353160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) 354160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 355160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int fd; 3568439dc9fd569794b1a31f67cf43d9212de33eeccTim Murray unsigned int cnt; 357160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* starting_off is set to the SEEK_SET offset 358160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * where the crypto structure starts 359160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall */ 360160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall off64_t starting_off; 361160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int rc = -1; 362160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char *fname = NULL; 363160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct stat statbuf; 3648f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 3653d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence set_ftr_sha(crypt_ftr); 3663d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 367160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_info(&fname, &starting_off)) { 368160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Unable to get crypt_ftr_info\n"); 369160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 370160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 371160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (fname[0] != '/') { 372160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Unexpected value for crypto key location\n"); 373160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 374160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 375ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (fd = open(fname, O_RDWR | O_CREAT|O_CLOEXEC, 0600)) < 0) { 376e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGE("Cannot open footer file %s for put\n", fname); 377160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 3788f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 3798f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 380160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Seek to the start of the crypt footer */ 381160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (lseek64(fd, starting_off, SEEK_SET) == -1) { 382160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot seek to real block device footer\n"); 383160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto errout; 384160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 385e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall 386160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { 387160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot write real block device footer\n"); 388160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto errout; 38929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 39029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 3913be890f59c04f94537f2f66f1d2841ed591f1a6eKen Sumrall fstat(fd, &statbuf); 3923be890f59c04f94537f2f66f1d2841ed591f1a6eKen Sumrall /* If the keys are kept on a raw block device, do not try to truncate it. */ 393e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall if (S_ISREG(statbuf.st_mode)) { 39429d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall if (ftruncate(fd, 0x4000)) { 39559846b654e8b4a22a1be11cd21d6c5b81375abd2Colin Cross SLOGE("Cannot set footer file size\n"); 396e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall goto errout; 397e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall } 398e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall } 399e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall 4008f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Success! */ 4018f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall rc = 0; 4028f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 4038f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallerrout: 4048f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(fd); 4058f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 4068f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 4078f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 4088f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 4093d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrencestatic bool check_ftr_sha(const struct crypt_mnt_ftr *crypt_ftr) 4103d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence{ 4113d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence struct crypt_mnt_ftr copy; 4123d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence memcpy(©, crypt_ftr, sizeof(copy)); 4133d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence set_ftr_sha(©); 4143d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence return memcmp(copy.sha256, crypt_ftr->sha256, sizeof(copy.sha256)) == 0; 4153d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence} 4163d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 417160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic inline int unix_read(int fd, void* buff, int len) 4188f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 419160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return TEMP_FAILURE_RETRY(read(fd, buff, len)); 420160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 4218f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 422160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic inline int unix_write(int fd, const void* buff, int len) 423160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 424160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return TEMP_FAILURE_RETRY(write(fd, buff, len)); 425160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 4268f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 427160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic void init_empty_persist_data(struct crypt_persist_data *pdata, int len) 428160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 429160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall memset(pdata, 0, len); 430160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall pdata->persist_magic = PERSIST_DATA_MAGIC; 431160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall pdata->persist_valid_entries = 0; 432160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 4338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 434160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall/* A routine to update the passed in crypt_ftr to the lastest version. 435160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * fd is open read/write on the device that holds the crypto footer and persistent 436160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * data, crypt_ftr is a pointer to the struct to be updated, and offset is the 437160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * absolute offset to the start of the crypt_mnt_ftr on the passed in fd. 438160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall */ 439160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t offset) 440160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 4417434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root int orig_major = crypt_ftr->major_version; 4427434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root int orig_minor = crypt_ftr->minor_version; 4437434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root 4447434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) { 4457434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root struct crypt_persist_data *pdata; 4467434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET; 4477434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root 448c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root SLOGW("upgrading crypto footer to 1.1"); 449c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 4504375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang pdata = (crypt_persist_data *)malloc(CRYPT_PERSIST_DATA_SIZE); 4517434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root if (pdata == NULL) { 4527434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root SLOGE("Cannot allocate persisent data\n"); 4537434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root return; 4547434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root } 4557434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE); 4567434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root 4577434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root /* Need to initialize the persistent data area */ 4587434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root if (lseek64(fd, pdata_offset, SEEK_SET) == -1) { 4597434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root SLOGE("Cannot seek to persisent data offset\n"); 46091064633ff3e5dd0a8a7d0c065cd82ba06b04aceHenrik Baard free(pdata); 4617434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root return; 4627434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root } 4637434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root /* Write all zeros to the first copy, making it invalid */ 4647434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE); 4657434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root 4667434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root /* Write a valid but empty structure to the second copy */ 4677434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); 4687434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE); 4697434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root 4707434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root /* Update the footer */ 4717434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE; 4727434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root crypt_ftr->persist_data_offset[0] = pdata_offset; 4737434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE; 4747434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root crypt_ftr->minor_version = 1; 47591064633ff3e5dd0a8a7d0c065cd82ba06b04aceHenrik Baard free(pdata); 47629d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 477160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 478f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 1)) { 479c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root SLOGW("upgrading crypto footer to 1.2"); 4807bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall /* But keep the old kdf_type. 4817bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall * It will get updated later to KDF_SCRYPT after the password has been verified. 4827bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall */ 483c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root crypt_ftr->kdf_type = KDF_PBKDF2; 484c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root get_device_scrypt_params(crypt_ftr); 485c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root crypt_ftr->minor_version = 2; 486c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root } 487c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 488f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 2)) { 489f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGW("upgrading crypto footer to 1.3"); 490f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr->crypt_type = CRYPT_TYPE_PASSWORD; 491f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr->minor_version = 3; 492f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 493f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 4947434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) { 4957434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root if (lseek64(fd, offset, SEEK_SET) == -1) { 4967434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root SLOGE("Cannot seek to crypt footer\n"); 4977434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root return; 4987434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root } 4997434b3111b80d2b84ddf656b66b7bf6591de5ab6Kenny Root unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr)); 500160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 501160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 502160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 503160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 504160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) 505160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 506160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int fd; 5078439dc9fd569794b1a31f67cf43d9212de33eeccTim Murray unsigned int cnt; 508160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall off64_t starting_off; 509160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int rc = -1; 510160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char *fname = NULL; 511160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct stat statbuf; 512160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 513160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_info(&fname, &starting_off)) { 514160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Unable to get crypt_ftr_info\n"); 515160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 516160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 517160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (fname[0] != '/') { 518e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall SLOGE("Unexpected value for crypto key location\n"); 519160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 520160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 521ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) { 522e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGE("Cannot open footer file %s for get\n", fname); 523160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 524160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 525160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 526160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Make sure it's 16 Kbytes in length */ 527160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall fstat(fd, &statbuf); 528160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) { 529160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("footer file %s is not the expected size!\n", fname); 530160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto errout; 531160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 532160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 533160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Seek to the start of the crypt footer */ 534160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (lseek64(fd, starting_off, SEEK_SET) == -1) { 535160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot seek to real block device footer\n"); 536160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto errout; 5378f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 5388f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 5398f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { 5408f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot read real block device footer\n"); 5418f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 5428f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 5438f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 5448f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (crypt_ftr->magic != CRYPT_MNT_MAGIC) { 54529d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall SLOGE("Bad magic for real block device %s\n", fname); 5468f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 5478f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 5488f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 549c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root if (crypt_ftr->major_version != CURRENT_MAJOR_VERSION) { 550c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root SLOGE("Cannot understand major version %d real block device footer; expected %d\n", 551c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root crypt_ftr->major_version, CURRENT_MAJOR_VERSION); 5528f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 5538f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 5548f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 555c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root if (crypt_ftr->minor_version > CURRENT_MINOR_VERSION) { 556c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root SLOGW("Warning: crypto footer minor version %d, expected <= %d, continuing...\n", 557c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root crypt_ftr->minor_version, CURRENT_MINOR_VERSION); 5588f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 5598f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 560160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the 561160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * copy on disk before returning. 562160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall */ 563c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) { 564160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall upgrade_crypt_ftr(fd, crypt_ftr, starting_off); 565e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall } 566e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall 5678f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Success! */ 5688f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall rc = 0; 5698f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 5708f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallerrout: 5718f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(fd); 5728f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 5738f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 5748f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 575160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic int validate_persistent_data_storage(struct crypt_mnt_ftr *crypt_ftr) 576160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 577160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size > 578160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall crypt_ftr->persist_data_offset[1]) { 579160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Crypt_ftr persist data regions overlap"); 580160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 581160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 582160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 583160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) { 584160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Crypt_ftr persist data region 0 starts after region 1"); 585160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 586160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 587160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 588160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) - 589160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) > 590160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall CRYPT_FOOTER_OFFSET) { 591160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Persistent data extends past crypto footer"); 592160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 593160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 594160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 595160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 596160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 597160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 598160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic int load_persistent_data(void) 599160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 600160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct crypt_mnt_ftr crypt_ftr; 601160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct crypt_persist_data *pdata = NULL; 602160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char encrypted_state[PROPERTY_VALUE_MAX]; 603160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char *fname; 604160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int found = 0; 605160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int fd; 606160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int ret; 607160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int i; 608160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 609160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data) { 610160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Nothing to do, we've already loaded or initialized it */ 611160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 612160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 613160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 614160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 615160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* If not encrypted, just allocate an empty table and initialize it */ 616160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall property_get("ro.crypto.state", encrypted_state, ""); 617160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (strcmp(encrypted_state, "encrypted") ) { 6184375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang pdata = (crypt_persist_data*)malloc(CRYPT_PERSIST_DATA_SIZE); 619160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (pdata) { 620160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); 621160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall persist_data = pdata; 622160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 623160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 624160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 625160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 626160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 627160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if(get_crypt_ftr_and_key(&crypt_ftr)) { 628160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 629160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 630160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 6318561b5c9f5d2f9c5e3f8e2963bdffe9ff3706b04Paul Lawrence if ((crypt_ftr.major_version < 1) 6328561b5c9f5d2f9c5e3f8e2963bdffe9ff3706b04Paul Lawrence || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) { 633160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Crypt_ftr version doesn't support persistent data"); 634160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 635160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 636160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 637160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_info(&fname, NULL)) { 638160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 639160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 640160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 641160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall ret = validate_persistent_data_storage(&crypt_ftr); 642160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (ret) { 643160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 644160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 645160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 646ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey fd = open(fname, O_RDONLY|O_CLOEXEC); 647160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (fd < 0) { 648160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot open %s metadata file", fname); 649160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 650160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 651160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 6524375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size); 653300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence if (pdata == NULL) { 654300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence SLOGE("Cannot allocate memory for persistent data"); 655300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence goto err; 656160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 657160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 658160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall for (i = 0; i < 2; i++) { 659160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) { 660160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot seek to read persistent data on %s", fname); 661160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 662160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 663160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0){ 664160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Error reading persistent data on iteration %d", i); 665160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 666160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 667160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (pdata->persist_magic == PERSIST_DATA_MAGIC) { 668160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall found = 1; 669160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall break; 670160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 671160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 672160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 673160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!found) { 674160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGI("Could not find valid persistent data, creating"); 675160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall init_empty_persist_data(pdata, crypt_ftr.persist_data_size); 676160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 677160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 678160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Success */ 679160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall persist_data = pdata; 680160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall close(fd); 681160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 682160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 683160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallerr2: 684160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall free(pdata); 685160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 686160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallerr: 687160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall close(fd); 688160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 689160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 690160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 691160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallstatic int save_persistent_data(void) 692160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 693160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct crypt_mnt_ftr crypt_ftr; 694160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct crypt_persist_data *pdata; 695160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char *fname; 696160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall off64_t write_offset; 697160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall off64_t erase_offset; 698160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int fd; 699160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int ret; 700160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 701160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 702160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("No persistent data to save"); 703160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 704160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 705160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 706160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if(get_crypt_ftr_and_key(&crypt_ftr)) { 707160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 708160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 709160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 7108561b5c9f5d2f9c5e3f8e2963bdffe9ff3706b04Paul Lawrence if ((crypt_ftr.major_version < 1) 7118561b5c9f5d2f9c5e3f8e2963bdffe9ff3706b04Paul Lawrence || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) { 712160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Crypt_ftr version doesn't support persistent data"); 713160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 714160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 715160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 716160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall ret = validate_persistent_data_storage(&crypt_ftr); 717160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (ret) { 718160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 719160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 720160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 721160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_info(&fname, NULL)) { 722160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 723160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 724160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 725ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey fd = open(fname, O_RDWR|O_CLOEXEC); 726160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (fd < 0) { 727160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot open %s metadata file", fname); 728160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 729160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 730160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 7314375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang pdata = (crypt_persist_data*)malloc(crypt_ftr.persist_data_size); 732160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (pdata == NULL) { 733160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot allocate persistant data"); 734160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err; 735160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 736160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 737160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) { 738160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot seek to read persistent data on %s", fname); 739160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 740160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 741160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 742160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) { 743160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Error reading persistent data before save"); 744160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 745160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 746160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 747160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (pdata->persist_magic == PERSIST_DATA_MAGIC) { 748160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* The first copy is the curent valid copy, so write to 749160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * the second copy and erase this one */ 750160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall write_offset = crypt_ftr.persist_data_offset[1]; 751160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall erase_offset = crypt_ftr.persist_data_offset[0]; 752160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } else { 753160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* The second copy must be the valid copy, so write to 754160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall * the first copy, and erase the second */ 755160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall write_offset = crypt_ftr.persist_data_offset[0]; 756160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall erase_offset = crypt_ftr.persist_data_offset[1]; 757160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 758160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 759160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Write the new copy first, if successful, then erase the old copy */ 76096dbee7bd6c64c0d38b4e390e12851e02b674b87Björn Landström if (lseek64(fd, write_offset, SEEK_SET) < 0) { 761160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot seek to write persistent data"); 762160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 763160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 764160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) == 765160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall (int) crypt_ftr.persist_data_size) { 76696dbee7bd6c64c0d38b4e390e12851e02b674b87Björn Landström if (lseek64(fd, erase_offset, SEEK_SET) < 0) { 767160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot seek to erase previous persistent data"); 768160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 769160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 770160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall fsync(fd); 771160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall memset(pdata, 0, crypt_ftr.persist_data_size); 772160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (unix_write(fd, pdata, crypt_ftr.persist_data_size) != 773160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall (int) crypt_ftr.persist_data_size) { 774160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot write to erase previous persistent data"); 775160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 776160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 777160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall fsync(fd); 778160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } else { 779160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Cannot write to save persistent data"); 780160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto err2; 781160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 782160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 783160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Success */ 784160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall free(pdata); 785160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall close(fd); 786160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 787160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 788160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallerr2: 789160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall free(pdata); 790160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallerr: 791160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall close(fd); 792160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 793160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 794160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 7958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall/* Convert a binary key of specified length into an ascii hex string equivalent, 7968f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * without the leading 0x and with null termination 7978f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 7989c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic void convert_key_to_hex_ascii(const unsigned char *master_key, 7993bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence unsigned int keysize, char *master_key_ascii) { 8003bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence unsigned int i, a; 8013bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence unsigned char nibble; 8028f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 8033bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence for (i=0, a=0; i<keysize; i++, a+=2) { 8043bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence /* For each byte, write out two ascii hex digits */ 8053bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence nibble = (master_key[i] >> 4) & 0xf; 8063bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30); 8078f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 8083bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence nibble = master_key[i] & 0xf; 8093bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30); 8103bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence } 8118f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 8123bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence /* Add the null termination */ 8133bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence master_key_ascii[a] = '\0'; 8148f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 8158f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 8168f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 8179c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, 8189c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey const unsigned char *master_key, const char *real_blk_name, 8199c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey const char *name, int fd, const char *extra_params) { 8204375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang alignas(struct dm_ioctl) char buffer[DM_CRYPT_BUF_SIZE]; 821db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall struct dm_ioctl *io; 822db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall struct dm_target_spec *tgt; 823db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall char *crypt_params; 824db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */ 825605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV size_t buff_offset; 826db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall int i; 827db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 828db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall io = (struct dm_ioctl *) buffer; 829db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 830db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall /* Load the mapping table for this device */ 831db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; 832db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 833db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); 834db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall io->target_count = 1; 835db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall tgt->status = 0; 836db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall tgt->sector_start = 0; 837db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall tgt->length = crypt_ftr->fs_size; 83887701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME); 839db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 840db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); 841db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii); 842605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV 843605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV buff_offset = crypt_params - buffer; 844605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV snprintf(crypt_params, sizeof(buffer) - buff_offset, "%s %s 0 %s 0 %s", 845605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV crypt_ftr->crypto_type_name, master_key_ascii, real_blk_name, 846605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV extra_params); 847db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall crypt_params += strlen(crypt_params) + 1; 848db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */ 849db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall tgt->next = crypt_params - buffer; 850db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 851db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall for (i = 0; i < TABLE_LOAD_RETRIES; i++) { 852db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if (! ioctl(fd, DM_TABLE_LOAD, io)) { 853db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall break; 854db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 855db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall usleep(500000); 856db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 857db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 858db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if (i == TABLE_LOAD_RETRIES) { 859db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall /* We failed to load the table, return an error */ 860db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall return -1; 861db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } else { 862db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall return i + 1; 863db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 864db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall} 865db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 866db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 867db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrallstatic int get_dm_crypt_version(int fd, const char *name, int *version) 868db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall{ 869db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall char buffer[DM_CRYPT_BUF_SIZE]; 870db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall struct dm_ioctl *io; 871db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall struct dm_target_versions *v; 872db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 873db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall io = (struct dm_ioctl *) buffer; 874db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 875db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); 876db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 877db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if (ioctl(fd, DM_LIST_VERSIONS, io)) { 878db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall return -1; 879db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 880db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 881db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall /* Iterate over the returned versions, looking for name of "crypt". 882db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall * When found, get and return the version. 883db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall */ 884db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)]; 885db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall while (v->next) { 886db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if (! strcmp(v->name, "crypt")) { 887db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall /* We found the crypt driver, return the version, and get out */ 888db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall version[0] = v->version[0]; 889db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall version[1] = v->version[1]; 890db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall version[2] = v->version[2]; 891db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall return 0; 892db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 893db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall v = (struct dm_target_versions *)(((char *)v) + v->next); 894db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 895db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 896db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall return -1; 897db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall} 898db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall 8999c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, 9009c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey const unsigned char *master_key, const char *real_blk_name, 9019c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey char *crypto_blk_name, const char *name) { 9028f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall char buffer[DM_CRYPT_BUF_SIZE]; 9038f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall struct dm_ioctl *io; 9048f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall unsigned int minor; 90587701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani int fd=0; 90625a5213c1f37dfdd15d0c52785addab15a8536b3Daniel Rosenberg int err; 9078f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int retval = -1; 908db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall int version[3]; 9094375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang const char *extra_params; 910db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall int load_count; 9118f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 912ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) { 9138f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot open device-mapper\n"); 9148f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 9158f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9168f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9178f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io = (struct dm_ioctl *) buffer; 9188f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9198f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); 92025a5213c1f37dfdd15d0c52785addab15a8536b3Daniel Rosenberg err = ioctl(fd, DM_DEV_CREATE, io); 92125a5213c1f37dfdd15d0c52785addab15a8536b3Daniel Rosenberg if (err) { 92225a5213c1f37dfdd15d0c52785addab15a8536b3Daniel Rosenberg SLOGE("Cannot create dm-crypt device %s: %s\n", name, strerror(errno)); 9238f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 9248f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9258f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9268f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Get the device status, in particular, the name of it's device file */ 9278f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); 9288f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (ioctl(fd, DM_DEV_STATUS, io)) { 9298f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot retrieve dm-crypt device status\n"); 9308f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 9318f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); 9338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor); 9348f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 935db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall extra_params = ""; 936db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if (! get_dm_crypt_version(fd, name, version)) { 937db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall /* Support for allow_discards was added in version 1.11.0 */ 938db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if ((version[0] >= 2) || 939db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall ((version[0] == 1) && (version[1] >= 11))) { 940db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall extra_params = "1 allow_discards"; 941db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall SLOGI("Enabling support for allow_discards in dmcrypt.\n"); 942db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } 943e919efea94b178ed214ed2e78ef0d008727d62abKen Sumrall } 944e919efea94b178ed214ed2e78ef0d008727d62abKen Sumrall 945db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, 946db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall fd, extra_params); 947db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall if (load_count < 0) { 9488f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot load dm-crypt mapping table.\n"); 9498f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 950db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall } else if (load_count > 1) { 951db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall SLOGI("Took %d tries to load dmcrypt table.\n", load_count); 9528f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9538f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9548f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Resume this device to activate it */ 955db5e026058927347ccff8f170c8f160b28cbc75bKen Sumrall ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); 9568f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9578f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (ioctl(fd, DM_DEV_SUSPEND, io)) { 9588f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot resume the dm-crypt device\n"); 9598f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 9608f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9618f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9628f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* We made it here with no errors. Woot! */ 9638f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall retval = 0; 9648f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9658f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallerrout: 9668f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */ 9678f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9688f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return retval; 9698f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 9708f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9714375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wangstatic int delete_crypto_blk_dev(const char *name) 9728f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 9738f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int fd; 9748f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall char buffer[DM_CRYPT_BUF_SIZE]; 9758f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall struct dm_ioctl *io; 9768f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int retval = -1; 9778f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 978ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) { 9798f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot open device-mapper\n"); 9808f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 9818f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9838f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall io = (struct dm_ioctl *) buffer; 9848f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9858f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); 9868f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (ioctl(fd, DM_DEV_REMOVE, io)) { 9878f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Cannot remove dm-crypt device\n"); 9888f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 9898f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 9908f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9918f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* We made it here with no errors. Woot! */ 9928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall retval = 0; 9938f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallerrout: 9958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */ 9968f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9978f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return retval; 9988f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 9998f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 10008f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 100169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int pbkdf2(const char *passwd, const unsigned char *salt, 1002f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence unsigned char *ikey, void *params UNUSED) 1003f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence{ 100469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGI("Using pbkdf2 for cryptfs KDF"); 100569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 10068f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Turn the password into a key and IV that can decrypt the master key */ 1007bf0d972ab4aa04918dc57ba277454ea65bbdee26Adam Langley return PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN, 1008bf0d972ab4aa04918dc57ba277454ea65bbdee26Adam Langley HASH_COUNT, KEY_LEN_BYTES + IV_LEN_BYTES, 1009bf0d972ab4aa04918dc57ba277454ea65bbdee26Adam Langley ikey) != 1; 10108ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall} 10118ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 101269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int scrypt(const char *passwd, const unsigned char *salt, 1013f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence unsigned char *ikey, void *params) 1014f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence{ 101569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGI("Using scrypt for cryptfs KDF"); 101669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 1017c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params; 1018c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 1019c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root int N = 1 << ftr->N_factor; 1020c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root int r = 1 << ftr->r_factor; 1021c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root int p = 1 << ftr->p_factor; 1022c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 1023c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root /* Turn the password into a key and IV that can decrypt the master key */ 1024f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence unsigned int keysize; 10253bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence crypto_scrypt((const uint8_t*)passwd, strlen(passwd), 10263bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence salt, SALT_LEN, N, r, p, ikey, 10273bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence KEY_LEN_BYTES + IV_LEN_BYTES); 1028f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 10293bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence return 0; 1030c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root} 1031c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 103269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int scrypt_keymaster(const char *passwd, const unsigned char *salt, 103369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence unsigned char *ikey, void *params) 103469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence{ 103569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGI("Using scrypt with keymaster for cryptfs KDF"); 103669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 103769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence int rc; 103869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence size_t signature_size; 103969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence unsigned char* signature; 104069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params; 104169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 104269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence int N = 1 << ftr->N_factor; 104369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence int r = 1 << ftr->r_factor; 104469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence int p = 1 << ftr->p_factor; 104569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 10463bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence rc = crypto_scrypt((const uint8_t*)passwd, strlen(passwd), 10473bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence salt, SALT_LEN, N, r, p, ikey, 10483bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence KEY_LEN_BYTES + IV_LEN_BYTES); 104969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 105069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (rc) { 105169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("scrypt failed"); 105269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return -1; 105369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 105469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 1055e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden if (keymaster_sign_object(ftr, ikey, KEY_LEN_BYTES + IV_LEN_BYTES, 1056e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden &signature, &signature_size)) { 1057e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden SLOGE("Signing failed"); 1058e17a9c4ad3ebb4051853a4860b18973e1a01ce11Shawn Willden return -1; 105969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 106069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 106169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence rc = crypto_scrypt(signature, signature_size, salt, SALT_LEN, 106269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence N, r, p, ikey, KEY_LEN_BYTES + IV_LEN_BYTES); 106369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence free(signature); 106469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 106569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (rc) { 106669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("scrypt failed"); 106769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return -1; 106869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 106969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 107069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return 0; 107169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence} 107269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 107369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int encrypt_master_key(const char *passwd, const unsigned char *salt, 107469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence const unsigned char *decrypted_master_key, 1075c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root unsigned char *encrypted_master_key, 1076c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root struct crypt_mnt_ftr *crypt_ftr) 10778ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall{ 10788ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */ 10798ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall EVP_CIPHER_CTX e_ctx; 10808ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall int encrypted_len, final_len; 1081d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence int rc = 0; 10828ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 1083d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence /* Turn the password into an intermediate key and IV that can decrypt the master key */ 1084c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root get_device_scrypt_params(crypt_ftr); 108569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 108669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence switch (crypt_ftr->kdf_type) { 108769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence case KDF_SCRYPT_KEYMASTER: 108869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (keymaster_create_key(crypt_ftr)) { 108969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("keymaster_create_key failed"); 109069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return -1; 109169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 109269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 109369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (scrypt_keymaster(passwd, salt, ikey, crypt_ftr)) { 109469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("scrypt failed"); 109569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return -1; 109669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 109769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence break; 109869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 109969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence case KDF_SCRYPT: 110069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (scrypt(passwd, salt, ikey, crypt_ftr)) { 110169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("scrypt failed"); 110269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return -1; 110369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 110469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence break; 110569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 110669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence default: 110769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("Invalid kdf_type"); 1108f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 1109f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 1110c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 11118f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Initialize the decryption engine */ 1112889c4f1e36f69c1d5a9a92a6ba40d8a729d3f7b0Adam Langley EVP_CIPHER_CTX_init(&e_ctx); 1113889c4f1e36f69c1d5a9a92a6ba40d8a729d3f7b0Adam Langley if (! EVP_EncryptInit_ex(&e_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+KEY_LEN_BYTES)) { 11148f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("EVP_EncryptInit failed\n"); 11158f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11168f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 11178f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */ 11188ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 11198f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Encrypt the master key */ 11208ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall if (! EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len, 1121731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence decrypted_master_key, KEY_LEN_BYTES)) { 11228f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("EVP_EncryptUpdate failed\n"); 11238f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11248f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 1125889c4f1e36f69c1d5a9a92a6ba40d8a729d3f7b0Adam Langley if (! EVP_EncryptFinal_ex(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) { 11268f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("EVP_EncryptFinal failed\n"); 11278f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11288f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 11298f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 11308f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (encrypted_len + final_len != KEY_LEN_BYTES) { 11318f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len); 11328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 113469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 1135d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence /* Store the scrypt of the intermediate key, so we can validate if it's a 1136d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence password error or mount error when things go wrong. 1137d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence Note there's no need to check for errors, since if this is incorrect, we 1138d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence simply won't wipe userdata, which is the correct default behavior 1139d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence */ 1140d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence int N = 1 << crypt_ftr->N_factor; 1141d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence int r = 1 << crypt_ftr->r_factor; 1142d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence int p = 1 << crypt_ftr->p_factor; 1143d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence 1144d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence rc = crypto_scrypt(ikey, KEY_LEN_BYTES, 1145d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence crypt_ftr->salt, sizeof(crypt_ftr->salt), N, r, p, 1146d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence crypt_ftr->scrypted_intermediate_key, 1147d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence sizeof(crypt_ftr->scrypted_intermediate_key)); 1148d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence 1149d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence if (rc) { 1150d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence SLOGE("encrypt_master_key: crypto_scrypt failed"); 1151d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence } 1152d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence 115306dc31181752c3e59b4c5b58b24f023640898564Thurston Hou Yeen Dang EVP_CIPHER_CTX_cleanup(&e_ctx); 115406dc31181752c3e59b4c5b58b24f023640898564Thurston Hou Yeen Dang 115569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return 0; 11568f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 11578f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1158731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrencestatic int decrypt_master_key_aux(const char *passwd, unsigned char *salt, 1159d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence unsigned char *encrypted_master_key, 1160d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence unsigned char *decrypted_master_key, 1161d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence kdf_func kdf, void *kdf_params, 1162d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence unsigned char** intermediate_key, 1163d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence size_t* intermediate_key_size) 11648f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 11658f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */ 11668f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall EVP_CIPHER_CTX d_ctx; 11678f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int decrypted_len, final_len; 11688f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1169d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence /* Turn the password into an intermediate key and IV that can decrypt the 1170d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence master key */ 1171f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (kdf(passwd, salt, ikey, kdf_params)) { 1172f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGE("kdf failed"); 1173f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 1174f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 11758f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 11768f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Initialize the decryption engine */ 1177889c4f1e36f69c1d5a9a92a6ba40d8a729d3f7b0Adam Langley EVP_CIPHER_CTX_init(&d_ctx); 1178889c4f1e36f69c1d5a9a92a6ba40d8a729d3f7b0Adam Langley if (! EVP_DecryptInit_ex(&d_ctx, EVP_aes_128_cbc(), NULL, ikey, ikey+KEY_LEN_BYTES)) { 11798f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11808f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 11818f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */ 11828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Decrypt the master key */ 11838f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len, 11848f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall encrypted_master_key, KEY_LEN_BYTES)) { 11858f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11868f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 1187889c4f1e36f69c1d5a9a92a6ba40d8a729d3f7b0Adam Langley if (! EVP_DecryptFinal_ex(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) { 11888f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11898f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 11908f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 11918f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (decrypted_len + final_len != KEY_LEN_BYTES) { 11928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return -1; 11938f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 1194d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence 1195d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence /* Copy intermediate key if needed by params */ 1196d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence if (intermediate_key && intermediate_key_size) { 1197d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence *intermediate_key = (unsigned char*) malloc(KEY_LEN_BYTES); 1198e8167afe55d4e33e93d7270701403708d9a03e7eGreg Kaiser if (*intermediate_key) { 1199d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence memcpy(*intermediate_key, ikey, KEY_LEN_BYTES); 1200d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence *intermediate_key_size = KEY_LEN_BYTES; 1201d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence } 1202d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence } 1203d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence 120406dc31181752c3e59b4c5b58b24f023640898564Thurston Hou Yeen Dang EVP_CIPHER_CTX_cleanup(&d_ctx); 120506dc31181752c3e59b4c5b58b24f023640898564Thurston Hou Yeen Dang 1206d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence return 0; 12078f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 12088f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1209c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Rootstatic void get_kdf_func(struct crypt_mnt_ftr *ftr, kdf_func *kdf, void** kdf_params) 12108ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall{ 1211db3730c454ef706dffee9bde0f9bf54e95ab06f8Paul Lawrence if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER) { 121269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence *kdf = scrypt_keymaster; 121369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence *kdf_params = ftr; 121469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } else if (ftr->kdf_type == KDF_SCRYPT) { 1215c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root *kdf = scrypt; 1216c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root *kdf_params = ftr; 1217c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root } else { 1218c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root *kdf = pbkdf2; 1219c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root *kdf_params = NULL; 1220c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root } 1221c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root} 1222c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 1223731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrencestatic int decrypt_master_key(const char *passwd, unsigned char *decrypted_master_key, 1224d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence struct crypt_mnt_ftr *crypt_ftr, 1225d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence unsigned char** intermediate_key, 1226d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence size_t* intermediate_key_size) 1227c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root{ 1228c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root kdf_func kdf; 1229c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root void *kdf_params; 1230c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root int ret; 1231c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 1232c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root get_kdf_func(crypt_ftr, &kdf, &kdf_params); 1233d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence ret = decrypt_master_key_aux(passwd, crypt_ftr->salt, crypt_ftr->master_key, 1234d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence decrypted_master_key, kdf, kdf_params, 1235d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence intermediate_key, intermediate_key_size); 1236c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root if (ret != 0) { 1237c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root SLOGW("failure decrypting master key"); 1238c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root } 1239c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 1240c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root return ret; 1241c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root} 1242c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 12434375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wangstatic int create_encrypted_random_key(const char *passwd, unsigned char *master_key, unsigned char *salt, 1244c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root struct crypt_mnt_ftr *crypt_ftr) { 12458ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall int fd; 1246e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall unsigned char key_buf[KEY_LEN_BYTES]; 12478ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 12488ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Get some random bits for a key */ 1249ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC); 1250e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall read(fd, key_buf, sizeof(key_buf)); 1251e87440703663f5ee326326f6438f3b00ea315623Ken Sumrall read(fd, salt, SALT_LEN); 12528ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall close(fd); 12538ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 12548ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Now encrypt it with the password */ 1255c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr); 12568ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall} 12578ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 12582f32cda63bf5c86db880d36029a27c8597fb5e3cPaul Lawrenceint wait_and_unmount(const char *mountpoint, bool kill) 12598f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 1260955653ebff68e29f5aeab3f05fddc199474e4174Greg Hackmann int i, err, rc; 12612eaf7138528d30c331d83ab8346a97e66b5499e2Ken Sumrall#define WAIT_UNMOUNT_COUNT 20 12628f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 12638f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Now umount the tmpfs filesystem */ 12648f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall for (i=0; i<WAIT_UNMOUNT_COUNT; i++) { 12656e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann if (umount(mountpoint) == 0) { 12666e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann break; 12676e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann } 12686e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann 12696e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann if (errno == EINVAL) { 12706e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann /* EINVAL is returned if the directory is not a mountpoint, 12716e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann * i.e. there is no filesystem mounted there. So just get out. 12726e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann */ 12736e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann break; 12746e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann } 12756e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann 12766e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann err = errno; 12776e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann 12786e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann /* If allowed, be increasingly aggressive before the last two retries */ 12796e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann if (kill) { 12806e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann if (i == (WAIT_UNMOUNT_COUNT - 3)) { 12816e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann SLOGW("sending SIGHUP to processes with open files\n"); 128236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey vold_killProcessesWithOpenFiles(mountpoint, SIGTERM); 12836e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann } else if (i == (WAIT_UNMOUNT_COUNT - 2)) { 12846e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann SLOGW("sending SIGKILL to processes with open files\n"); 128536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey vold_killProcessesWithOpenFiles(mountpoint, SIGKILL); 128629d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 12878f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 12886e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann 12896e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann sleep(1); 12908f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 12918f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 12928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (i < WAIT_UNMOUNT_COUNT) { 12938f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGD("unmounting %s succeeded\n", mountpoint); 12948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall rc = 0; 12958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } else { 12963f14fe45a3e7bc0d12ba26d20a36d355a10f623ejessica_yu vold_killProcessesWithOpenFiles(mountpoint, 0); 1297955653ebff68e29f5aeab3f05fddc199474e4174Greg Hackmann SLOGE("unmounting %s failed: %s\n", mountpoint, strerror(err)); 12988f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall rc = -1; 12998f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 13008f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 13018f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 13028f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 13038f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 13048ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrallstatic int prep_data_fs(void) 13058ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall{ 13068ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall int i; 13078ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 130847695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey // NOTE: post_fs_data results in init calling back around to vold, so all 130947695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey // callers to this method must be async 131047695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey 13118ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Do the prep of the /data filesystem */ 13128ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall property_set("vold.post_fs_data_done", "0"); 13138ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall property_set("vold.decrypt", "trigger_post_fs_data"); 13148ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall SLOGD("Just triggered post_fs_data\n"); 13158ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 1316c587269c5a34d4e7412ff42e53ed6312359a8505Ken Sumrall /* Wait a max of 50 seconds, hopefully it takes much less */ 13174375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang if (!android::base::WaitForProperty("vold.post_fs_data_done", 13184375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang "1", 13194375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang std::chrono::seconds(50))) { 13208ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Ugh, we failed to prep /data in time. Bail. */ 1321c587269c5a34d4e7412ff42e53ed6312359a8505Ken Sumrall SLOGE("post_fs_data timed out!\n"); 13228ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall return -1; 13238ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } else { 13248ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall SLOGD("post_fs_data done\n"); 13258ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall return 0; 13268ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 13278ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall} 13288ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 132974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrencestatic void cryptfs_set_corrupt() 133074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence{ 133174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence // Mark the footer as bad 133274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence struct crypt_mnt_ftr crypt_ftr; 133374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (get_crypt_ftr_and_key(&crypt_ftr)) { 133474f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Failed to get crypto footer - panic"); 133574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return; 133674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 133774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 133874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence crypt_ftr.flags |= CRYPT_DATA_CORRUPT; 133974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (put_crypt_ftr_and_key(&crypt_ftr)) { 134074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Failed to set crypto footer - panic"); 134174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return; 134274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 134374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence} 134474f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 134574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrencestatic void cryptfs_trigger_restart_min_framework() 134674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence{ 134774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) { 134874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Failed to mount tmpfs on data - panic"); 134974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return; 135074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 135174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 135274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (property_set("vold.decrypt", "trigger_post_fs_data")) { 135374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Failed to trigger post fs data - panic"); 135474f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return; 135574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 135674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 135774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (property_set("vold.decrypt", "trigger_restart_min_framework")) { 135874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Failed to trigger restart min framework - panic"); 135974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return; 136074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 136174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence} 136274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 13638e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence/* returns < 0 on failure */ 1364f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrencestatic int cryptfs_restart_internal(int restart_main) 13658f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 13666864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall char crypto_blkdev[MAXPATHLEN]; 13678439dc9fd569794b1a31f67cf43d9212de33eeccTim Murray int rc = -1; 13680cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall static int restart_successful = 0; 13690cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall 13700cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall /* Validate that it's OK to call this routine */ 137170a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks if (! master_key_saved) { 13720cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall SLOGE("Encrypted filesystem not validated, aborting"); 13730cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall return -1; 13740cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall } 13750cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall 13760cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall if (restart_successful) { 13770cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall SLOGE("System already restarted with encrypted disk, aborting"); 13780cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall return -1; 13790cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall } 13808f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1381f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (restart_main) { 1382f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence /* Here is where we shut down the framework. The init scripts 1383f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * start all services in one of three classes: core, main or late_start. 1384f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * On boot, we start core and main. Now, we stop main, but not core, 1385f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * as core includes vold and a few other really important things that 1386f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * we need to keep running. Once main has stopped, we should be able 1387f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * to umount the tmpfs /data, then mount the encrypted /data. 1388f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * We then restart the class main, and also the class late_start. 1389f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * At the moment, I've only put a few things in late_start that I know 1390f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * are not needed to bring up the framework, and that also cause problems 1391f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * with unmounting the tmpfs /data, but I hope to add add more services 1392f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * to the late_start class as we optimize this to decrease the delay 1393f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * till the user is asked for the password to the filesystem. 1394f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence */ 13958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1396f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence /* The init files are setup to stop the class main when vold.decrypt is 1397f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * set to trigger_reset_main. 1398f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence */ 1399f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence property_set("vold.decrypt", "trigger_reset_main"); 1400f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGD("Just asked init to shut down class main\n"); 14018f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1402f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence /* Ugh, shutting down the framework is not synchronous, so until it 1403f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * can be fixed, this horrible hack will wait a moment for it all to 1404f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * shut down before proceeding. Without it, some devices cannot 1405f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * restart the graphics services. 1406f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence */ 1407f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence sleep(2); 1408f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 14099dedfd473dc59e0277004e5b917e4eced02c8af5Ken Sumrall 14108f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Now that the framework is shutdown, we should be able to umount() 14118f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * the tmpfs filesystem, and mount the real one. 14128f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 14138f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 14146864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, ""); 14156864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall if (strlen(crypto_blkdev) == 0) { 14166864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall SLOGE("fs_crypto_blkdev not set\n"); 14176864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall return -1; 14186864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall } 14196864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall 14206e8440fd5072a673dd861ffb531fc17b4673ad90Greg Hackmann if (! (rc = wait_and_unmount(DATA_MNT_POINT, true)) ) { 14216fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker /* If ro.crypto.readonly is set to 1, mount the decrypted 14226fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker * filesystem readonly. This is used when /data is mounted by 14236fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker * recovery mode. 14246fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker */ 14256fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker char ro_prop[PROPERTY_VALUE_MAX]; 14266fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker property_get("ro.crypto.readonly", ro_prop, ""); 14276fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker if (strlen(ro_prop) > 0 && atoi(ro_prop)) { 14286fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT); 14296fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker rec->flags |= MS_RDONLY; 14306fd5771337fddc13bfd8b8030a0767a9f0c47f98Doug Zongker } 143162c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall 1432e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall /* If that succeeded, then mount the decrypted filesystem */ 14338e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence int retries = RETRY_MOUNT_ATTEMPTS; 14348e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence int mount_rc; 1435df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep 1436df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep /* 1437df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep * fs_mgr_do_mount runs fsck. Use setexeccon to run trusted 1438df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep * partitions in the fsck domain. 1439df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep */ 1440df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep if (setexeccon(secontextFsck())){ 1441df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep SLOGE("Failed to setexeccon"); 1442df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep return -1; 1443df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep } 14448e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence while ((mount_rc = fs_mgr_do_mount(fstab, DATA_MNT_POINT, 14458e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence crypto_blkdev, 0)) 14468e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence != 0) { 14478e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence if (mount_rc == FS_MGR_DOMNT_BUSY) { 14488e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence /* TODO: invoke something similar to 14498e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence Process::killProcessWithOpenFiles(DATA_MNT_POINT, 14508e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */ 14518e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence SLOGI("Failed to mount %s because it is busy - waiting", 14528e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence crypto_blkdev); 14538e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence if (--retries) { 14548e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence sleep(RETRY_MOUNT_DELAY_SECONDS); 14558e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence } else { 14568e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence /* Let's hope that a reboot clears away whatever is keeping 14578e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence the mount busy */ 14588e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence cryptfs_reboot(reboot); 14598e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence } 14608e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence } else { 14618e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence SLOGE("Failed to mount decrypted data"); 14628e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence cryptfs_set_corrupt(); 14638e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence cryptfs_trigger_restart_min_framework(); 14648e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence SLOGI("Started framework to offer wipe"); 1465df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep if (setexeccon(NULL)) { 1466df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep SLOGE("Failed to setexeccon"); 1467df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep } 14688e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence return -1; 14698e3f4510a88871a2d489ca4cdf7b738d4229053dPaul Lawrence } 147074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 1471df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep if (setexeccon(NULL)) { 1472df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep SLOGE("Failed to setexeccon"); 1473df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep return -1; 1474df725758628a0a250c82a9071af6a06a89e474fdJeff Vander Stoep } 14758ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 1476e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall /* Create necessary paths on /data */ 1477e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall if (prep_data_fs()) { 1478e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall return -1; 1479e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall } 1480e2ef0c0da454a5b9224d340260e9ad5be46092feSeigo Nonaka property_set("vold.decrypt", "trigger_load_persist_props"); 14818f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1482e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall /* startup service classes main and late_start */ 1483e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall property_set("vold.decrypt", "trigger_restart_framework"); 1484e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall SLOGD("Just triggered restart_framework\n"); 14858f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1486e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall /* Give it a few moments to get started */ 1487e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall sleep(1); 14888f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 14898f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 14900cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall if (rc == 0) { 14910cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall restart_successful = 1; 14920cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall } 14930cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall 14948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 14958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 14968f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1497f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrenceint cryptfs_restart(void) 1498f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence{ 149905335c344d73411439774dfa548c633020e158e1Paul Lawrence SLOGI("cryptfs_restart"); 150038132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 15017b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence SLOGE("cryptfs_restart not valid for file encryption:"); 15027b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence return -1; 150305335c344d73411439774dfa548c633020e158e1Paul Lawrence } 150405335c344d73411439774dfa548c633020e158e1Paul Lawrence 1505f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence /* Call internal implementation forcing a restart of main service group */ 1506f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return cryptfs_restart_internal(1); 1507f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence} 1508f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 15094375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wangstatic int do_crypto_complete(const char *mount_point) 15107f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall{ 15117f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall struct crypt_mnt_ftr crypt_ftr; 151229d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall char encrypted_state[PROPERTY_VALUE_MAX]; 1513e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall char key_loc[PROPERTY_VALUE_MAX]; 15147f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 15157f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall property_get("ro.crypto.state", encrypted_state, ""); 15167f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall if (strcmp(encrypted_state, "encrypted") ) { 15177f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall SLOGE("not running with encryption, aborting"); 151874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_NOT_ENCRYPTED; 15197f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall } 15207f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 15217b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence // crypto_complete is full disk encrypted status 152238132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 15237b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence return CRYPTO_COMPLETE_NOT_ENCRYPTED; 152405335c344d73411439774dfa548c633020e158e1Paul Lawrence } 152505335c344d73411439774dfa548c633020e158e1Paul Lawrence 1526160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_and_key(&crypt_ftr)) { 152756ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc)); 1528e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall 1529e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall /* 1530e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall * Only report this error if key_loc is a file and it exists. 1531e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall * If the device was never encrypted, and /data is not mountable for 1532e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall * some reason, returning 1 should prevent the UI from presenting the 1533e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall * a "enter password" screen, or worse, a "press button to wipe the 1534e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall * device" screen. 1535e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall */ 1536e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall if ((key_loc[0] == '/') && (access("key_loc", F_OK) == -1)) { 1537e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall SLOGE("master key file does not exist, aborting"); 153874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_NOT_ENCRYPTED; 1539e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall } else { 1540e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall SLOGE("Error getting crypt footer and key\n"); 154174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_BAD_METADATA; 1542e1a458578474954ea38456aacedbaf2ddfd37988Ken Sumrall } 15437f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall } 15447f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 154574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence // Test for possible error flags 154674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS){ 154774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Encryption process is partway completed\n"); 154874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_PARTIAL; 154974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 155074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 155174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE){ 155274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Encryption process was interrupted but cannot continue\n"); 155374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_INCONSISTENT; 155474f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 155574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 155674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (crypt_ftr.flags & CRYPT_DATA_CORRUPT){ 155774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Encryption is successful but data is corrupt\n"); 155874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_CORRUPT; 15597f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall } 15607f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 15617f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall /* We passed the test! We shall diminish, and return to the west */ 156274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence return CRYPTO_COMPLETE_ENCRYPTED; 15637f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall} 15647f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 1565f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrencestatic int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, 15664375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang const char *passwd, const char *mount_point, const char *label) 15678f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 15688f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Allocate enough space for a 256 bit key, but we may use less */ 1569160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned char decrypted_master_key[32]; 15708f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall char crypto_blkdev[MAXPATHLEN]; 15718f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall char real_blkdev[MAXPATHLEN]; 15728f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall char tmp_mount_point[64]; 15738f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall unsigned int orig_failed_decrypt_count; 15748f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int rc; 157569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence int use_keymaster = 0; 157669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence int upgrade = 0; 1577d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence unsigned char* intermediate_key = 0; 1578d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence size_t intermediate_key_size = 0; 15794375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang int N = 1 << crypt_ftr->N_factor; 15804375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang int r = 1 << crypt_ftr->r_factor; 15814375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang int p = 1 << crypt_ftr->p_factor; 15828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1583f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size); 1584f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count; 15850cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall 1586f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (! (crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED) ) { 1587d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr, 1588d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence &intermediate_key, &intermediate_key_size)) { 15897bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall SLOGE("Failed to decrypt master key\n"); 1590d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence rc = -1; 1591d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence goto errout; 15927bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall } 15938f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 15948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1595f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev)); 1596f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 159774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence // Create crypto block device - all (non fatal) code paths 159874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence // need it 1599f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, 1600f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence real_blkdev, crypto_blkdev, label)) { 160174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Error creating decrypted block device\n"); 160274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = -1; 160374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence goto errout; 16048f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 16058f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 160674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence /* Work out if the problem is the password or the data */ 160774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence unsigned char scrypted_intermediate_key[sizeof(crypt_ftr-> 160874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence scrypted_intermediate_key)]; 160974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 161074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = crypto_scrypt(intermediate_key, intermediate_key_size, 161174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence crypt_ftr->salt, sizeof(crypt_ftr->salt), 161274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence N, r, p, scrypted_intermediate_key, 161374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence sizeof(scrypted_intermediate_key)); 161474f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 161574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence // Does the key match the crypto footer? 161674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (rc == 0 && memcmp(scrypted_intermediate_key, 161774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence crypt_ftr->scrypted_intermediate_key, 161874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence sizeof(scrypted_intermediate_key)) == 0) { 161974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGI("Password matches"); 162074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = 0; 162174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } else { 162274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence /* Try mounting the file system anyway, just in case the problem's with 162374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence * the footer, not the key. */ 1624605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt", 1625605d7ae18d6e33b5dc1f6bb813ae32781498a4cdGeorge Burgess IV mount_point); 162674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence mkdir(tmp_mount_point, 0755); 162774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) { 162874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGE("Error temp mounting decrypted block device\n"); 162974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence delete_crypto_blk_dev(label); 1630d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence 1631d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence rc = ++crypt_ftr->failed_decrypt_count; 1632d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence put_crypt_ftr_and_key(crypt_ftr); 163374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } else { 163474f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence /* Success! */ 163574f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence SLOGI("Password did not match but decrypted drive mounted - continue"); 163674f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence umount(tmp_mount_point); 163774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = 0; 1638d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence } 163974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence } 164074f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence 164174f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence if (rc == 0) { 164274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence crypt_ftr->failed_decrypt_count = 0; 164372b8b82780c062f48350d743c5ee43ced369507dPaul Lawrence if (orig_failed_decrypt_count != 0) { 164472b8b82780c062f48350d743c5ee43ced369507dPaul Lawrence put_crypt_ftr_and_key(crypt_ftr); 164572b8b82780c062f48350d743c5ee43ced369507dPaul Lawrence } 16468f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1647d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence /* Save the name of the crypto block device 164874f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence * so we can mount it when restarting the framework. */ 16496864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev); 165070a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks 165170a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks /* Also save a the master key so we can reencrypted the key 165274f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence * the key when we want to change the password on it. */ 165370a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES); 16543ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall saved_mount_point = strdup(mount_point); 165570a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks master_key_saved = 1; 16567bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall SLOGD("%s(): Master key saved\n", __FUNCTION__); 16576864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall rc = 0; 165869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 165974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence // Upgrade if we're not using the latest KDF. 166069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence use_keymaster = keymaster_check_compatibility(); 166169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (crypt_ftr->kdf_type == KDF_SCRYPT_KEYMASTER) { 166247ba10d6d53e0d2e54453fe62324afdfa8d6c78aShawn Willden // Don't allow downgrade 166369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } else if (use_keymaster == 1 && crypt_ftr->kdf_type != KDF_SCRYPT_KEYMASTER) { 166469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence crypt_ftr->kdf_type = KDF_SCRYPT_KEYMASTER; 166569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence upgrade = 1; 166669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } else if (use_keymaster == 0 && crypt_ftr->kdf_type != KDF_SCRYPT) { 1667f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr->kdf_type = KDF_SCRYPT; 166869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence upgrade = 1; 166969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 167069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 167169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (upgrade) { 1672f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence rc = encrypt_master_key(passwd, crypt_ftr->salt, saved_master_key, 1673f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr->master_key, crypt_ftr); 16747bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall if (!rc) { 1675f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence rc = put_crypt_ftr_and_key(crypt_ftr); 16767bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall } 16777bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall SLOGD("Key Derivation Function upgrade: rc=%d\n", rc); 1678b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence 1679b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence // Do not fail even if upgrade failed - machine is bootable 1680b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence // Note that if this code is ever hit, there is a *serious* problem 1681b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence // since KDFs should never fail. You *must* fix the kdf before 1682b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence // proceeding! 1683b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence if (rc) { 1684b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence SLOGW("Upgrade failed with error %d," 1685b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence " but continuing with previous state", 1686b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence rc); 1687b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence rc = 0; 1688b2f682bda8443fb93ab67f19be84fd80d5ed2838Paul Lawrence } 16897bdfa52d934465e2182e2f1c200c4d8581ad5da6JP Abgrall } 16908f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 16918f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1692d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence errout: 1693d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence if (intermediate_key) { 1694d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence memset(intermediate_key, 0, intermediate_key_size); 1695d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence free(intermediate_key); 1696d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence } 16978f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 16988f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 16998f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 170029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall/* 17019c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * Called by vold when it's asked to mount an encrypted external 17029c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * storage volume. The incoming partition has no crypto header/footer, 17039c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * as any metadata is been stored in a separate, small partition. 17049c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * 17059c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * out_crypto_blkdev must be MAXPATHLEN. 170629d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall */ 17079c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeyint cryptfs_setup_ext_volume(const char* label, const char* real_blkdev, 17089c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey const unsigned char* key, int keysize, char* out_crypto_blkdev) { 1709ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC); 171014eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa if (fd == -1) { 17119c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey SLOGE("Failed to open %s: %s", real_blkdev, strerror(errno)); 171214eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa return -1; 171314eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa } 171414eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa 171514eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa unsigned long nr_sec = 0; 171614eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa get_blkdev_size(fd, &nr_sec); 171729d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall close(fd); 171814eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa 171929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall if (nr_sec == 0) { 17209c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey SLOGE("Failed to get size of %s: %s", real_blkdev, strerror(errno)); 172129d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall return -1; 172229d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 172329d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 17249c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey struct crypt_mnt_ftr ext_crypt_ftr; 17259c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey memset(&ext_crypt_ftr, 0, sizeof(ext_crypt_ftr)); 17269c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey ext_crypt_ftr.fs_size = nr_sec; 17279c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey ext_crypt_ftr.keysize = keysize; 17289c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey strcpy((char*) ext_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256"); 172929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 17309c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return create_crypto_blk_dev(&ext_crypt_ftr, key, real_blkdev, 17319c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey out_crypto_blkdev, label); 17329c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey} 173329d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 17349c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey/* 17359c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * Called by vold when it's asked to unmount an encrypted external 17369c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey * storage volume. 17379c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey */ 17389c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeyint cryptfs_revert_ext_volume(const char* label) { 17399c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return delete_crypto_blk_dev((char*) label); 174029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall} 174129d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 17427f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrallint cryptfs_crypto_complete(void) 17437f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall{ 17447f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall return do_crypto_complete("/data"); 17457f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall} 17467f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 1747f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrenceint check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr) 1748f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence{ 1749f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence char encrypted_state[PROPERTY_VALUE_MAX]; 1750f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence property_get("ro.crypto.state", encrypted_state, ""); 1751f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if ( master_key_saved || strcmp(encrypted_state, "encrypted") ) { 1752f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGE("encrypted fs already validated or not running with encryption," 1753f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence " aborting"); 1754f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 1755f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 1756f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 1757f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (get_crypt_ftr_and_key(crypt_ftr)) { 1758f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGE("Error getting crypt footer and key"); 1759f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 1760f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 1761f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 1762f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return 0; 1763f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence} 1764f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 17654375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wangint cryptfs_check_passwd(const char *passwd) 17668f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 176705335c344d73411439774dfa548c633020e158e1Paul Lawrence SLOGI("cryptfs_check_passwd"); 176838132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 17697b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence SLOGE("cryptfs_check_passwd not valid for file encryption"); 17707b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence return -1; 177105335c344d73411439774dfa548c633020e158e1Paul Lawrence } 177205335c344d73411439774dfa548c633020e158e1Paul Lawrence 1773f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence struct crypt_mnt_ftr crypt_ftr; 1774f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence int rc; 17758f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 1776f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence rc = check_unmounted_and_get_ftr(&crypt_ftr); 17773d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (rc) { 17783d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SLOGE("Could not get footer"); 1779f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return rc; 17803d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 17818f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 17823bd36d5e5f14dff4dadba88eb27664e495d0e16ePaul Lawrence rc = test_mount_encrypted_fs(&crypt_ftr, passwd, 17833d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE); 17843d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (rc) { 17853d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SLOGE("Password did not match"); 17863d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence return rc; 17873d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 17883d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 17893d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (crypt_ftr.flags & CRYPT_FORCE_COMPLETE) { 17903d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence // Here we have a default actual password but a real password 17913d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence // we must test against the scrypted value 17923d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence // First, we must delete the crypto block device that 17933d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence // test_mount_encrypted_fs leaves behind as a side effect 17943d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE); 17953d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence rc = test_mount_encrypted_fs(&crypt_ftr, DEFAULT_PASSWORD, 17963d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE); 17973d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (rc) { 17983d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SLOGE("Default password did not match on reboot encryption"); 17993d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence return rc; 18003d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 18013d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 18023d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags &= ~CRYPT_FORCE_COMPLETE; 18033d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence put_crypt_ftr_and_key(&crypt_ftr); 18043d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence rc = cryptfs_changepw(crypt_ftr.crypt_type, passwd); 18053d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (rc) { 18063d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SLOGE("Could not change password on reboot encryption"); 18073d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence return rc; 18083d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 18093d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 1810684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence 18113d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) { 1812399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence cryptfs_clear_password(); 1813399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence password = strdup(passwd); 1814399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence struct timespec now; 1815399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence clock_gettime(CLOCK_BOOTTIME, &now); 1816399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence password_expiry_time = now.tv_sec + password_max_age_seconds; 1817684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence } 1818684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence 18198f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 18208f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 18218f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 18223ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrallint cryptfs_verify_passwd(char *passwd) 18233ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall{ 18243ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall struct crypt_mnt_ftr crypt_ftr; 18253ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall /* Allocate enough space for a 256 bit key, but we may use less */ 1826160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned char decrypted_master_key[32]; 18273ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall char encrypted_state[PROPERTY_VALUE_MAX]; 18283ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall int rc; 18293ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 18303ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall property_get("ro.crypto.state", encrypted_state, ""); 18313ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall if (strcmp(encrypted_state, "encrypted") ) { 18323ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall SLOGE("device not encrypted, aborting"); 18333ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall return -2; 18343ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } 18353ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 18363ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall if (!master_key_saved) { 18373ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall SLOGE("encrypted fs not yet mounted, aborting"); 18383ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall return -1; 18393ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } 18403ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 18413ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall if (!saved_mount_point) { 18423ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall SLOGE("encrypted fs failed to save mount point, aborting"); 18433ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall return -1; 18443ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } 18453ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 1846160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_and_key(&crypt_ftr)) { 18473ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall SLOGE("Error getting crypt footer and key\n"); 18483ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall return -1; 18493ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } 18503ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 18513ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall if (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) { 18523ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall /* If the device has no password, then just say the password is valid */ 18533ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall rc = 0; 18543ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } else { 1855d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0); 18563ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) { 18573ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall /* They match, the password is correct */ 18583ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall rc = 0; 18593ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } else { 18603ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall /* If incorrect, sleep for a bit to prevent dictionary attacks */ 18613ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall sleep(1); 18623ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall rc = 1; 18633ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } 18643ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall } 18653ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 18663ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall return rc; 18673ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall} 18683ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall 18698f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall/* Initialize a crypt_mnt_ftr structure. The keysize is 18708f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * defaulted to 16 bytes, and the filesystem size to 0. 18718f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * Presumably, at a minimum, the caller will update the 18728f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * filesystem size and crypto_type_name after calling this function. 18738f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 187469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrencestatic int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr) 18758f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 1876160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall off64_t off; 1877160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 1878160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall memset(ftr, 0, sizeof(struct crypt_mnt_ftr)); 18798f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall ftr->magic = CRYPT_MNT_MAGIC; 1880c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root ftr->major_version = CURRENT_MAJOR_VERSION; 1881c96a5f8edf65a8abe441d0cfd3ce227bdf1bf55fKenny Root ftr->minor_version = CURRENT_MINOR_VERSION; 18828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall ftr->ftr_size = sizeof(struct crypt_mnt_ftr); 188370a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks ftr->keysize = KEY_LEN_BYTES; 1884160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 188569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence switch (keymaster_check_compatibility()) { 188669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence case 1: 188769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence ftr->kdf_type = KDF_SCRYPT_KEYMASTER; 188869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence break; 188969f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 189069f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence case 0: 189169f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence ftr->kdf_type = KDF_SCRYPT; 189269f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence break; 189369f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 189469f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence default: 189569f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence SLOGE("keymaster_check_compatibility failed"); 189669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return -1; 189769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 189869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 1899c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root get_device_scrypt_params(ftr); 1900c4c70f15bb8845b02f9ec1d624794757badd6933Kenny Root 1901160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE; 1902160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_info(NULL, &off) == 0) { 1903160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall ftr->persist_data_offset[0] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET; 1904160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall ftr->persist_data_offset[1] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET + 1905160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall ftr->persist_data_size; 1906160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 190769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence 190869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence return 0; 19098f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 19108f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 191129d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrallstatic int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type) 19128f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 1913e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall const char *args[10]; 1914e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall char size_str[32]; /* Must be large enough to hold a %lld and null byte */ 1915e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall int num_args; 1916e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall int status; 1917e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall int tmp; 19188f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int rc = -1; 19198f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 192029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall if (type == EXT4_FS) { 1921e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht#ifdef TARGET_USES_MKE2FS 1922e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[0] = "/system/bin/mke2fs"; 1923e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[1] = "-M"; 1924e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[2] = "/data"; 1925e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[3] = "-b"; 1926e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[4] = "4096"; 1927e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[5] = "-t"; 1928e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[6] = "ext4"; 1929e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[7] = crypto_blkdev; 1930e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht snprintf(size_str, sizeof(size_str), "%" PRId64, size / (4096 / 512)); 1931e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht args[8] = size_str; 1932e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht num_args = 9; 1933e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht#else 1934e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[0] = "/system/bin/make_ext4fs"; 1935e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[1] = "-a"; 1936e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[2] = "/data"; 1937e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[3] = "-l"; 19387373716c6d65ca328de11c994c60f698a9ef6290Elliott Hughes snprintf(size_str, sizeof(size_str), "%" PRId64, size * 512); 1939e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[4] = size_str; 1940e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[5] = crypto_blkdev; 1941e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall num_args = 6; 1942e0f409ca32b4bb434c30557a2ed28cf1957098c0Adrien Schildknecht#endif 1943e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGI("Making empty filesystem with command %s %s %s %s %s %s\n", 1944e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall args[0], args[1], args[2], args[3], args[4], args[5]); 194562c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall } else if (type == F2FS_FS) { 194662c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall args[0] = "/system/bin/mkfs.f2fs"; 194762c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall args[1] = "-t"; 194862c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall args[2] = "-d1"; 194962c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall args[3] = crypto_blkdev; 19507373716c6d65ca328de11c994c60f698a9ef6290Elliott Hughes snprintf(size_str, sizeof(size_str), "%" PRId64, size); 195162c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall args[4] = size_str; 195262c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall num_args = 5; 195362c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall SLOGI("Making empty filesystem with command %s %s %s %s %s\n", 195462c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall args[0], args[1], args[2], args[3], args[4]); 195529d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } else { 195629d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall SLOGE("cryptfs_enable_wipe(): unknown filesystem type %d\n", type); 195729d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall return -1; 195829d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 195929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 1960e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall tmp = android_fork_execvp(num_args, (char **)args, &status, false, true); 1961e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall 1962e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall if (tmp != 0) { 1963e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGE("Error creating empty filesystem on %s due to logwrap error\n", crypto_blkdev); 19648f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } else { 1965e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall if (WIFEXITED(status)) { 1966e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall if (WEXITSTATUS(status)) { 1967e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGE("Error creating filesystem on %s, exit status %d ", 1968e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall crypto_blkdev, WEXITSTATUS(status)); 1969e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall } else { 1970e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGD("Successfully created filesystem on %s\n", crypto_blkdev); 1971e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall rc = 0; 1972e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall } 1973e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall } else { 1974e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall SLOGE("Error creating filesystem on %s, did not exit normally\n", crypto_blkdev); 1975e550f78a3ff5985ba21cac263629c957500ef4e4Ken Sumrall } 19768f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 19778f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 19788f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 19798f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 19808f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 19818f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#define CRYPT_INPLACE_BUFSIZE 4096 198287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE) 198387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence#define CRYPT_SECTOR_SIZE 512 1984ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 1985ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence/* aligned 32K writes tends to make flash happy. 1986ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence * SD card association recommends it. 1987ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence */ 1988ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence#define BLOCKS_AT_A_TIME 8 1989ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 1990ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrencestruct encryptGroupsData 1991ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence{ 1992ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence int realfd; 1993ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence int cryptofd; 1994ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t numblocks; 1995ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t one_pct, cur_pct, new_pct; 1996ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t blocks_already_done, tot_numblocks; 199758c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence off64_t used_blocks_already_done, tot_used_blocks; 1998ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence char* real_blkdev, * crypto_blkdev; 1999ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence int count; 2000ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t offset; 2001ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence char* buffer; 200287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t last_written_sector; 200387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence int completed; 2004a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence time_t time_started; 2005a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence int remaining_time; 2006ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence}; 2007ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 200858c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrencestatic void update_progress(struct encryptGroupsData* data, int is_used) 2009ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence{ 2010ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->blocks_already_done++; 201158c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence 201258c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence if (is_used) { 201358c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence data->used_blocks_already_done++; 201458c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence } 201558c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence if (data->tot_used_blocks) { 201658c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence data->new_pct = data->used_blocks_already_done / data->one_pct; 201758c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence } else { 201858c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence data->new_pct = data->blocks_already_done / data->one_pct; 201958c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence } 202058c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence 2021ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (data->new_pct > data->cur_pct) { 2022ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence char buf[8]; 2023ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->cur_pct = data->new_pct; 2024cb33f5741cd37c93f7f1888a3dcbabdfab1524a9Elliott Hughes snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct); 2025ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence property_set("vold.encrypt_progress", buf); 2026ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2027a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence 2028a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence if (data->cur_pct >= 5) { 20299c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence struct timespec time_now; 20309c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence if (clock_gettime(CLOCK_MONOTONIC, &time_now)) { 20319c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence SLOGW("Error getting time"); 20329c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence } else { 20339c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence double elapsed_time = difftime(time_now.tv_sec, data->time_started); 20349c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence off64_t remaining_blocks = data->tot_used_blocks 20359c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence - data->used_blocks_already_done; 20369c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence int remaining_time = (int)(elapsed_time * remaining_blocks 20379c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence / data->used_blocks_already_done); 20389c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence 20399c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence // Change time only if not yet set, lower, or a lot higher for 20409c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence // best user experience 20419c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence if (data->remaining_time == -1 20429c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence || remaining_time < data->remaining_time 20439c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence || remaining_time > data->remaining_time + 60) { 20449c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence char buf[8]; 20459c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence snprintf(buf, sizeof(buf), "%d", remaining_time); 20469c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence property_set("vold.encrypt_time_remaining", buf); 20479c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence data->remaining_time = remaining_time; 20489c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence } 2049a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence } 2050a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence } 2051ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence} 2052ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 20533846be17feba13150a5db22204622db6a762a0d8Paul Lawrencestatic void log_progress(struct encryptGroupsData const* data, bool completed) 20543846be17feba13150a5db22204622db6a762a0d8Paul Lawrence{ 20553846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Precondition - if completed data = 0 else data != 0 20563846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 20573846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Track progress so we can skip logging blocks 20583846be17feba13150a5db22204622db6a762a0d8Paul Lawrence static off64_t offset = -1; 20593846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 20603846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Need to close existing 'Encrypting from' log? 20613846be17feba13150a5db22204622db6a762a0d8Paul Lawrence if (completed || (offset != -1 && data->offset != offset)) { 20623846be17feba13150a5db22204622db6a762a0d8Paul Lawrence SLOGI("Encrypted to sector %" PRId64, 20633846be17feba13150a5db22204622db6a762a0d8Paul Lawrence offset / info.block_size * CRYPT_SECTOR_SIZE); 20643846be17feba13150a5db22204622db6a762a0d8Paul Lawrence offset = -1; 20653846be17feba13150a5db22204622db6a762a0d8Paul Lawrence } 20663846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 20673846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Need to start new 'Encrypting from' log? 20683846be17feba13150a5db22204622db6a762a0d8Paul Lawrence if (!completed && offset != data->offset) { 20693846be17feba13150a5db22204622db6a762a0d8Paul Lawrence SLOGI("Encrypting from sector %" PRId64, 20703846be17feba13150a5db22204622db6a762a0d8Paul Lawrence data->offset / info.block_size * CRYPT_SECTOR_SIZE); 20713846be17feba13150a5db22204622db6a762a0d8Paul Lawrence } 20723846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 20733846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Update offset 20743846be17feba13150a5db22204622db6a762a0d8Paul Lawrence if (!completed) { 20753846be17feba13150a5db22204622db6a762a0d8Paul Lawrence offset = data->offset + (off64_t)data->count * info.block_size; 20763846be17feba13150a5db22204622db6a762a0d8Paul Lawrence } 20773846be17feba13150a5db22204622db6a762a0d8Paul Lawrence} 20783846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 2079ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrencestatic int flush_outstanding_data(struct encryptGroupsData* data) 2080ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence{ 2081ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (data->count == 0) { 2082ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence return 0; 2083ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2084ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2085231bdba012fd7e6d545d8ba67b32e49a66ec52e0Elliott Hughes SLOGV("Copying %d blocks at offset %" PRIx64, data->count, data->offset); 2086ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2087ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (pread64(data->realfd, data->buffer, 2088ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence info.block_size * data->count, data->offset) 2089ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence <= 0) { 2090ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGE("Error reading real_blkdev %s for inplace encrypt", 2091ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->real_blkdev); 2092ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence return -1; 2093ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2094ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2095ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (pwrite64(data->cryptofd, data->buffer, 2096ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence info.block_size * data->count, data->offset) 2097ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence <= 0) { 2098ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGE("Error writing crypto_blkdev %s for inplace encrypt", 2099ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->crypto_blkdev); 2100ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence return -1; 210187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 21023846be17feba13150a5db22204622db6a762a0d8Paul Lawrence log_progress(data, false); 2103ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2104ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2105ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->count = 0; 210687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence data->last_written_sector = (data->offset + data->count) 210787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence / info.block_size * CRYPT_SECTOR_SIZE - 1; 2108ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence return 0; 2109ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence} 2110ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2111ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrencestatic int encrypt_groups(struct encryptGroupsData* data) 2112ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence{ 2113ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence unsigned int i; 2114ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence u8 *block_bitmap = 0; 2115ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence unsigned int block; 2116ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t ret; 2117ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence int rc = -1; 2118ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 21194375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang data->buffer = (char *)malloc(info.block_size * BLOCKS_AT_A_TIME); 2120ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (!data->buffer) { 2121ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGE("Failed to allocate crypto buffer"); 2122ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2123ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2124ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 21254375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang block_bitmap = (u8 *)malloc(info.block_size); 2126ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (!block_bitmap) { 2127ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGE("failed to allocate block bitmap"); 2128ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2129ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2130ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2131ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence for (i = 0; i < aux_info.groups; ++i) { 2132ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGI("Encrypting group %d", i); 2133ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2134ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence u32 first_block = aux_info.first_data_block + i * info.blocks_per_group; 21354375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang u32 block_count = std::min(info.blocks_per_group, 21364375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang (u32)(aux_info.len_blocks - first_block)); 2137ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2138ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t offset = (u64)info.block_size 2139ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence * aux_info.bg_desc[i].bg_block_bitmap; 2140ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2141ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence ret = pread64(data->realfd, block_bitmap, info.block_size, offset); 2142ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (ret != (int)info.block_size) { 2143ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGE("failed to read all of block group bitmap %d", i); 2144ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2145ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2146ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2147ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence offset = (u64)info.block_size * first_block; 2148ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2149ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->count = 0; 2150ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2151ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence for (block = 0; block < block_count; block++) { 2152aa08e58e3a5d66bf3714c537336337b766458d9fliminghao int used = (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT) ? 2153aa08e58e3a5d66bf3714c537336337b766458d9fliminghao 0 : bitmap_get_bit(block_bitmap, block); 215458c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence update_progress(data, used); 215558c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence if (used) { 2156ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (data->count == 0) { 2157ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->offset = offset; 2158ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2159ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data->count++; 2160ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } else { 2161ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (flush_outstanding_data(data)) { 2162ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2163ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2164ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2165ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2166ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence offset += info.block_size; 2167ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2168ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence /* Write data if we are aligned or buffer size reached */ 2169ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0 2170ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence || data->count == BLOCKS_AT_A_TIME) { 2171ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (flush_outstanding_data(data)) { 2172ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2173ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2174ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 217587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 217673d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence if (!is_battery_ok_to_continue()) { 217787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Stopping encryption due to low battery"); 217887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = 0; 217987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto errout; 218087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 218187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 2182ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2183ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (flush_outstanding_data(data)) { 2184ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2185ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2186ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2187ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 218887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence data->completed = 1; 2189ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence rc = 0; 2190ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2191ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrenceerrout: 21923846be17feba13150a5db22204622db6a762a0d8Paul Lawrence log_progress(0, true); 2193ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence free(data->buffer); 2194ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence free(block_bitmap); 2195ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence return rc; 2196ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence} 2197ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2198ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrencestatic int cryptfs_enable_inplace_ext4(char *crypto_blkdev, 2199ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence char *real_blkdev, 2200ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t size, 2201ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t *size_already_done, 220287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t tot_size, 220387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t previously_encrypted_upto) 2204ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence{ 220558c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence u32 i; 2206ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence struct encryptGroupsData data; 220774f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence int rc; // Can't initialize without causing warning -Wclobbered 22084375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang struct timespec time_started = {0}; 22094375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang int retries = RETRY_MOUNT_ATTEMPTS; 2210ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 221187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (previously_encrypted_upto > *size_already_done) { 221287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGD("Not fast encrypting since resuming part way through"); 221387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return -1; 221487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 221587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 2216ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence memset(&data, 0, sizeof(data)); 2217ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data.real_blkdev = real_blkdev; 2218ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data.crypto_blkdev = crypto_blkdev; 2219ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2220ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) { 22213334c6a1ae38b2c7886fc9c0a69467e586af8635JP Abgrall SLOGE("Error opening real_blkdev %s for inplace encrypt. err=%d(%s)\n", 22223334c6a1ae38b2c7886fc9c0a69467e586af8635JP Abgrall real_blkdev, errno, strerror(errno)); 222374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = -1; 2224ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2225ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2226ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 222782fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng // Wait until the block device appears. Re-use the mount retry values since it is reasonable. 222882fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { 222982fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng if (--retries) { 223082fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng SLOGE("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s), retrying\n", 223182fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng crypto_blkdev, errno, strerror(errno)); 223282fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng sleep(RETRY_MOUNT_DELAY_SECONDS); 223382fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng } else { 223482fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng SLOGE("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n", 223582fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng crypto_blkdev, errno, strerror(errno)); 223682fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng rc = ENABLE_INPLACE_ERR_DEV; 223782fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng goto errout; 223882fd804f8ba49399f425bf43681b9b7fe464d9a1David Ng } 2239ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2240ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2241ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (setjmp(setjmp_env)) { 22427fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Reading ext4 extent caused an exception\n"); 224374f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = -1; 2244ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2245ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2246ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2247ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (read_ext(data.realfd, 0) != 0) { 22487fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Failed to read ext4 extent\n"); 224974f29f1df7d12c0cc06e9d6685adf15e757d8edaPaul Lawrence rc = -1; 2250ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2251ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2252ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2253ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; 2254ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; 2255ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; 2256ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 22577fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGI("Encrypting ext4 filesystem in place..."); 2258ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 225958c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence data.tot_used_blocks = data.numblocks; 226058c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence for (i = 0; i < aux_info.groups; ++i) { 226158c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count; 226258c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence } 226358c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence 226458c58cf7ef922ef019ce78ce1c418a7643c39518Paul Lawrence data.one_pct = data.tot_used_blocks / 100; 2265ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence data.cur_pct = 0; 22669c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence 22679c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence if (clock_gettime(CLOCK_MONOTONIC, &time_started)) { 22689c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence SLOGW("Error getting time at start"); 22699c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence // Note - continue anyway - we'll run with 0 22709c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence } 22719c58a871f9fb356409d3b90734bf706d1463f041Paul Lawrence data.time_started = time_started.tv_sec; 2272a96d9c9b3861506003930d4dbdc669173bf9a50ePaul Lawrence data.remaining_time = -1; 2273ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2274ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence rc = encrypt_groups(&data); 2275ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence if (rc) { 2276ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence SLOGE("Error encrypting groups"); 2277ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence goto errout; 2278ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 2279ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 228087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence *size_already_done += data.completed ? size : data.last_written_sector; 2281ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence rc = 0; 2282ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2283ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrenceerrout: 2284ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence close(data.realfd); 2285ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence close(data.cryptofd); 2286ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 2287ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence return rc; 2288ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence} 2289ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 22903846be17feba13150a5db22204622db6a762a0d8Paul Lawrencestatic void log_progress_f2fs(u64 block, bool completed) 22913846be17feba13150a5db22204622db6a762a0d8Paul Lawrence{ 22923846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Precondition - if completed data = 0 else data != 0 22933846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 22943846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Track progress so we can skip logging blocks 22953846be17feba13150a5db22204622db6a762a0d8Paul Lawrence static u64 last_block = (u64)-1; 22963846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 22973846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Need to close existing 'Encrypting from' log? 22983846be17feba13150a5db22204622db6a762a0d8Paul Lawrence if (completed || (last_block != (u64)-1 && block != last_block + 1)) { 22993846be17feba13150a5db22204622db6a762a0d8Paul Lawrence SLOGI("Encrypted to block %" PRId64, last_block); 23003846be17feba13150a5db22204622db6a762a0d8Paul Lawrence last_block = -1; 23013846be17feba13150a5db22204622db6a762a0d8Paul Lawrence } 23023846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 23033846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Need to start new 'Encrypting from' log? 23043846be17feba13150a5db22204622db6a762a0d8Paul Lawrence if (!completed && (last_block == (u64)-1 || block != last_block + 1)) { 23053846be17feba13150a5db22204622db6a762a0d8Paul Lawrence SLOGI("Encrypting from block %" PRId64, block); 23063846be17feba13150a5db22204622db6a762a0d8Paul Lawrence } 23073846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 23083846be17feba13150a5db22204622db6a762a0d8Paul Lawrence // Update offset 23093846be17feba13150a5db22204622db6a762a0d8Paul Lawrence if (!completed) { 23103846be17feba13150a5db22204622db6a762a0d8Paul Lawrence last_block = block; 23113846be17feba13150a5db22204622db6a762a0d8Paul Lawrence } 23123846be17feba13150a5db22204622db6a762a0d8Paul Lawrence} 23133846be17feba13150a5db22204622db6a762a0d8Paul Lawrence 2314e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenbergstatic int encrypt_one_block_f2fs(u64 pos, void *data) 2315e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg{ 2316e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg struct encryptGroupsData *priv_dat = (struct encryptGroupsData *)data; 2317e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2318e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg priv_dat->blocks_already_done = pos - 1; 2319e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg update_progress(priv_dat, 1); 2320e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2321e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg off64_t offset = pos * CRYPT_INPLACE_BUFSIZE; 2322e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2323e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) { 23247fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Error reading real_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev); 2325e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return -1; 2326e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2327e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2328e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) { 23297fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Error writing crypto_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev); 2330e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return -1; 2331e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } else { 23323846be17feba13150a5db22204622db6a762a0d8Paul Lawrence log_progress_f2fs(pos, false); 2333e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2334e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2335e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return 0; 2336e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg} 2337e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2338e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenbergstatic int cryptfs_enable_inplace_f2fs(char *crypto_blkdev, 2339e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg char *real_blkdev, 2340e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg off64_t size, 2341e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg off64_t *size_already_done, 2342e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg off64_t tot_size, 2343e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg off64_t previously_encrypted_upto) 2344e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg{ 2345e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg struct encryptGroupsData data; 2346e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg struct f2fs_info *f2fs_info = NULL; 23477fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall int rc = ENABLE_INPLACE_ERR_OTHER; 2348e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (previously_encrypted_upto > *size_already_done) { 2349e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg SLOGD("Not fast encrypting since resuming part way through"); 23507fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall return ENABLE_INPLACE_ERR_OTHER; 2351e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2352e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg memset(&data, 0, sizeof(data)); 2353e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.real_blkdev = real_blkdev; 2354e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.crypto_blkdev = crypto_blkdev; 2355e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.realfd = -1; 2356e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.cryptofd = -1; 2357ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) { 23587fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Error opening real_blkdev %s for f2fs inplace encrypt\n", 2359e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg real_blkdev); 2360e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg goto errout; 2361e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2362ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { 23637fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n", 23643334c6a1ae38b2c7886fc9c0a69467e586af8635JP Abgrall crypto_blkdev, errno, strerror(errno)); 23657fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall rc = ENABLE_INPLACE_ERR_DEV; 2366e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg goto errout; 2367e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2368e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2369e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg f2fs_info = generate_f2fs_info(data.realfd); 2370e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (!f2fs_info) 2371e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg goto errout; 2372e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2373e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; 2374e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; 2375e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; 2376e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2377e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.tot_used_blocks = get_num_blocks_used(f2fs_info); 2378e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2379e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.one_pct = data.tot_used_blocks / 100; 2380e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.cur_pct = 0; 2381e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.time_started = time(NULL); 2382e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.remaining_time = -1; 2383e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 23844375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang data.buffer = (char *)malloc(f2fs_info->block_size); 2385e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (!data.buffer) { 2386e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg SLOGE("Failed to allocate crypto buffer"); 2387e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg goto errout; 2388e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2389e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2390e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg data.count = 0; 2391e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2392e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg /* Currently, this either runs to completion, or hits a nonrecoverable error */ 2393e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data); 2394e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2395e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (rc) { 23967fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("Error in running over f2fs blocks"); 23977fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall rc = ENABLE_INPLACE_ERR_OTHER; 2398e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg goto errout; 2399e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 2400e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2401e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg *size_already_done += size; 2402e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg rc = 0; 2403e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2404e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenbergerrout: 2405e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (rc) 2406e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg SLOGE("Failed to encrypt f2fs filesystem on %s", real_blkdev); 2407e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 24083846be17feba13150a5db22204622db6a762a0d8Paul Lawrence log_progress_f2fs(0, true); 2409e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg free(f2fs_info); 2410e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg free(data.buffer); 2411e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg close(data.realfd); 2412e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg close(data.cryptofd); 2413e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2414e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return rc; 2415e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg} 2416e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 2417ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrencestatic int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev, 2418ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t size, off64_t *size_already_done, 241987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t tot_size, 242087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t previously_encrypted_upto) 24218f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 24228f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int realfd, cryptofd; 24238f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall char *buf[CRYPT_INPLACE_BUFSIZE]; 24247fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall int rc = ENABLE_INPLACE_ERR_OTHER; 24258f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall off64_t numblocks, i, remainder; 24268ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall off64_t one_pct, cur_pct, new_pct; 242729d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall off64_t blocks_already_done, tot_numblocks; 24288ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 2429ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (realfd = open(real_blkdev, O_RDONLY|O_CLOEXEC)) < 0) { 24308f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev); 24317fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall return ENABLE_INPLACE_ERR_OTHER; 24328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 24338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 2434ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if ( (cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { 24353334c6a1ae38b2c7886fc9c0a69467e586af8635JP Abgrall SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n", 24363334c6a1ae38b2c7886fc9c0a69467e586af8635JP Abgrall crypto_blkdev, errno, strerror(errno)); 24378f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(realfd); 24387fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall return ENABLE_INPLACE_ERR_DEV; 24398f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 24408f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 24418f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* This is pretty much a simple loop of reading 4K, and writing 4K. 24428f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * The size passed in is the number of 512 byte sectors in the filesystem. 24438f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * So compute the number of whole 4K blocks we should read/write, 24448f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall * and the remainder. 24458f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 24468f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; 24478f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall remainder = size % CRYPT_SECTORS_PER_BUFSIZE; 244829d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; 244929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; 24508f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 24518f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGE("Encrypting filesystem in place..."); 24528f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 245387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence i = previously_encrypted_upto + 1 - *size_already_done; 245487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 245587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) { 245687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Cannot seek to previously encrypted point on %s", real_blkdev); 245787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto errout; 245887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 245987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 246087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) { 246187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Cannot seek to previously encrypted point on %s", crypto_blkdev); 246287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto errout; 246387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 246487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 246587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence for (;i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) { 246687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) { 246787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error reading initial sectors from real_blkdev %s for " 246887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence "inplace encrypt\n", crypto_blkdev); 246987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto errout; 247087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 247187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) { 247287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error writing initial sectors to crypto_blkdev %s for " 247387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence "inplace encrypt\n", crypto_blkdev); 247487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto errout; 247587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 2476cb33f5741cd37c93f7f1888a3dcbabdfab1524a9Elliott Hughes SLOGI("Encrypted 1 block at %" PRId64, i); 247787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 247887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 247987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 248029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall one_pct = tot_numblocks / 100; 24818ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall cur_pct = 0; 24828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* process the majority of the filesystem in blocks */ 248387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) { 248429d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall new_pct = (i + blocks_already_done) / one_pct; 24858ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall if (new_pct > cur_pct) { 24868ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall char buf[8]; 24878ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 24888ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall cur_pct = new_pct; 2489cb33f5741cd37c93f7f1888a3dcbabdfab1524a9Elliott Hughes snprintf(buf, sizeof(buf), "%" PRId64, cur_pct); 24908ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall property_set("vold.encrypt_progress", buf); 24918ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 24928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) { 249387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error reading real_blkdev %s for inplace encrypt", crypto_blkdev); 24948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 24958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 24968f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) { 249787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error writing crypto_blkdev %s for inplace encrypt", crypto_blkdev); 249887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto errout; 249987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 2500cb33f5741cd37c93f7f1888a3dcbabdfab1524a9Elliott Hughes SLOGD("Encrypted %d block at %" PRId64, 250187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence CRYPT_SECTORS_PER_BUFSIZE, 250287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence i * CRYPT_SECTORS_PER_BUFSIZE); 250387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 250487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 250573d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence if (!is_battery_ok_to_continue()) { 250687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Stopping encryption due to low battery"); 250787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence *size_already_done += (i + 1) * CRYPT_SECTORS_PER_BUFSIZE - 1; 250887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = 0; 25098f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 25108f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 25118f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 25128f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 25138f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Do any remaining sectors */ 25148f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall for (i=0; i<remainder; i++) { 251587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) { 251687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error reading final sectors from real_blkdev %s for inplace encrypt", crypto_blkdev); 25178f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 25188f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 251987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) { 252087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error writing final sectors to crypto_blkdev %s for inplace encrypt", crypto_blkdev); 25218f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall goto errout; 252287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 252387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGI("Encrypted 1 block at next location"); 25248f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 25258f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 25268f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 252729d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall *size_already_done += size; 25288f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall rc = 0; 25298f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 25308f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallerrout: 25318f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(realfd); 25328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall close(cryptofd); 25338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 25348f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return rc; 25358f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 25368f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 25377fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall/* returns on of the ENABLE_INPLACE_* return codes */ 2538ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrencestatic int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev, 2539ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence off64_t size, off64_t *size_already_done, 254087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t tot_size, 254187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t previously_encrypted_upto) 2542ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence{ 25437fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall int rc_ext4, rc_f2fs, rc_full; 254487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (previously_encrypted_upto) { 2545cb33f5741cd37c93f7f1888a3dcbabdfab1524a9Elliott Hughes SLOGD("Continuing encryption from %" PRId64, previously_encrypted_upto); 254687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 254787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 254887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (*size_already_done + size < previously_encrypted_upto) { 254987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence *size_already_done += size; 255087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return 0; 255187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 255287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 2553e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg /* TODO: identify filesystem type. 2554e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and 2555e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg * then we will drop down to cryptfs_enable_inplace_f2fs. 2556e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg * */ 25577fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, 2558e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg size, size_already_done, 25597fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall tot_size, previously_encrypted_upto)) == 0) { 2560e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return 0; 2561e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg } 25627fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGD("cryptfs_enable_inplace_ext4()=%d\n", rc_ext4); 2563e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 25647fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, 2565e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg size, size_already_done, 25667fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall tot_size, previously_encrypted_upto)) == 0) { 2567e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg return 0; 2568ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence } 25697fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGD("cryptfs_enable_inplace_f2fs()=%d\n", rc_f2fs); 2570ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 25717fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall rc_full = cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, 257287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence size, size_already_done, tot_size, 257387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence previously_encrypted_upto); 25747fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGD("cryptfs_enable_inplace_full()=%d\n", rc_full); 25757fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall 25767fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall /* Hack for b/17898962, the following is the symptom... */ 25777fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall if (rc_ext4 == ENABLE_INPLACE_ERR_DEV 25787fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall && rc_f2fs == ENABLE_INPLACE_ERR_DEV 25797fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall && rc_full == ENABLE_INPLACE_ERR_DEV) { 25807fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall return ENABLE_INPLACE_ERR_DEV; 25817fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall } 25827fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall return rc_full; 2583ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence} 2584ae59fe6c1988af93c171e1b921a465c4fb1daabbPaul Lawrence 25858f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#define CRYPTO_ENABLE_WIPE 1 25868f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#define CRYPTO_ENABLE_INPLACE 2 25878ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 25888ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall#define FRAMEWORK_BOOT_WAIT 60 25898ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 259087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrencestatic int cryptfs_SHA256_fileblock(const char* filename, __le8* buf) 259187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence{ 2592ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey int fd = open(filename, O_RDONLY|O_CLOEXEC); 259387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (fd == -1) { 259487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error opening file %s", filename); 259587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return -1; 259687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 259787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 259887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence char block[CRYPT_INPLACE_BUFSIZE]; 259987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence memset(block, 0, sizeof(block)); 260087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (unix_read(fd, block, sizeof(block)) < 0) { 260187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error reading file %s", filename); 260287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence close(fd); 260387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return -1; 260487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 260587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 260687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence close(fd); 260787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 260887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SHA256_CTX c; 260987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SHA256_Init(&c); 261087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SHA256_Update(&c, block, sizeof(block)); 261187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SHA256_Final(buf, &c); 261287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 261387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return 0; 261487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence} 261587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 261662c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrallstatic int get_fs_type(struct fstab_rec *rec) 261762c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall{ 261862c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall if (!strcmp(rec->fs_type, "ext4")) { 261962c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall return EXT4_FS; 262062c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall } else if (!strcmp(rec->fs_type, "f2fs")) { 262162c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall return F2FS_FS; 262262c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall } else { 262362c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall return -1; 262462c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall } 262562c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall} 262662c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall 262787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrencestatic int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how, 262887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence char *crypto_blkdev, char *real_blkdev, 262987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence int previously_encrypted_upto) 263087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence{ 263187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t cur_encryption_done=0, tot_encryption_size=0; 26328439dc9fd569794b1a31f67cf43d9212de33eeccTim Murray int rc = -1; 263387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 263473d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence if (!is_battery_ok_to_start()) { 263573d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence SLOGW("Not starting encryption due to low battery"); 263687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return 0; 263787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 263887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 263987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* The size of the userdata partition, and add in the vold volumes below */ 264087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence tot_encryption_size = crypt_ftr->fs_size; 264187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 264287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (how == CRYPTO_ENABLE_WIPE) { 264362c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT); 264462c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall int fs_type = get_fs_type(rec); 264562c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall if (fs_type < 0) { 264662c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall SLOGE("cryptfs_enable: unsupported fs type %s\n", rec->fs_type); 264762c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall return -1; 264862c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall } 264962c7af38f2f30b3f152460a8f716fe43e4acad7bJP Abgrall rc = cryptfs_enable_wipe(crypto_blkdev, crypt_ftr->fs_size, fs_type); 265087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else if (how == CRYPTO_ENABLE_INPLACE) { 265187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, 265287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr->fs_size, &cur_encryption_done, 265387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence tot_encryption_size, 265487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence previously_encrypted_upto); 265587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 26567fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall if (rc == ENABLE_INPLACE_ERR_DEV) { 26577fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall /* Hack for b/17898962 */ 26587fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall SLOGE("cryptfs_enable: crypto block dev failure. Must reboot...\n"); 26597fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall cryptfs_reboot(reboot); 26607fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall } 26617fc1de8a44307d6c51826ab90f804702e08d1e6dJP Abgrall 266273d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence if (!rc) { 266387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr->encrypted_upto = cur_encryption_done; 266487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 266587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 266673d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) { 266787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* The inplace routine never actually sets the progress to 100% due 266887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence * to the round down nature of integer division, so set it here */ 266987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence property_set("vold.encrypt_progress", "100"); 267087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 267187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 267287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* Shouldn't happen */ 267387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("cryptfs_enable: internal error, unknown option\n"); 267487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = -1; 267587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 267687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 267787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence return rc; 267887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence} 267987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 26804375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wangint cryptfs_enable_internal(char *howarg, int crypt_type, const char *passwd, 2681569649ff1d6d76f89982c391a5b0e119050250e4Paul Lawrence int no_ui) 26828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall{ 26838f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall int how = 0; 268487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN]; 2685160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned char decrypted_master_key[KEY_LEN_BYTES]; 268614eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa int rc=-1, i; 268787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence struct crypt_mnt_ftr crypt_ftr; 2688160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall struct crypt_persist_data *pdata; 268929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall char encrypted_state[PROPERTY_VALUE_MAX]; 26905d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall char lockid[32] = { 0 }; 269129d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall char key_loc[PROPERTY_VALUE_MAX]; 269229d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall int num_vols; 269387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence off64_t previously_encrypted_upto = 0; 26943d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence bool rebootEncryption = false; 26954375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang bool onlyCreateHeader = false; 26964375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang int fd = -1; 269729d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 26988f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall if (!strcmp(howarg, "wipe")) { 26998f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall how = CRYPTO_ENABLE_WIPE; 27008f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } else if (! strcmp(howarg, "inplace")) { 27018f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall how = CRYPTO_ENABLE_INPLACE; 27028f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } else { 27038f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* Shouldn't happen, as CommandListener vets the args */ 27043ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall goto error_unencrypted; 27058f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 27068f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 270787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (how == CRYPTO_ENABLE_INPLACE 27083d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence && get_crypt_ftr_and_key(&crypt_ftr) == 0) { 27093d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) { 27103d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence /* An encryption was underway and was interrupted */ 27113d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence previously_encrypted_upto = crypt_ftr.encrypted_upto; 27123d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.encrypted_upto = 0; 27133d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS; 27143d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 27153d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence /* At this point, we are in an inconsistent state. Until we successfully 27163d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence complete encryption, a reboot will leave us broken. So mark the 27173d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence encryption failed in case that happens. 27183d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence On successfully completing encryption, remove this flag */ 27193d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE; 27203d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 27213d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence put_crypt_ftr_and_key(&crypt_ftr); 27223d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } else if (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) { 27233d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (!check_ftr_sha(&crypt_ftr)) { 27243d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence memset(&crypt_ftr, 0, sizeof(crypt_ftr)); 27253d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence put_crypt_ftr_and_key(&crypt_ftr); 27263d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence goto error_unencrypted; 27273d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 27286bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence 27293d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence /* Doing a reboot-encryption*/ 27303d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags &= ~CRYPT_FORCE_ENCRYPTION; 27313d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags |= CRYPT_FORCE_COMPLETE; 27323d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence rebootEncryption = true; 27333d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 273487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 273587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 273687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence property_get("ro.crypto.state", encrypted_state, ""); 273787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) { 273887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Device is already running encrypted, aborting"); 273987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto error_unencrypted; 274087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 274187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 274287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence // TODO refactor fs_mgr_get_crypt_info to get both in one call 274387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc)); 274456ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev)); 27458f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 27463ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* Get the size of the real block device */ 27474375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang fd = open(real_blkdev, O_RDONLY|O_CLOEXEC); 274814eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa if (fd == -1) { 274914eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa SLOGE("Cannot open block device %s\n", real_blkdev); 275014eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa goto error_unencrypted; 275114eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa } 275214eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa unsigned long nr_sec; 275314eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa get_blkdev_size(fd, &nr_sec); 275414eab550e8a4f28889cc9ffbb92ddff8f18c4f03Hiroaki Miyazawa if (nr_sec == 0) { 27553ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall SLOGE("Cannot get size of block device %s\n", real_blkdev); 27563ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall goto error_unencrypted; 27573ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } 27583ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall close(fd); 27593ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 27603ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */ 276129d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall if ((how == CRYPTO_ENABLE_INPLACE) && (!strcmp(key_loc, KEY_IN_FOOTER))) { 27623ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall unsigned int fs_size_sec, max_fs_size_sec; 2763a70abc60091aed3c3eaf8bc8e1766e233c1c3a2fJim Miller fs_size_sec = get_fs_size(real_blkdev); 2764e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg if (fs_size_sec == 0) 2765e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev); 2766e82df164e8128ec9df0072c4a4f3d92e79a0f5f4Daniel Rosenberg 276787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE); 27683ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 27693ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall if (fs_size_sec > max_fs_size_sec) { 27703ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall SLOGE("Orig filesystem overlaps crypto footer region. Cannot encrypt in place."); 27713ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall goto error_unencrypted; 27723ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } 27733ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } 27743ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 27755d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall /* Get a wakelock as this may take a while, and we don't want the 27765d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall * device to sleep on us. We'll grab a partial wakelock, and if the UI 27775d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall * wants to keep the screen on, it can grab a full wakelock. 27785d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall */ 277929d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int) getpid()); 27805d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid); 27815d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall 27828f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall /* The init files are setup to stop the class main and late start when 27838ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall * vold sets trigger_shutdown_framework. 27848f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall */ 27858f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall property_set("vold.decrypt", "trigger_shutdown_framework"); 27868f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall SLOGD("Just asked init to shut down class main\n"); 27878f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 27889c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey /* Ask vold to unmount all devices that it manages */ 27899c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (vold_unmountAll()) { 27909c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey SLOGE("Failed to unmount all vold managed devices"); 27912eaf7138528d30c331d83ab8346a97e66b5499e2Ken Sumrall } 27928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 27933d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence /* no_ui means we are being called from init, not settings. 27943d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence Now we always reboot from settings, so !no_ui means reboot 27953d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence */ 27963d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (!no_ui) { 27973d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence /* Try fallback, which is to reboot and try there */ 27983d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence onlyCreateHeader = true; 27993d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence FILE* breadcrumb = fopen(BREADCRUMB_FILE, "we"); 28003d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (breadcrumb == 0) { 28013d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence SLOGE("Failed to create breadcrumb file"); 28023d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence goto error_shutting_down; 28033d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 28043d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence fclose(breadcrumb); 28058ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 28068f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 28078ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Do extra work for a better UX when doing the long inplace encryption */ 28083d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (how == CRYPTO_ENABLE_INPLACE && !onlyCreateHeader) { 28098ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Now that /data is unmounted, we need to mount a tmpfs 28108ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall * /data, set a property saying we're doing inplace encryption, 28118ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall * and restart the framework. 28128ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall */ 2813e5032c42da3c33a854df0a24a7968b4ab54190b9Ken Sumrall if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) { 28143ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall goto error_shutting_down; 28158f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 28168ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Tells the framework that inplace encryption is starting */ 28177df84120b25dca713f623528801385b00208c2aaKen Sumrall property_set("vold.encrypt_progress", "0"); 28188f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 28198ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* restart the framework. */ 28208ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Create necessary paths on /data */ 28218ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall if (prep_data_fs()) { 28223ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall goto error_shutting_down; 28238f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall } 28248f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 282592736efab068bdbfeb1177544907b84511fb04e0Ken Sumrall /* Ugh, shutting down the framework is not synchronous, so until it 282692736efab068bdbfeb1177544907b84511fb04e0Ken Sumrall * can be fixed, this horrible hack will wait a moment for it all to 282792736efab068bdbfeb1177544907b84511fb04e0Ken Sumrall * shut down before proceeding. Without it, some devices cannot 282892736efab068bdbfeb1177544907b84511fb04e0Ken Sumrall * restart the graphics services. 282992736efab068bdbfeb1177544907b84511fb04e0Ken Sumrall */ 283092736efab068bdbfeb1177544907b84511fb04e0Ken Sumrall sleep(2); 28318ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 28328f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 28338ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Start the actual work of making an encrypted filesystem */ 28348ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Initialize a crypt_mnt_ftr for the partition */ 28353d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (previously_encrypted_upto == 0 && !rebootEncryption) { 283669f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) { 283769f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence goto error_shutting_down; 283869f4ebd81e22f91a4571763842b5960d95d2758dPaul Lawrence } 2839160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 284087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (!strcmp(key_loc, KEY_IN_FOOTER)) { 284187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr.fs_size = nr_sec 284287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE); 284387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 284487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr.fs_size = nr_sec; 284587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 28466bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence /* At this point, we are in an inconsistent state. Until we successfully 28476bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence complete encryption, a reboot will leave us broken. So mark the 28486bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence encryption failed in case that happens. 28496bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence On successfully completing encryption, remove this flag */ 28503d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (onlyCreateHeader) { 28513d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags |= CRYPT_FORCE_ENCRYPTION; 28523d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } else { 28533d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE; 28543d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 285587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr.crypt_type = crypt_type; 285687701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani strlcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256", MAX_CRYPTO_TYPE_NAME_LEN); 28578ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 285887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* Make an encrypted master key */ 28593d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd, 28603d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) { 286187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Cannot create encrypted master key\n"); 286287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence goto error_shutting_down; 286387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 28648ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 28653d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence /* Replace scrypted intermediate key if we are preparing for a reboot */ 28663d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (onlyCreateHeader) { 28673d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence unsigned char fake_master_key[KEY_LEN_BYTES]; 28683d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence unsigned char encrypted_fake_master_key[KEY_LEN_BYTES]; 28693d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence memset(fake_master_key, 0, sizeof(fake_master_key)); 28703d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence encrypt_master_key(passwd, crypt_ftr.salt, fake_master_key, 28713d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence encrypted_fake_master_key, &crypt_ftr); 28723d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 28733d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 287487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* Write the key to the end of the partition */ 287587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence put_crypt_ftr_and_key(&crypt_ftr); 28768ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 287787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* If any persistent data has been remembered, save it. 287887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence * If none, create a valid empty table and save that. 287987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence */ 288087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (!persist_data) { 28814375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang pdata = (crypt_persist_data *)malloc(CRYPT_PERSIST_DATA_SIZE); 288287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (pdata) { 288387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); 288487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence persist_data = pdata; 288587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 288687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 288787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (persist_data) { 288887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence save_persistent_data(); 288987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 2890160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 2891160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 28923d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (onlyCreateHeader) { 28933d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence sleep(2); 28943d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence cryptfs_reboot(reboot); 28953d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 28963d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence 28973d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (how == CRYPTO_ENABLE_INPLACE && (!no_ui || rebootEncryption)) { 289887701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani /* startup service classes main and late_start */ 289987701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani property_set("vold.decrypt", "trigger_restart_min_framework"); 290087701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani SLOGD("Just triggered restart_min_framework\n"); 290187701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani 290287701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani /* OK, the framework is restarted and will soon be showing a 290387701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani * progress bar. Time to setup an encrypted mapping, and 290487701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani * either write a new filesystem, or encrypt in place updating 290587701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani * the progress bar as we work. 290687701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani */ 290787701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani } 290887701e2755f039d6ea8c1510dcddf468ee947a62Ajay Dudani 2909d0c7b17070d4321fef096873b4890794024a5f63Paul Lawrence decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0); 291029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, 29113d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence CRYPTO_BLOCK_DEVICE); 291229d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 291387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* If we are continuing, check checksums match */ 291487999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = 0; 291587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (previously_encrypted_upto) { 291687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence __le8 hash_first_block[SHA256_DIGEST_LENGTH]; 291787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = cryptfs_SHA256_fileblock(crypto_blkdev, hash_first_block); 291887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 291987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (!rc && memcmp(hash_first_block, crypt_ftr.hash_first_block, 292087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence sizeof(hash_first_block)) != 0) { 292187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Checksums do not match - trigger wipe"); 292287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = -1; 292329d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 292429d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 29258ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 292687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence if (!rc) { 292787999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = cryptfs_enable_all_volumes(&crypt_ftr, how, 292887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypto_blkdev, real_blkdev, 292987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence previously_encrypted_upto); 293087999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 293187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence 293287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence /* Calculate checksum if we are not finished */ 2933b1eb7a06ee24078efb3a7efaa32c1561b92f4cb8Paul Lawrence if (!rc && how == CRYPTO_ENABLE_INPLACE 2934b1eb7a06ee24078efb3a7efaa32c1561b92f4cb8Paul Lawrence && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) { 293587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = cryptfs_SHA256_fileblock(crypto_blkdev, 293687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr.hash_first_block); 293773d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence if (rc) { 293887999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGE("Error calculating checksum for continuing encryption"); 293987999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence rc = -1; 294029d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall } 29418ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 29428ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 29438ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Undo the dm-crypt mapping whether we succeed or not */ 29443d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE); 294529d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 29468ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall if (! rc) { 29478ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* Success */ 29486bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE; 29497f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall 2950b1eb7a06ee24078efb3a7efaa32c1561b92f4cb8Paul Lawrence if (how == CRYPTO_ENABLE_INPLACE 2951b1eb7a06ee24078efb3a7efaa32c1561b92f4cb8Paul Lawrence && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) { 295287999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence SLOGD("Encrypted up to sector %lld - will continue after reboot", 295387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence crypt_ftr.encrypted_upto); 29546bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS; 295587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 295673d7a02dc6e18b4c0a6f29e8f89b432c1b6cc808Paul Lawrence 29576bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence put_crypt_ftr_and_key(&crypt_ftr); 2958d33d417e3a057fffad22c23f5f002177531db2a5Ken Sumrall 2959b1eb7a06ee24078efb3a7efaa32c1561b92f4cb8Paul Lawrence if (how == CRYPTO_ENABLE_WIPE 2960b1eb7a06ee24078efb3a7efaa32c1561b92f4cb8Paul Lawrence || crypt_ftr.encrypted_upto == crypt_ftr.fs_size) { 2961b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence char value[PROPERTY_VALUE_MAX]; 2962b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence property_get("ro.crypto.state", value, ""); 2963b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence if (!strcmp(value, "")) { 2964b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence /* default encryption - continue first boot sequence */ 2965b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence property_set("ro.crypto.state", "encrypted"); 29664ed4526e68b10c9d583541da9dadaf3d29b769cdPaul Lawrence property_set("ro.crypto.type", "block"); 2967b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence release_wake_lock(lockid); 29683d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence if (rebootEncryption && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) { 29693d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence // Bring up cryptkeeper that will check the password and set it 29703d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence property_set("vold.decrypt", "trigger_shutdown_framework"); 29713d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence sleep(2); 29723d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence property_set("vold.encrypt_progress", ""); 29733d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence cryptfs_trigger_restart_min_framework(); 29743d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } else { 29753d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence cryptfs_check_passwd(DEFAULT_PASSWORD); 29763d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence cryptfs_restart_internal(1); 29773d99ebad3ddcd7e4a30bca82ba8bd641c3a71038Paul Lawrence } 2978b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence return 0; 2979b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence } else { 2980b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence sleep(2); /* Give the UI a chance to show 100% progress */ 298187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence cryptfs_reboot(reboot); 2982b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence } 298387999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } else { 2984b6672e135ac7a5a1d5b1d277cf678096c57dd7ddPaul Lawrence sleep(2); /* Partially encrypted, ensure writes flushed to ssd */ 298587999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence cryptfs_reboot(shutdown); 298687999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence } 29873ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall } else { 2988ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood char value[PROPERTY_VALUE_MAX]; 2989ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood 2990319369ac111aec79b42668477c998c36b5f3be06Ken Sumrall property_get("ro.vold.wipe_on_crypt_fail", value, "0"); 2991ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood if (!strcmp(value, "1")) { 2992ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood /* wipe data if encryption failed */ 2993ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood SLOGE("encryption failed - rebooting into recovery to wipe data\n"); 29944375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang std::string err; 29954375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang const std::vector<std::string> options = { 29964375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang "--wipe_data\n--reason=cryptfs_enable_internal\n" 29974375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang }; 29984375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang if (!write_bootloader_message(options, &err)) { 29994375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang SLOGE("could not write bootloader message: %s", err.c_str()); 3000ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood } 300187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence cryptfs_reboot(recovery); 3002ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood } else { 3003ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood /* set property to trigger dialog */ 3004ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood property_set("vold.encrypt_progress", "error_partially_encrypted"); 3005ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood release_wake_lock(lockid); 3006ee6d8c42f337ea1446a319df53f6d1a96afbd209Mike Lockwood } 30073ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return -1; 30088ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 30098ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 30103ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* hrm, the encrypt step claims success, but the reboot failed. 30113ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall * This should not happen. 30123ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall * Set the property and return. Hope the framework can deal with it. 30133ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall */ 30143ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall property_set("vold.encrypt_progress", "error_reboot_failed"); 30155d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall release_wake_lock(lockid); 30168ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall return rc; 30173ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 30183ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrallerror_unencrypted: 30193ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall property_set("vold.encrypt_progress", "error_not_encrypted"); 30205d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall if (lockid[0]) { 30215d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall release_wake_lock(lockid); 30225d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall } 30233ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return -1; 30243ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 30253ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrallerror_shutting_down: 30263ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* we failed, and have not encrypted anthing, so the users's data is still intact, 30273ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall * but the framework is stopped and not restarted to show the error, so it's up to 30283ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall * vold to restart the system. 30293ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall */ 30303ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall SLOGE("Error enabling encryption after framework is shutdown, no data changed, restarting system"); 303187999173dd79dbcbd8cb97f5476007e867aaeebaPaul Lawrence cryptfs_reboot(reboot); 30323ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall 30333ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall /* shouldn't get here */ 30343ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall property_set("vold.encrypt_progress", "error_shutting_down"); 30355d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall if (lockid[0]) { 30365d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall release_wake_lock(lockid); 30375d4c68e40700424b65a4331be75620706a0dd49cKen Sumrall } 30383ed8236de11a1be8b45d4c37b2208682f5e97c72Ken Sumrall return -1; 30398ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall} 30408ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 3041569649ff1d6d76f89982c391a5b0e119050250e4Paul Lawrenceint cryptfs_enable(char *howarg, int type, char *passwd, int no_ui) 304213486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence{ 3043569649ff1d6d76f89982c391a5b0e119050250e4Paul Lawrence return cryptfs_enable_internal(howarg, type, passwd, no_ui); 304413486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence} 304513486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence 3046569649ff1d6d76f89982c391a5b0e119050250e4Paul Lawrenceint cryptfs_enable_default(char *howarg, int no_ui) 304713486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence{ 304813486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence return cryptfs_enable_internal(howarg, CRYPT_TYPE_DEFAULT, 3049569649ff1d6d76f89982c391a5b0e119050250e4Paul Lawrence DEFAULT_PASSWORD, no_ui); 305013486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence} 305113486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrence 305213486033575e6e4affccbb3dd201515d79f6f44bPaul Lawrenceint cryptfs_changepw(int crypt_type, const char *newpw) 30538ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall{ 305438132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 30557b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence SLOGE("cryptfs_changepw not valid for file encryption"); 30567b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence return -1; 305705335c344d73411439774dfa548c633020e158e1Paul Lawrence } 305805335c344d73411439774dfa548c633020e158e1Paul Lawrence 30598ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall struct crypt_mnt_ftr crypt_ftr; 3060933216c8861b6b3f0e65cd27812ce2e3c26721c4JP Abgrall int rc; 30618ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 30628ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* This is only allowed after we've successfully decrypted the master key */ 3063f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (!master_key_saved) { 30640cc166385a7e1d3026bbcb62f094e419f779e872Ken Sumrall SLOGE("Key not saved, aborting"); 30658ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall return -1; 30668ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 30678ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 3068f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) { 3069f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGE("Invalid crypt_type %d", crypt_type); 3070f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 3071f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 3072f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 30738ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall /* get key */ 3074160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (get_crypt_ftr_and_key(&crypt_ftr)) { 3075f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGE("Error getting crypt footer and key"); 3076f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 30778ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall } 30788ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall 3079f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr.crypt_type = crypt_type; 3080f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 3081933216c8861b6b3f0e65cd27812ce2e3c26721c4JP Abgrall rc = encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD 3082f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence : newpw, 3083f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr.salt, 3084f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence saved_master_key, 3085f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence crypt_ftr.master_key, 3086f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence &crypt_ftr); 3087933216c8861b6b3f0e65cd27812ce2e3c26721c4JP Abgrall if (rc) { 3088933216c8861b6b3f0e65cd27812ce2e3c26721c4JP Abgrall SLOGE("Encrypt master key failed: %d", rc); 3089933216c8861b6b3f0e65cd27812ce2e3c26721c4JP Abgrall return -1; 3090933216c8861b6b3f0e65cd27812ce2e3c26721c4JP Abgrall } 309170a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks /* save the key */ 3092160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall put_crypt_ftr_and_key(&crypt_ftr); 30938f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall 30948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall return 0; 30958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall} 3096160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 309785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xustatic unsigned int persist_get_max_entries(int encrypted) { 309885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu struct crypt_mnt_ftr crypt_ftr; 309985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int dsize; 310085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int max_persistent_entries; 310185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 310285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu /* If encrypted, use the values from the crypt_ftr, otherwise 310385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * use the values for the current spec. 310485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu */ 310585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (encrypted) { 310685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (get_crypt_ftr_and_key(&crypt_ftr)) { 310785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return -1; 310885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 310985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu dsize = crypt_ftr.persist_data_size; 311085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } else { 311185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu dsize = CRYPT_PERSIST_DATA_SIZE; 311285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 311385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 311485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu max_persistent_entries = (dsize - sizeof(struct crypt_persist_data)) / 311585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu sizeof(struct crypt_persist_entry); 311685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 311785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return max_persistent_entries; 311885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu} 311985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 312085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xustatic int persist_get_key(const char *fieldname, char *value) 3121160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 3122160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned int i; 3123160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3124160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 3125160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 3126160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3127160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall for (i = 0; i < persist_data->persist_valid_entries; i++) { 3128160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) { 3129160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* We found it! */ 3130160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX); 3131160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 3132160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3133160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3134160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3135160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 3136160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 3137160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 313885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xustatic int persist_set_key(const char *fieldname, const char *value, int encrypted) 3139160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 3140160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned int i; 3141160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned int num; 3142160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall unsigned int max_persistent_entries; 3143160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3144160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 3145160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 3146160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3147160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 314885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu max_persistent_entries = persist_get_max_entries(encrypted); 3149160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3150160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall num = persist_data->persist_valid_entries; 3151160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3152160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall for (i = 0; i < num; i++) { 3153160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) { 3154160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* We found an existing entry, update it! */ 3155160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX); 3156160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX); 3157160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 3158160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3159160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3160160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3161160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* We didn't find it, add it to the end, if there is room */ 3162160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data->persist_valid_entries < max_persistent_entries) { 3163160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry)); 3164160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX); 3165160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX); 3166160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall persist_data->persist_valid_entries++; 3167160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return 0; 3168160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3169160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3170160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return -1; 3171160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 3172160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 317385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu/** 317485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * Test if key is part of the multi-entry (field, index) sequence. Return non-zero if key is in the 317585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * sequence and its index is greater than or equal to index. Return 0 otherwise. 317685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu */ 317785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xustatic int match_multi_entry(const char *key, const char *field, unsigned index) { 317885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int field_len; 317985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int key_index; 318085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu field_len = strlen(field); 318185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 318285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (index == 0) { 318385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // The first key in a multi-entry field is just the filedname itself. 318485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (!strcmp(key, field)) { 318585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return 1; 318685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 318785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 318885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Match key against "%s_%d" % (field, index) 318985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (strlen(key) < field_len + 1 + 1) { 319085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Need at least a '_' and a digit. 319185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return 0; 319285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 319385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (strncmp(key, field, field_len)) { 319485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // If the key does not begin with field, it's not a match. 319585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return 0; 319685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 319785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (1 != sscanf(&key[field_len],"_%d", &key_index)) { 319885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return 0; 319985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 320085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return key_index >= index; 320185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu} 320285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 320385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu/* 320485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * Delete entry/entries from persist_data. If the entries are part of a multi-segment field, all 320585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * remaining entries starting from index will be deleted. 320685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * returns PERSIST_DEL_KEY_OK if deletion succeeds, 320785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * PERSIST_DEL_KEY_ERROR_NO_FIELD if the field does not exist, 320885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * and PERSIST_DEL_KEY_ERROR_OTHER if error occurs. 320985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * 321085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu */ 321185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xustatic int persist_del_keys(const char *fieldname, unsigned index) 321285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu{ 321385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int i; 321485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int j; 321585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int num; 321685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 321785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (persist_data == NULL) { 321885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return PERSIST_DEL_KEY_ERROR_OTHER; 321985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 322085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 322185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu num = persist_data->persist_valid_entries; 322285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 322385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu j = 0; // points to the end of non-deleted entries. 322485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Filter out to-be-deleted entries in place. 322585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu for (i = 0; i < num; i++) { 322685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (!match_multi_entry(persist_data->persist_entry[i].key, fieldname, index)) { 322785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu persist_data->persist_entry[j] = persist_data->persist_entry[i]; 322885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu j++; 322985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 323085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 323185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 323285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (j < num) { 323385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu persist_data->persist_valid_entries = j; 323485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Zeroise the remaining entries 323585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu memset(&persist_data->persist_entry[j], 0, (num - j) * sizeof(struct crypt_persist_entry)); 323685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return PERSIST_DEL_KEY_OK; 323785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } else { 323885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Did not find an entry matching the given fieldname 323985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return PERSIST_DEL_KEY_ERROR_NO_FIELD; 324085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 324185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu} 324285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 324385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xustatic int persist_count_keys(const char *fieldname) 324485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu{ 324585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int i; 324685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int count; 324785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 324885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (persist_data == NULL) { 324985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return -1; 325085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 325185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 325285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu count = 0; 325385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu for (i = 0; i < persist_data->persist_valid_entries; i++) { 325485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (match_multi_entry(persist_data->persist_entry[i].key, fieldname, 0)) { 325585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu count++; 325685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 325785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 325885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 325985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu return count; 326085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu} 326185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 3262160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall/* Return the value of the specified field. */ 326385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xuint cryptfs_getfield(const char *fieldname, char *value, int len) 3264160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 326538132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 32665a06a6481bff8916bf366bf9e951ab5c6a405207Paul Lawrence SLOGE("Cannot get field when file encrypted"); 32675a06a6481bff8916bf366bf9e951ab5c6a405207Paul Lawrence return -1; 3268368d79459e8d30474dd5cbc414623c1e2f78ee98Paul Lawrence } 3269368d79459e8d30474dd5cbc414623c1e2f78ee98Paul Lawrence 3270160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char temp_value[PROPERTY_VALUE_MAX]; 327185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu /* CRYPTO_GETFIELD_OK is success, 327285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * CRYPTO_GETFIELD_ERROR_NO_FIELD is value not set, 327385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL is buffer (as given by len) too small, 327485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu * CRYPTO_GETFIELD_ERROR_OTHER is any other error 3275160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall */ 327685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu int rc = CRYPTO_GETFIELD_ERROR_OTHER; 327785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu int i; 327885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu char temp_field[PROPERTY_KEY_MAX]; 3279160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3280160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 3281160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall load_persistent_data(); 3282160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 3283160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Getfield error, cannot load persistent data"); 3284160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto out; 3285160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3286160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3287160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 328885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Read value from persistent entries. If the original value is split into multiple entries, 328985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // stitch them back together. 3290160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!persist_get_key(fieldname, temp_value)) { 329185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // We found it, copy it to the caller's buffer and keep going until all entries are read. 329285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (strlcpy(value, temp_value, len) >= (unsigned) len) { 329385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // value too small 329485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL; 329585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu goto out; 329685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 329785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_GETFIELD_OK; 329885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 329985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu for (i = 1; /* break explicitly */; i++) { 330085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (snprintf(temp_field, sizeof(temp_field), "%s_%d", fieldname, i) >= 330185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu (int) sizeof(temp_field)) { 330285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // If the fieldname is very long, we stop as soon as it begins to overflow the 330385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // maximum field length. At this point we have in fact fully read out the original 330485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // value because cryptfs_setfield would not allow fields with longer names to be 330585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // written in the first place. 330685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu break; 330785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 330885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (!persist_get_key(temp_field, temp_value)) { 330985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (strlcat(value, temp_value, len) >= (unsigned)len) { 331085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // value too small. 331185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL; 331285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu goto out; 331385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 331485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } else { 331585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Exhaust all entries. 331685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu break; 331785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 331885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 3319160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } else { 3320160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* Sadness, it's not there. Return the error */ 332185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_GETFIELD_ERROR_NO_FIELD; 3322160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3323160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3324160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallout: 3325160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return rc; 3326160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 3327160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3328160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall/* Set the value of the specified field. */ 332985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xuint cryptfs_setfield(const char *fieldname, const char *value) 3330160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall{ 333138132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 33325a06a6481bff8916bf366bf9e951ab5c6a405207Paul Lawrence SLOGE("Cannot set field when file encrypted"); 33335a06a6481bff8916bf366bf9e951ab5c6a405207Paul Lawrence return -1; 3334368d79459e8d30474dd5cbc414623c1e2f78ee98Paul Lawrence } 3335368d79459e8d30474dd5cbc414623c1e2f78ee98Paul Lawrence 3336160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall char encrypted_state[PROPERTY_VALUE_MAX]; 333785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu /* 0 is success, negative values are error */ 333885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu int rc = CRYPTO_SETFIELD_ERROR_OTHER; 3339160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall int encrypted = 0; 334085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int field_id; 334185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu char temp_field[PROPERTY_KEY_MAX]; 334285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int num_entries; 334385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu unsigned int max_keylen; 3344160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3345160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 3346160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall load_persistent_data(); 3347160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_data == NULL) { 3348160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Setfield error, cannot load persistent data"); 3349160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto out; 3350160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3351160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3352160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3353160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall property_get("ro.crypto.state", encrypted_state, ""); 3354160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (!strcmp(encrypted_state, "encrypted") ) { 3355160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall encrypted = 1; 3356160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3357160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 335885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Compute the number of entries required to store value, each entry can store up to 335985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // (PROPERTY_VALUE_MAX - 1) chars 336085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (strlen(value) == 0) { 336185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Empty value also needs one entry to store. 336285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu num_entries = 1; 336385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } else { 336485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu num_entries = (strlen(value) + (PROPERTY_VALUE_MAX - 1) - 1) / (PROPERTY_VALUE_MAX - 1); 336585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 336685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 336785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu max_keylen = strlen(fieldname); 336885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (num_entries > 1) { 336985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Need an extra "_%d" suffix. 337085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu max_keylen += 1 + log10(num_entries); 337185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 337285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (max_keylen > PROPERTY_KEY_MAX - 1) { 337385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG; 337485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu goto out; 337585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 337685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 337785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Make sure we have enough space to write the new value 337885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (persist_data->persist_valid_entries + num_entries - persist_count_keys(fieldname) > 337985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu persist_get_max_entries(encrypted)) { 338085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG; 338185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu goto out; 338285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 338385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 338485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // Now that we know persist_data has enough space for value, let's delete the old field first 338585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // to make up space. 338685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu persist_del_keys(fieldname, 0); 338785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 3388160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (persist_set_key(fieldname, value, encrypted)) { 338985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // fail to set key, should not happen as we have already checked the available space 339085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu SLOGE("persist_set_key() error during setfield()"); 3391160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto out; 3392160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3393160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 339485c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu for (field_id = 1; field_id < num_entries; field_id++) { 339585c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu snprintf(temp_field, sizeof(temp_field), "%s_%d", fieldname, field_id); 339685c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 339785c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu if (persist_set_key(temp_field, value + field_id * (PROPERTY_VALUE_MAX - 1), encrypted)) { 339885c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu // fail to set key, should not happen as we have already checked the available space. 339985c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu SLOGE("persist_set_key() error during setfield()"); 340085c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu goto out; 340185c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 340285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu } 340385c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu 3404160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall /* If we are running encrypted, save the persistent data now */ 3405160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (encrypted) { 3406160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall if (save_persistent_data()) { 3407160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall SLOGE("Setfield error, cannot save persistent data"); 3408160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall goto out; 3409160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3410160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall } 3411160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 341285c01f95c7a3c009e79867fe36181cc0793a0440Rubin Xu rc = CRYPTO_SETFIELD_OK; 3413160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall 3414160b4d68ece15947057e31edde4e5608a010c695Ken Sumrallout: 3415160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall return rc; 3416160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall} 3417f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 3418f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence/* Checks userdata. Attempt to mount the volume if default- 3419f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * encrypted. 3420f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * On success trigger next init phase and return 0. 3421f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence * Currently do not handle failure - see TODO below. 3422f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence */ 3423f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrenceint cryptfs_mount_default_encrypted(void) 3424f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence{ 342584274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence int crypt_type = cryptfs_get_password_type(); 342684274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) { 342784274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence SLOGE("Bad crypt type - error"); 342884274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence } else if (crypt_type != CRYPT_TYPE_DEFAULT) { 342984274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence SLOGD("Password is not default - " 343084274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence "starting min framework to prompt"); 343184274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence property_set("vold.decrypt", "trigger_restart_min_framework"); 343284274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence return 0; 343384274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) { 343484274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence SLOGD("Password is default - restarting filesystem"); 343584274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence cryptfs_restart_internal(0); 343684274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence return 0; 3437f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } else { 343884274cc35cf4100794796e2027e733fa2fc8cd1fPaul Lawrence SLOGE("Encrypted, default crypt type but can't decrypt"); 3439f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 3440f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 34416bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence /** Corrupt. Allow us to boot into framework, which will detect bad 34426bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence crypto when it calls do_crypto_complete, then do a factory reset 3443f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence */ 34446bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence property_set("vold.decrypt", "trigger_restart_min_framework"); 3445f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return 0; 3446f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence} 3447f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 3448f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence/* Returns type of the password, default, pattern, pin or password. 3449f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence */ 3450f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrenceint cryptfs_get_password_type(void) 3451f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence{ 345238132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 34537b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence SLOGE("cryptfs_get_password_type not valid for file encryption"); 34547b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence return -1; 345505335c344d73411439774dfa548c633020e158e1Paul Lawrence } 345605335c344d73411439774dfa548c633020e158e1Paul Lawrence 3457f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence struct crypt_mnt_ftr crypt_ftr; 3458f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 3459f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (get_crypt_ftr_and_key(&crypt_ftr)) { 3460f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SLOGE("Error getting crypt footer and key\n"); 3461f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return -1; 3462f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 3463f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 34646bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) { 34656bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence return -1; 34666bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence } 34676bfed20c77184d00d948130d88d86db7ddd8a3f1Paul Lawrence 3468f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence return crypt_ftr.crypt_type; 3469f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence} 3470684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence 347105335c344d73411439774dfa548c633020e158e1Paul Lawrenceconst char* cryptfs_get_password() 3472684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence{ 347338132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley if (e4crypt_is_native()) { 34747b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence SLOGE("cryptfs_get_password not valid for file encryption"); 34757b6b565fa0d3658be8dc021f1beee5024d54b8c0Paul Lawrence return 0; 347605335c344d73411439774dfa548c633020e158e1Paul Lawrence } 347705335c344d73411439774dfa548c633020e158e1Paul Lawrence 3478399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence struct timespec now; 3479ef2b5bea6b72331568036788c6fcaadf63f1f178Paul Lawrence clock_gettime(CLOCK_BOOTTIME, &now); 3480399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence if (now.tv_sec < password_expiry_time) { 3481399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence return password; 3482399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence } else { 3483399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence cryptfs_clear_password(); 3484399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence return 0; 3485399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence } 3486399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence} 3487399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence 3488399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrencevoid cryptfs_clear_password() 3489399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence{ 3490399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence if (password) { 3491399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence size_t len = strlen(password); 3492399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence memset(password, 0, len); 3493399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence free(password); 3494399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence password = 0; 3495399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence password_expiry_time = 0; 3496399317ede45340eebc035ba204b6201b6d62dd66Paul Lawrence } 3497684dbdf316a02cf6a7694018f7c3a4bcd65142ccPaul Lawrence} 3498731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3499731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrenceint cryptfs_enable_file() 3500731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence{ 350138132a1f667412d6b08ae90cc64a011d76906cc0Paul Crowley return e4crypt_initialize_global_de(); 3502731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence} 3503731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 35040c24746627e642460b7b0b9133aee0e1da764ae4Paul Lawrenceint cryptfs_isConvertibleToFBE() 35050c24746627e642460b7b0b9133aee0e1da764ae4Paul Lawrence{ 35060c24746627e642460b7b0b9133aee0e1da764ae4Paul Lawrence struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT); 35070c24746627e642460b7b0b9133aee0e1da764ae4Paul Lawrence return fs_mgr_is_convertible_to_fbe(rec) ? 1 : 0; 35080c24746627e642460b7b0b9133aee0e1da764ae4Paul Lawrence} 35090c24746627e642460b7b0b9133aee0e1da764ae4Paul Lawrence 3510731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrenceint cryptfs_create_default_ftr(struct crypt_mnt_ftr* crypt_ftr, __attribute__((unused))int key_length) 3511731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence{ 3512731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence if (cryptfs_init_crypt_mnt_ftr(crypt_ftr)) { 3513731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence SLOGE("Failed to initialize crypt_ftr"); 3514731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence return -1; 3515731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence } 3516731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3517731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence if (create_encrypted_random_key(DEFAULT_PASSWORD, crypt_ftr->master_key, 3518731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence crypt_ftr->salt, crypt_ftr)) { 3519731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence SLOGE("Cannot create encrypted master key\n"); 3520731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence return -1; 3521731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence } 3522731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3523731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence //crypt_ftr->keysize = key_length / 8; 3524731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence return 0; 3525731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence} 3526731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3527731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrenceint cryptfs_get_master_key(struct crypt_mnt_ftr* ftr, const char* password, 3528731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence unsigned char* master_key) 3529731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence{ 3530731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence int rc; 3531731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3532731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence unsigned char* intermediate_key = 0; 3533731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence size_t intermediate_key_size = 0; 3534c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3535c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence if (password == 0 || *password == 0) { 3536c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence password = DEFAULT_PASSWORD; 3537c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence } 3538c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3539731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence rc = decrypt_master_key(password, master_key, ftr, &intermediate_key, 3540731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence &intermediate_key_size); 3541731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3542300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence if (rc) { 3543300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence SLOGE("Can't calculate intermediate key"); 3544300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence return rc; 3545300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence } 3546300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence 3547c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence int N = 1 << ftr->N_factor; 3548c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence int r = 1 << ftr->r_factor; 3549c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence int p = 1 << ftr->p_factor; 3550c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3551c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence unsigned char scrypted_intermediate_key[sizeof(ftr->scrypted_intermediate_key)]; 3552c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3553c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence rc = crypto_scrypt(intermediate_key, intermediate_key_size, 3554c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence ftr->salt, sizeof(ftr->salt), N, r, p, 3555c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence scrypted_intermediate_key, 3556c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence sizeof(scrypted_intermediate_key)); 3557c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3558c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence free(intermediate_key); 3559c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3560c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence if (rc) { 3561300dae7c38e6853148a998dfc1030b2be40490b5Paul Lawrence SLOGE("Can't scrypt intermediate key"); 3562c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence return rc; 3563c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence } 3564c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence 3565c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence return memcmp(scrypted_intermediate_key, ftr->scrypted_intermediate_key, 3566c78c71b1717613a5be921bbb8ac63c007d4af86aPaul Lawrence intermediate_key_size); 3567731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence} 3568731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence 3569731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrenceint cryptfs_set_password(struct crypt_mnt_ftr* ftr, const char* password, 3570731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence const unsigned char* master_key) 3571731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence{ 3572731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence return encrypt_master_key(password, ftr->salt, master_key, ftr->master_key, 3573731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence ftr); 3574731a7a242df6cc3441ac82b4f9521546fac5ac2dPaul Lawrence} 35756e410597343716924ed4943d1eabd3dea614d325Paul Lawrence 3576b45caafbccbb743c8b01a5287188969883dec377Eric Biggersvoid cryptfs_get_file_encryption_modes(const char **contents_mode_ret, 3577b45caafbccbb743c8b01a5287188969883dec377Eric Biggers const char **filenames_mode_ret) 35786e410597343716924ed4943d1eabd3dea614d325Paul Lawrence{ 35796e410597343716924ed4943d1eabd3dea614d325Paul Lawrence struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT); 3580b45caafbccbb743c8b01a5287188969883dec377Eric Biggers fs_mgr_get_file_encryption_modes(rec, contents_mode_ret, filenames_mode_ret); 35816e410597343716924ed4943d1eabd3dea614d325Paul Lawrence} 3582