BuildRequires: pkgconfig(aul)
BuildRequires: pkgconfig(storage)
BuildRequires: pkgconfig(pkgmgr)
+BuildRequires: pkgconfig(libcryptsetup)
BuildRequires: cmake
%description
# Required packages
-pkg_check_modules(app2sd_pkgs REQUIRED dlog pkgmgr-info gio-2.0 glib-2.0 db-util libtzplatform-config aul storage pkgmgr)
+pkg_check_modules(app2sd_pkgs REQUIRED dlog pkgmgr-info gio-2.0 glib-2.0 db-util libtzplatform-config aul storage pkgmgr libcryptsetup)
pkg_check_modules(app2sd_libpkgs REQUIRED dlog pkgmgr-info gio-2.0 glib-2.0)
# Compiler flags
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <libcryptsetup.h>
+#include <string.h>
+
+#include "app2sd_utils.h"
+
+#define APP2SD_AES_HASH "sha1"
+#define APP2SD_PLAIN_HASH "plain"
+#define APP2SD_CIPHER "aes"
+#define APP2SD_CIPHER_MODE "cbc-lmk"
+#define APP2SD_CIPHER_MODE_PLAIN "cbc-plain"
+#define APP2SD_ITERATION_TIME 50
+#define APP2SD_KEY_SIZE 16 /* 128 BITS */
+#define APP2SD_KEY_SIZE_PLAIN 32 /* 256 BITS (default) */
+
+static void __log_cb(int level, const char *msg, void *usrptr)
+{
+ switch (level) {
+ case CRYPT_LOG_NORMAL:
+ _I("[CRYPTSETUP] %s", msg);
+ break;
+ case CRYPT_LOG_ERROR:
+ _E("[CRYPTSETUP] %s", msg);
+ break;
+ default:
+ _D("[CRYPTSETUP] %s", msg);
+ break;
+ }
+}
+
+static void __set_log_cb(struct crypt_device *cd)
+{
+ crypt_set_debug_level(CRYPT_DEBUG_ALL);
+ crypt_set_log_callback(cd, &__log_cb, NULL);
+}
+
+/* same as below command:
+ * $ /sbin/crpytsetup -i 50 -c aes-cbc-lmk -s 128
+ * --align-payload=8 luksFormat <device>
+ */
+int _app2sd_crypt_luks_format(const char *loopback_device, const char *passwd)
+{
+ int r;
+ struct crypt_device *cd;
+ struct crypt_params_luks1 params = {
+ .hash = APP2SD_AES_HASH,
+ .data_alignment = 8,
+ .data_device = NULL,
+ };
+ const char *cipher = APP2SD_CIPHER;
+ const char *cipher_mode = APP2SD_CIPHER_MODE;
+
+ r = crypt_init(&cd, loopback_device);
+ if (r < 0) {
+ _E("crypt_init() for %s failed: %d", loopback_device, r);
+ return -1;
+ }
+ __set_log_cb(cd);
+
+ crypt_set_iteration_time(cd, APP2SD_ITERATION_TIME);
+
+ r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
+ NULL, NULL, APP2SD_KEY_SIZE, ¶ms);
+ if (r < 0) {
+ _E("crypt_format() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT,
+ NULL, APP2SD_KEY_SIZE, passwd, strlen(passwd));
+ if (r < 0) {
+ _E("crypt_keyslot_add_by_volume_key() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ crypt_free(cd);
+
+ return 0;
+}
+
+/* same as below command:
+ * $ /sbin/cryptsetup isLuks <device>
+ */
+int _app2sd_crypt_is_luks(const char *loopback_device)
+{
+ int r;
+ struct crypt_device *cd;
+ int is_luks = 0;
+
+ r = crypt_init(&cd, loopback_device);
+ if (r < 0) {
+ _E("crypt_init() for %s failed: %d", loopback_device, r);
+ return is_luks;
+ }
+ __set_log_cb(cd);
+
+ r = crypt_load(cd, CRYPT_LUKS1, NULL);
+ if (!r)
+ is_luks = 1;
+
+ crypt_free(cd);
+
+ return is_luks;
+}
+
+/* same as below command:
+ * $ /sbin/cryptsetup luksOpen <device> <name>
+ */
+int _app2sd_crypt_luks_open(const char *loopback_device, const char *passwd,
+ const char *dev_name)
+{
+ int r;
+ struct crypt_device *cd;
+
+ r = crypt_init(&cd, loopback_device);
+ if (r < 0) {
+ _E("crypt_init() for %s failed: %d", loopback_device, r);
+ return -1;
+ }
+ __set_log_cb(cd);
+
+ r = crypt_load(cd, CRYPT_LUKS1, NULL);
+ if (r < 0) {
+ _E("crypt_load() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ r = crypt_activate_by_passphrase(cd, dev_name, CRYPT_ANY_SLOT,
+ passwd, strlen(passwd), 0);
+ if (r < 0) {
+ _E("crypt_activate_by_passphrase() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ crypt_free(cd);
+
+ return 0;
+}
+
+/* same as below command:
+ * $ /sbin/cryptsetup luksClose <name>
+ */
+int _app2sd_crypt_luks_close(const char *dev_name)
+{
+ int r;
+ struct crypt_device *cd;
+
+ r = crypt_init_by_name(&cd, dev_name);
+ if (r < 0) {
+ _E("crypt_init_by_name() for %s failed: %d", dev_name, r);
+ return -1;
+ }
+ __set_log_cb(cd);
+
+ r = crypt_deactivate(cd, dev_name);
+ if (r < 0) {
+ _E("crypt_deactivate() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ crypt_free(cd);
+
+ return 0;
+}
+
+/* same as below command:
+ * $ /sbin/cryptsetup -M plain -c aes-cbc-plain -h plain open <device> <name>
+ */
+int _app2sd_crypt_plain_open(const char *loopback_device, const char *passwd,
+ const char *dev_name)
+{
+ int r;
+ struct crypt_device *cd;
+ struct crypt_params_plain params = {
+ .hash = NULL,
+ .skip = 0,
+ .offset = 0,
+ .size = 0,
+ };
+ const char *cipher = APP2SD_CIPHER;
+ const char *cipher_mode = APP2SD_CIPHER_MODE_PLAIN;
+
+ r = crypt_init(&cd, loopback_device);
+ if (r < 0) {
+ _E("crypt_init() for %s failed: %d", loopback_device, r);
+ return -1;
+ }
+ __set_log_cb(cd);
+
+ r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode,
+ NULL, NULL, APP2SD_KEY_SIZE_PLAIN, ¶ms);
+ if (r < 0) {
+ _E("crypt_format() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ r = crypt_activate_by_passphrase(cd, dev_name, CRYPT_ANY_SLOT,
+ passwd, strlen(passwd), 0);
+ if (r < 0) {
+ _E("crypt_activate_by_passphrase() failed: %d", r);
+ crypt_free(cd);
+ return -1;
+ }
+
+ crypt_free(cd);
+
+ return 0;
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __APP2SD_CRYPT_H__
+#define __APP2SD_CRYPT_H__
+
+int _app2sd_crypt_luks_format(const char *loopback_device, const char *passwd);
+
+int _app2sd_crypt_is_luks(const char *loopback_device);
+
+int _app2sd_crypt_luks_open(const char *loopback_device, const char *passwd,
+ const char *dev_name);
+
+int _app2sd_crypt_luks_close(const char *dev_name);
+
+int _app2sd_crypt_plain_open(const char *loopback_device, const char *passwd,
+ const char *dev_name);
+
+#endif // __APP2SD_CRYPT_H__
#include <package-manager.h>
#include <aul.h>
+#include "app2sd_crypt.h"
#include "app2sd_internals.h"
static int __app2sd_create_app2sd_directories(uid_t uid, char *mmc_path)
snprintf(loopback_device, sizeof(loopback_device), "%s/%s",
app2sd_path, entry->d_name);
/* check losetup image */
- if (_app2sd_check_is_luks_device(loopback_device) == 0) {
+ if (_app2sd_crypt_is_luks(loopback_device) == 0) {
/* call installer backend
* to change access-rule and broadcast this update
*/
#include <time.h>
#include <pwd.h>
+#include "app2sd_crypt.h"
#include "app2sd_internals.h"
#define DMCRYPT_ITER_TIME 50
{
int ret;
char *passwd;
- char dmcrypt_setup_cmd[BUF_SIZE];
char err_buf[BUF_SIZE];
const char *err_str;
}
}
- snprintf(dmcrypt_setup_cmd, sizeof(dmcrypt_setup_cmd),
- "/bin/echo '%s' | /sbin/cryptsetup -q -i %d "
- "-c aes-cbc-lmk -s %d --align-payload=8 luksFormat %s",
- passwd, DMCRYPT_ITER_TIME, DMCRYPT_KEY_LEN,
- loopback_device);
+ ret = _app2sd_crypt_luks_format(loopback_device, passwd);
memset(passwd, 0, strlen(passwd));
free(passwd);
- ret = system(dmcrypt_setup_cmd);
- memset(dmcrypt_setup_cmd, 0, BUF_SIZE);
if (ret) {
err_str = strerror_r(errno, err_buf, sizeof(err_buf));
_E("Error setting up dmcrypt on app2sd file, error:%s, ret:%d",
{
int ret;
char *passwd;
- char dmcrypt_open_cmd[BUF_SIZE];
char dev_name[BUF_SIZE];
char buf[BUF_SIZE];
- const char *err_str;
if (pkgid == NULL || loopback_device == NULL) {
_E("invalid argument");
return APP2EXT_ERROR_SQLITE_REGISTRY;
}
- if (_app2sd_check_is_luks_device(loopback_device) == 0) {
+ if (_app2sd_crypt_is_luks(loopback_device) == 0) {
_W("legacy image format!");
- snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
- "/bin/echo '%s' | /sbin/cryptsetup "
- "-M plain -c aes-cbc-plain -h plain open %s %s",
- passwd, loopback_device, dev_name);
+ ret = _app2sd_crypt_plain_open(loopback_device, passwd,
+ dev_name);
} else {
- snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
- "/bin/echo '%s' | /sbin/cryptsetup -q luksOpen "
- "%s %s",
- passwd, loopback_device, dev_name);
+ ret = _app2sd_crypt_luks_open(loopback_device, passwd,
+ dev_name);
}
free(passwd);
-
- ret = system(dmcrypt_open_cmd);
if (ret) {
- err_str = strerror_r(errno, buf, sizeof(buf));
- _E("error opening dmcrypt device, error: [%s]", err_str);
+ _E("error opening dmcrypt device");
return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
}
{
int ret;
char dev_node[BUF_SIZE];
- char dmcrypt_close_cmd[BUF_SIZE];
- char err_buf[BUF_SIZE];
- const char *err_str;
char *t_dev_node;
if (pkgid == NULL) {
free(t_dev_node);
snprintf(dev_node, sizeof(dev_node), "/dev/mapper/%s_%d", pkgid, uid);
- snprintf(dmcrypt_close_cmd, sizeof(dmcrypt_close_cmd),
- "/sbin/cryptsetup -q luksClose %s", dev_node);
- ret = system(dmcrypt_close_cmd);
+ ret = _app2sd_crypt_luks_close(dev_node);
if (ret) {
- err_str = strerror_r(errno, err_buf, sizeof(err_buf));
- _E("error closing dmcrypt on app2sd file: %s", err_str);
+ _E("error closing dmcrypt on app2sd file: %s", dev_node);
return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
}
/* this function find associated dmcrypt device node */
char *_app2sd_find_associated_dmcrypt_device_node(const char *pkgid, uid_t uid);
-int _app2sd_check_is_luks_device(const char *device_path);
-
int _app2sd_get_loopback_device_path(const char *mmc_path, const char *pkgid,
uid_t uid, char *loopback_device, size_t len);
return passwd;
}
-int _app2sd_check_is_luks_device(const char *device_path)
-{
- int ret = 0;
- int result = 1; /* default: luks format */
- const char *argv_bin[] = { "/sbin/cryptsetup", "isLuks", device_path };
- ret = _xsystem(argv_bin);
- if (ret < 0)
- _E("there was errot to check isLuks");
-
- if (ret == 1) /* legacy format */
- result = 0;
-
- _D("ret(%d), result(%d)", ret, result);
- return result;
-}
-
int _app2sd_get_loopback_device_path(const char *mmc_path,
const char *pkgid, uid_t uid, char *loopback_device, size_t len)
{