1 /*
2  * Copyright (C) 2020 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 //
18 // Test that metadata encryption is working, via:
19 //
20 // - Correctness tests.  These test the standard metadata encryption formats
21 //   supported by Android R and higher via dm-default-key v2.
22 //
23 // - Randomness test.  This runs on all devices that use metadata encryption.
24 //
25 // The correctness tests create a temporary default-key mapping over the raw
26 // userdata partition, read from it, and verify that the data got decrypted
27 // correctly.  This only tests decryption, since this avoids having to find a
28 // region on disk that can safely be modified.  This should be good enough since
29 // the device wouldn't work anyway if decryption didn't invert encryption.
30 //
31 // Note that this temporary default-key mapping will overlap the device's "real"
32 // default-key mapping, if the device has one.  The kernel allows this.  The
33 // tests don't use a loopback device instead, since dm-default-key over a
34 // loopback device can't use the real inline encryption hardware.
35 //
36 // The correctness tests cover the following settings:
37 //
38 //    metadata_encryption=aes-256-xts
39 //    metadata_encryption=adiantum
40 //    metadata_encryption=aes-256-xts:wrappedkey_v0
41 //
42 // The tests don't check which one of those settings, if any, the device is
43 // actually using; they just try to test everything they can.
44 //
45 // These tests don't specifically test that file contents aren't encrypted
46 // twice.  That's already implied by the file-based encryption test cases,
47 // provided that the device actually has metadata encryption enabled.
48 //
49 
50 #include <android-base/file.h>
51 #include <android-base/unique_fd.h>
52 #include <asm/byteorder.h>
53 #include <fcntl.h>
54 #include <fstab/fstab.h>
55 #include <gtest/gtest.h>
56 #include <libdm/dm.h>
57 #include <linux/types.h>
58 #include <stdlib.h>
59 #include <unistd.h>
60 
61 #include <chrono>
62 
63 #include "vts_kernel_encryption.h"
64 
65 using namespace android::dm;
66 
67 namespace android {
68 namespace kernel {
69 
70 #define cpu_to_le64 __cpu_to_le64
71 #define le64_to_cpu __le64_to_cpu
72 
73 // Alignment to use for direct I/O reads of block devices
74 static constexpr int kDirectIOAlignment = 4096;
75 
76 // Assumed size of filesystem blocks, in bytes
77 static constexpr int kFilesystemBlockSize = 4096;
78 
79 // Checks whether the kernel supports version 2 or higher of dm-default-key.
IsDmDefaultKeyV2Supported(DeviceMapper & dm)80 static bool IsDmDefaultKeyV2Supported(DeviceMapper &dm) {
81   DmTargetTypeInfo info;
82   if (!dm.GetTargetByName("default-key", &info)) {
83     GTEST_LOG_(INFO) << "dm-default-key not enabled";
84     return false;
85   }
86   if (!info.IsAtLeast(2, 0, 0)) {
87     // The legacy version of dm-default-key (which was never supported by the
88     // Android common kernels) used a vendor-specific on-disk format, so it's
89     // not testable by a vendor-independent test.
90     GTEST_LOG_(INFO) << "Detected legacy dm-default-key";
91     return false;
92   }
93   return true;
94 }
95 
96 // Reads |count| bytes from the beginning of |blk_device|, using direct I/O to
97 // avoid getting any stale cached data.  Direct I/O requires using a hardware
98 // sector size aligned buffer.
ReadBlockDevice(const std::string & blk_device,size_t count,std::vector<uint8_t> * data)99 static bool ReadBlockDevice(const std::string &blk_device, size_t count,
100                             std::vector<uint8_t> *data) {
101   GTEST_LOG_(INFO) << "Reading " << count << " bytes from " << blk_device;
102   std::unique_ptr<void, void (*)(void *)> buf_mem(
103       aligned_alloc(kDirectIOAlignment, count), free);
104   if (buf_mem == nullptr) {
105     ADD_FAILURE() << "out of memory";
106     return false;
107   }
108   uint8_t *buffer = static_cast<uint8_t *>(buf_mem.get());
109 
110   android::base::unique_fd fd(
111       open(blk_device.c_str(), O_RDONLY | O_DIRECT | O_CLOEXEC));
112   if (fd < 0) {
113     ADD_FAILURE() << "Failed to open " << blk_device << Errno();
114     return false;
115   }
116   if (!android::base::ReadFully(fd, buffer, count)) {
117     ADD_FAILURE() << "Failed to read from " << blk_device << Errno();
118     return false;
119   }
120 
121   *data = std::vector<uint8_t>(buffer, buffer + count);
122   return true;
123 }
124 
125 class DmDefaultKeyTest : public ::testing::Test {
126   // Name to assign to the dm-default-key test device
127   static constexpr const char *kTestDmDeviceName = "vts-test-default-key";
128 
129   // Filesystem whose underlying partition the test will use
130   static constexpr const char *kTestMountpoint = "/data";
131 
132   // Size of the dm-default-key crypto sector size (data unit size) in bytes
133   static constexpr int kCryptoSectorSize = 4096;
134 
135   // Size of the test data in crypto sectors
136   static constexpr int kTestDataSectors = 256;
137 
138   // Size of the test data in bytes
139   static constexpr int kTestDataBytes = kTestDataSectors * kCryptoSectorSize;
140 
141   // Device-mapper API sector size in bytes.
142   // This is unrelated to the crypto sector size.
143   static constexpr int kDmApiSectorSize = 512;
144 
145  protected:
146   void SetUp() override;
147   void TearDown() override;
148   bool CreateTestDevice(const std::string &cipher,
149                         const std::vector<uint8_t> &key, bool is_wrapped_key);
150   void VerifyDecryption(const std::vector<uint8_t> &key, const Cipher &cipher);
151   void DoTest(const std::string &cipher_string, const Cipher &cipher);
152   bool skip_test_ = false;
153   DeviceMapper *dm_ = nullptr;
154   std::string raw_blk_device_;
155   std::string dm_device_path_;
156 };
157 
158 // Test setup procedure.  Checks for the needed kernel support, finds the raw
159 // partition to use, and does other preparations.  skip_test_ is set to true if
160 // the test should be skipped.
SetUp()161 void DmDefaultKeyTest::SetUp() {
162   dm_ = &DeviceMapper::Instance();
163 
164   if (!IsDmDefaultKeyV2Supported(*dm_)) {
165     int first_api_level;
166     ASSERT_TRUE(GetFirstApiLevel(&first_api_level));
167     // Devices launching with R or higher must support dm-default-key v2.
168     ASSERT_LE(first_api_level, __ANDROID_API_Q__);
169     GTEST_LOG_(INFO)
170         << "Skipping test because dm-default-key v2 is unsupported";
171     skip_test_ = true;
172     return;
173   }
174 
175   FilesystemInfo fs_info;
176   ASSERT_TRUE(GetFilesystemInfo(kTestMountpoint, &fs_info));
177   raw_blk_device_ = fs_info.raw_blk_device;
178 
179   dm_->DeleteDevice(kTestDmDeviceName);
180 }
181 
TearDown()182 void DmDefaultKeyTest::TearDown() { dm_->DeleteDevice(kTestDmDeviceName); }
183 
184 // Creates the test dm-default-key mapping using the given key and settings.
185 // If the dm device creation fails, then it is assumed the kernel doesn't
186 // support the given encryption settings, and a failure is not added.
CreateTestDevice(const std::string & cipher,const std::vector<uint8_t> & key,bool is_wrapped_key)187 bool DmDefaultKeyTest::CreateTestDevice(const std::string &cipher,
188                                         const std::vector<uint8_t> &key,
189                                         bool is_wrapped_key) {
190   static_assert(kTestDataBytes % kDmApiSectorSize == 0);
191   std::unique_ptr<DmTargetDefaultKey> target =
192       std::make_unique<DmTargetDefaultKey>(0, kTestDataBytes / kDmApiSectorSize,
193                                            cipher.c_str(), BytesToHex(key),
194                                            raw_blk_device_, 0);
195   target->SetSetDun();
196   if (is_wrapped_key) target->SetWrappedKeyV0();
197 
198   DmTable table;
199   if (!table.AddTarget(std::move(target))) {
200     ADD_FAILURE() << "Failed to add default-key target to table";
201     return false;
202   }
203   if (!table.valid()) {
204     ADD_FAILURE() << "Device-mapper table failed to validate";
205     return false;
206   }
207   if (!dm_->CreateDevice(kTestDmDeviceName, table, &dm_device_path_,
208                          std::chrono::seconds(5))) {
209     GTEST_LOG_(INFO) << "Unable to create default-key mapping" << Errno()
210                      << ".  Assuming that the encryption settings cipher=\""
211                      << cipher << "\", is_wrapped_key=" << is_wrapped_key
212                      << " are unsupported and skipping the test.";
213     return false;
214   }
215   GTEST_LOG_(INFO) << "Created default-key mapping at " << dm_device_path_
216                    << " using cipher=\"" << cipher
217                    << "\", key=" << BytesToHex(key)
218                    << ", is_wrapped_key=" << is_wrapped_key;
219   return true;
220 }
221 
VerifyDecryption(const std::vector<uint8_t> & key,const Cipher & cipher)222 void DmDefaultKeyTest::VerifyDecryption(const std::vector<uint8_t> &key,
223                                         const Cipher &cipher) {
224   std::vector<uint8_t> raw_data;
225   std::vector<uint8_t> decrypted_data;
226 
227   ASSERT_TRUE(ReadBlockDevice(raw_blk_device_, kTestDataBytes, &raw_data));
228   ASSERT_TRUE(
229       ReadBlockDevice(dm_device_path_, kTestDataBytes, &decrypted_data));
230 
231   // Verify that the decrypted data encrypts to the raw data.
232 
233   GTEST_LOG_(INFO) << "Verifying correctness of decrypted data";
234 
235   // Initialize the IV for crypto sector 0.
236   ASSERT_GE(cipher.ivsize(), sizeof(__le64));
237   std::unique_ptr<__le64> iv(new (::operator new(cipher.ivsize())) __le64);
238   memset(iv.get(), 0, cipher.ivsize());
239 
240   // Encrypt each sector.
241   std::vector<uint8_t> encrypted_data(kTestDataBytes);
242   static_assert(kTestDataBytes % kCryptoSectorSize == 0);
243   for (size_t i = 0; i < kTestDataBytes; i += kCryptoSectorSize) {
244     ASSERT_TRUE(cipher.Encrypt(key, reinterpret_cast<const uint8_t *>(iv.get()),
245                                &decrypted_data[i], &encrypted_data[i],
246                                kCryptoSectorSize));
247 
248     // Update the IV by incrementing the crypto sector number.
249     *iv = cpu_to_le64(le64_to_cpu(*iv) + 1);
250   }
251 
252   ASSERT_EQ(encrypted_data, raw_data);
253 }
254 
DoTest(const std::string & cipher_string,const Cipher & cipher)255 void DmDefaultKeyTest::DoTest(const std::string &cipher_string,
256                               const Cipher &cipher) {
257   if (skip_test_) return;
258 
259   std::vector<uint8_t> key = GenerateTestKey(cipher.keysize());
260 
261   if (!CreateTestDevice(cipher_string, key, false)) return;
262 
263   VerifyDecryption(key, cipher);
264 }
265 
266 // Tests dm-default-key parameters matching metadata_encryption=aes-256-xts.
TEST_F(DmDefaultKeyTest,TestAes256Xts)267 TEST_F(DmDefaultKeyTest, TestAes256Xts) {
268   DoTest("aes-xts-plain64", Aes256XtsCipher());
269 }
270 
271 // Tests dm-default-key parameters matching metadata_encryption=adiantum.
TEST_F(DmDefaultKeyTest,TestAdiantum)272 TEST_F(DmDefaultKeyTest, TestAdiantum) {
273   DoTest("xchacha12,aes-adiantum-plain64", AdiantumCipher());
274 }
275 
276 // Tests dm-default-key parameters matching
277 // metadata_encryption=aes-256-xts:wrappedkey_v0.
TEST_F(DmDefaultKeyTest,TestHwWrappedKey)278 TEST_F(DmDefaultKeyTest, TestHwWrappedKey) {
279   if (skip_test_) return;
280 
281   std::vector<uint8_t> master_key, exported_key;
282   if (!CreateHwWrappedKey(&master_key, &exported_key)) return;
283 
284   if (!CreateTestDevice("aes-xts-plain64", exported_key, true)) return;
285 
286   std::vector<uint8_t> enc_key;
287   ASSERT_TRUE(DeriveHwWrappedEncryptionKey(master_key, &enc_key));
288 
289   VerifyDecryption(enc_key, Aes256XtsCipher());
290 }
291 
292 // Tests that if the device uses metadata encryption, then the first
293 // kFilesystemBlockSize bytes of the userdata partition appear random.  For ext4
294 // and f2fs, this block should contain the filesystem superblock; it therefore
295 // should be initialized and metadata-encrypted.  Ideally we'd check additional
296 // blocks too, but that would require awareness of the filesystem structure.
297 //
298 // This isn't as strong a test as the correctness tests, but it's useful because
299 // it applies regardless of the encryption format and key.  Thus it runs even on
300 // old devices, including ones that used a vendor-specific encryption format.
TEST(MetadataEncryptionTest,TestRandomness)301 TEST(MetadataEncryptionTest, TestRandomness) {
302   constexpr const char *mountpoint = "/data";
303 
304   android::fs_mgr::Fstab fstab;
305   ASSERT_TRUE(android::fs_mgr::ReadDefaultFstab(&fstab));
306   const fs_mgr::FstabEntry *entry = GetEntryForMountPoint(&fstab, mountpoint);
307   ASSERT_TRUE(entry != nullptr);
308 
309   if (entry->metadata_key_dir.empty()) {
310     int first_api_level;
311     ASSERT_TRUE(GetFirstApiLevel(&first_api_level));
312     ASSERT_LE(first_api_level, __ANDROID_API_Q__)
313         << "Metadata encryption is required";
314     GTEST_LOG_(INFO)
315         << "Skipping test because device doesn't use metadata encryption";
316     return;
317   }
318 
319   GTEST_LOG_(INFO) << "Verifying randomness of ciphertext";
320   std::vector<uint8_t> raw_data;
321   FilesystemInfo fs_info;
322   ASSERT_TRUE(GetFilesystemInfo(mountpoint, &fs_info));
323   ASSERT_TRUE(
324       ReadBlockDevice(fs_info.raw_blk_device, kFilesystemBlockSize, &raw_data));
325   ASSERT_TRUE(VerifyDataRandomness(raw_data));
326 }
327 
328 }  // namespace kernel
329 }  // namespace android
330