2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
21 #include <sys/mount.h>
22 #include <sys/types.h>
29 #include <klay/error.h>
30 #include <klay/exception.h>
31 #include <klay/audit/logger.h>
34 #include "kernel-keyring.h"
35 #include "key-manager.h"
36 #include "key-generator.h"
38 int generateKey(const std::string& keyName)
40 if (KeyManager::isKeyExist(keyName)) {
41 ERROR("Key already registered");
46 std::string pass = KeyGenerator::generateKey(ECRYPTFS_MAX_KEY_SIZE);
47 std::string salt = KeyGenerator::generateKey(ECRYPTFS_SALT_SIZE);
48 std::string wrappedKey = KeyGenerator::wrapKey(pass, salt, ECRYPTFS_MAX_KEY_SIZE);
50 KeyManager::addKey(keyName, wrappedKey);
51 } catch (runtime::Exception& e) {
59 EcryptfsPayload* generateToken(char* key)
61 auto *payload = new EcryptfsPayload(EcryptfsPayload::Type::PasswordToken);
62 payload->token.password.flags = EcryptfsPassword::Flag::
63 SessionKeyEncryptionKeySet;
64 payload->token.password.sessionKeyEncryptionKeySize = ECRYPTFS_MAX_KEY_SIZE;
65 ::memcpy(payload->token.password.sessionKeyEncryptionKey, key,
66 payload->token.password.sessionKeyEncryptionKeySize);
68 ::memcpy((char *)payload->token.password.signature,
69 key, ECRYPTFS_SIGNATURE_SIZE);
74 int mountEcryptfs(const std::string& src, const std::string& keyName)
77 char ecryptfsOpts[1024];
78 EcryptfsPayload* payload = NULL;
82 key = KeyManager::getKey(keyName);
83 } catch (runtime::Exception& e) {
88 if (KernelKeyRing::link(KEY_SPEC_USER_KEYRING, KEY_SPEC_SESSION_KEYRING) != 0) {
89 ERROR("Failed to link key");
93 if ((payload = generateToken((char*)key.c_str())) == NULL) {
94 ERROR("Failed to generate Token");
98 const char* signature = (const char*)payload->token.password.signature;
99 rc = KernelKeyRing::search(KEY_SPEC_USER_KEYRING,
105 if (errno != ENOKEY) {
106 ERROR("Failed to find key");
111 rc = KernelKeyRing::add("user",
115 KEY_SPEC_USER_KEYRING);
118 ERROR("Failed to add key");
124 ::snprintf(ecryptfsOpts, 1024,
125 "ecryptfs_passthrough,"
126 "ecryptfs_cipher=aes,"
127 "ecryptfs_key_bytes=%d,"
129 "smackfsroot=*,smackfsdef=*",
130 ECRYPTFS_MAX_KEY_SIZE, signature);
134 rc = ::mount(src.c_str(), src.c_str(), "ecryptfs", MS_NODEV, ecryptfsOpts);
136 ERROR(runtime::GetSystemErrorMessage());
143 int mountEcryptfsToAll()
148 void usage(const std::string& prog)
150 std::cout << "Usage: " << prog << std::endl
151 << "-a : Automount" << std::endl
152 << "-g name : Generate key for krate" << std::endl
153 << "-m name : Apply filesystem encrytion to krate" << std::endl;
156 int main(int argc, char* argv[])
158 int opt, index, ret = -1;
159 struct option options[] = {
160 {"automount", no_argument, 0, 'a'},
161 {"generate", required_argument, 0, 'g'},
162 {"mount", required_argument, 0, 'm'},
166 while ((opt = getopt_long(argc, argv, "ag:m:", options, &index)) != -1) {
169 ret = mountEcryptfsToAll();
172 ret = generateKey(optarg);
175 ret = mountEcryptfs("/home/" + std::string(optarg), optarg);
178 std::cerr << "unknown" << std::endl;