mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-21 14:03:11 -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
|
@ -99,16 +99,26 @@ target_include_directories(chiaki-lib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/includ
|
|||
find_package(Threads REQUIRED)
|
||||
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)
|
||||
else()
|
||||
# default
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(chiaki-lib OpenSSL::Crypto)
|
||||
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 jerasure)
|
||||
|
||||
if(CHIAKI_LIB_ENABLE_OPUS)
|
||||
target_link_libraries(chiaki-lib ${Opus_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -27,12 +27,28 @@
|
|||
extern "C" {
|
||||
#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
|
||||
|
||||
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_key_st *key_local;
|
||||
#endif
|
||||
} ChiakiECDH;
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh);
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -36,6 +38,15 @@ typedef struct chiaki_stop_pipe_t
|
|||
{
|
||||
#ifdef _WIN32
|
||||
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
|
||||
int fds[2];
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
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->socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
discovery->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(CHIAKI_SOCKET_IS_INVALID(discovery->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;
|
||||
if(family == AF_INET6)
|
||||
{
|
||||
#ifndef __SWITCH__
|
||||
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
|
||||
#endif
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&discovery->local_addr;
|
||||
#ifndef __SWITCH__
|
||||
addr->sin6_addr = anyaddr;
|
||||
#endif
|
||||
addr->sin6_port = htons(0);
|
||||
}
|
||||
else // AF_INET
|
||||
|
|
134
lib/src/ecdh.c
134
lib/src/ecdh.c
|
@ -19,23 +19,58 @@
|
|||
#include <chiaki/ecdh.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/ec.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#endif
|
||||
|
||||
// memset
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_ecdh_init(ChiakiECDH *ecdh)
|
||||
{
|
||||
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; }
|
||||
|
||||
CHECK(ecdh->group = EC_GROUP_new_by_curve_name(NID_secp256k1));
|
||||
|
||||
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));
|
||||
|
||||
#undef CHECK
|
||||
#endif
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
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_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)
|
||||
{
|
||||
#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;
|
||||
|
||||
BIGNUM *private_key_bn = BN_bin2bn(private_key, (int)private_key_size, NULL);
|
||||
|
@ -92,10 +161,40 @@ error_pub:
|
|||
error_priv:
|
||||
BN_free(private_key_bn);
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
if(!point)
|
||||
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))
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
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)
|
||||
{
|
||||
//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);
|
||||
if(!remote_public_key)
|
||||
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_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -21,9 +21,16 @@
|
|||
#include <string.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/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -69,7 +76,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_init(ChiakiGKCrypt *gkcrypt, Chiaki
|
|||
{
|
||||
gkcrypt->key_buf = NULL;
|
||||
}
|
||||
|
||||
err = gkcrypt_gen_key_iv(gkcrypt, index, handshake_key, ecdh_secret);
|
||||
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];
|
||||
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))
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
#endif
|
||||
assert(hmac_size == sizeof(hmac));
|
||||
|
||||
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);
|
||||
counter_add(data + 0x10, iv, index * CHIAKI_GKCRYPT_GMAC_KEY_REFRESH_IV_OFFSET);
|
||||
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);
|
||||
#endif
|
||||
xor_bytes(md, md + 0x10, 0x10);
|
||||
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(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();
|
||||
if(!ctx)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
@ -204,12 +256,23 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gen_key_stream(ChiakiGKCrypt *gkcry
|
|||
EVP_CIPHER_CTX_free(ctx);
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
#endif
|
||||
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)
|
||||
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;
|
||||
EVP_EncryptUpdate(ctx, buf, &outl, buf, (int)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);
|
||||
#endif
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -310,6 +374,38 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_gkcrypt_gmac(ChiakiGKCrypt *gkcrypt, size_t
|
|||
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;
|
||||
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
|
@ -360,6 +456,7 @@ fail_cipher:
|
|||
EVP_CIPHER_CTX_free(ctx);
|
||||
fail:
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ChiakiGKCrypt *gkcrypt = user;
|
||||
|
||||
CHIAKI_LOGV(gkcrypt->log, "GKCrypt %d thread starting", (int)gkcrypt->index);
|
||||
|
||||
ChiakiErrorCode err = chiaki_mutex_lock(&gkcrypt->key_buf_mutex);
|
||||
assert(err == CHIAKI_ERR_SUCCESS);
|
||||
|
||||
while(1)
|
||||
{
|
||||
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)
|
||||
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_populated -= KEY_BUF_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
err = gkcrypt_generate_next_chunk(gkcrypt);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
break;
|
||||
|
|
|
@ -17,17 +17,52 @@
|
|||
|
||||
#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>
|
||||
#endif
|
||||
|
||||
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);
|
||||
if(!r)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT uint32_t chiaki_random_32()
|
||||
{
|
||||
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));
|
||||
|
||||
sock = socket(ai->ai_family, SOCK_DGRAM, 0);
|
||||
sock = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(CHIAKI_SOCKET_IS_INVALID(sock))
|
||||
{
|
||||
CHIAKI_LOGE(regist->log, "Regist failed to create socket for search");
|
||||
|
|
|
@ -17,12 +17,18 @@
|
|||
|
||||
#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/evp.h>
|
||||
#endif
|
||||
|
||||
#include <string.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 };
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#if defined(__SWITCH__) || defined(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||
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 };
|
||||
|
@ -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 + 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];
|
||||
unsigned int hmac_len = 0;
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -34,11 +34,36 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_init(ChiakiStopPipe *stop_pipe)
|
|||
stop_pipe->event = WSACreateEvent();
|
||||
if(stop_pipe->event == WSA_INVALID_EVENT)
|
||||
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
|
||||
int r = pipe(stop_pipe->fds);
|
||||
if(r < 0)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
r = fcntl(stop_pipe->fds[0], F_SETFL, O_NONBLOCK);
|
||||
if(r == -1)
|
||||
{
|
||||
|
@ -47,7 +72,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_init(ChiakiStopPipe *stop_pipe)
|
|||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -55,6 +79,8 @@ CHIAKI_EXPORT void chiaki_stop_pipe_fini(ChiakiStopPipe *stop_pipe)
|
|||
{
|
||||
#ifdef _WIN32
|
||||
WSACloseEvent(stop_pipe->event);
|
||||
#elif defined(__SWITCH__) || defined(CHIAKI_ENABLE_SWITCH_LINUX)
|
||||
close(stop_pipe->fd);
|
||||
#else
|
||||
close(stop_pipe->fds[0]);
|
||||
close(stop_pipe->fds[1]);
|
||||
|
@ -65,6 +91,10 @@ CHIAKI_EXPORT void chiaki_stop_pipe_stop(ChiakiStopPipe *stop_pipe)
|
|||
{
|
||||
#ifdef _WIN32
|
||||
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
|
||||
write(stop_pipe->fds[1], "\x00", 1);
|
||||
#endif
|
||||
|
@ -105,12 +135,17 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
|
|||
#else
|
||||
fd_set 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_ZERO(&wfds);
|
||||
|
||||
int nfds = stop_pipe->fds[0];
|
||||
if(!CHIAKI_SOCKET_IS_INVALID(fd))
|
||||
{
|
||||
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);
|
||||
|
||||
if(r < 0)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
if(FD_ISSET(stop_pipe->fds[0], &rfds))
|
||||
if(FD_ISSET(stop_fd, &rfds))
|
||||
return CHIAKI_ERR_CANCELED;
|
||||
|
||||
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
|
||||
BOOL r = WSAResetEvent(stop_pipe->event);
|
||||
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
|
||||
uint8_t v;
|
||||
int r;
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#elif defined(__SWITCH__)
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -252,7 +257,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki
|
|||
#if defined(_WIN32)
|
||||
const DWORD dontfragment_val = 1;
|
||||
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;
|
||||
r = setsockopt(takion->sock, IPPROTO_IP, IP_DONTFRAG, (const void *)&dontfrag_val, sizeof(dontfrag_val));
|
||||
#elif defined(IP_PMTUDISC_DO)
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
static DWORD WINAPI win32_thread_func(LPVOID param)
|
||||
{
|
||||
|
@ -33,6 +37,18 @@ static DWORD WINAPI win32_thread_func(LPVOID param)
|
|||
}
|
||||
#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)
|
||||
{
|
||||
#if _WIN32
|
||||
|
@ -43,6 +59,11 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_create(ChiakiThread *thread, ChiakiT
|
|||
if(!thread->thread)
|
||||
return CHIAKI_ERR_THREAD;
|
||||
#else
|
||||
#ifdef __SWITCH__
|
||||
if(get_thread_limit() <= 1){
|
||||
return CHIAKI_ERR_THREAD;
|
||||
}
|
||||
#endif
|
||||
int r = pthread_create(&thread->thread, NULL, func, arg);
|
||||
if(r != 0)
|
||||
return CHIAKI_ERR_THREAD;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue