| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2016 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
 | 17 | #include "MetadataCrypt.h" | 
| Paul Crowley | 14c8c07 | 2018-09-18 13:30:21 -0700 | [diff] [blame] | 18 | #include "KeyBuffer.h" | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 19 |  | 
 | 20 | #include <string> | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 21 |  | 
 | 22 | #include <fcntl.h> | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 23 | #include <sys/param.h> | 
 | 24 | #include <sys/stat.h> | 
 | 25 | #include <sys/types.h> | 
 | 26 |  | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 27 | #include <android-base/logging.h> | 
| Paul Crowley | 0fd2626 | 2018-01-30 09:48:19 -0800 | [diff] [blame] | 28 | #include <android-base/properties.h> | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 29 | #include <android-base/strings.h> | 
| Paul Crowley | e4c93da | 2017-06-16 09:21:18 -0700 | [diff] [blame] | 30 | #include <android-base/unique_fd.h> | 
| Paul Crowley | 0fd2626 | 2018-01-30 09:48:19 -0800 | [diff] [blame] | 31 | #include <cutils/fs.h> | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 32 | #include <fs_mgr.h> | 
| David Anderson | b922473 | 2019-05-13 13:02:54 -0700 | [diff] [blame] | 33 | #include <libdm/dm.h> | 
| Yo Chiang | 0af25a3 | 2020-10-07 14:20:00 +0800 | [diff] [blame] | 34 | #include <libgsi/libgsi.h> | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 35 |  | 
| Daniel Rosenberg | 65f99c9 | 2018-08-28 01:58:49 -0700 | [diff] [blame] | 36 | #include "Checkpoint.h" | 
| Paul Crowley | 220567c | 2020-02-07 12:45:20 -0800 | [diff] [blame] | 37 | #include "CryptoType.h" | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 38 | #include "EncryptInplace.h" | 
 | 39 | #include "KeyStorage.h" | 
 | 40 | #include "KeyUtil.h" | 
| Daniel Rosenberg | 690d6de | 2018-12-14 01:08:10 -0800 | [diff] [blame] | 41 | #include "Keymaster.h" | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 42 | #include "Utils.h" | 
 | 43 | #include "VoldUtil.h" | 
| Jaegeuk Kim | 0c52c71 | 2020-12-15 09:00:49 -0800 | [diff] [blame] | 44 | #include "fs/Ext4.h" | 
 | 45 | #include "fs/F2fs.h" | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 46 |  | 
| Paul Crowley | 220567c | 2020-02-07 12:45:20 -0800 | [diff] [blame] | 47 | namespace android { | 
 | 48 | namespace vold { | 
 | 49 |  | 
| Tom Cherry | 4c5bde2 | 2019-01-29 14:34:01 -0800 | [diff] [blame] | 50 | using android::fs_mgr::FstabEntry; | 
 | 51 | using android::fs_mgr::GetEntryForMountPoint; | 
| Pavel Grafov | e2e2d30 | 2017-08-01 17:15:53 +0100 | [diff] [blame] | 52 | using android::vold::KeyBuffer; | 
| David Anderson | b922473 | 2019-05-13 13:02:54 -0700 | [diff] [blame] | 53 | using namespace android::dm; | 
| Pavel Grafov | e2e2d30 | 2017-08-01 17:15:53 +0100 | [diff] [blame] | 54 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 55 | // Parsed from metadata options | 
 | 56 | struct CryptoOptions { | 
 | 57 |     struct CryptoType cipher = invalid_crypto_type; | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 58 |     bool use_legacy_options_format = false; | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 59 |     bool set_dun = true;  // Non-legacy driver always sets DUN | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 60 |     bool use_hw_wrapped_key = false; | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 61 | }; | 
 | 62 |  | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 63 | static const std::string kDmNameUserdata = "userdata"; | 
 | 64 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 65 | // The first entry in this table is the default crypto type. | 
| Paul Crowley | 220567c | 2020-02-07 12:45:20 -0800 | [diff] [blame] | 66 | constexpr CryptoType supported_crypto_types[] = {aes_256_xts, adiantum}; | 
 | 67 |  | 
 | 68 | static_assert(validateSupportedCryptoTypes(64, supported_crypto_types, | 
 | 69 |                                            array_length(supported_crypto_types)), | 
 | 70 |               "We have a CryptoType which was incompletely constructed."); | 
 | 71 |  | 
 | 72 | constexpr CryptoType legacy_aes_256_xts = | 
 | 73 |         CryptoType().set_config_name("aes-256-xts").set_kernel_name("AES-256-XTS").set_keysize(64); | 
 | 74 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 75 | static_assert(isValidCryptoType(64, legacy_aes_256_xts), | 
| Paul Crowley | 220567c | 2020-02-07 12:45:20 -0800 | [diff] [blame] | 76 |               "We have a CryptoType which was incompletely constructed."); | 
 | 77 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 78 | // Returns KeyGeneration suitable for key as described in CryptoOptions | 
 | 79 | const KeyGeneration makeGen(const CryptoOptions& options) { | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 80 |     return KeyGeneration{options.cipher.get_keysize(), true, options.use_hw_wrapped_key}; | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 81 | } | 
 | 82 |  | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 83 | static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) { | 
 | 84 |     // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted | 
 | 85 |     // partitions in the fsck domain. | 
| LongPing Wei | 7f3ab95 | 2019-01-30 16:03:14 +0800 | [diff] [blame] | 86 |     if (setexeccon(android::vold::sFsckContext)) { | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 87 |         PLOG(ERROR) << "Failed to setexeccon"; | 
 | 88 |         return false; | 
 | 89 |     } | 
| Tom Cherry | 4c5bde2 | 2019-01-29 14:34:01 -0800 | [diff] [blame] | 90 |     auto mount_rc = fs_mgr_do_mount(&fstab_default, const_cast<char*>(mount_point), | 
| Daniel Rosenberg | 65f99c9 | 2018-08-28 01:58:49 -0700 | [diff] [blame] | 91 |                                     const_cast<char*>(blk_device), nullptr, | 
| Paul Lawrence | 3fe9311 | 2020-06-12 08:12:48 -0700 | [diff] [blame] | 92 |                                     android::vold::cp_needsCheckpoint(), true); | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 93 |     if (setexeccon(nullptr)) { | 
 | 94 |         PLOG(ERROR) << "Failed to clear setexeccon"; | 
 | 95 |         return false; | 
 | 96 |     } | 
 | 97 |     if (mount_rc != 0) { | 
 | 98 |         LOG(ERROR) << "fs_mgr_do_mount failed with rc " << mount_rc; | 
 | 99 |         return false; | 
 | 100 |     } | 
 | 101 |     LOG(DEBUG) << "Mounted " << mount_point; | 
 | 102 |     return true; | 
 | 103 | } | 
 | 104 |  | 
| Paul Crowley | 4eac264 | 2020-02-12 11:04:05 -0800 | [diff] [blame] | 105 | static bool read_key(const std::string& metadata_key_dir, const KeyGeneration& gen, | 
 | 106 |                      KeyBuffer* key) { | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 107 |     if (metadata_key_dir.empty()) { | 
| Paul Crowley | c9b92f0 | 2020-01-30 15:26:15 -0800 | [diff] [blame] | 108 |         LOG(ERROR) << "Failed to get metadata_key_dir"; | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 109 |         return false; | 
 | 110 |     } | 
| Daniel Rosenberg | 690d6de | 2018-12-14 01:08:10 -0800 | [diff] [blame] | 111 |     std::string sKey; | 
| Paul Crowley | c9b92f0 | 2020-01-30 15:26:15 -0800 | [diff] [blame] | 112 |     auto dir = metadata_key_dir + "/key"; | 
 | 113 |     LOG(DEBUG) << "metadata_key_dir/key: " << dir; | 
| Eric Biggers | fec0c0e | 2021-02-16 15:59:17 -0800 | [diff] [blame] | 114 |     if (!MkdirsSync(dir, 0700)) return false; | 
| Paul Crowley | d31f36d | 2021-08-12 19:20:40 +0000 | [diff] [blame] | 115 |     if (!pathExists(dir)) { | 
 | 116 |         auto delete_all = android::base::GetBoolProperty( | 
 | 117 |                 "ro.crypto.metadata_init_delete_all_keys.enabled", false); | 
 | 118 |         if (delete_all) { | 
 | 119 |             LOG(INFO) << "Metadata key does not exist, calling deleteAllKeys"; | 
 | 120 |             Keymaster::deleteAllKeys(); | 
 | 121 |         } else { | 
 | 122 |             LOG(DEBUG) << "Metadata key does not exist but " | 
 | 123 |                           "ro.crypto.metadata_init_delete_all_keys.enabled is false"; | 
 | 124 |         } | 
 | 125 |     } | 
| Paul Crowley | c9b92f0 | 2020-01-30 15:26:15 -0800 | [diff] [blame] | 126 |     auto temp = metadata_key_dir + "/tmp"; | 
| Eric Biggers | f74373b | 2020-11-05 19:58:26 -0800 | [diff] [blame] | 127 |     return retrieveOrGenerateKey(dir, temp, kEmptyAuthentication, gen, key); | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 128 | } | 
 | 129 |  | 
| Paul Crowley | 14c8c07 | 2018-09-18 13:30:21 -0700 | [diff] [blame] | 130 | static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t* nr_sec) { | 
| Oleksiy Avramchenko | 625dc78 | 2018-05-23 10:50:46 +0200 | [diff] [blame] | 131 |     if (android::vold::GetBlockDev512Sectors(real_blkdev, nr_sec) != android::OK) { | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 132 |         PLOG(ERROR) << "Unable to measure size of " << real_blkdev; | 
 | 133 |         return false; | 
 | 134 |     } | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 135 |     return true; | 
 | 136 | } | 
 | 137 |  | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 138 | static bool create_crypto_blk_dev(const std::string& dm_name, const std::string& blk_device, | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 139 |                                   const KeyBuffer& key, const CryptoOptions& options, | 
| Paul Crowley | 886e572 | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 140 |                                   std::string* crypto_blkdev, uint64_t* nr_sec) { | 
 | 141 |     if (!get_number_of_sectors(blk_device, nr_sec)) return false; | 
 | 142 |     // TODO(paulcrowley): don't hardcode that DmTargetDefaultKey uses 4096-byte | 
 | 143 |     // sectors | 
 | 144 |     *nr_sec &= ~7; | 
| Paul Crowley | 84e84c5 | 2020-01-29 16:09:19 -0800 | [diff] [blame] | 145 |  | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 146 |     KeyBuffer module_key; | 
 | 147 |     if (options.use_hw_wrapped_key) { | 
 | 148 |         if (!exportWrappedStorageKey(key, &module_key)) { | 
 | 149 |             LOG(ERROR) << "Failed to get ephemeral wrapped key"; | 
 | 150 |             return false; | 
 | 151 |         } | 
 | 152 |     } else { | 
 | 153 |         module_key = key; | 
 | 154 |     } | 
 | 155 |  | 
| David Anderson | b922473 | 2019-05-13 13:02:54 -0700 | [diff] [blame] | 156 |     KeyBuffer hex_key_buffer; | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 157 |     if (android::vold::StrToHex(module_key, hex_key_buffer) != android::OK) { | 
| David Anderson | b922473 | 2019-05-13 13:02:54 -0700 | [diff] [blame] | 158 |         LOG(ERROR) << "Failed to turn key to hex"; | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 159 |         return false; | 
 | 160 |     } | 
| David Anderson | b922473 | 2019-05-13 13:02:54 -0700 | [diff] [blame] | 161 |     std::string hex_key(hex_key_buffer.data(), hex_key_buffer.size()); | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 162 |  | 
| Paul Crowley | 886e572 | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 163 |     auto target = std::make_unique<DmTargetDefaultKey>(0, *nr_sec, options.cipher.get_kernel_name(), | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 164 |                                                        hex_key, blk_device, 0); | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 165 |     if (options.use_legacy_options_format) target->SetUseLegacyOptionsFormat(); | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 166 |     if (options.set_dun) target->SetSetDun(); | 
 | 167 |     if (options.use_hw_wrapped_key) target->SetWrappedKeyV0(); | 
 | 168 |  | 
| Paul Crowley | c9b92f0 | 2020-01-30 15:26:15 -0800 | [diff] [blame] | 169 |     DmTable table; | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 170 |     table.AddTarget(std::move(target)); | 
| Paul Crowley | c9b92f0 | 2020-01-30 15:26:15 -0800 | [diff] [blame] | 171 |  | 
 | 172 |     auto& dm = DeviceMapper::Instance(); | 
| Eric Biggers | 836b51b | 2020-10-15 14:39:34 -0700 | [diff] [blame] | 173 |     if (!dm.CreateDevice(dm_name, table, crypto_blkdev, std::chrono::seconds(5))) { | 
 | 174 |         PLOG(ERROR) << "Could not create default-key device " << dm_name; | 
 | 175 |         return false; | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 176 |     } | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 177 |     return true; | 
 | 178 | } | 
 | 179 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 180 | static const CryptoType& lookup_cipher(const std::string& cipher_name) { | 
 | 181 |     if (cipher_name.empty()) return supported_crypto_types[0]; | 
 | 182 |     for (size_t i = 0; i < array_length(supported_crypto_types); i++) { | 
 | 183 |         if (cipher_name == supported_crypto_types[i].get_config_name()) { | 
 | 184 |             return supported_crypto_types[i]; | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 185 |         } | 
 | 186 |     } | 
 | 187 |     return invalid_crypto_type; | 
 | 188 | } | 
 | 189 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 190 | static bool parse_options(const std::string& options_string, CryptoOptions* options) { | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 191 |     auto parts = android::base::Split(options_string, ":"); | 
 | 192 |     if (parts.size() < 1 || parts.size() > 2) { | 
 | 193 |         LOG(ERROR) << "Invalid metadata encryption option: " << options_string; | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 194 |         return false; | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 195 |     } | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 196 |     std::string cipher_name = parts[0]; | 
 | 197 |     options->cipher = lookup_cipher(cipher_name); | 
 | 198 |     if (options->cipher.get_kernel_name() == nullptr) { | 
 | 199 |         LOG(ERROR) << "No metadata cipher named " << cipher_name << " found"; | 
 | 200 |         return false; | 
 | 201 |     } | 
 | 202 |  | 
 | 203 |     if (parts.size() == 2) { | 
 | 204 |         if (parts[1] == "wrappedkey_v0") { | 
 | 205 |             options->use_hw_wrapped_key = true; | 
 | 206 |         } else { | 
 | 207 |             LOG(ERROR) << "Invalid metadata encryption flag: " << parts[1]; | 
 | 208 |             return false; | 
 | 209 |         } | 
 | 210 |     } | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 211 |     return true; | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 212 | } | 
 | 213 |  | 
| Paul Lawrence | 236e5e8 | 2019-06-25 14:44:33 -0700 | [diff] [blame] | 214 | bool fscrypt_mount_metadata_encrypted(const std::string& blk_device, const std::string& mount_point, | 
| Jaegeuk Kim | 0c52c71 | 2020-12-15 09:00:49 -0800 | [diff] [blame] | 215 |                                       bool needs_encrypt, bool should_format, | 
 | 216 |                                       const std::string& fs_type) { | 
 | 217 |     LOG(DEBUG) << "fscrypt_mount_metadata_encrypted: " << mount_point | 
 | 218 |                << " encrypt: " << needs_encrypt << " format: " << should_format << " with " | 
 | 219 |                << fs_type; | 
| Paul Crowley | 0fd2626 | 2018-01-30 09:48:19 -0800 | [diff] [blame] | 220 |     auto encrypted_state = android::base::GetProperty("ro.crypto.state", ""); | 
| Nikita Ioffe | f850e6e | 2019-12-09 21:19:11 +0000 | [diff] [blame] | 221 |     if (encrypted_state != "" && encrypted_state != "encrypted") { | 
| Eric Biggers | a701c45 | 2018-10-23 13:06:55 -0700 | [diff] [blame] | 222 |         LOG(DEBUG) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state; | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 223 |         return false; | 
 | 224 |     } | 
| Tom Cherry | 4c5bde2 | 2019-01-29 14:34:01 -0800 | [diff] [blame] | 225 |  | 
 | 226 |     auto data_rec = GetEntryForMountPoint(&fstab_default, mount_point); | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 227 |     if (!data_rec) { | 
| Paul Crowley | c9b92f0 | 2020-01-30 15:26:15 -0800 | [diff] [blame] | 228 |         LOG(ERROR) << "Failed to get data_rec for " << mount_point; | 
 | 229 |         return false; | 
 | 230 |     } | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 231 |  | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 232 |     unsigned int options_format_version = android::base::GetUintProperty<unsigned int>( | 
 | 233 |             "ro.crypto.dm_default_key.options_format.version", | 
| Eric Biggers | 72d0713 | 2020-08-10 10:55:56 -0700 | [diff] [blame] | 234 |             (GetFirstApiLevel() <= __ANDROID_API_Q__ ? 1 : 2)); | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 235 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 236 |     CryptoOptions options; | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 237 |     if (options_format_version == 1) { | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 238 |         if (!data_rec->metadata_encryption.empty()) { | 
 | 239 |             LOG(ERROR) << "metadata_encryption options cannot be set in legacy mode"; | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 240 |             return false; | 
 | 241 |         } | 
 | 242 |         options.cipher = legacy_aes_256_xts; | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 243 |         options.use_legacy_options_format = true; | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 244 |         options.set_dun = android::base::GetBoolProperty("ro.crypto.set_dun", false); | 
 | 245 |         if (!options.set_dun && data_rec->fs_mgr_flags.checkpoint_blk) { | 
 | 246 |             LOG(ERROR) | 
 | 247 |                     << "Block checkpoints and metadata encryption require ro.crypto.set_dun option"; | 
 | 248 |             return false; | 
 | 249 |         } | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 250 |     } else if (options_format_version == 2) { | 
| Barani Muthukumaran | 312b7df | 2020-02-06 22:56:27 -0800 | [diff] [blame] | 251 |         if (!parse_options(data_rec->metadata_encryption, &options)) return false; | 
| Paul Crowley | f56d553 | 2020-03-22 08:02:06 -0700 | [diff] [blame] | 252 |     } else { | 
 | 253 |         LOG(ERROR) << "Unknown options_format_version: " << options_format_version; | 
 | 254 |         return false; | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 255 |     } | 
 | 256 |  | 
| Paul Crowley | 249c2fb | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 257 |     auto gen = needs_encrypt ? makeGen(options) : neverGen(); | 
| Paul Crowley | 0fd2626 | 2018-01-30 09:48:19 -0800 | [diff] [blame] | 258 |     KeyBuffer key; | 
| Paul Crowley | 4eac264 | 2020-02-12 11:04:05 -0800 | [diff] [blame] | 259 |     if (!read_key(data_rec->metadata_key_dir, gen, &key)) return false; | 
| Paul Lawrence | 4b140d3 | 2019-08-07 15:22:57 -0700 | [diff] [blame] | 260 |  | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 261 |     std::string crypto_blkdev; | 
| Paul Crowley | 886e572 | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 262 |     uint64_t nr_sec; | 
| Paul Crowley | 48aa90c | 2020-03-02 12:57:58 -0800 | [diff] [blame] | 263 |     if (!create_crypto_blk_dev(kDmNameUserdata, blk_device, key, options, &crypto_blkdev, &nr_sec)) | 
| Paul Crowley | 572c024 | 2020-02-14 01:15:35 -0800 | [diff] [blame] | 264 |         return false; | 
| Paul Lawrence | 236e5e8 | 2019-06-25 14:44:33 -0700 | [diff] [blame] | 265 |  | 
| Jaegeuk Kim | 0c52c71 | 2020-12-15 09:00:49 -0800 | [diff] [blame] | 266 |     if (needs_encrypt) { | 
 | 267 |         if (should_format) { | 
 | 268 |             status_t error; | 
 | 269 |  | 
 | 270 |             if (fs_type == "ext4") { | 
 | 271 |                 error = ext4::Format(crypto_blkdev, 0, mount_point); | 
 | 272 |             } else if (fs_type == "f2fs") { | 
 | 273 |                 error = f2fs::Format(crypto_blkdev); | 
 | 274 |             } else { | 
 | 275 |                 LOG(ERROR) << "Unknown filesystem type: " << fs_type; | 
 | 276 |                 return false; | 
 | 277 |             } | 
 | 278 |             LOG(DEBUG) << "Format (err=" << error << ") " << crypto_blkdev << " on " << mount_point; | 
 | 279 |             if (error != 0) return false; | 
 | 280 |         } else { | 
 | 281 |             if (!encrypt_inplace(crypto_blkdev, blk_device, nr_sec, false)) return false; | 
 | 282 |         } | 
 | 283 |     } | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 284 |  | 
| Paul Crowley | 0fd2626 | 2018-01-30 09:48:19 -0800 | [diff] [blame] | 285 |     LOG(DEBUG) << "Mounting metadata-encrypted filesystem:" << mount_point; | 
| Paul Crowley | 48aa90c | 2020-03-02 12:57:58 -0800 | [diff] [blame] | 286 |     mount_via_fs_mgr(mount_point.c_str(), crypto_blkdev.c_str()); | 
| Paul Crowley | 7fbd8d4 | 2020-03-23 08:59:12 -0700 | [diff] [blame] | 287 |  | 
 | 288 |     // Record that there's at least one fstab entry with metadata encryption | 
 | 289 |     if (!android::base::SetProperty("ro.crypto.metadata.enabled", "true")) { | 
 | 290 |         LOG(WARNING) << "failed to set ro.crypto.metadata.enabled";  // This isn't fatal | 
 | 291 |     } | 
| Paul Crowley | d575981 | 2016-06-02 11:04:27 -0700 | [diff] [blame] | 292 |     return true; | 
 | 293 | } | 
| Paul Crowley | 220567c | 2020-02-07 12:45:20 -0800 | [diff] [blame] | 294 |  | 
| Paul Crowley | 886e572 | 2020-02-07 12:51:56 -0800 | [diff] [blame] | 295 | static bool get_volume_options(CryptoOptions* options) { | 
 | 296 |     return parse_options(android::base::GetProperty("ro.crypto.volume.metadata.encryption", ""), | 
 | 297 |                          options); | 
 | 298 | } | 
 | 299 |  | 
 | 300 | bool defaultkey_volume_keygen(KeyGeneration* gen) { | 
 | 301 |     CryptoOptions options; | 
 | 302 |     if (!get_volume_options(&options)) return false; | 
 | 303 |     *gen = makeGen(options); | 
 | 304 |     return true; | 
 | 305 | } | 
 | 306 |  | 
 | 307 | bool defaultkey_setup_ext_volume(const std::string& label, const std::string& blk_device, | 
 | 308 |                                  const KeyBuffer& key, std::string* out_crypto_blkdev) { | 
 | 309 |     LOG(DEBUG) << "defaultkey_setup_ext_volume: " << label << " " << blk_device; | 
 | 310 |  | 
 | 311 |     CryptoOptions options; | 
 | 312 |     if (!get_volume_options(&options)) return false; | 
 | 313 |     uint64_t nr_sec; | 
 | 314 |     return create_crypto_blk_dev(label, blk_device, key, options, out_crypto_blkdev, &nr_sec); | 
 | 315 | } | 
 | 316 |  | 
| Yo Chiang | 0af25a3 | 2020-10-07 14:20:00 +0800 | [diff] [blame] | 317 | bool destroy_dsu_metadata_key(const std::string& dsu_slot) { | 
 | 318 |     LOG(DEBUG) << "destroy_dsu_metadata_key: " << dsu_slot; | 
 | 319 |  | 
 | 320 |     const auto dsu_metadata_key_dir = android::gsi::GetDsuMetadataKeyDir(dsu_slot); | 
 | 321 |     if (!pathExists(dsu_metadata_key_dir)) { | 
 | 322 |         LOG(DEBUG) << "DSU metadata_key_dir doesn't exist, nothing to remove: " | 
 | 323 |                    << dsu_metadata_key_dir; | 
 | 324 |         return true; | 
 | 325 |     } | 
 | 326 |  | 
 | 327 |     // Ensure that the DSU key directory is different from the host OS'. | 
 | 328 |     // Under normal circumstances, this should never happen, but handle it just in case. | 
 | 329 |     if (auto data_rec = GetEntryForMountPoint(&fstab_default, "/data")) { | 
 | 330 |         if (dsu_metadata_key_dir == data_rec->metadata_key_dir) { | 
 | 331 |             LOG(ERROR) << "DSU metadata_key_dir is same as host OS: " << dsu_metadata_key_dir; | 
 | 332 |             return false; | 
 | 333 |         } | 
 | 334 |     } | 
 | 335 |  | 
 | 336 |     bool ok = true; | 
 | 337 |     for (auto suffix : {"/key", "/tmp"}) { | 
 | 338 |         const auto key_path = dsu_metadata_key_dir + suffix; | 
 | 339 |         if (pathExists(key_path)) { | 
 | 340 |             LOG(DEBUG) << "Destroy key: " << key_path; | 
 | 341 |             if (!android::vold::destroyKey(key_path)) { | 
 | 342 |                 LOG(ERROR) << "Failed to destroyKey(): " << key_path; | 
 | 343 |                 ok = false; | 
 | 344 |             } | 
 | 345 |         } | 
 | 346 |     } | 
 | 347 |     if (!ok) { | 
 | 348 |         return false; | 
 | 349 |     } | 
 | 350 |  | 
 | 351 |     LOG(DEBUG) << "Remove DSU metadata_key_dir: " << dsu_metadata_key_dir; | 
 | 352 |     // DeleteDirContentsAndDir() already logged any error, so don't log repeatedly. | 
 | 353 |     return android::vold::DeleteDirContentsAndDir(dsu_metadata_key_dir) == android::OK; | 
 | 354 | } | 
 | 355 |  | 
| Paul Crowley | 220567c | 2020-02-07 12:45:20 -0800 | [diff] [blame] | 356 | }  // namespace vold | 
 | 357 | }  // namespace android |