1 #include "Ext4Crypt.h"
2 
3 #include <iomanip>
4 #include <map>
5 #include <fstream>
6 #include <string>
7 #include <sstream>
8 
9 #include <errno.h>
10 #include <sys/mount.h>
11 #include <cutils/properties.h>
12 #include <openssl/sha.h>
13 
14 #include "unencrypted_properties.h"
15 #include "key_control.h"
16 #include "cryptfs.h"
17 
18 #define LOG_TAG "Ext4Crypt"
19 #include "cutils/log.h"
20 #include <cutils/klog.h>
21 
22 namespace {
23     // Key length in bits
24     const int key_length = 128;
25     static_assert(key_length % 8 == 0,
26                   "Key length must be multiple of 8 bits");
27 
28     // How long do we store passwords for?
29     const int password_max_age_seconds = 60;
30 
31     // How is device encrypted
32     struct keys {
33         std::string master_key;
34         std::string password;
35         time_t expiry_time;
36     };
37     std::map<std::string, keys> s_key_store;
38 
39     // ext4enc:TODO get these consts from somewhere good
40     const int SHA512_LENGTH = 64;
41     const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
42 
43     // ext4enc:TODO Include structure from somewhere sensible
44     // MUST be in sync with ext4_crypto.c in kernel
45     const int EXT4_MAX_KEY_SIZE = 64;
46     const int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
47     struct ext4_encryption_key {
48         uint32_t mode;
49         char raw[EXT4_MAX_KEY_SIZE];
50         uint32_t size;
51     };
52 
53     namespace tag {
54         const char* magic = "magic";
55         const char* major_version = "major_version";
56         const char* minor_version = "minor_version";
57         const char* flags = "flags";
58         const char* crypt_type = "crypt_type";
59         const char* failed_decrypt_count = "failed_decrypt_count";
60         const char* crypto_type_name = "crypto_type_name";
61         const char* master_key = "master_key";
62         const char* salt = "salt";
63         const char* kdf_type = "kdf_type";
64         const char* N_factor = "N_factor";
65         const char* r_factor = "r_factor";
66         const char* p_factor = "p_factor";
67         const char* keymaster_blob = "keymaster_blob";
68         const char* scrypted_intermediate_key = "scrypted_intermediate_key";
69     }
70 }
71 
put_crypt_ftr_and_key(const crypt_mnt_ftr & crypt_ftr,UnencryptedProperties & props)72 static int put_crypt_ftr_and_key(const crypt_mnt_ftr& crypt_ftr,
73                                  UnencryptedProperties& props)
74 {
75     SLOGI("Putting crypt footer");
76 
77     bool success = props.Set<int>(tag::magic, crypt_ftr.magic)
78       && props.Set<int>(tag::major_version, crypt_ftr.major_version)
79       && props.Set<int>(tag::minor_version, crypt_ftr.minor_version)
80       && props.Set<int>(tag::flags, crypt_ftr.flags)
81       && props.Set<int>(tag::crypt_type, crypt_ftr.crypt_type)
82       && props.Set<int>(tag::failed_decrypt_count,
83                         crypt_ftr.failed_decrypt_count)
84       && props.Set<std::string>(tag::crypto_type_name,
85                                 std::string(reinterpret_cast<const char*>(crypt_ftr.crypto_type_name)))
86       && props.Set<std::string>(tag::master_key,
87                                 std::string((const char*) crypt_ftr.master_key,
88                                             crypt_ftr.keysize))
89       && props.Set<std::string>(tag::salt,
90                                 std::string((const char*) crypt_ftr.salt,
91                                             SALT_LEN))
92       && props.Set<int>(tag::kdf_type, crypt_ftr.kdf_type)
93       && props.Set<int>(tag::N_factor, crypt_ftr.N_factor)
94       && props.Set<int>(tag::r_factor, crypt_ftr.r_factor)
95       && props.Set<int>(tag::p_factor, crypt_ftr.p_factor)
96       && props.Set<std::string>(tag::keymaster_blob,
97                                 std::string((const char*) crypt_ftr.keymaster_blob,
98                                             crypt_ftr.keymaster_blob_size))
99       && props.Set<std::string>(tag::scrypted_intermediate_key,
100                                 std::string((const char*) crypt_ftr.scrypted_intermediate_key,
101                                             SCRYPT_LEN));
102     return success ? 0 : -1;
103 }
104 
get_crypt_ftr_and_key(crypt_mnt_ftr & crypt_ftr,const UnencryptedProperties & props)105 static int get_crypt_ftr_and_key(crypt_mnt_ftr& crypt_ftr,
106                                  const UnencryptedProperties& props)
107 {
108     memset(&crypt_ftr, 0, sizeof(crypt_ftr));
109     crypt_ftr.magic = props.Get<int>(tag::magic);
110     crypt_ftr.major_version = props.Get<int>(tag::major_version);
111     crypt_ftr.minor_version = props.Get<int>(tag::minor_version);
112     crypt_ftr.ftr_size = sizeof(crypt_ftr);
113     crypt_ftr.flags = props.Get<int>(tag::flags);
114     crypt_ftr.crypt_type = props.Get<int>(tag::crypt_type);
115     crypt_ftr.failed_decrypt_count = props.Get<int>(tag::failed_decrypt_count);
116     std::string crypto_type_name = props.Get<std::string>(tag::crypto_type_name);
117     strlcpy(reinterpret_cast<char*>(crypt_ftr.crypto_type_name),
118             crypto_type_name.c_str(),
119             sizeof(crypt_ftr.crypto_type_name));
120     std::string master_key = props.Get<std::string>(tag::master_key);
121     crypt_ftr.keysize = master_key.size();
122     if (crypt_ftr.keysize > sizeof(crypt_ftr.master_key)) {
123         SLOGE("Master key size too long");
124         return -1;
125     }
126     memcpy(crypt_ftr.master_key, &master_key[0], crypt_ftr.keysize);
127     std::string salt = props.Get<std::string>(tag::salt);
128     if (salt.size() != SALT_LEN) {
129         SLOGE("Salt wrong length");
130         return -1;
131     }
132     memcpy(crypt_ftr.salt, &salt[0], SALT_LEN);
133     crypt_ftr.kdf_type = props.Get<int>(tag::kdf_type);
134     crypt_ftr.N_factor = props.Get<int>(tag::N_factor);
135     crypt_ftr.r_factor = props.Get<int>(tag::r_factor);
136     crypt_ftr.p_factor = props.Get<int>(tag::p_factor);
137     std::string keymaster_blob = props.Get<std::string>(tag::keymaster_blob);
138     crypt_ftr.keymaster_blob_size = keymaster_blob.size();
139     if (crypt_ftr.keymaster_blob_size > sizeof(crypt_ftr.keymaster_blob)) {
140         SLOGE("Keymaster blob too long");
141         return -1;
142     }
143     memcpy(crypt_ftr.keymaster_blob, &keymaster_blob[0],
144            crypt_ftr.keymaster_blob_size);
145     std::string scrypted_intermediate_key = props.Get<std::string>(tag::scrypted_intermediate_key);
146     if (scrypted_intermediate_key.size() != SCRYPT_LEN) {
147         SLOGE("scrypted intermediate key wrong length");
148         return -1;
149     }
150     memcpy(crypt_ftr.scrypted_intermediate_key, &scrypted_intermediate_key[0],
151            SCRYPT_LEN);
152 
153     return 0;
154 }
155 
GetProps(const char * path)156 static UnencryptedProperties GetProps(const char* path)
157 {
158     return UnencryptedProperties(path);
159 }
160 
GetAltProps(const char * path)161 static UnencryptedProperties GetAltProps(const char* path)
162 {
163     return UnencryptedProperties((std::string() + path + "/tmp_mnt").c_str());
164 }
165 
GetPropsOrAltProps(const char * path)166 static UnencryptedProperties GetPropsOrAltProps(const char* path)
167 {
168     UnencryptedProperties props = GetProps(path);
169     if (props.OK()) {
170         return props;
171     }
172     return GetAltProps(path);
173 }
174 
e4crypt_enable(const char * path)175 int e4crypt_enable(const char* path)
176 {
177     // Already enabled?
178     if (s_key_store.find(path) != s_key_store.end()) {
179         return 0;
180     }
181 
182     // Not an encryptable device?
183     UnencryptedProperties key_props = GetProps(path).GetChild(properties::key);
184     if (!key_props.OK()) {
185         return 0;
186     }
187 
188     if (key_props.Get<std::string>(tag::master_key).empty()) {
189         crypt_mnt_ftr ftr;
190         if (cryptfs_create_default_ftr(&ftr, key_length)) {
191             SLOGE("Failed to create crypto footer");
192             return -1;
193         }
194 
195         // Scrub fields not used by ext4enc
196         ftr.persist_data_offset[0] = 0;
197         ftr.persist_data_offset[1] = 0;
198         ftr.persist_data_size = 0;
199 
200         if (put_crypt_ftr_and_key(ftr, key_props)) {
201             SLOGE("Failed to write crypto footer");
202             return -1;
203         }
204 
205         crypt_mnt_ftr ftr2;
206         if (get_crypt_ftr_and_key(ftr2, key_props)) {
207             SLOGE("Failed to read crypto footer back");
208             return -1;
209         }
210 
211         if (memcmp(&ftr, &ftr2, sizeof(ftr)) != 0) {
212             SLOGE("Crypto footer not correctly written");
213             return -1;
214         }
215     }
216 
217     if (!UnencryptedProperties(path).Remove(properties::ref)) {
218         SLOGE("Failed to remove key ref");
219         return -1;
220     }
221 
222     return e4crypt_check_passwd(path, "");
223 }
224 
e4crypt_change_password(const char * path,int crypt_type,const char * password)225 int e4crypt_change_password(const char* path, int crypt_type,
226                             const char* password)
227 {
228     SLOGI("e4crypt_change_password");
229     auto key_props = GetProps(path).GetChild(properties::key);
230 
231     crypt_mnt_ftr ftr;
232     if (get_crypt_ftr_and_key(ftr, key_props)) {
233         SLOGE("Failed to read crypto footer back");
234         return -1;
235     }
236 
237     auto mki = s_key_store.find(path);
238     if (mki == s_key_store.end()) {
239         SLOGE("No stored master key - can't change password");
240         return -1;
241     }
242 
243     const unsigned char* master_key
244         = reinterpret_cast<const unsigned char*>(&mki->second.master_key[0]);
245 
246     if (cryptfs_set_password(&ftr, password, master_key)) {
247         SLOGE("Failed to set password");
248         return -1;
249     }
250 
251     ftr.crypt_type = crypt_type;
252 
253     if (put_crypt_ftr_and_key(ftr, key_props)) {
254         SLOGE("Failed to write crypto footer");
255         return -1;
256     }
257 
258     if (!UnencryptedProperties(path).Set(properties::is_default,
259                             crypt_type == CRYPT_TYPE_DEFAULT)) {
260         SLOGE("Failed to update default flag");
261         return -1;
262     }
263 
264     return 0;
265 }
266 
e4crypt_crypto_complete(const char * path)267 int e4crypt_crypto_complete(const char* path)
268 {
269     SLOGI("ext4 crypto complete called on %s", path);
270     auto key_props = GetPropsOrAltProps(path).GetChild(properties::key);
271     if (key_props.Get<std::string>(tag::master_key).empty()) {
272         SLOGI("No master key, so not ext4enc");
273         return -1;
274     }
275 
276     return 0;
277 }
278 
generate_key_ref(const char * key,int length)279 static std::string generate_key_ref(const char* key, int length)
280 {
281     SHA512_CTX c;
282 
283     SHA512_Init(&c);
284     SHA512_Update(&c, key, length);
285     unsigned char key_ref1[SHA512_LENGTH];
286     SHA512_Final(key_ref1, &c);
287 
288     SHA512_Init(&c);
289     SHA512_Update(&c, key_ref1, SHA512_LENGTH);
290     unsigned char key_ref2[SHA512_LENGTH];
291     SHA512_Final(key_ref2, &c);
292 
293     return std::string((char*)key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
294 }
295 
e4crypt_check_passwd(const char * path,const char * password)296 int e4crypt_check_passwd(const char* path, const char* password)
297 {
298     SLOGI("e4crypt_check_password");
299     auto props = GetPropsOrAltProps(path);
300     auto key_props = props.GetChild(properties::key);
301 
302     crypt_mnt_ftr ftr;
303     if (get_crypt_ftr_and_key(ftr, key_props)) {
304         SLOGE("Failed to read crypto footer back");
305         return -1;
306     }
307 
308     unsigned char master_key[key_length / 8];
309     if (cryptfs_get_master_key (&ftr, password, master_key)){
310         SLOGI("Incorrect password");
311         ftr.failed_decrypt_count++;
312         if (put_crypt_ftr_and_key(ftr, key_props)) {
313             SLOGW("Failed to update failed_decrypt_count");
314         }
315         return ftr.failed_decrypt_count;
316     }
317 
318     if (ftr.failed_decrypt_count) {
319         ftr.failed_decrypt_count = 0;
320         if (put_crypt_ftr_and_key(ftr, key_props)) {
321             SLOGW("Failed to reset failed_decrypt_count");
322         }
323     }
324 
325     struct timespec now;
326     clock_gettime(CLOCK_BOOTTIME, &now);
327     s_key_store[path] = keys{std::string(reinterpret_cast<char*>(master_key),
328                                          sizeof(master_key)),
329                              password,
330                              now.tv_sec + password_max_age_seconds};
331 
332     // Install password into global keyring
333     // ext4enc:TODO Currently raw key is required to be of length
334     // sizeof(ext4_key.raw) == EXT4_MAX_KEY_SIZE, so zero pad to
335     // this length. Change when kernel bug is fixed.
336     ext4_encryption_key ext4_key = {EXT4_ENCRYPTION_MODE_AES_256_XTS,
337                                     {0},
338                                     sizeof(ext4_key.raw)};
339     memset(ext4_key.raw, 0, sizeof(ext4_key.raw));
340     static_assert(key_length / 8 <= sizeof(ext4_key.raw),
341                   "Key too long!");
342     memcpy(ext4_key.raw, master_key, key_length / 8);
343 
344     // Get raw keyref - used to make keyname and to pass to ioctl
345     auto raw_ref = generate_key_ref(ext4_key.raw, ext4_key.size);
346 
347     // Generate keyname
348     std::ostringstream o;
349     for (auto i = raw_ref.begin(); i != raw_ref.end(); ++i) {
350         o << std::hex << std::setw(2) << std::setfill('0') << (int)*i;
351     }
352     auto ref = std::string("ext4:") + o.str();
353 
354     // Find existing keyring
355     key_serial_t device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING,
356                                                 "keyring", "e4crypt", 0);
357 
358     SLOGI("Found device_keyring - id is %d", device_keyring);
359 
360     // Add key ...
361     key_serial_t key_id = add_key("logon", ref.c_str(),
362                                   (void*)&ext4_key, sizeof(ext4_key),
363                                   device_keyring);
364 
365     if (key_id == -1) {
366         SLOGE("Failed to insert key into keyring with error %s",
367               strerror(errno));
368         return -1;
369     }
370 
371     SLOGI("Added key %d (%s) to keyring %d in process %d",
372           key_id, ref.c_str(), device_keyring, getpid());
373 
374     // Save reference to key so we can set policy later
375     if (!props.Set(properties::ref, raw_ref)) {
376         SLOGE("Cannot save key reference");
377         return -1;
378     }
379 
380     return 0;
381 }
382 
e4crypt_restart(const char * path)383 int e4crypt_restart(const char* path)
384 {
385     SLOGI("e4crypt_restart");
386 
387     int rc = 0;
388 
389     SLOGI("ext4 restart called on %s", path);
390     property_set("vold.decrypt", "trigger_reset_main");
391     SLOGI("Just asked init to shut down class main");
392     sleep(2);
393 
394     std::string tmp_path = std::string() + path + "/tmp_mnt";
395 
396     rc = wait_and_unmount(tmp_path.c_str(), true);
397     if (rc) {
398         SLOGE("umount %s failed with rc %d, msg %s",
399               tmp_path.c_str(), rc, strerror(errno));
400         return rc;
401     }
402 
403     rc = wait_and_unmount(path, true);
404     if (rc) {
405         SLOGE("umount %s failed with rc %d, msg %s",
406               path, rc, strerror(errno));
407         return rc;
408     }
409 
410     return 0;
411 }
412 
e4crypt_get_password_type(const char * path)413 int e4crypt_get_password_type(const char* path)
414 {
415     SLOGI("e4crypt_get_password_type");
416     return GetPropsOrAltProps(path).GetChild(properties::key)
417       .Get<int>(tag::crypt_type, CRYPT_TYPE_DEFAULT);
418 }
419 
e4crypt_get_password(const char * path)420 const char* e4crypt_get_password(const char* path)
421 {
422     SLOGI("e4crypt_get_password");
423 
424     auto i = s_key_store.find(path);
425     if (i == s_key_store.end()) {
426         return 0;
427     }
428 
429     struct timespec now;
430     clock_gettime(CLOCK_BOOTTIME, &now);
431     if (i->second.expiry_time < now.tv_sec) {
432         e4crypt_clear_password(path);
433         return 0;
434     }
435 
436     return i->second.password.c_str();
437 }
438 
e4crypt_clear_password(const char * path)439 void e4crypt_clear_password(const char* path)
440 {
441     SLOGI("e4crypt_clear_password");
442 
443     auto i = s_key_store.find(path);
444     if (i == s_key_store.end()) {
445         return;
446     }
447 
448     memset(&i->second.password[0], 0, i->second.password.size());
449     i->second.password = std::string();
450 }
451 
e4crypt_get_field(const char * path,const char * fieldname,char * value,size_t len)452 int e4crypt_get_field(const char* path, const char* fieldname,
453                       char* value, size_t len)
454 {
455     auto v = GetPropsOrAltProps(path).GetChild(properties::props)
456       .Get<std::string>(fieldname);
457 
458     if (v == "") {
459         return CRYPTO_GETFIELD_ERROR_NO_FIELD;
460     }
461 
462     if (v.length() >= len) {
463         return CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL;
464     }
465 
466     strlcpy(value, v.c_str(), len);
467     return 0;
468 }
469 
e4crypt_set_field(const char * path,const char * fieldname,const char * value)470 int e4crypt_set_field(const char* path, const char* fieldname,
471                       const char* value)
472 {
473     return GetPropsOrAltProps(path).GetChild(properties::props)
474         .Set(fieldname, std::string(value)) ? 0 : -1;
475 }
476