blob: 70ad070dd024c043f99a26a3518a015d7a5641c5 [file] [log] [blame]
Elliott Hughesee296862015-03-28 10:39:46 -07001#define TAG "ext4_utils"
2
Paul Lawrence92da49d2015-02-25 15:11:13 -08003#include "ext4_crypt.h"
4
5#include <string>
6#include <fstream>
7#include <map>
8
9#include <errno.h>
10#include <sys/mount.h>
Paul Lawrence92da49d2015-02-25 15:11:13 -080011
Elliott Hughesee296862015-03-28 10:39:46 -070012#include <cutils/klog.h>
13#include <cutils/properties.h>
Paul Lawrence92da49d2015-02-25 15:11:13 -080014
15// ext4enc::TODO remove this duplicated const
16static const std::string unencrypted_path = "/unencrypted";
17
18static std::map<std::string, std::string> s_password_store;
19
20bool e4crypt_non_default_key(const char* dir)
21{
22 int type = e4crypt_get_password_type(dir);
23 return type != -1 && type != 1;
24}
25
26int e4crypt_get_password_type(const char* path)
27{
28 auto full_path = std::string() + path + unencrypted_path;
29 if (!std::ifstream(full_path + "/key")) {
Elliott Hughesee296862015-03-28 10:39:46 -070030 KLOG_INFO(TAG, "No master key, so not ext4enc\n");
Paul Lawrence92da49d2015-02-25 15:11:13 -080031 return -1;
32 }
33
34 std::ifstream type(full_path + "/type");
35 if (!type) {
Elliott Hughesee296862015-03-28 10:39:46 -070036 KLOG_INFO(TAG, "No password type so default\n");
Paul Lawrence92da49d2015-02-25 15:11:13 -080037 return 1; // Default
38 }
39
40 int value = 0;
41 type >> value;
Elliott Hughesee296862015-03-28 10:39:46 -070042 KLOG_INFO(TAG, "Password type is %d\n", value);
Paul Lawrence92da49d2015-02-25 15:11:13 -080043 return value;
44}
45
46int e4crypt_change_password(const char* path, int crypt_type,
47 const char* password)
48{
49 // ext4enc:TODO Encrypt master key with password securely. Store hash of
50 // master key for validation
51 auto full_path = std::string() + path + unencrypted_path;
52 std::ofstream(full_path + "/password") << password;
53 std::ofstream(full_path + "/type") << crypt_type;
54 return 0;
55}
56
57int e4crypt_crypto_complete(const char* path)
58{
Elliott Hughesee296862015-03-28 10:39:46 -070059 KLOG_INFO(TAG, "ext4 crypto complete called on %s\n", path);
Paul Lawrence92da49d2015-02-25 15:11:13 -080060
61 auto full_path = std::string() + path + unencrypted_path;
62 if (!std::ifstream(full_path + "/key")) {
Elliott Hughesee296862015-03-28 10:39:46 -070063 KLOG_INFO(TAG, "No master key, so not ext4enc\n");
Paul Lawrence92da49d2015-02-25 15:11:13 -080064 return -1;
65 }
66
67 return 0;
68}
69
70int e4crypt_check_passwd(const char* path, const char* password)
71{
72 auto full_path = std::string() + path + unencrypted_path;
73 if (!std::ifstream(full_path + "/key")) {
Elliott Hughesee296862015-03-28 10:39:46 -070074 KLOG_INFO(TAG, "No master key, so not ext4enc\n");
Paul Lawrence92da49d2015-02-25 15:11:13 -080075 return -1;
76 }
77
78 std::string actual_password;
79 std::ifstream(full_path + "/password") >> actual_password;
80
81 if (actual_password == password) {
82 s_password_store[path] = password;
83 return 0;
84 } else {
85 return -1;
86 }
87}
88
89int e4crypt_restart(const char* path)
90{
91 int rc = 0;
92
Elliott Hughesee296862015-03-28 10:39:46 -070093 KLOG_INFO(TAG, "ext4 restart called on %s\n", path);
Paul Lawrence92da49d2015-02-25 15:11:13 -080094 property_set("vold.decrypt", "trigger_reset_main");
Elliott Hughesee296862015-03-28 10:39:46 -070095 KLOG_INFO(TAG, "Just asked init to shut down class main\n");
Paul Lawrence92da49d2015-02-25 15:11:13 -080096 sleep(2);
97
98 std::string tmp_path = std::string() + path + "/tmp_mnt";
99
100 // ext4enc:TODO add retry logic
101 rc = umount(tmp_path.c_str());
102 if (rc) {
Elliott Hughesee296862015-03-28 10:39:46 -0700103 KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n",
104 tmp_path.c_str(), rc, strerror(errno));
Paul Lawrence92da49d2015-02-25 15:11:13 -0800105 return rc;
106 }
107
108 // ext4enc:TODO add retry logic
109 rc = umount(path);
110 if (rc) {
Elliott Hughesee296862015-03-28 10:39:46 -0700111 KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n",
112 path, rc, strerror(errno));
Paul Lawrence92da49d2015-02-25 15:11:13 -0800113 return rc;
114 }
115
116 return 0;
117}
118
119const char* e4crypt_get_password(const char* path)
120{
121 // ext4enc:TODO scrub password after timeout
122 auto i = s_password_store.find(path);
123 if (i == s_password_store.end()) {
124 return 0;
125 } else {
126 return i->second.c_str();
127 }
128}