bb573323d3e009f3e3e3c0203f743b6fa2a658f8
[project/make_ext4fs.git] / ext4_crypt.cpp
1 #define TAG "ext4_utils"
2
3 #include "ext4_crypt.h"
4
5 #include <string>
6 #include <fstream>
7 #include <map>
8
9 #include <errno.h>
10 #include <sys/mount.h>
11
12 #include <cutils/klog.h>
13 #include <cutils/properties.h>
14
15 #include "unencrypted_properties.h"
16
17 namespace {
18     std::map<std::string, std::string> s_password_store;
19 }
20
21 bool e4crypt_non_default_key(const char* dir)
22 {
23     int type = e4crypt_get_password_type(dir);
24
25     // ext4enc:TODO Use consts, not 1 here
26     return type != -1 && type != 1;
27 }
28
29 int e4crypt_get_password_type(const char* path)
30 {
31     UnencryptedProperties props(path);
32     if (props.Get<std::string>(properties::key).empty()) {
33         KLOG_INFO(TAG, "No master key, so not ext4enc\n");
34         return -1;
35     }
36
37     return props.Get<int>(properties::type, 1);
38 }
39
40 int e4crypt_change_password(const char* path, int crypt_type,
41                             const char* password)
42 {
43     // ext4enc:TODO Encrypt master key with password securely. Store hash of
44     // master key for validation
45     UnencryptedProperties props(path);
46     if (   props.Set(properties::password, password)
47         && props.Set(properties::type, crypt_type))
48         return 0;
49     return -1;
50 }
51
52 int e4crypt_crypto_complete(const char* path)
53 {
54     KLOG_INFO(TAG, "ext4 crypto complete called on %s\n", path);
55     if (UnencryptedProperties(path).Get<std::string>(properties::key).empty()) {
56         KLOG_INFO(TAG, "No master key, so not ext4enc\n");
57         return -1;
58     }
59
60     return 0;
61 }
62
63 int e4crypt_check_passwd(const char* path, const char* password)
64 {
65     UnencryptedProperties props(path);
66     if (props.Get<std::string>(properties::key).empty()) {
67         KLOG_INFO(TAG, "No master key, so not ext4enc\n");
68         return -1;
69     }
70
71     auto actual_password = props.Get<std::string>(properties::password);
72
73     if (actual_password == password) {
74         s_password_store[path] = password;
75         return 0;
76     } else {
77         return -1;
78     }
79 }
80
81 int e4crypt_restart(const char* path)
82 {
83     int rc = 0;
84
85     KLOG_INFO(TAG, "ext4 restart called on %s\n", path);
86     property_set("vold.decrypt", "trigger_reset_main");
87     KLOG_INFO(TAG, "Just asked init to shut down class main\n");
88     sleep(2);
89
90     std::string tmp_path = std::string() + path + "/tmp_mnt";
91
92     // ext4enc:TODO add retry logic
93     rc = umount(tmp_path.c_str());
94     if (rc) {
95         KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n",
96                    tmp_path.c_str(), rc, strerror(errno));
97         return rc;
98     }
99
100     // ext4enc:TODO add retry logic
101     rc = umount(path);
102     if (rc) {
103         KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n",
104                    path, rc, strerror(errno));
105         return rc;
106     }
107
108     return 0;
109 }
110
111 const char* e4crypt_get_password(const char* path)
112 {
113     // ext4enc:TODO scrub password after timeout
114     auto i = s_password_store.find(path);
115     if (i == s_password_store.end()) {
116         return 0;
117     } else {
118         return i->second.c_str();
119     }
120 }