Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] Add Key Management Enclaves with YubiKey and NanoPC-T6 Support #223

Open
wants to merge 1 commit into
base: 0.1.4-dogebox-pre
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 215 additions & 34 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,9 @@ qrtest.jpg
# Store
store/*
.store/*

# OPTEE
!/src/optee/Makefile
!/src/optee/host/Makefile
!/src/optee/ta/Makefile
/src/optee/build
50 changes: 41 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ SET(USE_AVX2 FALSE CACHE BOOL "enable intel avx2")
SET(USE_SSE FALSE CACHE BOOL "enable intel sse")
SET(USE_SSE2 FALSE CACHE BOOL "enable scrypt sse2")
SET(USE_TPM2 TRUE CACHE BOOL "enable tpm2")
SET(USE_OPENENCLAVE FALSE CACHE BOOL "enable openenclave")
SET(TEST_PASSWD FALSE CACHE BOOL "enable test password")
SET(USE_OPENENCLAVE TRUE CACHE BOOL "enable openenclave")
SET(USE_YUBIKEY FALSE CACHE BOOL "enable yubikey")
SET(TEST_PASSWD TRUE CACHE BOOL "enable test password")
string(RANDOM LENGTH 12 ALPHABET abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 PASSWD_STR)
SET(RANDOM_DEVICE "/dev/urandom" CACHE STRING "set the device to read random data from")

Expand Down Expand Up @@ -74,7 +75,26 @@ IF(WITH_NET)
FIND_LIBRARY(LIBEVENT NAMES event event_core event_extras event_pthreads HINTS "${PROJECT_SOURCE_DIR}/src/libevent/build/lib/${CMAKE_BUILD_TYPE}" REQUIRED)
FIND_LIBRARY(WINPTHREADS NAMES pthreadVC2 pthreadwin32 pthreads pthread HINTS "${PROJECT_SOURCE_DIR}/contrib/winpthreads/include/lib/x64/" REQUIRED)
ELSE()
FIND_LIBRARY(LIBEVENT event REQUIRED)
# build libevent
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/src/libevent/build)
execute_process(COMMAND cmake ..
-DCMAKE_C_FLAGS=-U_FORTIFY_SOURCE
-DEVENT__DISABLE_OPENSSL=ON
-DEVENT__DISABLE_SAMPLES=ON
-DEVENT__LIBRARY_TYPE=STATIC
-DEVENT__DISABLE_TESTS=ON
-DEVENT__DISABLE_THREAD_SUPPORT=OFF
-DEVENT__DISABLE_MM_REPLACEMENT=ON
-DEVENT__DISABLE_REGRESS=ON
-DEVENT__DISABLE_BENCHMARK=ON
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/libevent/build)
execute_process(COMMAND cmake --build .
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/libevent/build)
file(COPY "${PROJECT_SOURCE_DIR}/src/libevent/build/include" DESTINATION "${PROJECT_SOURCE_DIR}")
file(COPY "${PROJECT_SOURCE_DIR}/src/libevent/include/event2" DESTINATION "${PROJECT_SOURCE_DIR}/include")
find_path(LIBEVENT_INCLUDE_DIR event.h PATHS "${PROJECT_SOURCE_DIR}/include/event2" REQUIRED)
find_path(LIBEVENT_INCLUDE_DIR event-config.h PATHS "${PROJECT_SOURCE_DIR}/include/event2" REQUIRED)
FIND_LIBRARY(LIBEVENT NAMES event event_core event_extras event_pthreads HINTS "${PROJECT_SOURCE_DIR}/src/libevent/build/lib/${CMAKE_BUILD_TYPE}" REQUIRED)
FIND_LIBRARY(LIBUNISTRING unistring REQUIRED)
ENDIF()
ENDIF()
Expand Down Expand Up @@ -159,6 +179,10 @@ ENDIF()
IF(USE_OPENENCLAVE)
ADD_DEFINITIONS(-DUSE_OPENENCLAVE=1)
ENDIF()
IF(USE_YUBIKEY)
FIND_LIBRARY(LIBYKPIV NAMES ykpiv REQUIRED HINTS /usr/lib/x86_64-linux-gnu)
ADD_DEFINITIONS(-DUSE_YUBIKEY=1)
ENDIF()
IF(TEST_PASSWD)
ADD_DEFINITIONS(-DTEST_PASSWD=1)
ADD_DEFINITIONS(-DPASSWD_STR="${PASSWD_STR}")
Expand All @@ -184,6 +208,7 @@ MESSAGE(STATUS " ${PASSWD_STR}")
ENDIF()
MESSAGE(STATUS "")
MESSAGE(STATUS " openenclave = ${USE_OPENENCLAVE}")
MESSAGE(STATUS " yubikey = ${USE_YUBIKEY}")
MESSAGE(STATUS "")
message(STATUS " library type = ${library_type}")
MESSAGE(STATUS "")
Expand Down Expand Up @@ -325,6 +350,7 @@ IF(USE_TESTS)
test/rmd160_tests.c
test/scrypt_tests.c
test/serialize_tests.c
test/sha1_tests.c
test/sha2_tests.c
test/signmsg_tests.c
test/tpm_tests.c
Expand All @@ -335,10 +361,16 @@ IF(USE_TESTS)
test/utils_tests.c
test/vector_tests.c
)
IF (USE_YUBIKEY)
SET(LIBS ${LIBDOGECOIN_NAME} ${LIBUNISTRING} ${LIBYKPIV})
ELSE()
SET(LIBS ${LIBDOGECOIN_NAME} ${LIBUNISTRING})
ENDIF()

IF (WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(tests ${LIBDOGECOIN_NAME} ${LIBUNISTRING} tbs ncrypt crypt32)
TARGET_LINK_LIBRARIES(tests ${LIBS} tbs ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(tests ${LIBDOGECOIN_NAME} ${LIBUNISTRING})
TARGET_LINK_LIBRARIES(tests ${LIBS})
ENDIF()
ADD_TEST(NAME ${LIBDOGECOIN_NAME}_tests COMMAND tests)
# move test/wordlist to build
Expand Down Expand Up @@ -405,9 +437,9 @@ IF(WITH_NET)
)

IF(WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(${LIBDOGECOIN_NAME} ${LIBEVENT} ${LIBEVENT_PTHREADS} ${LIBUNISTRING} tbs ncrypt crypt32)
TARGET_LINK_LIBRARIES(${LIBS} ${LIBEVENT} ${LIBEVENT_PTHREADS} tbs ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(${LIBDOGECOIN_NAME} ${LIBEVENT} ${LIBEVENT_PTHREADS} ${LIBUNISTRING})
TARGET_LINK_LIBRARIES(${LIBS} ${LIBEVENT} ${LIBEVENT_PTHREADS})
ENDIF()
IF(USE_TESTS)
TARGET_SOURCES(tests ${visibility}
Expand All @@ -428,9 +460,9 @@ IF(WITH_TOOLS)
ADD_EXECUTABLE(such src/cli/such.c)
INSTALL(TARGETS such RUNTIME)
IF (WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(such ${LIBDOGECOIN_NAME} ${LIBUNISTRING} tbs ncrypt crypt32)
TARGET_LINK_LIBRARIES(such ${LIBS} tbs ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(such ${LIBDOGECOIN_NAME} ${LIBUNISTRING})
TARGET_LINK_LIBRARIES(such ${LIBS})
ENDIF()
TARGET_INCLUDE_DIRECTORIES(such ${visibility} src)

Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ tests_SOURCES = \
test/rmd160_tests.c \
test/scrypt_tests.c \
test/serialize_tests.c \
test/sha1_tests.c \
test/sha2_tests.c \
test/signmsg_tests.c \
test/tpm_tests.c \
Expand Down
28 changes: 28 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ AC_ARG_ENABLE([openenclave],
[use_openenclave=$enableval],
[use_openenclave=no])

AC_ARG_ENABLE([optee],
[AS_HELP_STRING([--enable-optee],
[Build with optee (default is no)])],
[use_optee=$enableval],
[use_optee=no])

AC_ARG_ENABLE([yubikey],
[AS_HELP_STRING([--enable-yubikey],
[Build with yubikey (default is no)])],
[use_yubikey=$enableval],
[use_yubikey=no])

AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
[use_tests=$enableval],
Expand Down Expand Up @@ -256,6 +268,16 @@ if test "x$use_openenclave" = xyes; then
AC_DEFINE(USE_OPENENCLAVE, 1, [Define this symbol if openenclave works])
fi

if test "x$use_optee" = xyes; then
AC_DEFINE_UNQUOTED([USE_OPTEE],[1],[Define this symbol if optee works])
fi

if test "x$use_yubikey" = xyes; then
AC_CHECK_LIB([ykpiv],[main],LIBYKPIV=-lykpiv,AC_MSG_ERROR(libpkpiv missing))
LIBS="$LIBS $LIBYKPIV"
AC_DEFINE(USE_YUBIKEY, 1, [Define this symbol if Yubikey works])
fi

AC_CONFIG_HEADERS([config/libdogecoin-config.h])
AC_CONFIG_FILES([Makefile libdogecoin.pc])
AC_SUBST(LIBTOOL_APP_LDFLAGS)
Expand All @@ -265,6 +287,7 @@ AC_SUBST(EVENT_CORE_LIBS)
AC_SUBST(EVENT_EXTRA_LIBS)
AC_SUBST(EVENT_PTHREADS_LIBS)
AC_SUBST(LIBUNISTRING)
AC_SUBST(LIBYKPIV)
AC_SUBST(NASMFLAGS)
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
AM_CONDITIONAL([WITH_BENCH], [test "x$with_bench" = "xyes"])
Expand All @@ -276,6 +299,8 @@ AM_CONDITIONAL([USE_AVX2], [test "x$use_intel_avx2" = "xyes"])
AM_CONDITIONAL([USE_SSE], [test "x$use_intel_sse" = "xyes"])
AM_CONDITIONAL([USE_SSE2], [test "x$use_scrypt_sse2" = "xyes"])
AM_CONDITIONAL([USE_OPENENCLAVE], [test "x$use_openenclave" = "xyes"])
AM_CONDITIONAL([USE_OPTEE], [test "x$use_optee" = "xyes"])
AM_CONDITIONAL([USE_YUBIKEY], [test "x$use_yubikey" = "xyes"])
AC_SUBST(LIB_VERSION_CURRENT, _LIB_VERSION_CURRENT)
AC_SUBST(LIB_VERSION_REVISION, _LIB_VERSION_REVISION)
AC_SUBST(LIB_VERSION_AGE, _LIB_VERSION_AGE)
Expand Down Expand Up @@ -304,6 +329,8 @@ echo " $PASSWD_STR"
fi
echo
echo " openenclave = $use_openenclave"
echo " optee = $use_optee"
echo " Yubikey = $use_yubikey"
echo
echo " host = $host"
echo " target os = $TARGET_OS"
Expand All @@ -314,4 +341,5 @@ echo " CFLAGS = $CFLAGS"
echo " CXX = $CXX"
echo " CXXFLAGS = $CXXFLAGS"
echo " LDFLAGS = $LDFLAGS"
echo " LIBS = $LIBS"
echo
35 changes: 29 additions & 6 deletions contrib/examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,22 +259,36 @@ int main() {
printf("Master public key: %s\n", master_public_key);

// Derive an extended normal (non-hardened) public key
char extkeypath[KEYPATHMAXLEN] = "m/0/0/0/0/0";
char extkeypath[KEYPATHMAXLEN] = "m/44'/3'/0'";
char extpubkey[HDKEYLEN] = {0};
getHDNodeAndExtKeyByPath(master_public_key, extkeypath, extpubkey, false);
printf("Keypath: %s\nExtended public key: %s\n", extkeypath, extpubkey);
if (strcmp(extpubkey, "dgub8wcWPRxhthgZYftisbirNJ5Ae3navJCCEfd6SzyL5SK44GC4tok3BGkNWbhrM4KeJ8o9ZAkXiVdLTnUyzz89ah1izJjWTo5pv7eboGtzktJ") != 0) {
dogecoin_hdnode* node_bypath = getHDNodeAndExtKeyByPath(masterkey, extkeypath, extpubkey, false);
printf("(Account) Extended public key: %s\n", extpubkey);
if (strcmp(extpubkey, "dgub8rUhDtD3YFGZTUphBfpBbzvFxSMKQXYLzg87Me2ta78r2SdVLmypBUkkxrrn9RTnchsyiJSkHZyLWxD13ibBiXtuFWktBoDaGaZjQUBLNLs") != 0) {
printf("extpubkey does not match!\n");
}
dogecoin_hdnode_free(node_bypath);

// Derive an address from the extended public key
char derived_address2[P2PKHLEN];
if (getDerivedHDAddressFromAcctPubKey(extpubkey, 0, BIP44_CHANGE_EXTERNAL, derived_address2, false) == 0) {
printf("(Account) Extended public key: %s\n", extpubkey);
if (strcmp(extpubkey, "dgub8rUhDtD3YFGZTUphBfpBbzvFxSMKQXYLzg87Me2ta78r2SdVLmypBUkkxrrn9RTnchsyiJSkHZyLWxD13ibBiXtuFWktBoDaGaZjQUBLNLs") != 0) {
printf("extpubkey does not match!\n");
}
printf("Derived address 0: %s\n", derived_address2);
} else {
printf("Error occurred.\n");
return -1;
}

// BASIC TRANSACTION FORMATION EXAMPLE
printf("\n\nBEGIN TRANSACTION FORMATION AND SIGNING:\n\n");
// declare keys and previous hashes
char *external_p2pkh_addr = "nbGfXLskPh7eM1iG5zz5EfDkkNTo9TRmde";
char *hash_2_doge = "b4455e7b7b7acb51fb6feba7a2702c42a5100f61f61abafa31851ed6ae076074";
char *hash_10_doge = "42113bdc65fc2943cf0359ea1a24ced0b6b0b5290db4c63a3329c6601c4616e2";
char myscriptpubkey [PUBKEYHASHLEN];
dogecoin_p2pkh_address_to_pubkey_hash (str, myscriptpubkey);
char myscriptpubkey [PUBKEYHASHLEN];
dogecoin_p2pkh_address_to_pubkey_hash (str, myscriptpubkey);

// build transaction
int idx = start_transaction();
Expand Down Expand Up @@ -314,6 +328,15 @@ int main() {
return -1;
}

printf("Transaction hex: %s\n", get_raw_transaction(idx));
printf("Transaction hex length: %ld\n", strlen(get_raw_transaction(idx)));
printf("Transaction unsigned hex: %s\n", get_raw_transaction(idx2));
printf("Transaction unsigned hex length: %ld\n", strlen(get_raw_transaction(idx2)));
printf("str: %s\n", str);
printf("my script pubkey: %s\n", myscriptpubkey);
printf("my script pubkey length: %ld\n", strlen(myscriptpubkey));
printf("privkeywif: %s\n", wifstr);

// sign transaction
if (sign_transaction(idx, myscriptpubkey, wifstr)) {
printf("\nAll transaction inputs signed successfully. \nFinal transaction hex: %s\n.", get_raw_transaction(idx));
Expand Down
22 changes: 22 additions & 0 deletions depends/packages/libusb.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package=libusb
$(package)_version=1.0.27
$(package)_download_path=https://github.com/libusb/libusb/releases/download/v1.0.27
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
$(package)_sha256_hash=ffaa41d741a8a3bee244ac8e54a72ea05bf2879663c098c82fc5757853441575

define $(package)_set_vars
$(package)_config_opts=--disable-shared --enable-static --disable-udev
$(package)_config_opts_mingw32=--enable-threads=windows
endef

define $(package)_config_cmds
$($(package)_autoconf) CFLAGS="-fPIC"
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
22 changes: 22 additions & 0 deletions depends/packages/libyubikey.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package=libyubikey
$(package)_version=1.13
$(package)_download_path=https://developers.yubico.com/yubico-c/Releases
$(package)_file_name=libyubikey-$($(package)_version).tar.gz
$(package)_sha256_hash=04edd0eb09cb665a05d808c58e1985f25bb7c5254d2849f36a0658ffc51c3401

define $(package)_set_vars
$(package)_config_opts=--disable-shared --enable-static
$(package)_config_opts_mingw32=--enable-threads=windows
endef

define $(package)_config_cmds
$($(package)_autoconf) CFLAGS="-fPIC"
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
4 changes: 2 additions & 2 deletions depends/packages/packages.mk
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
packages:=libevent libunistring
packages:=libevent libunistring libyubikey libusb ykpers
native_packages := native_ccache

wallet_packages=

upnp_packages=

darwin_native_packages =
darwin_native_packages =

ifneq ($(build_os),darwin)
darwin_native_packages += native_cctools native_libtapi
Expand Down
29 changes: 29 additions & 0 deletions depends/packages/ykpers.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package=ykpers
$(package)_version=1.20.0
$(package)_download_path=https://developers.yubico.com/yubikey-personalization/Releases
$(package)_file_name=ykpers-$($(package)_version).tar.gz
$(package)_sha256_hash=0ec84d0ea862f45a7d85a1a3afe5e60b8da42df211bb7d27a50f486e31a79b93
$(package)_dependencies=libyubikey libusb
$(package)_patches=ykpers-args.patch

define $(package)_set_vars
$(package)_config_opts=--disable-shared --enable-static --with-backend=libusb-1.0
$(package)_config_opts_mingw32=--enable-threads=windows
$(package)_ldflags_darwin=-framework CoreFoundation -framework IOKit -framework Security
endef

define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/ykpers-args.patch
endef

define $(package)_config_cmds
$($(package)_autoconf) CFLAGS="-fPIC" LIBUSB_CFLAGS="-I$(host_prefix)/include/libusb-1.0" LIBUSB_LIBS="-L$(host_prefix)/lib -lusb-1.0"
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
13 changes: 13 additions & 0 deletions depends/patches/ykpers/ykpers-args.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- a/ykpers-args.h
+++ b/ykpers-args.h
@@ -33,8 +33,8 @@

#include "ykpers.h"

-const char *usage;
-const char *optstring;
+extern const char *usage;
+extern const char *optstring;

int args_to_config(int argc, char **argv, YKP_CONFIG *cfg, char *oathid,
size_t oathid_len, const char **infname,
Loading
Loading