mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 18:57:07 -07:00
Add Regist Tests
This commit is contained in:
parent
2a20ac4246
commit
0694af09ad
12 changed files with 187 additions and 58 deletions
|
@ -22,6 +22,7 @@
|
|||
#include "log.h"
|
||||
#include "thread.h"
|
||||
#include "stoppipe.h"
|
||||
#include "rpcrypt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -62,6 +63,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_start(ChiakiRegist *regist, ChiakiLo
|
|||
CHIAKI_EXPORT void chiaki_regist_fini(ChiakiRegist *regist);
|
||||
CHIAKI_EXPORT void chiaki_regist_stop(ChiakiRegist *regist);
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(uint8_t *buf, size_t *buf_size, ChiakiRPCrypt *crypt, const char *psn_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,19 +27,19 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CHIAKI_KEY_BYTES 0x10
|
||||
#define CHIAKI_RPCRYPT_KEY_SIZE 0x10
|
||||
|
||||
typedef struct chiaki_rpcrypt_t
|
||||
{
|
||||
uint8_t bright[CHIAKI_KEY_BYTES];
|
||||
uint8_t ambassador[CHIAKI_KEY_BYTES];
|
||||
uint8_t bright[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
uint8_t ambassador[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
} ChiakiRPCrypt;
|
||||
|
||||
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_aeropause(uint8_t *aeropause, const uint8_t *nonce);
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause(uint8_t *aeropause, const uint8_t *ambassador);
|
||||
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_init_auth(ChiakiRPCrypt *rpcrypt, const uint8_t *nonce, const uint8_t *morning);
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *nonce, uint32_t pin);
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, uint32_t pin);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt, uint8_t *iv, uint64_t counter);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_encrypt(ChiakiRPCrypt *rpcrypt, uint64_t counter, uint8_t *in, uint8_t *out, size_t sz);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_decrypt(ChiakiRPCrypt *rpcrypt, uint64_t counter, uint8_t *in, uint8_t *out, size_t sz);
|
||||
|
|
|
@ -137,13 +137,13 @@ typedef struct chiaki_session_t
|
|||
char hostname[128];
|
||||
char *regist_key;
|
||||
char *ostype;
|
||||
char auth[CHIAKI_KEY_BYTES];
|
||||
uint8_t morning[CHIAKI_KEY_BYTES];
|
||||
char auth[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
uint8_t morning[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
uint8_t did[CHIAKI_RP_DID_SIZE];
|
||||
ChiakiConnectVideoProfile video_profile;
|
||||
} connect_info;
|
||||
|
||||
uint8_t nonce[CHIAKI_KEY_BYTES];
|
||||
uint8_t nonce[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
ChiakiRPCrypt rpcrypt;
|
||||
char session_id[CHIAKI_SESSION_ID_SIZE_MAX]; // zero-terminated
|
||||
uint8_t handshake_key[CHIAKI_HANDSHAKE_KEY_SIZE];
|
||||
|
|
|
@ -341,11 +341,11 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
|
|||
CHIAKI_LOGI(session->log, "Connected to %s:%d", session->connect_info.hostname, SESSION_CTRL_PORT);
|
||||
|
||||
|
||||
uint8_t auth_enc[CHIAKI_KEY_BYTES];
|
||||
ChiakiErrorCode err = chiaki_rpcrypt_encrypt(&session->rpcrypt, 0, (uint8_t *)session->connect_info.auth, auth_enc, CHIAKI_KEY_BYTES);
|
||||
uint8_t auth_enc[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
ChiakiErrorCode err = chiaki_rpcrypt_encrypt(&session->rpcrypt, 0, (uint8_t *)session->connect_info.auth, auth_enc, CHIAKI_RPCRYPT_KEY_SIZE);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto error;
|
||||
char auth_b64[CHIAKI_KEY_BYTES*2];
|
||||
char auth_b64[CHIAKI_RPCRYPT_KEY_SIZE*2];
|
||||
err = chiaki_base64_encode(auth_enc, sizeof(auth_enc), auth_b64, sizeof(auth_b64));
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto error;
|
||||
|
|
|
@ -93,14 +93,30 @@ static const char * const request_fmt =
|
|||
|
||||
static const char * const request_inner_fmt =
|
||||
"Client-Type: Windows\r\n"
|
||||
"Np-Online-Id: %s\r\n\r\n";
|
||||
"Np-Online-Id: %s\r\n";
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(uint8_t *buf, size_t *buf_size, ChiakiRPCrypt *crypt, const char *psn_id)
|
||||
{
|
||||
size_t buf_size_val = *buf_size;
|
||||
static const size_t inner_header_off = 0x1e0;
|
||||
if(buf_size_val < inner_header_off)
|
||||
return CHIAKI_ERR_BUF_TOO_SMALL;
|
||||
memset(buf, 'A', inner_header_off);
|
||||
chiaki_rpcrypt_aeropause(buf + 0x11c, crypt->ambassador);
|
||||
int inner_header_size = snprintf((char *)buf + inner_header_off, buf_size_val - inner_header_off, request_inner_fmt, psn_id);
|
||||
if(inner_header_size < 0 || inner_header_size >= buf_size_val - inner_header_off)
|
||||
return CHIAKI_ERR_BUF_TOO_SMALL;
|
||||
ChiakiErrorCode err = chiaki_rpcrypt_encrypt(crypt, 0, buf + inner_header_off, buf + inner_header_off, inner_header_size);
|
||||
*buf_size = inner_header_off + inner_header_size;
|
||||
return err;
|
||||
}
|
||||
|
||||
static void *regist_thread_func(void *user)
|
||||
{
|
||||
ChiakiRegist *regist = user;
|
||||
|
||||
uint8_t nonce[CHIAKI_KEY_BYTES];
|
||||
ChiakiErrorCode err = chiaki_random_bytes_crypt(nonce, sizeof(nonce));
|
||||
uint8_t ambassador[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
ChiakiErrorCode err = chiaki_random_bytes_crypt(ambassador, sizeof(ambassador));
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(regist->log, "Regist failed to generate random nonce");
|
||||
|
@ -108,20 +124,16 @@ static void *regist_thread_func(void *user)
|
|||
}
|
||||
|
||||
ChiakiRPCrypt crypt;
|
||||
chiaki_rpcrypt_init_regist(&crypt, nonce, regist->info.pin);
|
||||
chiaki_rpcrypt_init_regist(&crypt, ambassador, regist->info.pin);
|
||||
|
||||
uint8_t payload[0x400];
|
||||
static const size_t inner_header_off = 0x1e0;
|
||||
memset(payload, 'A', inner_header_off);
|
||||
chiaki_rpcrypt_aeropause(payload + 0x11c, nonce);
|
||||
int inner_header_size = snprintf((char *)payload + inner_header_off, sizeof(payload) - inner_header_off, request_inner_fmt, regist->info.psn_id);
|
||||
if(inner_header_size >= sizeof(payload) - inner_header_off)
|
||||
size_t payload_size = sizeof(payload);
|
||||
err = chiaki_regist_request_payload_format(payload, &payload_size, &crypt, regist->info.psn_id);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(regist->log, "Regist failed to format payload");
|
||||
goto fail;
|
||||
}
|
||||
chiaki_rpcrypt_encrypt(&crypt, 0, payload + inner_header_off, payload + inner_header_off, inner_header_size);
|
||||
size_t payload_size = inner_header_off + inner_header_size;
|
||||
|
||||
char request_header[0x100];
|
||||
int request_header_size = snprintf(request_header, sizeof(request_header), request_fmt, (unsigned long long)payload_size);
|
||||
|
|
|
@ -29,7 +29,7 @@ CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(uint8_t *bright, uint8_t *am
|
|||
{
|
||||
static const uint8_t echo_a[] = { 0x01, 0x49, 0x87, 0x9b, 0x65, 0x39, 0x8b, 0x39, 0x4b, 0x3a, 0x8d, 0x48, 0xc3, 0x0a, 0xef, 0x51 };
|
||||
|
||||
for(uint8_t i=0; i<CHIAKI_KEY_BYTES; i++)
|
||||
for(uint8_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
|
||||
{
|
||||
uint8_t v = nonce[i];
|
||||
v -= i;
|
||||
|
@ -38,7 +38,7 @@ CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(uint8_t *bright, uint8_t *am
|
|||
ambassador[i] = v;
|
||||
}
|
||||
|
||||
for(uint8_t i=0; i<CHIAKI_KEY_BYTES; i++)
|
||||
for(uint8_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
|
||||
{
|
||||
uint8_t v = morning[i];
|
||||
v -= i;
|
||||
|
@ -49,11 +49,11 @@ CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(uint8_t *bright, uint8_t *am
|
|||
}
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause(uint8_t *aeropause, const uint8_t *nonce)
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause(uint8_t *aeropause, const uint8_t *ambassador)
|
||||
{
|
||||
for(size_t i=0; i<CHIAKI_KEY_BYTES; i++)
|
||||
for(size_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
|
||||
{
|
||||
uint8_t v = nonce[i];
|
||||
uint8_t v = ambassador[i];
|
||||
v -= i;
|
||||
v -= 0x29;
|
||||
v ^= echo_b[i];
|
||||
|
@ -66,10 +66,10 @@ CHIAKI_EXPORT void chiaki_rpcrypt_init_auth(ChiakiRPCrypt *rpcrypt, const uint8_
|
|||
chiaki_rpcrypt_bright_ambassador(rpcrypt->bright, rpcrypt->ambassador, nonce, morning);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *nonce, uint32_t pin)
|
||||
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, uint32_t pin)
|
||||
{
|
||||
static const uint8_t regist_aes_key[CHIAKI_KEY_BYTES] = { 0x3f, 0x1c, 0xc4, 0xb6, 0xdc, 0xbb, 0x3e, 0xcc, 0x50, 0xba, 0xed, 0xef, 0x97, 0x34, 0xc7, 0xc9 };
|
||||
memcpy(rpcrypt->ambassador, nonce, sizeof(rpcrypt->ambassador));
|
||||
static const uint8_t regist_aes_key[CHIAKI_RPCRYPT_KEY_SIZE] = { 0x3f, 0x1c, 0xc4, 0xb6, 0xdc, 0xbb, 0x3e, 0xcc, 0x50, 0xba, 0xed, 0xef, 0x97, 0x34, 0xc7, 0xc9 };
|
||||
memcpy(rpcrypt->ambassador, ambassador, sizeof(rpcrypt->ambassador));
|
||||
memcpy(rpcrypt->bright, regist_aes_key, sizeof(rpcrypt->bright));
|
||||
rpcrypt->bright[0] ^= (uint8_t)((pin >> 0x18) & 0xff);
|
||||
rpcrypt->bright[1] ^= (uint8_t)((pin >> 0x10) & 0xff);
|
||||
|
@ -81,26 +81,26 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt,
|
|||
{
|
||||
uint8_t hmac_key[] = { 0xac, 0x07, 0x88, 0x83, 0xc8, 0x3a, 0x1f, 0xe8, 0x11, 0x46, 0x3a, 0xf3, 0x9e, 0xe3, 0xe3, 0x77 };
|
||||
|
||||
uint8_t buf[CHIAKI_KEY_BYTES + 8];
|
||||
memcpy(buf, rpcrypt->ambassador, CHIAKI_KEY_BYTES);
|
||||
buf[CHIAKI_KEY_BYTES + 0] = (uint8_t)((counter >> 0x38) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 1] = (uint8_t)((counter >> 0x30) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 2] = (uint8_t)((counter >> 0x28) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 3] = (uint8_t)((counter >> 0x20) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 4] = (uint8_t)((counter >> 0x18) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 5] = (uint8_t)((counter >> 0x10) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 6] = (uint8_t)((counter >> 0x08) & 0xff);
|
||||
buf[CHIAKI_KEY_BYTES + 7] = (uint8_t)((counter >> 0x00) & 0xff);
|
||||
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_KEY_BYTES, buf, sizeof(buf), hmac, &hmac_len))
|
||||
if(!HMAC(EVP_sha256(), hmac_key, CHIAKI_RPCRYPT_KEY_SIZE, buf, sizeof(buf), hmac, &hmac_len))
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
if(hmac_len < CHIAKI_KEY_BYTES)
|
||||
if(hmac_len < CHIAKI_RPCRYPT_KEY_SIZE)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
memcpy(iv, hmac, CHIAKI_KEY_BYTES);
|
||||
memcpy(iv, hmac, CHIAKI_RPCRYPT_KEY_SIZE);
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ static ChiakiErrorCode chiaki_rpcrypt_crypt(ChiakiRPCrypt *rpcrypt, uint64_t cou
|
|||
if(!ctx)
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
|
||||
uint8_t iv[CHIAKI_KEY_BYTES];
|
||||
uint8_t iv[CHIAKI_RPCRYPT_KEY_SIZE];
|
||||
ChiakiErrorCode err = chiaki_rpcrypt_generate_iv(rpcrypt, iv, counter);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return err;
|
||||
|
|
|
@ -584,9 +584,9 @@ static bool session_thread_request_session(ChiakiSession *session)
|
|||
|
||||
if(response.success)
|
||||
{
|
||||
size_t nonce_len = CHIAKI_KEY_BYTES;
|
||||
size_t nonce_len = CHIAKI_RPCRYPT_KEY_SIZE;
|
||||
err = chiaki_base64_decode(response.nonce, strlen(response.nonce), session->nonce, &nonce_len);
|
||||
if(err != CHIAKI_ERR_SUCCESS || nonce_len != CHIAKI_KEY_BYTES)
|
||||
if(err != CHIAKI_ERR_SUCCESS || nonce_len != CHIAKI_RPCRYPT_KEY_SIZE)
|
||||
{
|
||||
CHIAKI_LOGE(session->log, "Nonce invalid");
|
||||
response.success = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue