From: Sangyoon Jang Date: Tue, 7 May 2019 09:59:31 +0000 (+0900) Subject: Use libcryptsetup API instead of using cryptsetup directly X-Git-Tag: submit/tizen/20191112.050420~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1d11e5eb763ab4a1aca136dc57ab6b68c764f42f;p=platform%2Fcore%2Fappfw%2Fapp2sd.git Use libcryptsetup API instead of using cryptsetup directly Change-Id: I6b83d840fa5cf96c2c18ed08b5cbf5fdcf99e6ac Signed-off-by: Sangyoon Jang --- diff --git a/packaging/app2sd.spec b/packaging/app2sd.spec index 42c3aa4..b56c222 100644 --- a/packaging/app2sd.spec +++ b/packaging/app2sd.spec @@ -20,6 +20,7 @@ BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(storage) BuildRequires: pkgconfig(pkgmgr) +BuildRequires: pkgconfig(libcryptsetup) BuildRequires: cmake %description diff --git a/plugin/app2sd/CMakeLists.txt b/plugin/app2sd/CMakeLists.txt index 47c4de8..e72e9e6 100644 --- a/plugin/app2sd/CMakeLists.txt +++ b/plugin/app2sd/CMakeLists.txt @@ -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 index 0000000..d49402e --- /dev/null +++ b/plugin/app2sd/server/app2sd_crypt.c @@ -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 +#include + +#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 + */ +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 + */ +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 + */ +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 + */ +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 + */ +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; + +} diff --git a/plugin/app2sd/server/app2sd_crypt.h b/plugin/app2sd/server/app2sd_crypt.h new file mode 100644 index 0000000..b72b74b --- /dev/null +++ b/plugin/app2sd/server/app2sd_crypt.h @@ -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__ diff --git a/plugin/app2sd/server/app2sd_interface.c b/plugin/app2sd/server/app2sd_interface.c index f926c57..f1df396 100644 --- a/plugin/app2sd/server/app2sd_interface.c +++ b/plugin/app2sd/server/app2sd_interface.c @@ -26,6 +26,7 @@ #include #include +#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 */ diff --git a/plugin/app2sd/server/app2sd_internals.c b/plugin/app2sd/server/app2sd_internals.c index d545b8b..a65116c 100644 --- a/plugin/app2sd/server/app2sd_internals.c +++ b/plugin/app2sd/server/app2sd_internals.c @@ -26,6 +26,7 @@ #include #include +#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; } diff --git a/plugin/app2sd/server/app2sd_internals.h b/plugin/app2sd/server/app2sd_internals.h index e0f8c40..b3ccfe3 100644 --- a/plugin/app2sd/server/app2sd_internals.h +++ b/plugin/app2sd/server/app2sd_internals.h @@ -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); diff --git a/plugin/app2sd/server/app2sd_internals_utils.c b/plugin/app2sd/server/app2sd_internals_utils.c index 678ace0..75425bc 100644 --- a/plugin/app2sd/server/app2sd_internals_utils.c +++ b/plugin/app2sd/server/app2sd_internals_utils.c @@ -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) {