Use libcryptsetup API instead of using cryptsetup directly 53/205553/4
authorSangyoon Jang <jeremy.jang@samsung.com>
Tue, 7 May 2019 09:59:31 +0000 (18:59 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Fri, 4 Oct 2019 04:32:26 +0000 (13:32 +0900)
Change-Id: I6b83d840fa5cf96c2c18ed08b5cbf5fdcf99e6ac
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
packaging/app2sd.spec
plugin/app2sd/CMakeLists.txt
plugin/app2sd/server/app2sd_crypt.c [new file with mode: 0644]
plugin/app2sd/server/app2sd_crypt.h [new file with mode: 0644]
plugin/app2sd/server/app2sd_interface.c
plugin/app2sd/server/app2sd_internals.c
plugin/app2sd/server/app2sd_internals.h
plugin/app2sd/server/app2sd_internals_utils.c

index 42c3aa4..b56c222 100644 (file)
@@ -20,6 +20,7 @@ BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(storage)
 BuildRequires:  pkgconfig(pkgmgr)
+BuildRequires:  pkgconfig(libcryptsetup)
 BuildRequires:  cmake
 
 %description
index 47c4de8..e72e9e6 100644 (file)
@@ -1,5 +1,5 @@
 # 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
diff --git a/plugin/app2sd/server/app2sd_crypt.c b/plugin/app2sd/server/app2sd_crypt.c
new file mode 100644 (file)
index 0000000..d49402e
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * 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, &params);
+       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, &params);
+       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;
+
+}
diff --git a/plugin/app2sd/server/app2sd_crypt.h b/plugin/app2sd/server/app2sd_crypt.h
new file mode 100644 (file)
index 0000000..b72b74b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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__
index f926c57..f1df396 100644 (file)
@@ -26,6 +26,7 @@
 #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)
@@ -1255,7 +1256,7 @@ int app2sd_migrate_legacy_all(void)
                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
                         */
index d545b8b..a65116c 100644 (file)
@@ -26,6 +26,7 @@
 #include <time.h>
 #include <pwd.h>
 
+#include "app2sd_crypt.h"
 #include "app2sd_internals.h"
 
 #define DMCRYPT_ITER_TIME      50
@@ -92,7 +93,6 @@ int _app2sd_dmcrypt_setup_device(const char *pkgid,
 {
        int ret;
        char *passwd;
-       char dmcrypt_setup_cmd[BUF_SIZE];
        char err_buf[BUF_SIZE];
        const char *err_str;
 
@@ -129,15 +129,9 @@ int _app2sd_dmcrypt_setup_device(const char *pkgid,
                }
        }
 
-       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",
@@ -153,10 +147,8 @@ int _app2sd_dmcrypt_open_device(const char *pkgid, const char *loopback_device,
 {
        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");
@@ -181,24 +173,17 @@ int _app2sd_dmcrypt_open_device(const char *pkgid, const char *loopback_device,
                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;
        }
 
@@ -216,9 +201,6 @@ int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid)
 {
        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) {
@@ -235,12 +217,9 @@ int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid)
        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;
        }
 
index e0f8c40..b3ccfe3 100644 (file)
@@ -177,8 +177,6 @@ int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid);
 /* 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);
 
index 678ace0..75425bc 100644 (file)
@@ -369,22 +369,6 @@ char *_app2sd_generate_password(void)
        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)
 {