mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 21:13:12 -07:00
Add Nintendo Switch chiaki-lib support (#233)
This commit is contained in:
parent
6d02714d0e
commit
f35311bf61
19 changed files with 771 additions and 20 deletions
|
@ -7,7 +7,9 @@ option(CHIAKI_ENABLE_TESTS "Enable tests for Chiaki" ON)
|
||||||
option(CHIAKI_ENABLE_CLI "Enable CLI for Chiaki" OFF)
|
option(CHIAKI_ENABLE_CLI "Enable CLI for Chiaki" OFF)
|
||||||
option(CHIAKI_ENABLE_GUI "Enable Qt GUI" ON)
|
option(CHIAKI_ENABLE_GUI "Enable Qt GUI" ON)
|
||||||
option(CHIAKI_ENABLE_ANDROID "Enable Android (Use only as part of the Gradle Project)" OFF)
|
option(CHIAKI_ENABLE_ANDROID "Enable Android (Use only as part of the Gradle Project)" OFF)
|
||||||
|
option(CHIAKI_ENABLE_SWITCH "Enable Nintendo Switch (Requires devKitPro libnx)" OFF)
|
||||||
option(CHIAKI_LIB_ENABLE_OPUS "Use Opus as part of Chiaki Lib" ON)
|
option(CHIAKI_LIB_ENABLE_OPUS "Use Opus as part of Chiaki Lib" ON)
|
||||||
|
option(CHIAKI_LIB_ENABLE_MBEDTLS "Use mbedtls instead of OpenSSL as part of Chiaki Lib" OFF)
|
||||||
option(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT "Use OpenSSL as CMake external project" OFF)
|
option(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT "Use OpenSSL as CMake external project" OFF)
|
||||||
option(CHIAKI_GUI_ENABLE_QT_GAMEPAD "Use QtGamepad for Input" OFF)
|
option(CHIAKI_GUI_ENABLE_QT_GAMEPAD "Use QtGamepad for Input" OFF)
|
||||||
option(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER "Use SDL Gamecontroller for Input" ON)
|
option(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER "Use SDL Gamecontroller for Input" ON)
|
||||||
|
@ -30,6 +32,22 @@ include(CPack)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
# configure nintendo switch toolchain
|
||||||
|
if(CHIAKI_ENABLE_SWITCH AND CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
# CHIAKI_ENABLE_SWITCH_LINUX is a special testing version
|
||||||
|
# the aim is to troubleshoot nitendo switch chiaki verison
|
||||||
|
# from a x86 linux os
|
||||||
|
add_definitions(-DCHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
elseif(CHIAKI_ENABLE_SWITCH)
|
||||||
|
add_definitions(-D__SWITCH__)
|
||||||
|
# load switch.cmake toolchain form ./cmake folder
|
||||||
|
include(switch)
|
||||||
|
# TODO check if android ... or other versions are enabled
|
||||||
|
# force mbedtls as crypto lib
|
||||||
|
set(CHIAKI_LIB_ENABLE_MBEDTLS ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(third-party)
|
add_subdirectory(third-party)
|
||||||
|
|
||||||
add_definitions(-DCHIAKI_VERSION_MAJOR=${CHIAKI_VERSION_MAJOR} -DCHIAKI_VERSION_MINOR=${CHIAKI_VERSION_MINOR} -DCHIAKI_VERSION_PATCH=${CHIAKI_VERSION_PATCH} -DCHIAKI_VERSION=\"${CHIAKI_VERSION}\")
|
add_definitions(-DCHIAKI_VERSION_MAJOR=${CHIAKI_VERSION_MAJOR} -DCHIAKI_VERSION_MINOR=${CHIAKI_VERSION_MINOR} -DCHIAKI_VERSION_PATCH=${CHIAKI_VERSION_PATCH} -DCHIAKI_VERSION=\"${CHIAKI_VERSION}\")
|
||||||
|
@ -38,6 +56,10 @@ if(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT)
|
||||||
include(OpenSSLExternalProject)
|
include(OpenSSLExternalProject)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
add_definitions(-DCHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
|
|
||||||
if(CHIAKI_ENABLE_CLI)
|
if(CHIAKI_ENABLE_CLI)
|
||||||
|
@ -56,3 +78,8 @@ endif()
|
||||||
if(CHIAKI_ENABLE_ANDROID)
|
if(CHIAKI_ENABLE_ANDROID)
|
||||||
add_subdirectory(android/app)
|
add_subdirectory(android/app)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CHIAKI_ENABLE_SWITCH)
|
||||||
|
#TODO
|
||||||
|
#add_subdirectory(switch)
|
||||||
|
endif()
|
||||||
|
|
99
cmake/switch.cmake
Normal file
99
cmake/switch.cmake
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# https://github.com/nxengine/nxengine-evo
|
||||||
|
|
||||||
|
# Find DEVKITPRO
|
||||||
|
if(NOT DEFINED ENV{DEVKITPRO})
|
||||||
|
message(FATAL_ERROR "You must have defined DEVKITPRO before calling cmake.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(DEVKITPRO $ENV{DEVKITPRO})
|
||||||
|
|
||||||
|
function(switchvar cmakevar var default)
|
||||||
|
# read or set env var
|
||||||
|
if(NOT DEFINED "ENV{$var}")
|
||||||
|
set("ENV{$var}" default)
|
||||||
|
endif()
|
||||||
|
set("$cmakevar" "ENV{$var}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# allow gcc -g to use
|
||||||
|
# aarch64-none-elf-addr2line -e build_switch/switch/chiaki -f -p -C -a 0xCCB5C
|
||||||
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
|
||||||
|
set( TOOL_OS_SUFFIX "" )
|
||||||
|
if( CMAKE_HOST_WIN32 )
|
||||||
|
set( TOOL_OS_SUFFIX ".exe" )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "armv8-a")
|
||||||
|
set(CMAKE_C_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
|
||||||
|
set(CMAKE_CXX_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
|
||||||
|
set(CMAKE_ASM_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-as${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
|
||||||
|
set(CMAKE_STRIP "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip")
|
||||||
|
set(CMAKE_AR "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive")
|
||||||
|
set(CMAKE_LINKER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker")
|
||||||
|
set(CMAKE_NM "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm")
|
||||||
|
set(CMAKE_OBJCOPY "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy")
|
||||||
|
set(CMAKE_OBJDUMP "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump")
|
||||||
|
set(CMAKE_RANLIB "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib")
|
||||||
|
|
||||||
|
# custom /opt/devkitpro/switchvars.sh
|
||||||
|
switchvar(PORTLIBS_PREFIX PORTLIBS_PREFIX "${DEVKITPRO}/portlibs/switch")
|
||||||
|
switchvar(ARCH ARCH "-march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec")
|
||||||
|
switchvar(CMAKE_C_FLAGS CFLAGS "${ARCH} -O2 -ffunction-sections -fdata-sections")
|
||||||
|
switchvar(CMAKE_CXX_FLAGS CXXFLAGS "${CMAKE_C_FLAGS}")
|
||||||
|
switchvar(CMAKE_CPP_FLAGS CPPFLAGS "-D__SWITCH__ -I${PORTLIBS_PREFIX}/include -isystem${DEVKITPRO}/libnx/include")
|
||||||
|
switchvar(CMAKE_LD_FLAGS LDFLAGS "${ARCH} -L${PORTLIBS_PREFIX}/lib -L${DEVKITPRO}/libnx/lib")
|
||||||
|
switchvar(LIBS LIBS "-lnx")
|
||||||
|
|
||||||
|
# switchvar(CMAKE_CXX_FLAGS CXXFLAGS "${CMAKE_C_FLAGS} -fno-rtti")
|
||||||
|
include_directories(${DEVKITPRO}/libnx/include ${PORTLIBS_PREFIX}/include)
|
||||||
|
|
||||||
|
# where is the target environment
|
||||||
|
set(CMAKE_FIND_ROOT_PATH
|
||||||
|
${DEVKITPRO}/devkitA64
|
||||||
|
${DEVKITPRO}/libnx
|
||||||
|
${DEVKITPRO}/portlibs/switch)
|
||||||
|
|
||||||
|
# only search for libraries and includes in toolchain
|
||||||
|
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
|
||||||
|
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
|
||||||
|
|
||||||
|
find_program(ELF2NRO elf2nro ${DEVKITPRO}/tools/bin)
|
||||||
|
if (ELF2NRO)
|
||||||
|
message(STATUS "elf2nro: ${ELF2NRO} - found")
|
||||||
|
else ()
|
||||||
|
message(WARNING "elf2nro - not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
find_program(NACPTOOL nacptool ${DEVKITPRO}/tools/bin)
|
||||||
|
if (NACPTOOL)
|
||||||
|
message(STATUS "nacptool: ${NACPTOOL} - found")
|
||||||
|
else ()
|
||||||
|
message(WARNING "nacptool - not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
function(__add_nacp target APP_TITLE APP_AUTHOR APP_VERSION)
|
||||||
|
set(__NACP_COMMAND ${NACPTOOL} --create ${APP_TITLE} ${APP_AUTHOR} ${APP_VERSION} ${CMAKE_CURRENT_BINARY_DIR}/${target})
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}
|
||||||
|
COMMAND ${__NACP_COMMAND}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(add_nro_target target title author version icon romfs)
|
||||||
|
get_filename_component(target_we ${target} NAME_WE)
|
||||||
|
if (NOT ${target_we}.nacp)
|
||||||
|
__add_nacp(${target_we}.nacp ${title} ${author} ${version})
|
||||||
|
endif ()
|
||||||
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.nro
|
||||||
|
COMMAND ${ELF2NRO} $<TARGET_FILE:${target}> ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.nro --icon=${icon} --nacp=${CMAKE_CURRENT_BINARY_DIR}/${target_we}.nacp
|
||||||
|
# --romfsdir=${romfs}
|
||||||
|
DEPENDS ${target} ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.nacp
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
add_custom_target(${target_we}_nro ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.nro)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
|
@ -99,16 +99,26 @@ target_include_directories(chiaki-lib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/includ
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(chiaki-lib Threads::Threads)
|
target_link_libraries(chiaki-lib Threads::Threads)
|
||||||
|
|
||||||
if(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT)
|
if(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
# provided by mbedtls-static (mbedtls-devel)
|
||||||
|
# find_package(mbedcrypto REQUIRED)
|
||||||
|
target_link_libraries(chiaki-lib mbedtls mbedx509 mbedcrypto)
|
||||||
|
elseif(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT)
|
||||||
target_link_libraries(chiaki-lib OpenSSL_Crypto)
|
target_link_libraries(chiaki-lib OpenSSL_Crypto)
|
||||||
else()
|
else()
|
||||||
|
# default
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
target_link_libraries(chiaki-lib OpenSSL::Crypto)
|
target_link_libraries(chiaki-lib OpenSSL::Crypto)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CHIAKI_ENABLE_SWITCH AND NOT CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
# to provides csrngGetRandomBytes
|
||||||
|
target_link_libraries(chiaki-lib nx)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(chiaki-lib protobuf-nanopb-static)
|
target_link_libraries(chiaki-lib protobuf-nanopb-static)
|
||||||
target_link_libraries(chiaki-lib jerasure)
|
target_link_libraries(chiaki-lib jerasure)
|
||||||
|
|
||||||
if(CHIAKI_LIB_ENABLE_OPUS)
|
if(CHIAKI_LIB_ENABLE_OPUS)
|
||||||
target_link_libraries(chiaki-lib ${Opus_LIBRARIES})
|
target_link_libraries(chiaki-lib ${Opus_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -27,12 +27,28 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
#include "mbedtls/ecdh.h"
|
||||||
|
#include "mbedtls/ctr_drbg.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CHIAKI_ECDH_SECRET_SIZE 32
|
#define CHIAKI_ECDH_SECRET_SIZE 32
|
||||||
|
|
||||||
typedef struct chiaki_ecdh_t
|
typedef struct chiaki_ecdh_t
|
||||||
{
|
{
|
||||||
|
// the following lines may lead to memory corruption
|
||||||
|
// __SWITCH__ or CHIAKI_LIB_ENABLE_MBEDTLS must be defined
|
||||||
|
// globally (whole project)
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
// mbedtls ecdh context
|
||||||
|
mbedtls_ecdh_context ctx;
|
||||||
|
// deterministic random bit generator
|
||||||
|
mbedtls_ctr_drbg_context drbg;
|
||||||
|
#else
|
||||||
struct ec_group_st *group;
|
struct ec_group_st *group;
|
||||||
struct ec_key_st *key_local;
|
struct ec_key_st *key_local;
|
||||||
|
#endif
|
||||||
} ChiakiECDH;
|
} ChiakiECDH;
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh);
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh);
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -36,6 +38,15 @@ typedef struct chiaki_stop_pipe_t
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSAEVENT event;
|
WSAEVENT event;
|
||||||
|
#elif defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
// due to a lack pipe/event/socketpair
|
||||||
|
// on switch env, we use a physical socket
|
||||||
|
// to send/trigger the cancel signal
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
// local stop socket file descriptor
|
||||||
|
// this fd is audited by 'select' as
|
||||||
|
// fd_set *readfds
|
||||||
|
int fd;
|
||||||
#else
|
#else
|
||||||
int fds[2];
|
int fds[2];
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void chiaki_audio_header_load(ChiakiAudioHeader *audio_header, const uint8_t *buf)
|
void chiaki_audio_header_load(ChiakiAudioHeader *audio_header, const uint8_t *buf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,7 +127,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery,
|
||||||
|
|
||||||
discovery->log = log;
|
discovery->log = log;
|
||||||
|
|
||||||
discovery->socket = socket(AF_INET, SOCK_DGRAM, 0);
|
discovery->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if(CHIAKI_SOCKET_IS_INVALID(discovery->socket))
|
if(CHIAKI_SOCKET_IS_INVALID(discovery->socket))
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(discovery->log, "Discovery failed to create socket");
|
CHIAKI_LOGE(discovery->log, "Discovery failed to create socket");
|
||||||
|
@ -138,9 +138,13 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery,
|
||||||
discovery->local_addr.sa_family = family;
|
discovery->local_addr.sa_family = family;
|
||||||
if(family == AF_INET6)
|
if(family == AF_INET6)
|
||||||
{
|
{
|
||||||
|
#ifndef __SWITCH__
|
||||||
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
|
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
|
||||||
|
#endif
|
||||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&discovery->local_addr;
|
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&discovery->local_addr;
|
||||||
|
#ifndef __SWITCH__
|
||||||
addr->sin6_addr = anyaddr;
|
addr->sin6_addr = anyaddr;
|
||||||
|
#endif
|
||||||
addr->sin6_port = htons(0);
|
addr->sin6_port = htons(0);
|
||||||
}
|
}
|
||||||
else // AF_INET
|
else // AF_INET
|
||||||
|
|
134
lib/src/ecdh.c
134
lib/src/ecdh.c
|
@ -19,23 +19,58 @@
|
||||||
#include <chiaki/ecdh.h>
|
#include <chiaki/ecdh.h>
|
||||||
#include <chiaki/base64.h>
|
#include <chiaki/base64.h>
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
#include "mbedtls/entropy.h"
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
#else
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ecdh.h>
|
#include <openssl/ecdh.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// memset
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh)
|
||||||
{
|
{
|
||||||
memset(ecdh, 0, sizeof(ChiakiECDH));
|
memset(ecdh, 0, sizeof(ChiakiECDH));
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
#define CHECK(err) if((err) != 0) { \
|
||||||
|
chiaki_ecdh_fini(ecdh); \
|
||||||
|
return CHIAKI_ERR_UNKNOWN; }
|
||||||
|
// mbedtls ecdh example:
|
||||||
|
// https://github.com/ARMmbed/mbedtls/blob/development/programs/pkey/ecdh_curve25519.c
|
||||||
|
const char pers[] = "ecdh";
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
//init RNG Seed context
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
// init local key
|
||||||
|
//mbedtls_ecp_keypair_init(&ecdh->key_local);
|
||||||
|
mbedtls_ecdh_init(&ecdh->ctx);
|
||||||
|
// init ecdh group
|
||||||
|
// keep rng context in ecdh for later reuse
|
||||||
|
mbedtls_ctr_drbg_init(&ecdh->drbg);
|
||||||
|
|
||||||
|
// build RNG seed
|
||||||
|
CHECK(mbedtls_ctr_drbg_seed(&ecdh->drbg, mbedtls_entropy_func, &entropy,
|
||||||
|
(const unsigned char *) pers, sizeof pers));
|
||||||
|
|
||||||
|
// build MBEDTLS_ECP_DP_SECP256K1 group
|
||||||
|
CHECK(mbedtls_ecp_group_load(&ecdh->ctx.grp, MBEDTLS_ECP_DP_SECP256K1));
|
||||||
|
// build key
|
||||||
|
CHECK(mbedtls_ecdh_gen_public(&ecdh->ctx.grp, &ecdh->ctx.d,
|
||||||
|
&ecdh->ctx.Q, mbedtls_ctr_drbg_random, &ecdh->drbg));
|
||||||
|
|
||||||
|
// relese entropy ptr
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
#undef CHECK
|
||||||
|
|
||||||
|
#else
|
||||||
#define CHECK(a) if(!(a)) { chiaki_ecdh_fini(ecdh); return CHIAKI_ERR_UNKNOWN; }
|
#define CHECK(a) if(!(a)) { chiaki_ecdh_fini(ecdh); return CHIAKI_ERR_UNKNOWN; }
|
||||||
|
|
||||||
CHECK(ecdh->group = EC_GROUP_new_by_curve_name(NID_secp256k1));
|
CHECK(ecdh->group = EC_GROUP_new_by_curve_name(NID_secp256k1));
|
||||||
|
|
||||||
CHECK(ecdh->key_local = EC_KEY_new());
|
CHECK(ecdh->key_local = EC_KEY_new());
|
||||||
|
@ -43,19 +78,53 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh)
|
||||||
CHECK(EC_KEY_generate_key(ecdh->key_local));
|
CHECK(EC_KEY_generate_key(ecdh->key_local));
|
||||||
|
|
||||||
#undef CHECK
|
#undef CHECK
|
||||||
|
#endif
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT void chiaki_ecdh_fini(ChiakiECDH *ecdh)
|
CHIAKI_EXPORT void chiaki_ecdh_fini(ChiakiECDH *ecdh)
|
||||||
{
|
{
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
mbedtls_ecdh_free(&ecdh->ctx);
|
||||||
|
mbedtls_ctr_drbg_free(&ecdh->drbg);
|
||||||
|
#else
|
||||||
EC_KEY_free(ecdh->key_local);
|
EC_KEY_free(ecdh->key_local);
|
||||||
EC_GROUP_free(ecdh->group);
|
EC_GROUP_free(ecdh->group);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_set_local_key(ChiakiECDH *ecdh, const uint8_t *private_key, size_t private_key_size, const uint8_t *public_key, size_t public_key_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_set_local_key(ChiakiECDH *ecdh, const uint8_t *private_key, size_t private_key_size, const uint8_t *public_key, size_t public_key_size)
|
||||||
{
|
{
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
//https://tls.mbed.org/discussions/generic/publickey-binary-data-in-der
|
||||||
|
// Load keys from buffers (i.e: config file)
|
||||||
|
// TODO test
|
||||||
|
|
||||||
|
// public
|
||||||
|
int r = 0;
|
||||||
|
r = mbedtls_ecp_point_read_binary(&ecdh->ctx.grp, &ecdh->ctx.Q,
|
||||||
|
public_key, public_key_size);
|
||||||
|
if(r != 0 ){
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// secret
|
||||||
|
r = mbedtls_mpi_read_binary(&ecdh->ctx.d, private_key, private_key_size);
|
||||||
|
if(r != 0 ){
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// regen key
|
||||||
|
r = mbedtls_ecdh_gen_public(&ecdh->ctx.grp, &ecdh->ctx.d,
|
||||||
|
&ecdh->ctx.Q, mbedtls_ctr_drbg_random, &ecdh->drbg);
|
||||||
|
if(r != 0 ){
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
#else
|
||||||
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
|
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
BIGNUM *private_key_bn = BN_bin2bn(private_key, (int)private_key_size, NULL);
|
BIGNUM *private_key_bn = BN_bin2bn(private_key, (int)private_key_size, NULL);
|
||||||
|
@ -92,10 +161,40 @@ error_pub:
|
||||||
error_priv:
|
error_priv:
|
||||||
BN_free(private_key_bn);
|
BN_free(private_key_bn);
|
||||||
return err;
|
return err;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_get_local_pub_key(ChiakiECDH *ecdh, uint8_t *key_out, size_t *key_out_size, const uint8_t *handshake_key, uint8_t *sig_out, size_t *sig_out_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_get_local_pub_key(ChiakiECDH *ecdh, uint8_t *key_out, size_t *key_out_size, const uint8_t *handshake_key, uint8_t *sig_out, size_t *sig_out_size)
|
||||||
{
|
{
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
mbedtls_md_context_t ctx;
|
||||||
|
mbedtls_md_init(&ctx);
|
||||||
|
|
||||||
|
#define GOTO_ERROR(err) do { \
|
||||||
|
if((err) !=0){ \
|
||||||
|
goto error; \
|
||||||
|
}} while(0)
|
||||||
|
// extract pub key to build dh shared secret
|
||||||
|
// this key is sent to the remote server
|
||||||
|
GOTO_ERROR(mbedtls_ecp_point_write_binary( &ecdh->ctx.grp, &ecdh->ctx.Q,
|
||||||
|
MBEDTLS_ECP_PF_UNCOMPRESSED, key_out_size, key_out, *key_out_size ));
|
||||||
|
|
||||||
|
// https://tls.mbed.org/module-level-design-hashing
|
||||||
|
// HMAC
|
||||||
|
GOTO_ERROR(mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256) , 1));
|
||||||
|
GOTO_ERROR(mbedtls_md_hmac_starts(&ctx, handshake_key, CHIAKI_HANDSHAKE_KEY_SIZE));
|
||||||
|
GOTO_ERROR(mbedtls_md_hmac_update(&ctx, key_out, *key_out_size));
|
||||||
|
GOTO_ERROR(mbedtls_md_hmac_finish(&ctx, sig_out));
|
||||||
|
// SHA256 = 8*32
|
||||||
|
*sig_out_size = 32;
|
||||||
|
#undef GOTO_ERROR
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
#else
|
||||||
const EC_POINT *point = EC_KEY_get0_public_key(ecdh->key_local);
|
const EC_POINT *point = EC_KEY_get0_public_key(ecdh->key_local);
|
||||||
if(!point)
|
if(!point)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
@ -106,12 +205,40 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_get_local_pub_key(ChiakiECDH *ecdh, ui
|
||||||
|
|
||||||
if(!HMAC(EVP_sha256(), handshake_key, CHIAKI_HANDSHAKE_KEY_SIZE, key_out, *key_out_size, sig_out, (unsigned int *)sig_out_size))
|
if(!HMAC(EVP_sha256(), handshake_key, CHIAKI_HANDSHAKE_KEY_SIZE, key_out, *key_out_size, sig_out, (unsigned int *)sig_out_size))
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_derive_secret(ChiakiECDH *ecdh, uint8_t *secret_out, const uint8_t *remote_key, size_t remote_key_size, const uint8_t *handshake_key, const uint8_t *remote_sig, size_t remote_sig_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_derive_secret(ChiakiECDH *ecdh, uint8_t *secret_out, const uint8_t *remote_key, size_t remote_key_size, const uint8_t *handshake_key, const uint8_t *remote_sig, size_t remote_sig_size)
|
||||||
{
|
{
|
||||||
|
//compute DH shared key
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
// https://github.com/ARMmbed/mbedtls/blob/development/programs/pkey/ecdh_curve25519.c#L151
|
||||||
|
#define GOTO_ERROR(err) do { \
|
||||||
|
if((err) !=0){ \
|
||||||
|
goto error;} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
GOTO_ERROR(mbedtls_mpi_lset(&ecdh->ctx.Qp.Z, 1));
|
||||||
|
// load Qp point form remote PK
|
||||||
|
GOTO_ERROR(mbedtls_ecp_point_read_binary(&ecdh->ctx.grp,
|
||||||
|
&ecdh->ctx.Qp, remote_key, remote_key_size));
|
||||||
|
|
||||||
|
// build shared secret (diffie-hellman)
|
||||||
|
GOTO_ERROR(mbedtls_ecdh_compute_shared(&ecdh->ctx.grp,
|
||||||
|
&ecdh->ctx.z, &ecdh->ctx.Qp, &ecdh->ctx.d,
|
||||||
|
mbedtls_ctr_drbg_random, &ecdh->drbg));
|
||||||
|
|
||||||
|
// export shared secret to data buffer
|
||||||
|
GOTO_ERROR(mbedtls_mpi_write_binary(&ecdh->ctx.z,
|
||||||
|
secret_out, CHIAKI_ECDH_SECRET_SIZE));
|
||||||
|
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
error:
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
|
||||||
|
#else
|
||||||
EC_POINT *remote_public_key = EC_POINT_new(ecdh->group);
|
EC_POINT *remote_public_key = EC_POINT_new(ecdh->group);
|
||||||
if(!remote_public_key)
|
if(!remote_public_key)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
@ -130,4 +257,5 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_derive_secret(ChiakiECDH *ecdh, uint8_
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,16 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
#include "mbedtls/gcm.h"
|
||||||
|
#include "mbedtls/sha256.h"
|
||||||
|
#else
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
@ -69,7 +76,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_init(ChiakiGKCrypt *gkcrypt, Chiaki
|
||||||
{
|
{
|
||||||
gkcrypt->key_buf = NULL;
|
gkcrypt->key_buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gkcrypt_gen_key_iv(gkcrypt, index, handshake_key, ecdh_secret);
|
err = gkcrypt_gen_key_iv(gkcrypt, index, handshake_key, ecdh_secret);
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -132,9 +138,37 @@ static ChiakiErrorCode gkcrypt_gen_key_iv(ChiakiGKCrypt *gkcrypt, uint8_t index,
|
||||||
|
|
||||||
uint8_t hmac[CHIAKI_GKCRYPT_BLOCK_SIZE*2];
|
uint8_t hmac[CHIAKI_GKCRYPT_BLOCK_SIZE*2];
|
||||||
size_t hmac_size = sizeof(hmac);
|
size_t hmac_size = sizeof(hmac);
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
mbedtls_md_context_t ctx;
|
||||||
|
mbedtls_md_init(&ctx);
|
||||||
|
|
||||||
|
if(mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256) , 1) != 0){
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbedtls_md_hmac_starts(&ctx, ecdh_secret, CHIAKI_ECDH_SECRET_SIZE) != 0){
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbedtls_md_hmac_update(&ctx, data, sizeof(data)) != 0){
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbedtls_md_hmac_finish(&ctx, hmac) != 0){
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
|
||||||
|
#else
|
||||||
if(!HMAC(EVP_sha256(), ecdh_secret, CHIAKI_ECDH_SECRET_SIZE, data, sizeof(data), hmac, (unsigned int *)&hmac_size))
|
if(!HMAC(EVP_sha256(), ecdh_secret, CHIAKI_ECDH_SECRET_SIZE, data, sizeof(data), hmac, (unsigned int *)&hmac_size))
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
|
||||||
|
#endif
|
||||||
assert(hmac_size == sizeof(hmac));
|
assert(hmac_size == sizeof(hmac));
|
||||||
|
|
||||||
memcpy(gkcrypt->key_base, hmac, CHIAKI_GKCRYPT_BLOCK_SIZE);
|
memcpy(gkcrypt->key_base, hmac, CHIAKI_GKCRYPT_BLOCK_SIZE);
|
||||||
|
@ -164,7 +198,14 @@ CHIAKI_EXPORT void chiaki_gkcrypt_gen_gmac_key(uint64_t index, const uint8_t *ke
|
||||||
memcpy(data, key_base, 0x10);
|
memcpy(data, key_base, 0x10);
|
||||||
counter_add(data + 0x10, iv, index * CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_IV_OFFSET);
|
counter_add(data + 0x10, iv, index * CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_IV_OFFSET);
|
||||||
uint8_t md[0x20];
|
uint8_t md[0x20];
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
// last param
|
||||||
|
// is224 Determines which function to use.
|
||||||
|
// This must be either 0 for SHA-256, or 1 for SHA-224.
|
||||||
|
mbedtls_sha256_ret(data, sizeof(data), md, 0);
|
||||||
|
#else
|
||||||
SHA256(data, 0x20, md);
|
SHA256(data, 0x20, md);
|
||||||
|
#endif
|
||||||
xor_bytes(md, md + 0x10, 0x10);
|
xor_bytes(md, md + 0x10, 0x10);
|
||||||
memcpy(key_out, md, CHIAKI_GKCRYPT_BLOCK_SIZE);
|
memcpy(key_out, md, CHIAKI_GKCRYPT_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -189,6 +230,17 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcry
|
||||||
assert(key_pos % CHIAKI_GKCRYPT_BLOCK_SIZE == 0);
|
assert(key_pos % CHIAKI_GKCRYPT_BLOCK_SIZE == 0);
|
||||||
assert(buf_size % CHIAKI_GKCRYPT_BLOCK_SIZE == 0);
|
assert(buf_size % CHIAKI_GKCRYPT_BLOCK_SIZE == 0);
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
// build mbedtls aes context
|
||||||
|
mbedtls_aes_context ctx;
|
||||||
|
mbedtls_aes_init(&ctx);
|
||||||
|
|
||||||
|
if(mbedtls_aes_setkey_enc(&ctx, gkcrypt->key_base, 128) != 0){
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||||
if(!ctx)
|
if(!ctx)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
@ -204,12 +256,23 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcry
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
int counter_offset = (int)(key_pos / CHIAKI_GKCRYPT_BLOCK_SIZE);
|
int counter_offset = (int)(key_pos / CHIAKI_GKCRYPT_BLOCK_SIZE);
|
||||||
|
|
||||||
for(uint8_t *cur = buf, *end = buf + buf_size; cur < end; cur += CHIAKI_GKCRYPT_BLOCK_SIZE)
|
for(uint8_t *cur = buf, *end = buf + buf_size; cur < end; cur += CHIAKI_GKCRYPT_BLOCK_SIZE)
|
||||||
counter_add(cur, gkcrypt->iv, counter_offset++);
|
counter_add(cur, gkcrypt->iv, counter_offset++);
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
for(int i=0; i<buf_size; i=i+16){
|
||||||
|
// loop over all blocks of 16 bytes (128 bits)
|
||||||
|
if(mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, buf+i, buf+i) != 0){
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
#else
|
||||||
int outl;
|
int outl;
|
||||||
EVP_EncryptUpdate(ctx, buf, &outl, buf, (int)buf_size);
|
EVP_EncryptUpdate(ctx, buf, &outl, buf, (int)buf_size);
|
||||||
if(outl != buf_size)
|
if(outl != buf_size)
|
||||||
|
@ -219,6 +282,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcry
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
#endif
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +374,38 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, size_t
|
||||||
gmac_key = gmac_key_tmp;
|
gmac_key = gmac_key_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
// build mbedtls gcm context AES_128_GCM
|
||||||
|
// Encryption
|
||||||
|
mbedtls_gcm_context actx;
|
||||||
|
mbedtls_gcm_init(&actx);
|
||||||
|
// set gmac_key 128 bits key
|
||||||
|
if(mbedtls_gcm_setkey(&actx, MBEDTLS_CIPHER_ID_AES, gmac_key, CHIAKI_GKCRYPT_BLOCK_SIZE*8) != 0){
|
||||||
|
mbedtls_gcm_free(&actx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt without additional data
|
||||||
|
if(mbedtls_gcm_starts(&actx, MBEDTLS_GCM_ENCRYPT, iv, CHIAKI_GKCRYPT_BLOCK_SIZE, NULL, 0) != 0){
|
||||||
|
mbedtls_gcm_free(&actx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
// set "additional data" only whitout input nor output
|
||||||
|
// to get the same result as:
|
||||||
|
// EVP_EncryptUpdate(ctx, NULL, &len, buf, (int)buf_size)
|
||||||
|
if(mbedtls_gcm_crypt_and_tag(&actx, MBEDTLS_GCM_ENCRYPT,
|
||||||
|
0, iv, CHIAKI_GKCRYPT_BLOCK_SIZE,
|
||||||
|
buf, buf_size, NULL, NULL,
|
||||||
|
CHIAKI_GKCRYPT_GMAC_SIZE, gmac_out) != 0){
|
||||||
|
|
||||||
|
mbedtls_gcm_free(&actx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_gcm_free(&actx);
|
||||||
|
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
#else
|
||||||
ChiakiErrorCode ret = CHIAKI_ERR_SUCCESS;
|
ChiakiErrorCode ret = CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||||
|
@ -360,6 +456,7 @@ fail_cipher:
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
fail:
|
fail:
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool key_buf_mutex_pred(void *user)
|
static bool key_buf_mutex_pred(void *user)
|
||||||
|
@ -401,15 +498,14 @@ static ChiakiErrorCode gkcrypt_generate_next_chunk(ChiakiGKCrypt *gkcrypt)
|
||||||
static void *gkcrypt_thread_func(void *user)
|
static void *gkcrypt_thread_func(void *user)
|
||||||
{
|
{
|
||||||
ChiakiGKCrypt *gkcrypt = user;
|
ChiakiGKCrypt *gkcrypt = user;
|
||||||
|
|
||||||
CHIAKI_LOGV(gkcrypt->log, "GKCrypt %d thread starting", (int)gkcrypt->index);
|
CHIAKI_LOGV(gkcrypt->log, "GKCrypt %d thread starting", (int)gkcrypt->index);
|
||||||
|
|
||||||
ChiakiErrorCode err = chiaki_mutex_lock(&gkcrypt->key_buf_mutex);
|
ChiakiErrorCode err = chiaki_mutex_lock(&gkcrypt->key_buf_mutex);
|
||||||
assert(err == CHIAKI_ERR_SUCCESS);
|
assert(err == CHIAKI_ERR_SUCCESS);
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
err = chiaki_cond_wait_pred(&gkcrypt->key_buf_cond, &gkcrypt->key_buf_mutex, key_buf_mutex_pred, gkcrypt);
|
err = chiaki_cond_wait_pred(&gkcrypt->key_buf_cond, &gkcrypt->key_buf_mutex, key_buf_mutex_pred, gkcrypt);
|
||||||
|
|
||||||
if(gkcrypt->key_buf_thread_stop || err != CHIAKI_ERR_SUCCESS)
|
if(gkcrypt->key_buf_thread_stop || err != CHIAKI_ERR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -438,7 +534,6 @@ static void *gkcrypt_thread_func(void *user)
|
||||||
gkcrypt->key_buf_key_pos_min += KEY_BUF_CHUNK_SIZE;
|
gkcrypt->key_buf_key_pos_min += KEY_BUF_CHUNK_SIZE;
|
||||||
gkcrypt->key_buf_populated -= KEY_BUF_CHUNK_SIZE;
|
gkcrypt->key_buf_populated -= KEY_BUF_CHUNK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gkcrypt_generate_next_chunk(gkcrypt);
|
err = gkcrypt_generate_next_chunk(gkcrypt);
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -17,17 +17,52 @@
|
||||||
|
|
||||||
#include <chiaki/random.h>
|
#include <chiaki/random.h>
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
//#include <mbedtls/havege.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
|
#else
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_random_bytes_crypt(uint8_t *buf, size_t buf_size)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_random_bytes_crypt(uint8_t *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
// mbedtls_havege_state hs;
|
||||||
|
// mbedtls_havege_init(&hs);
|
||||||
|
// int r = mbedtls_havege_random( &hs, buf, sizeof( buf ) );
|
||||||
|
// if(r != 0 )
|
||||||
|
// return CHIAKI_ERR_UNKNOWN;
|
||||||
|
// return CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
// https://github.com/ARMmbed/mbedtls/blob/development/programs/random/gen_random_ctr_drbg.c
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF);
|
||||||
|
if(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) "RANDOM_GEN", 10 ) != 0 ){
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
if(mbedtls_ctr_drbg_random(&ctr_drbg, buf, buf_size) != 0){
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
#else
|
||||||
int r = RAND_bytes(buf, (int)buf_size);
|
int r = RAND_bytes(buf, (int)buf_size);
|
||||||
if(!r)
|
if(!r)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT uint32_t chiaki_random_32()
|
CHIAKI_EXPORT uint32_t chiaki_random_32()
|
||||||
{
|
{
|
||||||
return rand() % UINT32_MAX;
|
return rand() % UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,7 +404,7 @@ static chiaki_socket_t regist_search_connect(ChiakiRegist *regist, struct addrin
|
||||||
|
|
||||||
set_port(send_addr, htons(REGIST_PORT));
|
set_port(send_addr, htons(REGIST_PORT));
|
||||||
|
|
||||||
sock = socket(ai->ai_family, SOCK_DGRAM, 0);
|
sock = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if(CHIAKI_SOCKET_IS_INVALID(sock))
|
if(CHIAKI_SOCKET_IS_INVALID(sock))
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(regist->log, "Regist failed to create socket for search");
|
CHIAKI_LOGE(regist->log, "Regist failed to create socket for search");
|
||||||
|
|
|
@ -17,12 +17,18 @@
|
||||||
|
|
||||||
#include <chiaki/rpcrypt.h>
|
#include <chiaki/rpcrypt.h>
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
#include "mbedtls/md.h"
|
||||||
|
#else
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
static const uint8_t echo_b[] = { 0xe1, 0xec, 0x9c, 0x3a, 0xdd, 0xbd, 0x08, 0x85, 0xfc, 0x0e, 0x1d, 0x78, 0x90, 0x32, 0xc0, 0x04 };
|
static const uint8_t echo_b[] = { 0xe1, 0xec, 0x9c, 0x3a, 0xdd, 0xbd, 0x08, 0x85, 0xfc, 0x0e, 0x1d, 0x78, 0x90, 0x32, 0xc0, 0x04 };
|
||||||
|
|
||||||
CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(uint8_t *bright, uint8_t *ambassador, const uint8_t *nonce, const uint8_t *morning)
|
CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(uint8_t *bright, uint8_t *ambassador, const uint8_t *nonce, const uint8_t *morning)
|
||||||
|
@ -77,6 +83,7 @@ CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint
|
||||||
rpcrypt->bright[3] ^= (uint8_t)((pin >> 0x00) & 0xff);
|
rpcrypt->bright[3] ^= (uint8_t)((pin >> 0x00) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt, uint8_t *iv, uint64_t counter)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt, uint8_t *iv, uint64_t counter)
|
||||||
{
|
{
|
||||||
uint8_t hmac_key[] = { 0xac, 0x07, 0x88, 0x83, 0xc8, 0x3a, 0x1f, 0xe8, 0x11, 0x46, 0x3a, 0xf3, 0x9e, 0xe3, 0xe3, 0x77 };
|
uint8_t hmac_key[] = { 0xac, 0x07, 0x88, 0x83, 0xc8, 0x3a, 0x1f, 0xe8, 0x11, 0x46, 0x3a, 0xf3, 0x9e, 0xe3, 0xe3, 0x77 };
|
||||||
|
@ -92,6 +99,93 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt,
|
||||||
buf[CHIAKI_RPCRYPT_KEY_SIZE + 6] = (uint8_t)((counter >> 0x08) & 0xff);
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 6] = (uint8_t)((counter >> 0x08) & 0xff);
|
||||||
buf[CHIAKI_RPCRYPT_KEY_SIZE + 7] = (uint8_t)((counter >> 0x00) & 0xff);
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 7] = (uint8_t)((counter >> 0x00) & 0xff);
|
||||||
|
|
||||||
|
uint8_t hmac[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||||
|
unsigned int hmac_len = 0;
|
||||||
|
|
||||||
|
|
||||||
|
mbedtls_md_context_t ctx;
|
||||||
|
mbedtls_md_type_t type = MBEDTLS_MD_SHA256;
|
||||||
|
|
||||||
|
mbedtls_md_init(&ctx);
|
||||||
|
|
||||||
|
#define GOTO_ERROR(err) do { \
|
||||||
|
if((err) !=0){ \
|
||||||
|
goto error;} \
|
||||||
|
} while(0)
|
||||||
|
// https://tls.mbed.org/module-level-design-hashing
|
||||||
|
GOTO_ERROR(mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(type) , 1));
|
||||||
|
GOTO_ERROR(mbedtls_md_hmac_starts(&ctx, hmac_key, sizeof(hmac_key)));
|
||||||
|
GOTO_ERROR(mbedtls_md_hmac_update(&ctx, (const unsigned char *) buf, sizeof(buf)));
|
||||||
|
GOTO_ERROR(mbedtls_md_hmac_finish(&ctx, hmac));
|
||||||
|
#undef GOTO_ERROR
|
||||||
|
memcpy(iv, hmac, CHIAKI_RPCRYPT_KEY_SIZE);
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
error:
|
||||||
|
mbedtls_md_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ChiakiErrorCode chiaki_rpcrypt_crypt(ChiakiRPCrypt *rpcrypt, uint64_t counter, const uint8_t *in, uint8_t *out, size_t sz, bool encrypt)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define GOTO_ERROR(err) do { \
|
||||||
|
if((err) !=0){ \
|
||||||
|
goto error;} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
// https://github.com/ARMmbed/mbedtls/blob/development/programs/aes/aescrypt2.c
|
||||||
|
// build aes context
|
||||||
|
mbedtls_aes_context ctx;
|
||||||
|
mbedtls_aes_init(&ctx);
|
||||||
|
|
||||||
|
// initialization vector
|
||||||
|
uint8_t iv[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||||
|
ChiakiErrorCode err = chiaki_rpcrypt_generate_iv(rpcrypt, iv, counter);
|
||||||
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
GOTO_ERROR(mbedtls_aes_setkey_enc(&ctx, rpcrypt->bright, 128));
|
||||||
|
size_t iv_off = 0;
|
||||||
|
if(encrypt)
|
||||||
|
{
|
||||||
|
GOTO_ERROR(mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_ENCRYPT, sz, &iv_off, iv, in, out));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the aes_crypt_cfb128 does not seems to use the setkey_dec
|
||||||
|
// GOTO_ERROR(mbedtls_aes_setkey_dec(&ctx, rpcrypt->bright, 128));
|
||||||
|
GOTO_ERROR(mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_DECRYPT, sz, &iv_off, iv, in, out));
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef GOTO_ERROR
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt, uint8_t *iv, uint64_t counter)
|
||||||
|
{
|
||||||
|
uint8_t hmac_key[] = { 0xac, 0x07, 0x88, 0x83, 0xc8, 0x3a, 0x1f, 0xe8, 0x11, 0x46, 0x3a, 0xf3, 0x9e, 0xe3, 0xe3, 0x77 };
|
||||||
|
|
||||||
|
uint8_t buf[CHIAKI_RPCRYPT_KEY_SIZE + 8];
|
||||||
|
memcpy(buf, rpcrypt->ambassador, CHIAKI_RPCRYPT_KEY_SIZE);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 0] = (uint8_t)((counter >> 0x38) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 1] = (uint8_t)((counter >> 0x30) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 2] = (uint8_t)((counter >> 0x28) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 3] = (uint8_t)((counter >> 0x20) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 4] = (uint8_t)((counter >> 0x18) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 5] = (uint8_t)((counter >> 0x10) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 6] = (uint8_t)((counter >> 0x08) & 0xff);
|
||||||
|
buf[CHIAKI_RPCRYPT_KEY_SIZE + 7] = (uint8_t)((counter >> 0x00) & 0xff);
|
||||||
|
|
||||||
|
|
||||||
uint8_t hmac[32];
|
uint8_t hmac[32];
|
||||||
unsigned int hmac_len = 0;
|
unsigned int hmac_len = 0;
|
||||||
if(!HMAC(EVP_sha256(), hmac_key, CHIAKI_RPCRYPT_KEY_SIZE, buf, sizeof(buf), hmac, &hmac_len))
|
if(!HMAC(EVP_sha256(), hmac_key, CHIAKI_RPCRYPT_KEY_SIZE, buf, sizeof(buf), hmac, &hmac_len))
|
||||||
|
@ -150,6 +244,7 @@ static ChiakiErrorCode chiaki_rpcrypt_crypt(ChiakiRPCrypt *rpcrypt, uint64_t cou
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_encrypt(ChiakiRPCrypt *rpcrypt, uint64_t counter, const uint8_t *in, uint8_t *out, size_t sz)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_encrypt(ChiakiRPCrypt *rpcrypt, uint64_t counter, const uint8_t *in, uint8_t *out, size_t sz)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,11 +34,36 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_init(ChiakiStopPipe *stop_pipe)
|
||||||
stop_pipe->event = WSACreateEvent();
|
stop_pipe->event = WSACreateEvent();
|
||||||
if(stop_pipe->event == WSA_INVALID_EVENT)
|
if(stop_pipe->event == WSA_INVALID_EVENT)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
#elif defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
// currently pipe or socketpare are not available on switch
|
||||||
|
// use a custom udp socket as pipe
|
||||||
|
|
||||||
|
// struct sockaddr_in addr;
|
||||||
|
int addr_size = sizeof(stop_pipe->addr);
|
||||||
|
|
||||||
|
stop_pipe->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if(stop_pipe->fd < 0){
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
stop_pipe->addr.sin_family = AF_INET;
|
||||||
|
// bind to localhost
|
||||||
|
stop_pipe->addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
// use a random port (dedicate one socket per object)
|
||||||
|
stop_pipe->addr.sin_port = htons(0);
|
||||||
|
// bind on localhost
|
||||||
|
bind(stop_pipe->fd, (struct sockaddr *) &stop_pipe->addr, addr_size);
|
||||||
|
// listen
|
||||||
|
getsockname(stop_pipe->fd, (struct sockaddr *) &stop_pipe->addr, &addr_size);
|
||||||
|
int r = fcntl(stop_pipe->fd, F_SETFL, O_NONBLOCK);
|
||||||
|
if(r == -1)
|
||||||
|
{
|
||||||
|
close(stop_pipe->fd);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int r = pipe(stop_pipe->fds);
|
int r = pipe(stop_pipe->fds);
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
|
||||||
r = fcntl(stop_pipe->fds[0], F_SETFL, O_NONBLOCK);
|
r = fcntl(stop_pipe->fds[0], F_SETFL, O_NONBLOCK);
|
||||||
if(r == -1)
|
if(r == -1)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +72,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_init(ChiakiStopPipe *stop_pipe)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +79,8 @@ CHIAKI_EXPORT void chiaki_stop_pipe_fini(ChiakiStopPipe *stop_pipe)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSACloseEvent(stop_pipe->event);
|
WSACloseEvent(stop_pipe->event);
|
||||||
|
#elif defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
close(stop_pipe->fd);
|
||||||
#else
|
#else
|
||||||
close(stop_pipe->fds[0]);
|
close(stop_pipe->fds[0]);
|
||||||
close(stop_pipe->fds[1]);
|
close(stop_pipe->fds[1]);
|
||||||
|
@ -65,6 +91,10 @@ CHIAKI_EXPORT void chiaki_stop_pipe_stop(ChiakiStopPipe *stop_pipe)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSASetEvent(stop_pipe->event);
|
WSASetEvent(stop_pipe->event);
|
||||||
|
#elif defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
// send to local socket (FIXME MSG_CONFIRM)
|
||||||
|
sendto(stop_pipe->fd, "\x00", 1, 0,
|
||||||
|
(struct sockaddr*)&stop_pipe->addr, sizeof(struct sockaddr_in));
|
||||||
#else
|
#else
|
||||||
write(stop_pipe->fds[1], "\x00", 1);
|
write(stop_pipe->fds[1], "\x00", 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -105,12 +135,17 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
|
||||||
#else
|
#else
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(stop_pipe->fds[0], &rfds);
|
#if defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
// push udp local socket as fd
|
||||||
|
int stop_fd = stop_pipe->fd;
|
||||||
|
#else
|
||||||
|
int stop_fd = stop_pipe->fds[0];
|
||||||
|
#endif
|
||||||
|
FD_SET(stop_fd, &rfds);
|
||||||
|
int nfds = stop_fd;
|
||||||
|
|
||||||
fd_set wfds;
|
fd_set wfds;
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
|
|
||||||
int nfds = stop_pipe->fds[0];
|
|
||||||
if(!CHIAKI_SOCKET_IS_INVALID(fd))
|
if(!CHIAKI_SOCKET_IS_INVALID(fd))
|
||||||
{
|
{
|
||||||
FD_SET(fd, write ? &wfds : &rfds);
|
FD_SET(fd, write ? &wfds : &rfds);
|
||||||
|
@ -129,10 +164,11 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = select(nfds, &rfds, write ? &wfds : NULL, NULL, timeout);
|
int r = select(nfds, &rfds, write ? &wfds : NULL, NULL, timeout);
|
||||||
|
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
return CHIAKI_ERR_UNKNOWN;
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
|
||||||
if(FD_ISSET(stop_pipe->fds[0], &rfds))
|
if(FD_ISSET(stop_fd, &rfds))
|
||||||
return CHIAKI_ERR_CANCELED;
|
return CHIAKI_ERR_CANCELED;
|
||||||
|
|
||||||
if(!CHIAKI_SOCKET_IS_INVALID(fd) && FD_ISSET(fd, write ? &wfds : &rfds))
|
if(!CHIAKI_SOCKET_IS_INVALID(fd) && FD_ISSET(fd, write ? &wfds : &rfds))
|
||||||
|
@ -223,6 +259,12 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_reset(ChiakiStopPipe *stop_pipe)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BOOL r = WSAResetEvent(stop_pipe->event);
|
BOOL r = WSAResetEvent(stop_pipe->event);
|
||||||
return r ? CHIAKI_ERR_SUCCESS : CHIAKI_ERR_UNKNOWN;
|
return r ? CHIAKI_ERR_SUCCESS : CHIAKI_ERR_UNKNOWN;
|
||||||
|
#elif defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||||
|
//FIXME
|
||||||
|
uint8_t v;
|
||||||
|
int r;
|
||||||
|
while((r = read(stop_pipe->fd, &v, sizeof(v))) > 0);
|
||||||
|
return r < 0 ? CHIAKI_ERR_UNKNOWN : CHIAKI_ERR_SUCCESS;
|
||||||
#else
|
#else
|
||||||
uint8_t v;
|
uint8_t v;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -28,6 +28,11 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
#elif defined(__SWITCH__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -252,7 +257,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
const DWORD dontfragment_val = 1;
|
const DWORD dontfragment_val = 1;
|
||||||
r = setsockopt(takion->sock, IPPROTO_IP, IP_DONTFRAGMENT, (const void *)&dontfragment_val, sizeof(dontfragment_val));
|
r = setsockopt(takion->sock, IPPROTO_IP, IP_DONTFRAGMENT, (const void *)&dontfragment_val, sizeof(dontfragment_val));
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__) || defined(__SWITCH__)
|
||||||
const int dontfrag_val = 1;
|
const int dontfrag_val = 1;
|
||||||
r = setsockopt(takion->sock, IPPROTO_IP, IP_DONTFRAG, (const void *)&dontfrag_val, sizeof(dontfrag_val));
|
r = setsockopt(takion->sock, IPPROTO_IP, IP_DONTFRAG, (const void *)&dontfrag_val, sizeof(dontfrag_val));
|
||||||
#elif defined(IP_PMTUDISC_DO)
|
#elif defined(IP_PMTUDISC_DO)
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
#include <switch.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
static DWORD WINAPI win32_thread_func(LPVOID param)
|
static DWORD WINAPI win32_thread_func(LPVOID param)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +37,18 @@ static DWORD WINAPI win32_thread_func(LPVOID param)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
int64_t get_thread_limit(){
|
||||||
|
uint64_t resource_limit_handle_value = INVALID_HANDLE;
|
||||||
|
svcGetInfo(&resource_limit_handle_value, InfoType_ResourceLimit, INVALID_HANDLE, 0);
|
||||||
|
int64_t thread_cur_value = 0, thread_lim_value = 0;
|
||||||
|
svcGetResourceLimitCurrentValue(&thread_cur_value, resource_limit_handle_value, LimitableResource_Threads);
|
||||||
|
svcGetResourceLimitLimitValue(&thread_lim_value, resource_limit_handle_value, LimitableResource_Threads);
|
||||||
|
//printf("thread_cur_value: %lu, thread_lim_value: %lu\n", thread_cur_value, thread_lim_value);
|
||||||
|
return thread_lim_value - thread_cur_value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_create(ChiakiThread *thread, ChiakiThreadFunc func, void *arg)
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_create(ChiakiThread *thread, ChiakiThreadFunc func, void *arg)
|
||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
@ -43,6 +59,11 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_create(ChiakiThread *thread, ChiakiT
|
||||||
if(!thread->thread)
|
if(!thread->thread)
|
||||||
return CHIAKI_ERR_THREAD;
|
return CHIAKI_ERR_THREAD;
|
||||||
#else
|
#else
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
if(get_thread_limit() <= 1){
|
||||||
|
return CHIAKI_ERR_THREAD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int r = pthread_create(&thread->thread, NULL, func, arg);
|
int r = pthread_create(&thread->thread, NULL, func, arg);
|
||||||
if(r != 0)
|
if(r != 0)
|
||||||
return CHIAKI_ERR_THREAD;
|
return CHIAKI_ERR_THREAD;
|
||||||
|
|
81
scripts/switch/Dockerfile
Normal file
81
scripts/switch/Dockerfile
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
FROM docker.io/archlinux/base
|
||||||
|
|
||||||
|
ENV DEVKITPRO=/opt/devkitpro
|
||||||
|
ENV DEVKITARM=/opt/devkitpro/devkitARM
|
||||||
|
ENV DEVKITPPC=/opt/devkitpro/devkitPPC
|
||||||
|
ENV PATH="${PATH}:${DEVKITARM}/bin/:${DEVKITPPC}/bin/"
|
||||||
|
|
||||||
|
|
||||||
|
ENV WORKDIR="/build"
|
||||||
|
WORKDIR "${WORKDIR}"
|
||||||
|
|
||||||
|
# Upgarde image
|
||||||
|
RUN pacman --noconfirm -Syu
|
||||||
|
|
||||||
|
# Install requirements for libtransistor
|
||||||
|
RUN pacman --noconfirm -S \
|
||||||
|
llvm \
|
||||||
|
clang \
|
||||||
|
lld \
|
||||||
|
python \
|
||||||
|
python-pip \
|
||||||
|
python-virtualenv \
|
||||||
|
squashfs-tools \
|
||||||
|
base-devel \
|
||||||
|
git \
|
||||||
|
cmake \
|
||||||
|
libx11 \
|
||||||
|
vim
|
||||||
|
|
||||||
|
RUN pacman-key --init
|
||||||
|
# Install devkitpro
|
||||||
|
# doc source :
|
||||||
|
# https://devkitpro.org/wiki/devkitPro_pacman
|
||||||
|
|
||||||
|
# First import the key which is used to validate the packages
|
||||||
|
RUN pacman-key --recv F7FD5492264BB9D0
|
||||||
|
RUN pacman-key --lsign F7FD5492264BB9D0
|
||||||
|
|
||||||
|
# Add the devkitPro repositories
|
||||||
|
ADD devkit_repo ./devkit_repo
|
||||||
|
RUN cat ./devkit_repo >> /etc/pacman.conf
|
||||||
|
# Install the keyring which adds more keys which may be used to verify the packages.
|
||||||
|
RUN pacman --noconfirm -U https://downloads.devkitpro.org/devkitpro-keyring-r1.787e015-2-any.pkg.tar.xz
|
||||||
|
# Now resync the database and update installed packages.
|
||||||
|
RUN pacman -Sy
|
||||||
|
|
||||||
|
RUN pacman --noconfirm -Syu
|
||||||
|
|
||||||
|
#RUN pacman --noconfirm -S $(pacman -Slq dkp-libs)
|
||||||
|
|
||||||
|
RUN pacman --noconfirm -S \
|
||||||
|
protobuf \
|
||||||
|
python-protobuf \
|
||||||
|
sfml \
|
||||||
|
devkitARM \
|
||||||
|
switch-pkg-config \
|
||||||
|
devkitpro-pkgbuild-helpers \
|
||||||
|
switch-dev \
|
||||||
|
switch-zlib \
|
||||||
|
switch-sdl2 \
|
||||||
|
switch-freetype \
|
||||||
|
switch-curl \
|
||||||
|
switch-mesa \
|
||||||
|
switch-glad \
|
||||||
|
switch-glm \
|
||||||
|
switch-libconfig \
|
||||||
|
switch-sdl2_gfx \
|
||||||
|
switch-sdl2_ttf \
|
||||||
|
switch-sdl2_image \
|
||||||
|
switch-libexpat \
|
||||||
|
switch-bzip2 \
|
||||||
|
switch-libopus \
|
||||||
|
switch-ffmpeg \
|
||||||
|
switch-mbedtls
|
||||||
|
|
||||||
|
RUN pip3 install -U pip
|
||||||
|
|
||||||
|
VOLUME ${WORKDIR}
|
||||||
|
# nxlink server port
|
||||||
|
EXPOSE 28771
|
||||||
|
ENTRYPOINT ["/bin/bash"]
|
42
scripts/switch/build.sh
Executable file
42
scripts/switch/build.sh
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xveo pipefail
|
||||||
|
|
||||||
|
arg1=$1
|
||||||
|
CHIAKI_ENABLE_SWITCH_LINUX="ON"
|
||||||
|
build="./build"
|
||||||
|
if [ "$arg1" != "linux" ]; then
|
||||||
|
CHIAKI_ENABLE_SWITCH_LINUX="OFF"
|
||||||
|
source /opt/devkitpro/switchvars.sh
|
||||||
|
toolchain=/opt/devkitpro/switch.cmake
|
||||||
|
|
||||||
|
export CC=${TOOL_PREFIX}gcc
|
||||||
|
export CXX=${TOOL_PREFIX}g++
|
||||||
|
build="./build_switch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPTDIR=$(dirname "$0")
|
||||||
|
BASEDIR=$(realpath "${SCRIPTDIR}/../../")
|
||||||
|
|
||||||
|
build_chiaki (){
|
||||||
|
pushd "${BASEDIR}"
|
||||||
|
#rm -rf ./build
|
||||||
|
|
||||||
|
cmake -B "${build}" -DCMAKE_TOOLCHAIN_FILE=${toolchain} \
|
||||||
|
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
|
||||||
|
-DCHIAKI_ENABLE_TESTS=OFF \
|
||||||
|
-DCHIAKI_ENABLE_CLI=OFF \
|
||||||
|
-DCHIAKI_ENABLE_GUI=OFF \
|
||||||
|
-DCHIAKI_ENABLE_ANDROID=OFF \
|
||||||
|
-DCHIAKI_ENABLE_SWITCH=ON \
|
||||||
|
-DCHIAKI_ENABLE_SWITCH_LINUX="${CHIAKI_ENABLE_SWITCH_LINUX}" \
|
||||||
|
-DCHIAKI_LIB_ENABLE_MBEDTLS=ON
|
||||||
|
|
||||||
|
pushd "${BASEDIR}/${build}/switch/"
|
||||||
|
make
|
||||||
|
popd
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
|
build_chiaki
|
||||||
|
|
6
scripts/switch/devkit_repo
Normal file
6
scripts/switch/devkit_repo
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[dkp-libs]
|
||||||
|
Server = http://downloads.devkitpro.org/packages
|
||||||
|
|
||||||
|
[dkp-linux]
|
||||||
|
Server = http://downloads.devkitpro.org/packages/linux
|
||||||
|
|
31
scripts/switch/fake_ctest.nintendo.net.py
Normal file
31
scripts/switch/fake_ctest.nintendo.net.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# simple python3 http server to emulate ctest.nintendo.net
|
||||||
|
# you have to redirect nintendo.net to your own host
|
||||||
|
# https://gitlab.com/a/90dns
|
||||||
|
|
||||||
|
# the aim is to fake ctest.nintendo.net server
|
||||||
|
# to allow nintendo switch lan connection
|
||||||
|
|
||||||
|
# The nintendo switch tries to join ctest to validate wifi settings
|
||||||
|
# without 200 OK from ctest.nintendo.net, the LAN connection is denied
|
||||||
|
|
||||||
|
import http.server
|
||||||
|
import socketserver
|
||||||
|
|
||||||
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-Type", "text/plain")
|
||||||
|
self.send_header("X-Organization", "Nintendo")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b'ok')
|
||||||
|
|
||||||
|
|
||||||
|
PORT = 80
|
||||||
|
|
||||||
|
httpd = HTTPServer(('0.0.0.0', PORT), SimpleHTTPRequestHandler)
|
||||||
|
httpd.serve_forever()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue