PS4 Firmware 8.0 Compatibility (Fix #328)

This commit is contained in:
Florian Märkl 2020-10-16 11:01:00 +02:00
commit 4dac2253df
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
20 changed files with 1273 additions and 136 deletions

1
.gitignore vendored
View file

@ -24,3 +24,4 @@ secret.tar
keystore-env.sh
compile_commands.json
.ccls-cache
.gdb_history

View file

@ -31,6 +31,7 @@ android {
arguments "-DCHIAKI_ENABLE_TESTS=OFF",
"-DCHIAKI_ENABLE_CLI=OFF",
"-DCHIAKI_ENABLE_GUI=OFF",
"-DCHIAKI_ENABLE_SETSU=OFF",
"-DCHIAKI_ENABLE_ANDROID=ON",
"-DCHIAKI_LIB_ENABLE_OPUS=OFF",
"-DCHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT=ON"

View file

@ -702,6 +702,11 @@ JNIEXPORT void JNICALL JNI_FCN(registStart)(JNIEnv *env, jobject obj, jobject re
")V");
jclass regist_info_class = E->GetObjectClass(env, regist_info_obj);
jobject target_obj = E->GetObjectField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "target", "L"BASE_PACKAGE"/Target;"));
jclass target_class = E->GetObjectClass(env, target_obj);
jint target_value = E->GetIntField(env, target_obj, E->GetFieldID(env, target_class, "value", "I"));
jstring host_string = E->GetObjectField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "host", "Ljava/lang/String;"));
jboolean broadcast = E->GetBooleanField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "broadcast", "Z"));
jstring psn_online_id_string = E->GetObjectField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "psnOnlineId", "Ljava/lang/String;"));
@ -709,6 +714,7 @@ JNIEXPORT void JNICALL JNI_FCN(registStart)(JNIEnv *env, jobject obj, jobject re
jint pin = E->GetIntField(env, regist_info_obj, E->GetFieldID(env, regist_info_class, "pin", "I"));
ChiakiRegistInfo regist_info = { 0 };
regist_info.target = (ChiakiTarget)target_value;
regist_info.host = E->GetStringUTFChars(env, host_string, NULL);
regist_info.broadcast = broadcast;
if(psn_online_id_string)

View file

@ -3,11 +3,19 @@ package com.metallic.chiaki.lib
import android.os.Parcelable
import android.util.Log
import android.view.Surface
import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize
import java.lang.Exception
import java.net.InetSocketAddress
import kotlin.math.abs
enum class Target(val value: Int)
{
PS4_8(800),
PS4_9(900),
PS4_10(1000)
}
enum class VideoResolutionPreset(val value: Int)
{
RES_360P(1),
@ -316,6 +324,7 @@ class DiscoveryService(
@Parcelize
data class RegistInfo(
val target: Target,
val host: String,
val broadcast: Boolean,
val psnOnlineId: String?,

View file

@ -28,6 +28,7 @@ import androidx.lifecycle.ViewModelProvider
import com.metallic.chiaki.R
import com.metallic.chiaki.common.ext.RevealActivity
import com.metallic.chiaki.lib.RegistInfo
import com.metallic.chiaki.lib.Target
import kotlinx.android.synthetic.main.activity_regist.*
import java.lang.IllegalArgumentException
@ -63,7 +64,8 @@ class RegistActivity: AppCompatActivity(), RevealActivity
registButton.setOnClickListener { doRegist() }
ps4VersionRadioGroup.check(when(viewModel.ps4Version.value ?: RegistViewModel.PS4Version.GE_7) {
ps4VersionRadioGroup.check(when(viewModel.ps4Version.value ?: RegistViewModel.PS4Version.GE_8) {
RegistViewModel.PS4Version.GE_8 -> R.id.ps4VersionGE8RadioButton
RegistViewModel.PS4Version.GE_7 -> R.id.ps4VersionGE7RadioButton
RegistViewModel.PS4Version.LT_7 -> R.id.ps4VersionLT7RadioButton
})
@ -71,6 +73,7 @@ class RegistActivity: AppCompatActivity(), RevealActivity
ps4VersionRadioGroup.setOnCheckedChangeListener { _, checkedId ->
viewModel.ps4Version.value = when(checkedId)
{
R.id.ps4VersionGE8RadioButton -> RegistViewModel.PS4Version.GE_8
R.id.ps4VersionGE7RadioButton -> RegistViewModel.PS4Version.GE_7
R.id.ps4VersionLT7RadioButton -> RegistViewModel.PS4Version.LT_7
else -> RegistViewModel.PS4Version.GE_7
@ -78,11 +81,11 @@ class RegistActivity: AppCompatActivity(), RevealActivity
}
viewModel.ps4Version.observe(this, Observer {
psnAccountIdHelpGroup.visibility = if(it == RegistViewModel.PS4Version.GE_7) View.VISIBLE else View.GONE
psnAccountIdHelpGroup.visibility = if(it == RegistViewModel.PS4Version.LT_7) View.GONE else View.VISIBLE
psnIdTextInputLayout.hint = getString(when(it!!)
{
RegistViewModel.PS4Version.GE_7 -> R.string.hint_regist_psn_account_id
RegistViewModel.PS4Version.LT_7 -> R.string.hint_regist_psn_online_id
else -> R.string.hint_regist_psn_account_id
})
})
}
@ -98,14 +101,14 @@ class RegistActivity: AppCompatActivity(), RevealActivity
val psnId = psnIdEditText.text.toString().trim()
val psnOnlineId: String? = if(ps4Version == RegistViewModel.PS4Version.LT_7) psnId else null
val psnAccountId: ByteArray? =
if(ps4Version == RegistViewModel.PS4Version.GE_7)
if(ps4Version != RegistViewModel.PS4Version.LT_7)
try { Base64.decode(psnId, Base64.DEFAULT) } catch(e: IllegalArgumentException) { null }
else
null
val psnIdValid = when(ps4Version)
{
RegistViewModel.PS4Version.GE_7 -> psnAccountId != null && psnAccountId.size == RegistInfo.ACCOUNT_ID_SIZE
RegistViewModel.PS4Version.LT_7 -> psnOnlineId?.isNotEmpty() ?: false
else -> psnAccountId != null && psnAccountId.size == RegistInfo.ACCOUNT_ID_SIZE
}
@ -117,8 +120,8 @@ class RegistActivity: AppCompatActivity(), RevealActivity
if(!psnIdValid)
getString(when(ps4Version)
{
RegistViewModel.PS4Version.GE_7 -> R.string.regist_psn_account_id_invalid
RegistViewModel.PS4Version.LT_7 -> R.string.regist_psn_online_id_invalid
else -> R.string.regist_psn_account_id_invalid
})
else
null
@ -127,7 +130,14 @@ class RegistActivity: AppCompatActivity(), RevealActivity
if(!hostValid || !psnIdValid || !pinValid)
return
val registInfo = RegistInfo(host, broadcast, psnOnlineId, psnAccountId, pin.toInt())
val target = when(ps4Version)
{
RegistViewModel.PS4Version.GE_8 -> Target.PS4_10
RegistViewModel.PS4Version.GE_7 -> Target.PS4_9
RegistViewModel.PS4Version.LT_7 -> Target.PS4_8
}
val registInfo = RegistInfo(target, host, broadcast, psnOnlineId, psnAccountId, pin.toInt())
Intent(this, RegistExecuteActivity::class.java).also {
it.putExtra(RegistExecuteActivity.EXTRA_REGIST_INFO, registInfo)

View file

@ -23,9 +23,10 @@ import androidx.lifecycle.ViewModel
class RegistViewModel: ViewModel()
{
enum class PS4Version {
GE_8,
GE_7,
LT_7
}
val ps4Version = MutableLiveData<PS4Version>(PS4Version.GE_7)
val ps4Version = MutableLiveData<PS4Version>(PS4Version.GE_8)
}

View file

@ -69,13 +69,22 @@
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/broadcastCheckBox">
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/ps4VersionGE8RadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/regist_option_ps4_ge_8"
android:layout_weight="1"
android:checked="true"/>
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/ps4VersionGE7RadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/regist_option_ps4_ge_7"
android:layout_weight="1"
android:checked="true"/>
android:checked="false"
android:text="@string/regist_option_ps4_ge_7" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/ps4VersionLT7RadioButton"
android:layout_width="wrap_content"

View file

@ -28,7 +28,8 @@
<string name="hint_regist_host">Host</string>
<string name="regist_broadcast">Broadcast</string>
<string name="regist_option_ps4_lt_7">PS4 &lt; 7.0</string>
<string name="regist_option_ps4_ge_7">PS4 ≥ 7.0</string>
<string name="regist_option_ps4_ge_7">PS4 ≥ 7.0, &lt; 8</string>
<string name="regist_option_ps4_ge_8">PS4 ≥ 8.0</string>
<string name="regist_psn_account_id_help">About obtaining your Account ID, see</string>
<string name="regist_psn_account_id_help_url">https://github.com/thestr4ng3r/chiaki/blob/master/README.md#obtaining-your-psn-accountid</string>
<string name="hint_regist_psn_online_id">PSN Online ID (username, case-sensitive)</string>

View file

@ -41,9 +41,10 @@ class RegistDialog : public QDialog
QLineEdit *host_edit;
QCheckBox *broadcast_check_box;
QRadioButton *psn_online_id_radio_button;
QRadioButton *ps4_pre9_radio_button;
QRadioButton *ps4_pre10_radio_button;
QRadioButton *ps4_10_radio_button;
QLineEdit *psn_online_id_edit;
QRadioButton *psn_account_id_radio_button;
QLineEdit *psn_account_id_edit;
QLineEdit *pin_edit;
QDialogButtonBox *button_box;
@ -51,6 +52,8 @@ class RegistDialog : public QDialog
RegisteredHost registered_host;
bool NeedAccountId();
private slots:
void ValidateInput();

View file

@ -59,20 +59,29 @@ RegistDialog::RegistDialog(Settings *settings, const QString &host, QWidget *par
broadcast_check_box->setChecked(host.isEmpty());
auto UpdatePSNIDEdits = [this]() {
psn_online_id_edit->setEnabled(psn_online_id_radio_button->isChecked());
psn_account_id_edit->setEnabled(psn_account_id_radio_button->isChecked());
bool need_account_id = NeedAccountId();
psn_online_id_edit->setEnabled(!need_account_id);
psn_account_id_edit->setEnabled(need_account_id);
};
psn_online_id_radio_button = new QRadioButton(tr("PSN Online-ID (username, case-sensitive) for PS4 < 7.0:"), this);
psn_online_id_edit = new QLineEdit(this);
form_layout->addRow(psn_online_id_radio_button, psn_online_id_edit);
connect(psn_online_id_radio_button, &QRadioButton::toggled, this, UpdatePSNIDEdits);
auto version_layout = new QVBoxLayout(nullptr);
ps4_pre9_radio_button = new QRadioButton(tr("< 7.0"), this);
version_layout->addWidget(ps4_pre9_radio_button);
connect(ps4_pre9_radio_button, &QRadioButton::toggled, this, UpdatePSNIDEdits);
ps4_pre10_radio_button = new QRadioButton(tr(">= 7.0, < 8.0"), this);
version_layout->addWidget(ps4_pre10_radio_button);
connect(ps4_pre10_radio_button, &QRadioButton::toggled, this, UpdatePSNIDEdits);
ps4_10_radio_button = new QRadioButton(tr(">= 8.0"), this);
version_layout->addWidget(ps4_10_radio_button);
connect(ps4_10_radio_button, &QRadioButton::toggled, this, UpdatePSNIDEdits);
form_layout->addRow(tr("PS4 Firmware:"), version_layout);
psn_account_id_radio_button = new QRadioButton(tr("PSN Account-ID (base64) for PS4 >= 7.0:"), this);
psn_online_id_edit = new QLineEdit(this);
form_layout->addRow(tr("PSN Online-ID (username, case-sensitive):"), psn_online_id_edit);
psn_account_id_edit = new QLineEdit(this);
form_layout->addRow(psn_account_id_radio_button, psn_account_id_edit);
psn_account_id_radio_button->setChecked(true);
connect(psn_account_id_radio_button, &QRadioButton::toggled, this, UpdatePSNIDEdits);
form_layout->addRow(tr("PSN Account-ID (base64):"), psn_account_id_edit);
ps4_10_radio_button->setChecked(true);
UpdatePSNIDEdits();
@ -96,11 +105,17 @@ RegistDialog::~RegistDialog()
{
}
bool RegistDialog::NeedAccountId()
{
return !ps4_pre9_radio_button->isChecked();
}
void RegistDialog::ValidateInput()
{
bool need_account_id = NeedAccountId();
bool valid = !host_edit->text().trimmed().isEmpty()
&& (!psn_online_id_radio_button->isChecked() || !psn_online_id_edit->text().trimmed().isEmpty())
&& (!psn_account_id_radio_button->isChecked() || !psn_account_id_radio_button->text().trimmed().isEmpty())
&& !(!need_account_id && psn_online_id_edit->text().trimmed().isEmpty())
&& !(need_account_id && psn_account_id_edit->text().trimmed().isEmpty())
&& pin_edit->text().length() == PIN_LENGTH;
register_button->setEnabled(valid);
}
@ -111,8 +126,16 @@ void RegistDialog::accept()
QByteArray host = host_edit->text().trimmed().toUtf8();
info.host = host.constData();
if(ps4_pre9_radio_button->isChecked())
info.target = CHIAKI_TARGET_PS4_8;
else if(ps4_pre10_radio_button->isChecked())
info.target = CHIAKI_TARGET_PS4_9;
else
info.target = CHIAKI_TARGET_PS4_10;
bool need_account_id = NeedAccountId();
QByteArray psn_id; // keep this out of the if scope
if(psn_online_id_radio_button->isChecked())
if(!need_account_id)
{
psn_id = psn_online_id_edit->text().trimmed().toUtf8();
info.psn_online_id = psn_id.constData();

View file

@ -72,6 +72,15 @@ CHIAKI_EXPORT const char *chiaki_error_string(ChiakiErrorCode code);
CHIAKI_EXPORT void *chiaki_aligned_alloc(size_t alignment, size_t size);
CHIAKI_EXPORT void chiaki_aligned_free(void *ptr);
typedef enum
{
// values must not change
CHIAKI_TARGET_PS4_UNKNOWN = 0,
CHIAKI_TARGET_PS4_8 = 800,
CHIAKI_TARGET_PS4_9 = 900,
CHIAKI_TARGET_PS4_10 = 1000
} ChiakiTarget;
/**
* Perform initialization of global state needed for using the Chiaki lib
*/

View file

@ -33,6 +33,7 @@ extern "C" {
typedef struct chiaki_regist_info_t
{
ChiakiTarget target;
const char *host;
bool broadcast;
@ -94,7 +95,7 @@ CHIAKI_EXPORT void chiaki_regist_stop(ChiakiRegist *regist);
/**
* @param psn_account_id must be exactly of size CHIAKI_PSN_ACCOUNT_ID_SIZE
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(uint8_t *buf, size_t *buf_size, ChiakiRPCrypt *crypt, const char *psn_online_id, const uint8_t *psn_account_id);
CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(ChiakiTarget target, const uint8_t *ambassador, uint8_t *buf, size_t *buf_size, ChiakiRPCrypt *crypt, const char *psn_online_id, const uint8_t *psn_account_id, uint32_t pin);
#ifdef __cplusplus
}

View file

@ -31,15 +31,18 @@ extern "C" {
typedef struct chiaki_rpcrypt_t
{
ChiakiTarget target;
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 *ambassador);
CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(ChiakiTarget target, uint8_t *bright, uint8_t *ambassador, const uint8_t *nonce, const uint8_t *morning);
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause_ps4_pre10(uint8_t *aeropause, const uint8_t *ambassador);
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause(size_t key_1_off, 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 *ambassador, uint32_t pin);
CHIAKI_EXPORT void chiaki_rpcrypt_init_auth(ChiakiRPCrypt *rpcrypt, ChiakiTarget target, const uint8_t *nonce, const uint8_t *morning);
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist_ps4_pre10(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, uint32_t pin);
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, size_t key_0_off, 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, const uint8_t *in, uint8_t *out, size_t sz);
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_decrypt(ChiakiRPCrypt *rpcrypt, uint64_t counter, const uint8_t *in, uint8_t *out, size_t sz);

View file

@ -43,22 +43,16 @@ extern "C" {
#define CHIAKI_RP_APPLICATION_REASON_IN_USE 0x80108b10
#define CHIAKI_RP_APPLICATION_REASON_CRASH 0x80108b15
#define CHIAKI_RP_APPLICATION_REASON_RP_VERSION 0x80108b11
// unknown: 0x80108bff
#define CHIAKI_RP_APPLICATION_REASON_UNKNOWN 0x80108bff
CHIAKI_EXPORT const char *chiaki_rp_application_reason_string(uint32_t reason);
typedef enum {
CHIAKI_RP_VERSION_UNKNOWN = 0,
CHIAKI_RP_VERSION_8_0 = 800,
CHIAKI_RP_VERSION_9_0 = 900
} ChiakiRpVersion;
/**
* @return RP-Version string or NULL
*/
CHIAKI_EXPORT const char *chiaki_rp_version_string(ChiakiRpVersion version);
CHIAKI_EXPORT const char *chiaki_rp_version_string(ChiakiTarget target);
CHIAKI_EXPORT ChiakiRpVersion chiaki_rp_version_parse(const char *rp_version_str);
CHIAKI_EXPORT ChiakiTarget chiaki_rp_version_parse(const char *rp_version_str);
#define CHIAKI_RP_DID_SIZE 32
@ -171,7 +165,7 @@ typedef struct chiaki_session_t
ChiakiConnectVideoProfile video_profile;
} connect_info;
ChiakiRpVersion rp_version;
ChiakiTarget target;
uint8_t nonce[CHIAKI_RPCRYPT_KEY_SIZE];
ChiakiRPCrypt rpcrypt;

View file

@ -576,9 +576,23 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
if(err != CHIAKI_ERR_SUCCESS)
goto error;
char bitrate_b64[256];
bool have_bitrate = session->target >= CHIAKI_TARGET_PS4_10;
if(have_bitrate)
{
uint8_t bitrate[4] = { 0 };
uint8_t bitrate_enc[4] = { 0 };
err = chiaki_rpcrypt_encrypt(&session->rpcrypt, ctrl->crypt_counter_local++, (const uint8_t *)bitrate, bitrate_enc, 4);
if(err != CHIAKI_ERR_SUCCESS)
goto error;
err = chiaki_base64_encode(bitrate_enc, 4, bitrate_b64, sizeof(bitrate_b64));
if(err != CHIAKI_ERR_SUCCESS)
goto error;
}
static const char request_fmt[] =
"GET /sce/rp/session/ctrl HTTP/1.1\r\n"
"GET %s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"User-Agent: remoteplay Windows\r\n"
"Connection: keep-alive\r\n"
@ -589,17 +603,27 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
"RP-ControllerType: 3\r\n"
"RP-ClientType: 11\r\n"
"RP-OSType: %s\r\n"
"RP-ConPath: 1\r\n\r\n";
"RP-ConPath: 1\r\n"
"%s%s%s"
"\r\n";
const char *rp_version = chiaki_rp_version_string(session->rp_version);
const char *path = (session->target == CHIAKI_TARGET_PS4_8 || session->target == CHIAKI_TARGET_PS4_9)
? "/sce/rp/session/ctrl"
: "/sie/ps4/rp/sess/ctrl";
const char *rp_version = chiaki_rp_version_string(session->target);
char buf[512];
int request_len = snprintf(buf, sizeof(buf), request_fmt,
session->connect_info.hostname, SESSION_CTRL_PORT, auth_b64, rp_version ? rp_version : "", did_b64, ostype_b64);
path, session->connect_info.hostname, SESSION_CTRL_PORT, auth_b64,
rp_version ? rp_version : "", did_b64, ostype_b64,
have_bitrate ? "RP-StartBitrate: " : "",
have_bitrate ? bitrate_b64 : "",
have_bitrate ? "\r\n" : "");
if(request_len < 0 || request_len >= sizeof(buf))
goto error;
CHIAKI_LOGI(session->log, "Sending ctrl request");
chiaki_log_hexdump(session->log, CHIAKI_LOG_VERBOSE, (const uint8_t *)buf, (size_t)request_len);
int sent = send(sock, buf, (size_t)request_len, 0);
if(sent < 0)

View file

@ -106,34 +106,42 @@ static void regist_event_simple(ChiakiRegist *regist, ChiakiRegistEventType type
regist->cb(&event, regist->cb_user);
}
static const char * const request_head_fmt =
"POST /sce/rp/regist HTTP/1.1\r\n"
static const char *const request_head_fmt =
"POST %s HTTP/1.1\r\n HTTP/1.1\r\n"
"HOST: 10.0.2.15\r\n" // random lol
"User-Agent: remoteplay Windows\r\n"
"Connection: close\r\n"
"Content-Length: %llu\r\n";
static const char * const request_rp_version_fmt = "RP-Version: %s\r\n";
static const char *request_path = "/sie/ps4/rp/sess/rgst";
static const char *request_path_ps4_pre10 = "/sce/rp/regist";
static const char * const request_tail = "\r\n";
static const char *const request_rp_version_fmt = "RP-Version: %s\r\n";
static const char * const request_inner_account_id_fmt =
"Client-Type: Windows\r\n"
static const char *const request_tail = "\r\n";
const char *client_type = "dabfa2ec873de5839bee8d3f4c0239c4282c07c25c6077a2931afcf0adc0d34f";
const char *client_type_ps4_pre10 = "Windows";
static const char *const request_inner_account_id_fmt =
"Client-Type: %s\r\n"
"Np-AccountId: %s\r\n";
static const char * const request_inner_online_id_fmt =
static const char *const request_inner_online_id_fmt =
"Client-Type: Windows\r\n"
"Np-Online-Id: %s\r\n";
static int request_header_format(char *buf, size_t buf_size, size_t payload_size, ChiakiRpVersion rp_version)
static int request_header_format(char *buf, size_t buf_size, size_t payload_size, ChiakiTarget target)
{
int cur = snprintf(buf, buf_size, request_head_fmt, (unsigned long long)payload_size);
int cur = snprintf(buf, buf_size, request_head_fmt,
target < CHIAKI_TARGET_PS4_10 ? request_path_ps4_pre10 : request_path,
(unsigned long long)payload_size);
if(cur < 0 || cur >= payload_size)
return -1;
if(rp_version >= CHIAKI_RP_VERSION_9_0)
if(target >= CHIAKI_TARGET_PS4_9)
{
const char *rp_version_str = chiaki_rp_version_string(rp_version);
const char *rp_version_str = chiaki_rp_version_string(target);
size_t s = buf_size - cur;
int r = snprintf(buf + cur, s, request_rp_version_fmt, rp_version_str);
if(r < 0 || r >= s)
@ -149,14 +157,31 @@ static int request_header_format(char *buf, size_t buf_size, size_t payload_size
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(uint8_t *buf, size_t *buf_size, ChiakiRPCrypt *crypt, const char *psn_online_id, const uint8_t *psn_account_id)
CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(ChiakiTarget target, const uint8_t *ambassador, uint8_t *buf, size_t *buf_size, ChiakiRPCrypt *crypt, const char *psn_online_id, const uint8_t *psn_account_id, uint32_t pin)
{
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);
memset(buf, 'A', inner_header_off); // can be random
if(target < CHIAKI_TARGET_PS4_10)
{
chiaki_rpcrypt_init_regist_ps4_pre10(crypt, ambassador, pin);
chiaki_rpcrypt_aeropause_ps4_pre10(buf + 0x11c, crypt->ambassador);
}
else
{
size_t key_0_off = buf[0x18D] & 0x1F;
size_t key_1_off = buf[0] >> 3;
chiaki_rpcrypt_init_regist(crypt, ambassador, key_0_off, pin);
uint8_t aeropause[0x10];
chiaki_rpcrypt_aeropause(key_1_off, aeropause, crypt->ambassador);
memcpy(buf + 0xc7, aeropause + 8, 8);
memcpy(buf + 0x191, aeropause, 8);
psn_online_id = NULL; // don't need this
}
int inner_header_size;
if(psn_online_id)
inner_header_size = snprintf((char *)buf + inner_header_off, buf_size_val - inner_header_off, request_inner_online_id_fmt, psn_online_id);
@ -166,7 +191,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_regist_request_payload_format(uint8_t *buf,
ChiakiErrorCode err = chiaki_base64_encode(psn_account_id, CHIAKI_PSN_ACCOUNT_ID_SIZE, account_id_b64, sizeof(account_id_b64));
if(err != CHIAKI_ERR_SUCCESS)
return err;
inner_header_size = snprintf((char *)buf + inner_header_off, buf_size_val - inner_header_off, request_inner_account_id_fmt, account_id_b64);
inner_header_size = snprintf((char *)buf + inner_header_off, buf_size_val - inner_header_off,
request_inner_account_id_fmt,
target < CHIAKI_TARGET_PS4_10 ? client_type_ps4_pre10 : client_type,
account_id_b64);
}
else
return CHIAKI_ERR_INVALID_DATA;
@ -184,29 +212,26 @@ static void *regist_thread_func(void *user)
bool canceled = false;
bool success = false;
ChiakiRPCrypt crypt;
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");
CHIAKI_LOGE(regist->log, "Regist failed to generate random ambassador");
goto fail;
}
ChiakiRPCrypt crypt;
chiaki_rpcrypt_init_regist(&crypt, ambassador, regist->info.pin);
uint8_t payload[0x400];
size_t payload_size = sizeof(payload);
err = chiaki_regist_request_payload_format(payload, &payload_size, &crypt, regist->info.psn_online_id, regist->info.psn_account_id);
err = chiaki_regist_request_payload_format(regist->info.target, ambassador, payload, &payload_size, &crypt, regist->info.psn_online_id, regist->info.psn_account_id, regist->info.pin);
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(regist->log, "Regist failed to format payload");
goto fail;
}
ChiakiRpVersion rp_version = regist->info.psn_online_id ? CHIAKI_RP_VERSION_8_0 : CHIAKI_RP_VERSION_9_0;
char request_header[0x100];
int request_header_size = request_header_format(request_header, sizeof(request_header), payload_size, rp_version);
int request_header_size = request_header_format(request_header, sizeof(request_header), payload_size, regist->info.target);
if(request_header_size < 0 || request_header_size >= sizeof(request_header))
{

View file

@ -31,7 +31,7 @@
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)
static void bright_ambassador_ps4_pre10(uint8_t *bright, uint8_t *ambassador, const uint8_t *nonce, const uint8_t *morning)
{
static const uint8_t echo_a[] = { 0x01, 0x49, 0x87, 0x9b, 0x65, 0x39, 0x8b, 0x39, 0x4b, 0x3a, 0x8d, 0x48, 0xc3, 0x0a, 0xef, 0x51 };
@ -55,7 +55,768 @@ 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 *ambassador)
static void bright_ambassador(uint8_t *bright, uint8_t *ambassador, const uint8_t *nonce, const uint8_t *morning)
{
static const uint8_t static_keys_a[0x70 * 0x20] = {
0xdf, 0x40, 0x82, 0xa6, 0x2e, 0xd8, 0x6b, 0x2b, 0xf5, 0x6c,
0x5f, 0xf5, 0xfb, 0x21, 0x69, 0xb4, 0x00, 0x27, 0x5e, 0x87,
0xfa, 0x1a, 0xa7, 0x95, 0x16, 0xa1, 0xb7, 0xb7, 0xca, 0xf2,
0x3d, 0x7a, 0x04, 0x97, 0xef, 0x49, 0xeb, 0x51, 0xbc, 0xe9,
0x2a, 0x47, 0x84, 0xba, 0xfb, 0x08, 0x78, 0x4a, 0xa7, 0x82,
0x17, 0xad, 0x4b, 0x26, 0x34, 0x97, 0xb2, 0xde, 0x41, 0x7d,
0xc6, 0x08, 0xc4, 0xe9, 0xe7, 0x73, 0xa1, 0x22, 0xa2, 0xf3,
0x2a, 0x6f, 0x8c, 0xc0, 0x45, 0xf6, 0x84, 0xb4, 0xd7, 0x54,
0x07, 0xd5, 0x76, 0x33, 0xd3, 0x8b, 0x61, 0xe7, 0xea, 0xd6,
0x98, 0x32, 0xf5, 0xeb, 0x9e, 0x1b, 0xbd, 0xe2, 0x01, 0x31,
0x45, 0x01, 0x0d, 0x51, 0x1f, 0x77, 0xaf, 0x0c, 0x34, 0xb7,
0x23, 0x40, 0x0d, 0xc0, 0xac, 0x7e, 0x04, 0xb5, 0xf0, 0x75,
0xde, 0x5e, 0xba, 0xfa, 0xa6, 0x25, 0x56, 0xde, 0x53, 0x83,
0x94, 0x4e, 0xa4, 0xd9, 0x4e, 0xf4, 0x73, 0xab, 0xd6, 0x96,
0xb6, 0xfc, 0x09, 0x46, 0xe2, 0x1a, 0x9d, 0x4f, 0xf1, 0x89,
0x90, 0xa0, 0x34, 0xf4, 0x55, 0x60, 0x29, 0xf9, 0x39, 0xdb,
0x20, 0xaa, 0xdf, 0x8b, 0xff, 0x6c, 0xc0, 0xa9, 0x96, 0xad,
0x71, 0x67, 0xae, 0xb6, 0x1a, 0x6e, 0xd4, 0x92, 0x7a, 0xc7,
0xac, 0x31, 0xc8, 0x21, 0x24, 0x3b, 0xb3, 0x6a, 0x1d, 0x4d,
0xc0, 0x82, 0x5f, 0x53, 0x9f, 0xf9, 0xeb, 0x4a, 0x41, 0x47,
0x27, 0x5a, 0xbc, 0x3b, 0xc8, 0x50, 0x20, 0xeb, 0x11, 0x02,
0xf8, 0xc5, 0x7e, 0xa4, 0xd3, 0x85, 0x52, 0x90, 0x61, 0x4e,
0x88, 0xff, 0x81, 0xcf, 0x75, 0x58, 0x21, 0xfe, 0x58, 0x8f,
0xd0, 0x75, 0xf6, 0x20, 0xaa, 0x54, 0x3a, 0x45, 0x54, 0xf3,
0xe4, 0x44, 0xda, 0x98, 0x7f, 0x09, 0x9e, 0xa6, 0x72, 0x63,
0xbc, 0x9f, 0x46, 0x77, 0x7e, 0x24, 0xf8, 0xda, 0xc4, 0x94,
0x04, 0xa9, 0x23, 0xa7, 0xea, 0x67, 0xe3, 0x85, 0x41, 0xa4,
0x4b, 0x8e, 0xc1, 0x92, 0xde, 0x96, 0xc8, 0x09, 0xb7, 0xd4,
0x41, 0x60, 0x89, 0xf0, 0xdb, 0x09, 0x56, 0x01, 0xc1, 0x6c,
0x33, 0xb1, 0x37, 0xbd, 0x79, 0x6f, 0xab, 0x1c, 0x61, 0xe9,
0x18, 0xfc, 0xb3, 0x6c, 0xbc, 0xfe, 0xea, 0xb1, 0x9e, 0xce,
0xba, 0x83, 0xda, 0xe5, 0x81, 0xd7, 0x07, 0xb7, 0x8a, 0xf0,
0x89, 0x39, 0xdc, 0x30, 0x6b, 0x0d, 0xa7, 0x2b, 0xc9, 0x51,
0xdc, 0x4f, 0x99, 0x98, 0x3c, 0xcf, 0x62, 0x1c, 0x56, 0xf1,
0x86, 0x88, 0xdb, 0xce, 0x10, 0xbf, 0x3d, 0xde, 0xe6, 0xf5,
0x02, 0x51, 0xf7, 0xa5, 0xe3, 0x0a, 0xdb, 0xeb, 0xae, 0xb0,
0x76, 0x89, 0x62, 0x4b, 0xa7, 0xbd, 0xd6, 0xfe, 0x8d, 0x01,
0x28, 0x26, 0xf3, 0x76, 0x65, 0xba, 0x0f, 0x44, 0x77, 0x65,
0x79, 0x47, 0x06, 0x43, 0xae, 0xa8, 0xd1, 0x5e, 0x20, 0x0e,
0x72, 0x2a, 0x15, 0xd9, 0x42, 0x96, 0xe7, 0xdb, 0x40, 0xae,
0x4e, 0x2b, 0x1c, 0x6d, 0x71, 0xa2, 0x8e, 0xa6, 0xe1, 0x4d,
0xe8, 0x84, 0xa3, 0xa5, 0x59, 0x41, 0x0c, 0x9e, 0xe9, 0x3e,
0x5a, 0xc8, 0x02, 0x3f, 0xbb, 0xf3, 0xe1, 0x0a, 0xf7, 0x3d,
0xd7, 0xaa, 0xe5, 0x64, 0xc6, 0x4e, 0xc3, 0xc9, 0xbb, 0x32,
0x30, 0xa9, 0x18, 0xec, 0xb8, 0xae, 0x61, 0xc9, 0x1a, 0x62,
0xeb, 0x47, 0x92, 0x0c, 0xa7, 0xe0, 0x6c, 0x33, 0xf5, 0x84,
0xec, 0x69, 0x31, 0xdb, 0xad, 0xdf, 0x3d, 0xbb, 0x4c, 0x4b,
0xa1, 0x8c, 0xf0, 0x46, 0x52, 0x65, 0x72, 0xaf, 0x6a, 0xc8,
0xce, 0xb3, 0x27, 0xd3, 0x32, 0x78, 0xb1, 0x39, 0xd6, 0xd1,
0x5e, 0x09, 0x06, 0xff, 0xdc, 0x8f, 0xca, 0x16, 0x9b, 0x5e,
0xa2, 0x18, 0x64, 0xee, 0x8c, 0x0b, 0x9b, 0xd7, 0x41, 0xf8,
0x35, 0x98, 0xd3, 0x5c, 0x78, 0xe2, 0xbb, 0xa5, 0xf7, 0x68,
0x02, 0x8a, 0xd2, 0x14, 0x85, 0x50, 0x8b, 0x98, 0x2a, 0x09,
0x15, 0xc0, 0x9e, 0x9c, 0x47, 0x1f, 0x92, 0xc2, 0xa5, 0x2a,
0x3b, 0xaa, 0x7b, 0xde, 0xb8, 0xe7, 0xee, 0xa7, 0xe0, 0x4a,
0xb4, 0x81, 0x28, 0x7f, 0x15, 0x38, 0xe8, 0x78, 0xff, 0xc1,
0xed, 0x98, 0xd8, 0x4f, 0x23, 0x3f, 0x77, 0x29, 0xac, 0xa5,
0xbc, 0xd0, 0x8f, 0x2b, 0x89, 0xb9, 0x99, 0xbe, 0xc1, 0xf1,
0x3e, 0x4e, 0xbd, 0x30, 0xd7, 0x6c, 0x1c, 0x09, 0x4e, 0x7c,
0x13, 0x28, 0xf5, 0xc3, 0xff, 0xc1, 0xcf, 0x8a, 0x2a, 0x41,
0xd0, 0x73, 0x24, 0x23, 0x31, 0x13, 0x77, 0xa4, 0x33, 0xc0,
0x7e, 0x7b, 0xc0, 0x81, 0xb5, 0xf5, 0x25, 0x80, 0x45, 0xc5,
0x94, 0x65, 0xa4, 0x8a, 0x94, 0xc1, 0xb6, 0xf4, 0x69, 0x61,
0x11, 0xd5, 0x43, 0xea, 0x4b, 0x38, 0x4a, 0x56, 0x14, 0xdd,
0x3b, 0xa6, 0x99, 0xdf, 0xe5, 0x87, 0x2a, 0xf9, 0x12, 0xbf,
0x45, 0xb1, 0xd9, 0x74, 0x67, 0x8b, 0x2b, 0x57, 0xc3, 0xd0,
0xb1, 0x9a, 0x4a, 0xcc, 0x4f, 0x63, 0x79, 0x5a, 0x4f, 0x1d,
0xa6, 0xff, 0x65, 0xee, 0xbe, 0xd9, 0x16, 0xea, 0xa9, 0x66,
0x07, 0x97, 0x71, 0x43, 0xdd, 0x64, 0xe3, 0x00, 0x03, 0xbc,
0xba, 0x1b, 0xf3, 0xa6, 0xa6, 0xee, 0xef, 0xf8, 0xa7, 0xf2,
0x15, 0xf9, 0xcf, 0x8c, 0x62, 0x2a, 0x1e, 0x9b, 0xbe, 0xfb,
0x5a, 0xb7, 0xed, 0xd5, 0xd2, 0x71, 0x2a, 0xc9, 0xeb, 0x65,
0x68, 0x77, 0x34, 0xa4, 0xbb, 0x44, 0xab, 0x01, 0xe5, 0x79,
0x19, 0x37, 0xb2, 0x07, 0x01, 0xc6, 0xca, 0xb3, 0x07, 0xb8,
0x55, 0xac, 0x03, 0xae, 0xf6, 0x3f, 0x29, 0x12, 0xa1, 0xba,
0x1d, 0x94, 0x3a, 0xa3, 0xb5, 0x6c, 0x6e, 0xf4, 0x31, 0x3f,
0x38, 0xa7, 0xe0, 0x34, 0x31, 0xf2, 0x2a, 0x7a, 0xe6, 0xcf,
0x3f, 0xc4, 0xe9, 0xb9, 0x0f, 0x05, 0x9f, 0xec, 0x9a, 0xdc,
0xb3, 0x59, 0xc4, 0x61, 0xaa, 0x10, 0xb6, 0xce, 0x73, 0xe3,
0xe3, 0x8c, 0xf8, 0x5d, 0x0e, 0x95, 0x3e, 0x1a, 0x4f, 0xbe,
0x77, 0x87, 0xce, 0x8a, 0x17, 0xf5, 0x20, 0xa7, 0x01, 0xf0,
0xd7, 0xe6, 0x34, 0x63, 0x04, 0x76, 0xbe, 0x74, 0xb3, 0x44,
0x7d, 0xdf, 0x11, 0x32, 0xb9, 0x13, 0x32, 0x15, 0x1a, 0xed,
0xcf, 0x1f, 0x85, 0x91, 0xdb, 0xa3, 0xc4, 0xf2, 0x0f, 0x2c,
0x8f, 0x77, 0x0a, 0xc4, 0x09, 0x7d, 0x19, 0x12, 0x7c, 0x46,
0xf7, 0x9d, 0x3a, 0x94, 0x86, 0x4b, 0x22, 0x67, 0x6f, 0x90,
0x57, 0x99, 0x70, 0x28, 0x3d, 0x9c, 0x53, 0xd2, 0xd3, 0x0b,
0xc1, 0x29, 0xb7, 0x39, 0x8c, 0xb7, 0x62, 0xc8, 0xbb, 0x64,
0x4d, 0xcf, 0xe0, 0x5f, 0x64, 0xfc, 0x47, 0xb2, 0xef, 0x0a,
0x68, 0x8d, 0x9a, 0xcd, 0x9f, 0x49, 0x77, 0x6b, 0x50, 0x47,
0x7c, 0xfc, 0xa4, 0xd4, 0x2c, 0x4d, 0x53, 0xc1, 0x26, 0x26,
0x92, 0x38, 0x0d, 0xba, 0x1c, 0x71, 0x81, 0x17, 0x4a, 0x59,
0x0f, 0x80, 0xfd, 0xad, 0x69, 0x5c, 0x58, 0xa7, 0xff, 0xef,
0x1a, 0xca, 0xd6, 0xfb, 0x7e, 0x09, 0xdc, 0x32, 0x17, 0x34,
0x31, 0x9c, 0xfa, 0x78, 0xf9, 0x88, 0x1a, 0x50, 0x6b, 0x09,
0x24, 0xfe, 0x75, 0xcd, 0x22, 0xbd, 0xf0, 0x12, 0x10, 0x9d,
0xc5, 0x7b, 0xbe, 0x9f, 0xa4, 0xc8, 0x7a, 0x7c, 0xb1, 0xa7,
0x46, 0x2d, 0x48, 0xa1, 0x08, 0xd8, 0x75, 0x3c, 0x40, 0x53,
0x59, 0x5a, 0x04, 0xf6, 0xcb, 0xd6, 0x2f, 0x51, 0x9e, 0x4a,
0xa8, 0xef, 0x02, 0x3c, 0x61, 0xa8, 0x45, 0x5a, 0x99, 0x9a,
0x73, 0x09, 0xc0, 0x71, 0x6f, 0x4d, 0xb7, 0x2c, 0x69, 0x6c,
0x1e, 0x85, 0x48, 0xea, 0x33, 0x5b, 0xb1, 0x28, 0x09, 0xe3,
0x24, 0x47, 0x7a, 0x12, 0xd8, 0x77, 0xa0, 0xfd, 0x3c, 0xcd,
0x23, 0x53, 0x61, 0xf0, 0x9e, 0x49, 0x44, 0x19, 0x9c, 0xe1,
0x0a, 0xb6, 0xc5, 0x93, 0x35, 0x4d, 0x06, 0xde, 0xb5, 0xac,
0x15, 0xe2, 0x8d, 0x47, 0x6a, 0x8a, 0x29, 0x58, 0x8f, 0xfc,
0x2b, 0x32, 0xc4, 0x0e, 0x4e, 0x75, 0xb2, 0x71, 0x44, 0x91,
0xb6, 0xfb, 0x50, 0x60, 0xc4, 0x50, 0x4d, 0xd9, 0x1c, 0xd7,
0x28, 0xb5, 0x2e, 0x08, 0x82, 0xfd, 0xbd, 0x7c, 0x48, 0x62,
0x00, 0x01, 0x30, 0xa5, 0x47, 0x2a, 0x10, 0x4b, 0xfe, 0x3e,
0xb5, 0xd7, 0xe2, 0x1e, 0x5a, 0xd0, 0xe3, 0x6b, 0xa0, 0x9c,
0xe3, 0x12, 0x05, 0xb9, 0x1c, 0x7b, 0x3f, 0x18, 0x88, 0x11,
0xc3, 0x4d, 0xe8, 0x83, 0x78, 0xf1, 0x8c, 0x6a, 0xb3, 0x87,
0x7f, 0x67, 0xdf, 0x47, 0xc4, 0x2f, 0xea, 0x9c, 0x79, 0x98,
0x35, 0x2d, 0x7b, 0x2d, 0xc7, 0x3e, 0x31, 0x13, 0x6e, 0xf3,
0xfd, 0xa8, 0x16, 0x25, 0x03, 0x3f, 0xb1, 0x14, 0x77, 0xff,
0xa1, 0xf2, 0xe9, 0x98, 0x32, 0xe4, 0x2f, 0x3e, 0xb0, 0x6e,
0x29, 0x84, 0x0f, 0xdd, 0x85, 0xbb, 0xda, 0x0a, 0xc6, 0x19,
0x78, 0x9a, 0x6b, 0xdd, 0x8b, 0x40, 0x39, 0x1f, 0x19, 0xce,
0xad, 0x79, 0xc9, 0xda, 0x59, 0xbf, 0x6e, 0xbc, 0xb0, 0xc8,
0x6e, 0x61, 0xeb, 0x2e, 0xba, 0xa6, 0x50, 0x06, 0x8c, 0x74,
0xab, 0x23, 0x4f, 0x9d, 0x9e, 0x20, 0x67, 0x9a, 0x0c, 0xea,
0x60, 0x14, 0x85, 0x42, 0xc4, 0x7d, 0xc0, 0x1c, 0x62, 0xa5,
0x7e, 0x65, 0x1d, 0xee, 0xa1, 0xfd, 0xed, 0x82, 0x19, 0x1e,
0x90, 0x87, 0xab, 0xdb, 0x80, 0xb7, 0xb2, 0xab, 0xa0, 0xbc,
0xdb, 0x99, 0x9b, 0x2e, 0x8e, 0xc4, 0x96, 0xfe, 0x31, 0x82,
0x9e, 0xe9, 0xc9, 0xa3, 0xd0, 0xe3, 0x52, 0x0f, 0x73, 0x24,
0xd7, 0xb6, 0x41, 0xcc, 0xfc, 0xae, 0x86, 0xb5, 0x79, 0xe5,
0x25, 0xc8, 0x76, 0x60, 0x48, 0x3c, 0xa4, 0x74, 0x6a, 0x7b,
0x7e, 0xa8, 0x5b, 0xf8, 0x5b, 0x79, 0x0f, 0x19, 0x95, 0x7d,
0x7f, 0x56, 0x31, 0xcc, 0x34, 0xd0, 0xb8, 0x0c, 0x29, 0x3f,
0x83, 0x54, 0x02, 0x75, 0xe3, 0x79, 0xb6, 0x64, 0xf9, 0x66,
0x7f, 0x90, 0xe1, 0xa7, 0x7b, 0xfa, 0x17, 0x68, 0x07, 0xd1,
0xef, 0x35, 0x52, 0xf3, 0x56, 0xde, 0x35, 0x35, 0x14, 0x1b,
0xcd, 0x97, 0x1a, 0xe5, 0xf4, 0xb5, 0xae, 0xfc, 0x53, 0x0c,
0xec, 0x36, 0xf0, 0xb4, 0x30, 0xea, 0x9b, 0xde, 0x60, 0x31,
0x72, 0x7e, 0x99, 0x41, 0x78, 0x90, 0x81, 0x73, 0x0a, 0x81,
0xe2, 0xaa, 0x70, 0x68, 0x67, 0x7a, 0x52, 0x4a, 0x4d, 0xd4,
0x9f, 0x90, 0x0d, 0xd9, 0x3a, 0x1f, 0x8d, 0x80, 0xfa, 0x68,
0x62, 0x54, 0xae, 0xb7, 0x0f, 0x3a, 0xfa, 0xed, 0xc9, 0xce,
0x20, 0x8d, 0x88, 0x48, 0x79, 0x82, 0x8a, 0xf6, 0xc5, 0x4d,
0x6e, 0xed, 0x38, 0x81, 0x75, 0x65, 0xac, 0xf6, 0x72, 0xee,
0xf0, 0x2e, 0x6d, 0x3f, 0x2e, 0x2a, 0x54, 0xf2, 0xf1, 0x5a,
0xb9, 0x81, 0xce, 0x56, 0xbf, 0xed, 0xab, 0xd5, 0x32, 0xf1,
0x95, 0x86, 0x81, 0xf9, 0xfd, 0x38, 0x1d, 0xc7, 0x9f, 0x55,
0xe1, 0x2c, 0xd1, 0x28, 0x66, 0x26, 0x81, 0xf5, 0x12, 0x72,
0x02, 0x35, 0x87, 0x65, 0x01, 0xea, 0x4f, 0xf7, 0x95, 0xba,
0xb1, 0x09, 0x91, 0x9c, 0x89, 0xb4, 0x48, 0x1d, 0x7b, 0xb4,
0x37, 0x76, 0x6c, 0xce, 0x83, 0x0e, 0x2c, 0xb8, 0xd5, 0xe0,
0x43, 0x36, 0x3c, 0x2d, 0xb1, 0x0f, 0x29, 0x4e, 0x1d, 0x36,
0x58, 0x9a, 0xcd, 0xf4, 0xa7, 0xad, 0xae, 0xdb, 0x8f, 0x59,
0xd0, 0x78, 0xb4, 0xcb, 0xfd, 0xe6, 0x1b, 0xa9, 0x24, 0x26,
0xb7, 0xa2, 0xc0, 0xbd, 0x08, 0x53, 0xd2, 0x4e, 0xb2, 0x19,
0x90, 0xb1, 0xb0, 0xa7, 0x57, 0xaa, 0xeb, 0x11, 0x71, 0xdd,
0x3b, 0xae, 0x04, 0xf4, 0x44, 0xa5, 0x27, 0xeb, 0xb3, 0x2e,
0xdd, 0x70, 0x7e, 0x0d, 0x2b, 0x2f, 0xc4, 0x4c, 0xee, 0xff,
0x4d, 0x94, 0xde, 0x6f, 0x48, 0xa1, 0x7b, 0xa2, 0xa2, 0xef,
0x3a, 0xa3, 0x0c, 0x99, 0x4e, 0x6e, 0xd4, 0x64, 0xbb, 0xd2,
0xa0, 0x38, 0x39, 0xe8, 0x16, 0xa3, 0x4b, 0x77, 0xb7, 0xa4,
0xf6, 0xc0, 0x12, 0xec, 0xfe, 0x97, 0xc0, 0xa4, 0xfc, 0x90,
0x8c, 0x07, 0xfb, 0x0a, 0xc9, 0x4f, 0xe8, 0xf7, 0x6e, 0x45,
0xf6, 0xab, 0x8b, 0xb1, 0x58, 0x56, 0x5b, 0xda, 0x12, 0xc0,
0x4c, 0xe1, 0x74, 0x1c, 0xb9, 0x14, 0xdf, 0xe4, 0x17, 0x53,
0xb3, 0x0c, 0xe2, 0xe1, 0xbc, 0xfc, 0xe6, 0x9c, 0xed, 0xed,
0x82, 0x20, 0x2a, 0x4d, 0xdf, 0xd8, 0x78, 0x6e, 0xf5, 0x16,
0x57, 0x48, 0x58, 0x9a, 0xb6, 0x57, 0x20, 0xf0, 0x74, 0xcc,
0xcf, 0xdd, 0x5c, 0xf4, 0xd6, 0x7e, 0xc4, 0x53, 0x13, 0xa4,
0xf1, 0x68, 0xc5, 0xa4, 0xe1, 0x91, 0x58, 0xcf, 0x5c, 0x9f,
0x36, 0xbf, 0x20, 0x21, 0x1b, 0x34, 0x5c, 0xbd, 0x2c, 0x64,
0xc5, 0x6f, 0x7f, 0xb9, 0x91, 0x65, 0xcf, 0x25, 0x44, 0x93,
0x99, 0x1f, 0xb9, 0x82, 0xeb, 0xc5, 0x3b, 0x4f, 0xd2, 0xad,
0x5e, 0xaf, 0x69, 0xfc, 0x2f, 0x54, 0xe4, 0xd0, 0x34, 0xdb,
0x47, 0xef, 0x8b, 0x16, 0x54, 0x2b, 0x67, 0x27, 0x3c, 0x50,
0x9f, 0xf0, 0x6c, 0xe6, 0xe2, 0x08, 0xd0, 0x0a, 0x36, 0x76,
0xc1, 0x65, 0x62, 0x01, 0x4d, 0x70, 0xb8, 0x42, 0xe4, 0x88,
0xee, 0x63, 0x0b, 0x74, 0x64, 0x2b, 0x15, 0xf1, 0x90, 0x6c,
0xa3, 0x3f, 0xf4, 0x94, 0xca, 0x3f, 0x48, 0x64, 0x5a, 0x09,
0x36, 0x5c, 0x7c, 0x4f, 0x75, 0xf0, 0x4e, 0xe3, 0x3d, 0xf3,
0x6d, 0x9b, 0x4f, 0x99, 0x29, 0xf1, 0xe2, 0xff, 0x92, 0x38,
0x5d, 0xf6, 0xf3, 0xd2, 0xc5, 0x5d, 0x1d, 0x89, 0x78, 0x09,
0xbb, 0x6a, 0x3a, 0x0a, 0x9c, 0x01, 0x4c, 0xd9, 0xfd, 0x55,
0x48, 0xa1, 0xf7, 0xa1, 0x9c, 0x55, 0xc1, 0x31, 0xaf, 0xa5,
0x03, 0xbb, 0xba, 0x8c, 0x76, 0x0a, 0xf0, 0xd6, 0x03, 0x57,
0x71, 0xf5, 0xfe, 0xad, 0x7f, 0x36, 0x23, 0x57, 0xba, 0x9b,
0x20, 0x92, 0x14, 0x9e, 0xcf, 0x76, 0x59, 0xcd, 0xe2, 0x47,
0x12, 0xb4, 0x1e, 0xb5, 0x52, 0xc3, 0x7f, 0xda, 0xa0, 0x35,
0xc2, 0x55, 0x56, 0x97, 0xd0, 0x57, 0xa0, 0xcc, 0xcd, 0x27,
0xcc, 0x08, 0x1c, 0x9c, 0x06, 0xfd, 0xbe, 0x47, 0xdf, 0x78,
0x08, 0x17, 0xb6, 0x7f, 0x31, 0x1e, 0x0a, 0xdc, 0x54, 0xcc,
0x06, 0xf7, 0xbf, 0xee, 0x74, 0x48, 0x21, 0x39, 0x6c, 0xf0,
0x1f, 0x29, 0x19, 0x76, 0x19, 0x7f, 0xc2, 0x38, 0x94, 0x8a,
0xe4, 0x2d, 0x7f, 0xff, 0xf7, 0x45, 0x57, 0x21, 0x98, 0xaa,
0x65, 0x35, 0xba, 0x3c, 0x56, 0xff, 0x62, 0x88, 0xb9, 0xe8,
0xe9, 0xdb, 0xd1, 0xf8, 0x59, 0x0f, 0x50, 0x13, 0x8b, 0xc2,
0xc2, 0xbd, 0xba, 0x44, 0x44, 0x36, 0xe1, 0xb0, 0x13, 0x32,
0x3a, 0x68, 0x4d, 0x62, 0xa8, 0x50, 0x87, 0x44, 0xbb, 0x31,
0xfb, 0xe3, 0x25, 0x73, 0xa0, 0xf1, 0x2c, 0xf5, 0x34, 0x19,
0x09, 0x66, 0xa9, 0x46, 0x21, 0xc7, 0xa2, 0x91, 0x7d, 0xe9,
0xf4, 0x9d, 0xa9, 0x82, 0x28, 0xf4, 0x1f, 0x28, 0xa8, 0xa9,
0x01, 0xf1, 0x97, 0x70, 0x9d, 0x61, 0x72, 0xd5, 0x8b, 0x84,
0xcf, 0xf1, 0x7c, 0xc2, 0x7d, 0xa7, 0xa3, 0x25, 0x4f, 0x68,
0x3f, 0x5e, 0x8e, 0xb6, 0x16, 0x18, 0x78, 0xcf, 0x63, 0x53,
0x57, 0x08, 0x11, 0x55, 0x65, 0x1b, 0x55, 0x5e, 0x8d, 0xce,
0x68, 0x2d, 0x77, 0x16, 0x1e, 0x87, 0xa6, 0xd0, 0x11, 0x44,
0x37, 0x8f, 0xa2, 0x8b, 0xb0, 0xdb, 0x4b, 0x01, 0x2f, 0xd7,
0x1e, 0x16, 0x93, 0xb5, 0x19, 0xad, 0xb7, 0xde, 0x13, 0x0d,
0xac, 0xcd, 0x77, 0x6a, 0x15, 0x61, 0xeb, 0xe0, 0xd1, 0xbf,
0xcf, 0x69, 0x10, 0x28, 0x72, 0x58, 0xfe, 0xc7, 0xce, 0xbc,
0x92, 0xfd, 0x5f, 0x9c, 0xd6, 0x6d, 0x56, 0xbd, 0x39, 0x35,
0xe0, 0xa6, 0x73, 0x19, 0x45, 0x6a, 0xf2, 0x36, 0x8a, 0x0a,
0x58, 0xe1, 0x23, 0x07, 0x28, 0xa4, 0x89, 0x7a, 0x51, 0xbb,
0xba, 0xd6, 0x42, 0x78, 0xbb, 0x5f, 0x42, 0x0b, 0xc0, 0x8f,
0xc9, 0x3c, 0xc3, 0x7e, 0x41, 0x22, 0x94, 0x3c, 0x02, 0xd3,
0x2c, 0xec, 0xf8, 0x8f, 0x14, 0x62, 0x7c, 0x78, 0x47, 0x73,
0xe8, 0xd5, 0x40, 0x2d, 0x26, 0x82, 0x72, 0x16, 0xd7, 0xdd,
0x9e, 0x8d, 0x8e, 0xfb, 0xaf, 0x83, 0x73, 0xd8, 0x4d, 0x85,
0x28, 0x53, 0x72, 0xc1, 0xb0, 0x08, 0x5a, 0xc6, 0x6e, 0xbe,
0xf9, 0x21, 0xdd, 0x8c, 0x30, 0xf5, 0x5e, 0xbe, 0xec, 0xcc,
0xd2, 0x8a, 0x1a, 0xc3, 0xf4, 0x83, 0x98, 0x86, 0x3b, 0x4e,
0x6d, 0x3e, 0x9e, 0xbe, 0x84, 0x80, 0x2f, 0x27, 0xbb, 0x6a,
0x3e, 0x51, 0x18, 0xb0, 0x7a, 0x82, 0x82, 0x02, 0x53, 0x6d,
0x2d, 0x2a, 0xab, 0x4a, 0x2e, 0x3b, 0xa4, 0x88, 0x90, 0x99,
0x74, 0x10, 0x27, 0xa7, 0xe9, 0x5c, 0x52, 0x5b, 0xf5, 0xb0,
0x00, 0xc7, 0x52, 0x91, 0x04, 0xc7, 0xff, 0x01, 0xb7, 0x56,
0x40, 0x9f, 0x56, 0x54, 0xde, 0x96, 0x65, 0x61, 0x76, 0x06,
0xb6, 0xdb, 0x16, 0xc8, 0x1c, 0x0b, 0xff, 0xf0, 0x73, 0xd0,
0x89, 0x22, 0x86, 0xc6, 0xac, 0xc5, 0xb1, 0x98, 0x21, 0xd0,
0x6c, 0x30, 0x92, 0x43, 0xb4, 0xa9, 0x80, 0xc8, 0xdd, 0x6f,
0xf0, 0x4b, 0x57, 0x80, 0x6d, 0x53, 0xfb, 0xd4, 0x95, 0x39,
0xde, 0x6e, 0xf5, 0x28, 0x9e, 0x92, 0x94, 0x42, 0x99, 0x42,
0x4d, 0x02, 0x0a, 0x7b, 0x9b, 0x8f, 0xc6, 0x32, 0xb0, 0xd9,
0x5d, 0x81, 0x74, 0xd2, 0x76, 0xdb, 0x64, 0x21, 0xdf, 0xc2,
0xee, 0x5f, 0x77, 0x88, 0x13, 0x60, 0x32, 0xd8, 0x97, 0xf4,
0x1c, 0x77, 0xe0, 0x49, 0xce, 0x1d, 0xa2, 0xbb, 0x66, 0xca,
0x27, 0xfd, 0xc1, 0x96, 0x3a, 0x50, 0x4f, 0x1f, 0xbb, 0x56,
0x24, 0x85, 0x76, 0x77, 0xfd, 0x84, 0x7b, 0xb4, 0x3c, 0x87,
0x01, 0x09, 0x89, 0x4c, 0x0f, 0x8e, 0x44, 0xc0, 0x49, 0x39,
0x49, 0x8b, 0x93, 0x09, 0xa6, 0x8d, 0x93, 0xf1, 0x5a, 0x3f,
0x1f, 0x64, 0x2f, 0xd2, 0xe2, 0xbe, 0x99, 0x38, 0x38, 0xf1,
0xec, 0x15, 0x46, 0xe3, 0x8a, 0x95, 0xe6, 0x3c, 0xf8, 0xa3,
0x38, 0xb8, 0xc0, 0x20, 0x5f, 0xcb, 0x36, 0xe4, 0x90, 0x79,
0x0c, 0x8e, 0xb6, 0xe5, 0x48, 0x23, 0x2d, 0xcb, 0x3c, 0x88,
0x31, 0x35, 0xe7, 0x8e, 0xfa, 0xf5, 0x81, 0x36, 0x35, 0x96,
0x98, 0x39, 0xb0, 0x2d, 0xa3, 0xd7, 0x84, 0x3a, 0x92, 0x30,
0x07, 0x9b, 0x70, 0x61, 0xda, 0xd6, 0x80, 0x94, 0x7b, 0x93,
0x01, 0x10, 0xe2, 0x03, 0x23, 0x83, 0xc2, 0xef, 0x2f, 0x4e,
0x31, 0x01, 0x87, 0x0c, 0x0b, 0x0c, 0x1f, 0x20, 0xaa, 0x75,
0x52, 0xb5, 0xbc, 0xa2, 0x55, 0xd6, 0x06, 0x3f, 0xf1, 0x6a,
0x1e, 0xa4, 0x00, 0x43, 0xdb, 0x0f, 0x9a, 0xd4, 0xc4, 0x45,
0x2f, 0x20, 0x94, 0x57, 0xbc, 0x6e, 0xeb, 0x63, 0xda, 0x90,
0xb2, 0x56, 0x9b, 0x6c, 0x81, 0xb3, 0x15, 0xd3, 0x1d, 0xe1,
0xe4, 0x75, 0xaa, 0x3b, 0xbf, 0x45, 0x46, 0xd7, 0x0d, 0x31,
0xb1, 0xf5, 0x8b, 0xfb, 0x5b, 0x3e, 0x48, 0x4b, 0xea, 0x09,
0x0c, 0x82, 0xd3, 0x7a, 0x45, 0x1c, 0xc2, 0x4d, 0xda, 0x4d,
0x08, 0xd1, 0x5d, 0x7c, 0xb5, 0x50, 0x24, 0xbf, 0x3b, 0x5a,
0xb7, 0xca, 0x76, 0xc4, 0xee, 0x64, 0xf7, 0xc7, 0x77, 0x2d,
0x06, 0x8d, 0x9b, 0xee, 0x7c, 0x6b, 0xf5, 0x6b, 0x8f, 0x62,
0x4d, 0x37, 0x66, 0x31, 0x5f, 0xde, 0x2b, 0xb2, 0xe4, 0x70,
0xda, 0xeb, 0x49, 0xe4, 0x1b, 0x1f, 0xdf, 0x45, 0xee, 0x5a,
0x69, 0x68, 0x59, 0xe5, 0x71, 0x14, 0xcc, 0x4e, 0x73, 0xa4,
0x20, 0x38, 0x5c, 0xc7, 0xa7, 0x28, 0xd5, 0xa0, 0xbf, 0xfd,
0x6a, 0x0f, 0x92, 0x6f, 0x02, 0x64, 0x49, 0x19, 0xe4, 0x18,
0x23, 0xa2, 0xda, 0x9b, 0x75, 0x7b, 0xc8, 0xdb, 0x8f, 0x78,
0x68, 0x4c, 0x67, 0x47, 0x82, 0xf6, 0x10, 0x44, 0x23, 0x36,
0x74, 0x02, 0x58, 0xad, 0x75, 0xd4, 0xad, 0x59, 0x9e, 0x2e,
0x99, 0x67, 0xc2, 0x5b, 0x89, 0x91, 0x01, 0x37, 0x2e, 0xfe,
0x50, 0xc4, 0x6d, 0xe7, 0x8b, 0x34, 0x53, 0x22, 0xd0, 0xc3,
0x1f, 0x16, 0xc9, 0x14, 0x2f, 0x0b, 0x76, 0xdf, 0x29, 0xb9,
0x32, 0xd4, 0xcd, 0x5e, 0x04, 0xdb, 0xf5, 0x47, 0x3f, 0x99,
0x26, 0xcb, 0x6b, 0xac, 0xae, 0x2b, 0xbc, 0x75, 0xf2, 0x8d,
0x64, 0xff, 0xd2, 0x2b, 0xfb, 0x8c, 0x81, 0x79, 0xed, 0x8d,
0x86, 0x89, 0xc7, 0xfd, 0xe8, 0xde, 0x1a, 0xe1, 0x96, 0x30,
0xba, 0xe3, 0x8d, 0xc8, 0x43, 0xd5, 0x97, 0x52, 0xe5, 0x19,
0x0b, 0xd4, 0xba, 0x41, 0xea, 0x9a, 0xad, 0xcc, 0x94, 0x24,
0x6e, 0x9c, 0x8f, 0xd1, 0x69, 0x6b, 0x4a, 0x50, 0x92, 0xba,
0x73, 0x41, 0xb1, 0xd1, 0x82, 0x10, 0xbb, 0xcf, 0x3c, 0x4b,
0xdf, 0x49, 0xdc, 0xdf, 0xd3, 0xbb, 0xa6, 0xac, 0x63, 0xbc,
0x88, 0x6a, 0x4f, 0x3b, 0xfa, 0xd4, 0xdd, 0xd4, 0x3c, 0x3a,
0xe5, 0x68, 0xd7, 0x86, 0xbd, 0xcd, 0xd3, 0x6d, 0xa8, 0x22,
0xca, 0x71, 0xd6, 0xd0, 0xa7, 0xa7, 0x75, 0xd2, 0x70, 0xd4,
0xb4, 0x27, 0x78, 0x2b, 0xcd, 0x16, 0x10, 0x81, 0xb1, 0x59,
0xfe, 0xe4, 0x1b, 0x62, 0xd1, 0xcf, 0x63, 0x7c, 0x72, 0x78,
0xc2, 0x96, 0xaf, 0x88, 0x76, 0x28, 0x0a, 0x47, 0xeb, 0xa8,
0xd9, 0xd1, 0xef, 0xea, 0x01, 0x20, 0x15, 0x63, 0x89, 0xb4,
0xe7, 0x99, 0xa0, 0x3b, 0x2f, 0xdf, 0x99, 0x0b, 0xc3, 0xef,
0xa6, 0xf3, 0xe0, 0x90, 0xc9, 0x82, 0x4c, 0x3e, 0x51, 0xe9,
0x2c, 0x86, 0x7d, 0x31, 0x7e, 0x8f, 0x5d, 0x7a, 0x24, 0xff,
0x65, 0xa9, 0xb6, 0xbc, 0x18, 0xc8, 0x28, 0x4c, 0x8d, 0xda,
0xc7, 0x98, 0x6a, 0x54, 0xad, 0x22, 0x19, 0xca, 0x3d, 0x4d,
0x88, 0xcc, 0x4e, 0x5c, 0x2a, 0xef, 0xd0, 0x60, 0x3c, 0xe3,
0x49, 0xd2, 0xf6, 0x59, 0x38, 0x25, 0xed, 0x31, 0x52, 0x18,
0xb4, 0x31, 0x31, 0x43, 0x8f, 0x85, 0x7d, 0x59, 0xa8, 0xd2,
0x26, 0x4c, 0xa0, 0xfb, 0xf8, 0xdb, 0x6a, 0x12, 0xad, 0x40,
0x73, 0xb1, 0x5d, 0x61, 0xf5, 0x49, 0x65, 0x7b, 0x44, 0x30,
0x49, 0x7a, 0xd7, 0xe9, 0xce, 0x34, 0x9c, 0x64, 0x6e, 0x31,
0xae, 0x48, 0xad, 0x4c, 0x69, 0xc4, 0xd9, 0xf8, 0x2a, 0xb0,
0x7e, 0xb3, 0xba, 0xec, 0xea, 0x2b, 0x49, 0x09, 0x21, 0x53,
0x63, 0xb7, 0xc6, 0xd6, 0x80, 0x9c, 0x77, 0x27, 0xe9, 0xf6,
0xc7, 0x06, 0x2c, 0x8e, 0xc1, 0xb8, 0x31, 0x15, 0xa9, 0x87,
0x13, 0xfd, 0xfd, 0x32, 0x18, 0xdd, 0x5c, 0xba, 0xf3, 0x70,
0x94, 0x09, 0x9d, 0xb6, 0xbc, 0x2c, 0x91, 0xef, 0x42, 0xb7,
0x13, 0x25, 0x90, 0x77, 0x10, 0xdd, 0x80, 0xa9, 0xd9, 0xab,
0xef, 0xcf, 0xbe, 0x75, 0x93, 0xe2, 0xbc, 0xe7, 0x26, 0xdf,
0x77, 0x88, 0xe0, 0x90, 0xc0, 0x2d, 0x20, 0xc9, 0x8c, 0xfa,
0x82, 0x91, 0x57, 0xfb, 0xb1, 0xec, 0xdf, 0x2b, 0x2f, 0x9b,
0x6a, 0x23, 0xa0, 0x3e, 0x2a, 0xa3, 0x39, 0x8c, 0xea, 0x09,
0x06, 0x03, 0x7b, 0xa8, 0xe7, 0x77, 0x32, 0x21, 0x1a, 0x29,
0xcd, 0x22, 0x60, 0x9b, 0xc0, 0xfe, 0xc2, 0xf3, 0x9c, 0x83,
0x56, 0x8f, 0xf0, 0x22, 0xad, 0xfd, 0xe3, 0xa9, 0xe3, 0xc5,
0xbf, 0xd1, 0xf3, 0xbd, 0xc6, 0x43, 0xc3, 0x84, 0xf2, 0x46,
0x91, 0x5b, 0x37, 0x43, 0xb9, 0xcf, 0xe4, 0x47, 0x7a, 0x5a,
0xfd, 0xd2, 0xc0, 0xb6, 0x7e, 0x99, 0xea, 0x15, 0x1b, 0x31,
0x3c, 0x14, 0x6b, 0xbf, 0x26, 0x4f, 0xfa, 0x38, 0x39, 0xef,
0x75, 0x4c, 0xda, 0x4c, 0x4f, 0x00, 0xef, 0x0f, 0xc6, 0x3b,
0x5b, 0x4c, 0xf1, 0x1b, 0x35, 0x92, 0xb9, 0x74, 0x9e, 0x0f,
0x16, 0x2a, 0x2b, 0x3c, 0xa0, 0x80, 0xf0, 0xe5, 0x56, 0xaa,
0xdb, 0x0e, 0x4f, 0xfc, 0x5f, 0xb2, 0xd1, 0x0b, 0xe2, 0x04,
0x1e, 0xe8, 0x6f, 0x4f, 0x81, 0xdb, 0xc7, 0x1a, 0x0c, 0xb0,
0x00, 0xed, 0x8a, 0x7b, 0x1d, 0x44, 0xde, 0x30, 0xfa, 0xb6,
0x88, 0x3b, 0x73, 0x81, 0xb3, 0x57, 0x31, 0x38, 0x0e, 0x13,
0x77, 0x9e, 0x5a, 0x4d, 0xa1, 0x93, 0x73, 0x30, 0x0d, 0x44,
0x56, 0x97, 0x88, 0xbf, 0xc4, 0x36, 0xe9, 0xec, 0xe2, 0x58,
0x11, 0x39, 0x33, 0x71, 0x6b, 0xd4, 0xb7, 0x4a, 0x9a, 0x2c,
0xc0, 0xac, 0x88, 0xeb, 0x08, 0x8c, 0x43, 0x48, 0xa2, 0xba,
0xfa, 0x98, 0x95, 0x92, 0x2d, 0xa2, 0xee, 0x72, 0xb3, 0x7e,
0xd9, 0x11, 0x1a, 0xa3, 0x41, 0xc4, 0x65, 0x19, 0x1d, 0xdb,
0x92, 0xf4, 0x3e, 0xf4, 0xaa, 0x49, 0xad, 0x77, 0xc6, 0x03,
0xdd, 0x19, 0x7a, 0x8d, 0x62, 0x09, 0x19, 0xd7, 0xf7, 0xd3,
0x84, 0xf1, 0xcb, 0x45, 0x54, 0xd1, 0x74, 0x1e, 0xf8, 0xe6,
0xa4, 0xfd, 0xaa, 0x30, 0xf8, 0xf9, 0xe1, 0x2b, 0xcf, 0x65,
0x22, 0xf9, 0x73, 0xcf, 0x5d, 0xe3, 0xde, 0x93, 0x94, 0x84,
0x8f, 0xe1, 0x66, 0x99, 0x6a, 0x71, 0x76, 0xae, 0xdb, 0x16,
0x2b, 0x73, 0xab, 0x4e, 0x61, 0x08, 0xa0, 0xdc, 0x3f, 0xd4,
0xe3, 0xac, 0x89, 0x7a, 0x31, 0xc1, 0xb9, 0x20, 0x92, 0x10,
0x58, 0x1b, 0x87, 0xfd, 0xe3, 0x7c, 0x42, 0xc8, 0x26, 0x06,
0x50, 0xce, 0xbb, 0x00, 0x0b, 0x9f, 0x09, 0xdc, 0xac, 0x31,
0xe0, 0xcd, 0xa6, 0xee, 0x23, 0xef, 0x64, 0x87, 0x65, 0x5f,
0xfb, 0x5f, 0x6c, 0x29, 0x4a, 0xf9, 0xd3, 0xaf, 0x4e, 0xaa,
0x39, 0x30, 0x82, 0x05, 0xc6, 0x1c, 0x1e, 0x83, 0x8f, 0xe4,
0xf7, 0x1c, 0xca, 0x3b, 0x03, 0x01, 0x80, 0xe4, 0x6a, 0x84,
0x71, 0xd4, 0xe9, 0xa6, 0xba, 0x72, 0x89, 0x69, 0xfa, 0x56,
0x6d, 0x26, 0xe3, 0x1d, 0xfa, 0x91, 0x8f, 0x4c, 0xcc, 0x50,
0x74, 0x75, 0x2f, 0xe3, 0x97, 0x16, 0x07, 0x78, 0x40, 0xde,
0x58, 0x22, 0xca, 0x41, 0xde, 0xb9, 0x92, 0x56, 0x55, 0x89,
0x85, 0x20, 0x44, 0x5a, 0xd0, 0xfc, 0x88, 0x4e, 0x49, 0x81,
0x32, 0xcf, 0x44, 0xb6, 0xee, 0x58, 0x0e, 0x22, 0xf8, 0x8f,
0x05, 0x2a, 0x78, 0x30, 0x34, 0x11, 0xb0, 0x8f, 0x21, 0x10,
0xb7, 0xe2, 0x80, 0xa2, 0xe0, 0x69, 0xbc, 0x29, 0xe3, 0x48,
0x08, 0xa6, 0xdc, 0xbc, 0x68, 0xd7, 0xd7, 0x84, 0x23, 0x3f,
0xb0, 0x0a, 0x69, 0xa1, 0x87, 0x13, 0x29, 0x0d, 0x71, 0x3d,
0xad, 0xad, 0xf0, 0x5e, 0x53, 0x04, 0x03, 0x9e, 0x4b, 0xb2,
0x24, 0xc2, 0x82, 0x8c, 0xef, 0x4c, 0x70, 0xcd, 0x58, 0xb3,
0x19, 0xa4, 0xe8, 0x0e, 0xc0, 0xfd, 0x57, 0x2b, 0x65, 0xee,
0xa5, 0x43, 0x02, 0xf2, 0xbe, 0xe7, 0x66, 0xc9, 0xb5, 0xfd,
0x70, 0xc0, 0x93, 0x9b, 0xe8, 0x60, 0x74, 0xd4, 0xcc, 0xa5,
0xa6, 0xa2, 0x66, 0x35, 0xdc, 0x74, 0xf3, 0x02, 0x16, 0x74,
0x9a, 0x91, 0x0a, 0x3d, 0xa4, 0x8b, 0x98, 0xd1, 0xfd, 0x29,
0x34, 0xea, 0x52, 0x89, 0x16, 0x62, 0xdd, 0xed, 0xb5, 0x8b,
0xed, 0xe4, 0x03, 0xd9
};
static const uint8_t static_keys_b[0x70 * 0x20] = {
0x76, 0x65, 0x9d, 0xe4, 0xf7, 0x6c, 0x45, 0x1f, 0x73, 0x42,
0x47, 0xc3, 0x92, 0x32, 0xf4, 0x38, 0x6f, 0x28, 0xcf, 0xfa,
0x41, 0x84, 0xbe, 0x1b, 0x5a, 0x23, 0x99, 0xfa, 0xcd, 0x74,
0xf0, 0x3b, 0x43, 0xc9, 0xd1, 0x30, 0x66, 0x77, 0x5e, 0xac,
0x39, 0x8e, 0x8a, 0x6c, 0x5c, 0xfe, 0xdd, 0x80, 0xf3, 0x03,
0x04, 0x30, 0x84, 0x9d, 0x12, 0xee, 0x4a, 0xe3, 0x0f, 0x5e,
0x5e, 0x97, 0xd0, 0xf9, 0x1b, 0x57, 0x05, 0x74, 0x03, 0x5a,
0x5d, 0x41, 0xda, 0x6e, 0xfd, 0x4b, 0x1e, 0xc4, 0x4b, 0x76,
0xe4, 0xd3, 0x39, 0xeb, 0x3c, 0x2c, 0xae, 0x27, 0xe2, 0x98,
0xe4, 0x08, 0xa3, 0xbe, 0xb0, 0x31, 0x69, 0x14, 0xa3, 0x6c,
0xdf, 0xfc, 0x1f, 0x56, 0x0d, 0xfe, 0x55, 0x12, 0x97, 0x5e,
0xad, 0x3d, 0x9b, 0xee, 0xb5, 0xad, 0xa3, 0x56, 0x85, 0xc3,
0xbd, 0x9b, 0xef, 0xac, 0x55, 0x98, 0x1f, 0xaf, 0xb8, 0x0b,
0xae, 0xed, 0xf3, 0x87, 0x34, 0xc9, 0x5b, 0x69, 0xf0, 0xed,
0x4f, 0x03, 0x40, 0xa5, 0x71, 0x24, 0xa2, 0x23, 0x93, 0x52,
0xe9, 0x87, 0xc4, 0x79, 0x4f, 0xe9, 0x20, 0xbc, 0x04, 0x58,
0x70, 0x96, 0xb1, 0xd7, 0x37, 0xc4, 0x29, 0x4d, 0x3d, 0x52,
0xd3, 0xcf, 0x7c, 0x08, 0xe9, 0x82, 0xc6, 0x99, 0xf5, 0xdb,
0x60, 0x11, 0x9b, 0x9d, 0x25, 0x86, 0x08, 0xb3, 0x77, 0x27,
0xa8, 0x2c, 0xf9, 0x28, 0x2f, 0x2b, 0x70, 0x6c, 0x4b, 0xbb,
0x1e, 0x49, 0x3e, 0xd6, 0x69, 0xd8, 0xe8, 0x09, 0xf4, 0x9c,
0x09, 0x32, 0xdf, 0xdd, 0xe1, 0x0b, 0x41, 0x0e, 0x26, 0x3e,
0x53, 0xcc, 0x7a, 0xd1, 0x15, 0x16, 0xfb, 0xc3, 0x09, 0xd3,
0xad, 0xa4, 0xea, 0xa3, 0x4a, 0xbe, 0xf2, 0x88, 0x9a, 0x34,
0x7b, 0x09, 0x41, 0x44, 0xf1, 0x5e, 0x3c, 0x4f, 0x0e, 0x9f,
0x5a, 0x95, 0x57, 0x7a, 0xfe, 0xbe, 0xc8, 0x24, 0x1f, 0x98,
0x85, 0x1e, 0x25, 0x74, 0x90, 0xdd, 0x5a, 0xd1, 0x7c, 0x02,
0xbe, 0x63, 0xe5, 0xc7, 0xa2, 0x0b, 0x26, 0xdf, 0x20, 0x84,
0x61, 0xe3, 0xff, 0x2c, 0x69, 0x32, 0x91, 0x62, 0xf8, 0x11,
0x7c, 0xf2, 0x1e, 0xe5, 0x1e, 0xc1, 0xb2, 0x2a, 0x84, 0x8e,
0x3a, 0x78, 0xf6, 0xf6, 0x76, 0x76, 0x4e, 0x34, 0x4f, 0x24,
0xf0, 0x8c, 0x34, 0xaf, 0x95, 0x7a, 0x35, 0x26, 0x5e, 0x28,
0xe3, 0x2c, 0x66, 0xf9, 0x7f, 0x35, 0xfc, 0xad, 0xfe, 0x6e,
0x4b, 0xe1, 0x5c, 0x48, 0xec, 0x1a, 0xba, 0xbd, 0xac, 0x73,
0x7a, 0xe8, 0xbc, 0xad, 0xba, 0x5e, 0xa6, 0xf0, 0xb8, 0x5a,
0x51, 0x2a, 0x97, 0xe4, 0x34, 0x8a, 0x3b, 0x64, 0x61, 0x97,
0x57, 0x59, 0x29, 0x87, 0x76, 0x80, 0x78, 0x05, 0x91, 0xc0,
0xa5, 0x5e, 0x7b, 0x5a, 0xa5, 0x7b, 0x2f, 0x8d, 0x07, 0x7d,
0xfa, 0x75, 0x32, 0xe8, 0x48, 0x0c, 0x68, 0xbf, 0x70, 0xb3,
0x79, 0x88, 0xc0, 0xbd, 0xbc, 0x49, 0x9a, 0x9a, 0x07, 0xb8,
0xa3, 0xc2, 0xb4, 0x1d, 0xca, 0x24, 0x90, 0xe8, 0x2f, 0xe8,
0x9f, 0x28, 0xba, 0x40, 0x17, 0x50, 0x56, 0xcf, 0x4e, 0xc8,
0x82, 0xcb, 0x77, 0xf1, 0x74, 0x8d, 0xef, 0x0b, 0x4c, 0x1f,
0x3d, 0x4d, 0xd2, 0x4e, 0x66, 0x2f, 0x13, 0xe7, 0x8a, 0xb6,
0xea, 0xd1, 0xd7, 0x36, 0xf3, 0x51, 0x65, 0x07, 0xc1, 0x88,
0x7d, 0xae, 0xf4, 0xb8, 0x89, 0xb5, 0xce, 0xdd, 0x27, 0xbe,
0x6f, 0x6c, 0x81, 0x8f, 0x56, 0x02, 0x0d, 0x49, 0xe4, 0x3f,
0x60, 0x93, 0x55, 0xa3, 0x68, 0x75, 0x5d, 0xc5, 0x5a, 0x09,
0x90, 0xdc, 0x8f, 0xaa, 0x9f, 0x47, 0xf6, 0xa9, 0xad, 0xdb,
0x5b, 0xe2, 0x64, 0xce, 0xc1, 0x26, 0xeb, 0xeb, 0xa0, 0x03,
0x23, 0x61, 0x14, 0x9e, 0x72, 0x48, 0xc2, 0x10, 0x3d, 0x73,
0xc3, 0xc9, 0x22, 0x01, 0x68, 0x2c, 0x3c, 0x98, 0xa5, 0x85,
0x0d, 0xa4, 0xec, 0xc6, 0xfc, 0x7d, 0xff, 0x2c, 0xae, 0x60,
0xc4, 0xb0, 0x71, 0xb9, 0xbc, 0xdb, 0x29, 0xc6, 0x78, 0x0b,
0xf6, 0x82, 0x38, 0xed, 0x35, 0xb7, 0x92, 0x2f, 0xeb, 0xa9,
0xe7, 0xc3, 0x1a, 0xa2, 0xae, 0x44, 0x51, 0x71, 0x6e, 0x8c,
0x21, 0x9f, 0x9c, 0x5d, 0x98, 0x72, 0xa3, 0x2e, 0x74, 0x49,
0x70, 0xaf, 0x85, 0x7b, 0x14, 0x66, 0x56, 0x99, 0x89, 0x07,
0xc4, 0xa9, 0xc2, 0xc2, 0xb3, 0x39, 0xa6, 0xf5, 0x5b, 0x3f,
0x30, 0xcc, 0x2d, 0x03, 0x22, 0xb4, 0x2a, 0x27, 0x1a, 0x46,
0xbc, 0xe5, 0xf6, 0x19, 0x34, 0xc1, 0x06, 0x6f, 0x28, 0x84,
0xe1, 0xe3, 0xb0, 0x21, 0x21, 0x84, 0x34, 0x33, 0x8d, 0x01,
0x26, 0x44, 0x5f, 0xa3, 0x56, 0x19, 0x46, 0xc1, 0x78, 0x29,
0x38, 0x0b, 0x9f, 0xe1, 0xf1, 0x2b, 0xfc, 0x01, 0x91, 0x71,
0x1c, 0xa5, 0x9c, 0xb6, 0xe1, 0x5e, 0xfa, 0x26, 0x56, 0x3f,
0xa8, 0xb2, 0xd1, 0xe4, 0xf3, 0x69, 0x08, 0x36, 0xac, 0xd6,
0x67, 0xb6, 0xe6, 0xb8, 0xc7, 0xa6, 0x7a, 0x10, 0x49, 0xe7,
0xba, 0x6f, 0xbf, 0xe8, 0x25, 0xaf, 0xc2, 0xdf, 0xf3, 0xa1,
0x76, 0xf4, 0x2b, 0x8c, 0x6f, 0x01, 0xce, 0x96, 0x30, 0xd2,
0x2d, 0xf8, 0x6c, 0xad, 0xed, 0x1e, 0xe5, 0x7a, 0xdf, 0x37,
0xe6, 0xff, 0xed, 0x9d, 0x5f, 0xa9, 0xfb, 0xf1, 0xbc, 0xc7,
0x47, 0x5a, 0x6f, 0x77, 0x83, 0x18, 0x0e, 0xba, 0x18, 0x2b,
0x38, 0xb4, 0x36, 0x32, 0x36, 0xdc, 0x98, 0xec, 0x16, 0xa1,
0x68, 0x42, 0x95, 0xee, 0xad, 0x43, 0x4c, 0x3d, 0x31, 0xcf,
0xdb, 0x57, 0xae, 0x0f, 0x78, 0x52, 0xd8, 0xa6, 0x47, 0x4b,
0xba, 0x94, 0xc2, 0xd2, 0x97, 0x56, 0x2b, 0xb0, 0xbd, 0x43,
0x30, 0x05, 0x4b, 0x30, 0x7b, 0x8b, 0xe4, 0xee, 0x61, 0xc4,
0xcd, 0xcb, 0x08, 0xb1, 0x16, 0x2e, 0xa3, 0xe4, 0x20, 0x0e,
0xd5, 0x02, 0x17, 0x81, 0xba, 0x43, 0xf7, 0x02, 0x7a, 0x0e,
0x77, 0x15, 0x45, 0x03, 0xaa, 0x84, 0x88, 0x56, 0xb1, 0xee,
0x3a, 0x1f, 0xe6, 0x28, 0xfd, 0x9f, 0x05, 0x81, 0x8d, 0xbf,
0x53, 0xa1, 0x5b, 0xbd, 0x9c, 0x79, 0x53, 0x28, 0x73, 0xba,
0x0d, 0x72, 0xe7, 0x14, 0xed, 0x5d, 0xb7, 0x95, 0x09, 0xa0,
0xbf, 0xef, 0x75, 0xa1, 0x20, 0xa4, 0x2d, 0x16, 0xa6, 0x58,
0x61, 0x93, 0x3a, 0x62, 0x40, 0xca, 0x4e, 0xef, 0xe4, 0x31,
0x18, 0xd1, 0x39, 0x35, 0x7c, 0x78, 0xe3, 0x6c, 0x76, 0x8a,
0x37, 0xdd, 0xc3, 0x8e, 0x60, 0xe2, 0x0d, 0x67, 0xfc, 0xe7,
0x37, 0x88, 0x48, 0xb6, 0xe4, 0x4b, 0x87, 0xe6, 0x04, 0x8c,
0x06, 0xd8, 0xc7, 0x4e, 0x9a, 0x97, 0x9d, 0x9d, 0xa1, 0xfa,
0x11, 0x27, 0x8c, 0x34, 0xe7, 0x02, 0x55, 0x0f, 0x6e, 0xc6,
0xcd, 0x6b, 0xc4, 0xf0, 0xa1, 0x05, 0x6b, 0x3f, 0xc4, 0xc9,
0x47, 0x95, 0x85, 0x1f, 0x80, 0x6a, 0x23, 0xe7, 0x24, 0x9f,
0xc3, 0xd0, 0x9d, 0x17, 0xea, 0x2f, 0xfa, 0xfa, 0xe4, 0xa6,
0x88, 0x9a, 0x57, 0x0c, 0x5b, 0xfe, 0xb4, 0x67, 0x3e, 0xf0,
0x0a, 0x58, 0xa0, 0xc8, 0xc7, 0x16, 0xd6, 0x0b, 0x41, 0x9e,
0xa9, 0xde, 0xbf, 0x17, 0x49, 0x08, 0x82, 0xc4, 0x4e, 0x56,
0x53, 0xb0, 0x4e, 0x23, 0x1d, 0xa8, 0x07, 0xde, 0x98, 0xf8,
0xe9, 0xec, 0x45, 0x3b, 0x50, 0xf6, 0xb6, 0xa3, 0xdc, 0xfa,
0xa1, 0x86, 0xd3, 0xfa, 0xda, 0xb6, 0x1d, 0x27, 0xed, 0x3d,
0x17, 0xc9, 0xcc, 0xf6, 0x2f, 0x7d, 0xea, 0x3b, 0x3d, 0x58,
0xb7, 0xf0, 0x4a, 0xae, 0xf9, 0x2f, 0xa0, 0x80, 0xe9, 0xde,
0x2e, 0x30, 0x3c, 0xd6, 0x46, 0xca, 0x50, 0x25, 0xf7, 0xa2,
0x66, 0xec, 0xa5, 0x6e, 0x06, 0x6e, 0x00, 0x3e, 0x08, 0x6c,
0xe6, 0x3b, 0xfb, 0xc8, 0xa7, 0xd0, 0x1e, 0xc8, 0x25, 0x24,
0x11, 0x0b, 0x39, 0x0f, 0x70, 0xd9, 0xf8, 0xff, 0x54, 0x54,
0x9d, 0x02, 0xab, 0x4c, 0x8c, 0x90, 0x94, 0xe5, 0x0e, 0xd5,
0x62, 0x78, 0xab, 0xa5, 0x9c, 0x11, 0x1c, 0x70, 0x07, 0x9b,
0x2a, 0xe4, 0xfb, 0xed, 0xfb, 0xcd, 0x92, 0x0d, 0xbc, 0x21,
0x25, 0x33, 0x0b, 0xbf, 0xf3, 0x18, 0x93, 0x73, 0xed, 0xf3,
0x88, 0x3b, 0x43, 0x97, 0xce, 0x19, 0x25, 0xf5, 0xbb, 0x71,
0x26, 0x98, 0x2c, 0xd6, 0xff, 0x32, 0x4f, 0x75, 0xcc, 0x92,
0x4e, 0xe3, 0xbe, 0xb8, 0xbf, 0x33, 0x89, 0xe5, 0x09, 0x4c,
0x41, 0x8c, 0xb0, 0x51, 0x74, 0x32, 0xea, 0x96, 0xce, 0x70,
0x1c, 0x5c, 0x26, 0x34, 0x66, 0x3a, 0x3a, 0xe8, 0x92, 0x4e,
0xd2, 0x61, 0x70, 0x12, 0x3c, 0x33, 0x9d, 0x09, 0x57, 0x23,
0x48, 0x81, 0x29, 0x7f, 0xc9, 0x4d, 0x06, 0xe8, 0xc5, 0x6e,
0x50, 0x7c, 0x8f, 0xfa, 0xf0, 0xb4, 0xe6, 0x9c, 0x7d, 0x5e,
0x09, 0x36, 0xb3, 0x24, 0xc4, 0xf8, 0xe3, 0x19, 0xa8, 0x65,
0x3f, 0x2a, 0x84, 0x98, 0x79, 0x18, 0x58, 0x26, 0x29, 0x5e,
0xbc, 0x3c, 0x7e, 0x80, 0xaa, 0x04, 0x43, 0x1b, 0xbd, 0x36,
0xef, 0x5c, 0xc6, 0x78, 0xfb, 0xa6, 0xfd, 0x26, 0x6a, 0xa4,
0xb6, 0x2e, 0x92, 0xb7, 0x7a, 0x02, 0xa7, 0xc8, 0xb0, 0x47,
0xa8, 0x6e, 0x6a, 0x53, 0x15, 0x81, 0x7d, 0x1c, 0xb0, 0x55,
0xbe, 0xa9, 0x11, 0x1e, 0xd0, 0xd8, 0x99, 0x37, 0xae, 0x35,
0xfa, 0xe4, 0x0b, 0x4c, 0x52, 0x0c, 0x12, 0x3a, 0x5f, 0x09,
0x4e, 0x21, 0xc6, 0x0d, 0x56, 0xe4, 0x23, 0xd2, 0x5e, 0x86,
0x7f, 0x04, 0xb0, 0x1c, 0xeb, 0x9f, 0x50, 0x17, 0xcc, 0x8e,
0xf9, 0x8f, 0x00, 0x91, 0xee, 0xa7, 0xa4, 0x91, 0x59, 0xb7,
0x11, 0x9e, 0x87, 0x40, 0xe2, 0x41, 0x08, 0x0f, 0xec, 0x40,
0xbc, 0x8c, 0x30, 0x14, 0xcc, 0x97, 0xc9, 0xf0, 0x50, 0x7b,
0x5c, 0x18, 0xe2, 0x1b, 0x02, 0x7f, 0xda, 0xc0, 0xe6, 0x23,
0x4b, 0x48, 0xbb, 0xe8, 0x01, 0xe9, 0xd4, 0xb8, 0x52, 0xfa,
0x36, 0x99, 0xdd, 0x03, 0x8d, 0x21, 0xd3, 0x16, 0x17, 0x2c,
0x25, 0x20, 0x70, 0x92, 0xd5, 0x57, 0xcb, 0xff, 0x70, 0x16,
0x33, 0x18, 0xf3, 0x31, 0x1a, 0xb0, 0x07, 0x27, 0x82, 0xc5,
0x13, 0x86, 0x3d, 0xb5, 0x22, 0xfb, 0x7d, 0x2a, 0x4d, 0x45,
0xaa, 0x2f, 0x46, 0x67, 0x1e, 0x9f, 0xc4, 0x8b, 0x3a, 0xb8,
0x8c, 0x56, 0x3c, 0xa4, 0xfe, 0xe7, 0x93, 0xb2, 0xed, 0xc8,
0x19, 0x3c, 0xc0, 0x5d, 0x38, 0xb0, 0xa2, 0x54, 0xe8, 0x71,
0xd1, 0x69, 0xc7, 0xb8, 0xdc, 0x33, 0x0c, 0x3b, 0x8f, 0xf4,
0x37, 0x23, 0x3d, 0x1e, 0x7b, 0x50, 0xc5, 0x4c, 0x3a, 0x6a,
0x8d, 0xa8, 0x2b, 0x3d, 0x8c, 0x63, 0x4e, 0x52, 0x79, 0xea,
0x7f, 0xa2, 0x0c, 0xc0, 0xdc, 0xba, 0x60, 0x04, 0x86, 0xa5,
0xd6, 0x2b, 0xab, 0x2a, 0x17, 0xbe, 0x95, 0x11, 0x2d, 0x14,
0x4e, 0xc1, 0x42, 0xa3, 0x8e, 0xaf, 0x57, 0x4d, 0x84, 0xd9,
0x3c, 0x91, 0xb9, 0x45, 0x09, 0x6a, 0xf5, 0xb3, 0x24, 0x4a,
0x2d, 0x69, 0x46, 0x51, 0x65, 0x9a, 0x37, 0x11, 0x7d, 0xde,
0x9c, 0x7c, 0x11, 0xaf, 0x81, 0xfa, 0xdf, 0x1e, 0x5d, 0xff,
0xb2, 0x64, 0x33, 0x75, 0x23, 0x7f, 0x99, 0xc2, 0xa6, 0xb8,
0x30, 0xdf, 0xd2, 0xb6, 0x5a, 0x35, 0x6b, 0xc5, 0x28, 0xb0,
0x60, 0x1a, 0x85, 0x59, 0x2e, 0x2b, 0x8b, 0x8f, 0x9a, 0x4c,
0xd2, 0x9b, 0x90, 0x1e, 0x95, 0x5a, 0xf3, 0xac, 0x34, 0x78,
0x8c, 0xeb, 0x67, 0x09, 0x6b, 0x95, 0x73, 0x5e, 0x54, 0x1f,
0x05, 0xd6, 0xe4, 0xf4, 0x3b, 0x4d, 0x93, 0x13, 0x8a, 0xa2,
0x36, 0x62, 0xb9, 0x76, 0xdc, 0x77, 0xf7, 0x10, 0xf6, 0x73,
0xb7, 0x49, 0x90, 0x53, 0x9a, 0xbe, 0x96, 0x9d, 0x4c, 0xd4,
0xf5, 0x09, 0x15, 0x88, 0xe8, 0xc7, 0xbd, 0x04, 0x1e, 0xf8,
0x70, 0x88, 0x7d, 0xf9, 0x2c, 0xf4, 0x80, 0x5c, 0x6f, 0x55,
0x73, 0xf2, 0xa0, 0x90, 0xb4, 0xb4, 0xb9, 0x80, 0x49, 0x3a,
0xc5, 0xda, 0x84, 0x8c, 0x26, 0x84, 0x90, 0xc1, 0x2b, 0xa6,
0xac, 0x48, 0x2d, 0x37, 0x61, 0x27, 0xd2, 0x18, 0xb8, 0x51,
0x28, 0x0b, 0x13, 0xbb, 0x35, 0x58, 0xe6, 0xf0, 0x24, 0x18,
0x28, 0x42, 0x6d, 0xdd, 0xba, 0xe8, 0x64, 0xf2, 0xff, 0x47,
0x27, 0x59, 0x16, 0x55, 0xcc, 0x5b, 0x54, 0xa3, 0xe2, 0xfb,
0xef, 0x14, 0x68, 0x8d, 0xbf, 0x2e, 0x9a, 0xbc, 0xfa, 0xb8,
0x8e, 0x5e, 0x37, 0x8a, 0x1b, 0x67, 0x09, 0xe8, 0x0b, 0xed,
0x44, 0x71, 0x16, 0x05, 0xbc, 0x5b, 0x2a, 0xf8, 0x8a, 0xdd,
0xd9, 0x74, 0x53, 0x73, 0xb0, 0xd9, 0xb9, 0xfd, 0xd6, 0x67,
0x52, 0x7e, 0x2c, 0x50, 0x36, 0xd0, 0x3b, 0xf7, 0x1f, 0xd8,
0x4a, 0x06, 0x11, 0xf3, 0x21, 0x1f, 0x6e, 0x8f, 0x24, 0x44,
0xb8, 0xa1, 0xba, 0x0a, 0xbb, 0x6c, 0x18, 0x02, 0x8e, 0xe7,
0x5b, 0xed, 0xaa, 0x39, 0xbb, 0xb5, 0x99, 0x00, 0xd9, 0x62,
0x26, 0x5f, 0x26, 0x3e, 0x8e, 0x49, 0x11, 0xd4, 0x2e, 0x70,
0x5e, 0x79, 0x08, 0x63, 0xfb, 0x8d, 0x70, 0x8f, 0x4f, 0x1d,
0x4f, 0x33, 0x72, 0xcd, 0xb1, 0xbd, 0x20, 0x4c, 0x74, 0x7f,
0xde, 0x54, 0xe3, 0x1e, 0xb1, 0x0d, 0xb1, 0xeb, 0x5c, 0x63,
0xd6, 0xc9, 0xaf, 0x82, 0xa6, 0xc5, 0x19, 0xe7, 0x96, 0x2f,
0xaf, 0x19, 0x79, 0x4a, 0xe4, 0x78, 0xd0, 0xb3, 0xfc, 0xff,
0xd7, 0x8f, 0x35, 0x93, 0x41, 0x2d, 0x59, 0xf2, 0xd8, 0xcc,
0x76, 0xb8, 0x3a, 0xf7, 0xdf, 0x1c, 0xa8, 0x85, 0xd5, 0xf8,
0x54, 0x63, 0x75, 0x36, 0xea, 0x30, 0x5a, 0x13, 0x74, 0xf9,
0x6d, 0x55, 0x27, 0x04, 0x0b, 0xa0, 0xa0, 0x6d, 0x9e, 0x3a,
0x93, 0xbf, 0x4e, 0x92, 0x28, 0x85, 0xe4, 0xcf, 0xc5, 0x06,
0xa7, 0x17, 0x5a, 0xec, 0xc2, 0x60, 0x6a, 0xab, 0x1b, 0x50,
0xc9, 0x0b, 0x84, 0x9a, 0x82, 0x45, 0x1e, 0x29, 0xcc, 0x85,
0x5a, 0xa8, 0xd4, 0x90, 0xfb, 0xa7, 0x2f, 0x89, 0xa7, 0x80,
0xd0, 0x69, 0xb6, 0xca, 0xe0, 0x00, 0x4e, 0xe8, 0xea, 0x12,
0x74, 0x85, 0xc8, 0x35, 0xea, 0x1d, 0x23, 0x75, 0x97, 0xcb,
0x1d, 0x94, 0x6f, 0x2a, 0xa9, 0x7a, 0x32, 0xc5, 0x92, 0xf0,
0x0a, 0x28, 0xbd, 0x77, 0xbc, 0xbe, 0xae, 0xa7, 0xa8, 0x34,
0x96, 0x26, 0xaf, 0x83, 0x2a, 0x8e, 0xe9, 0xda, 0xad, 0xb2,
0x52, 0x94, 0x74, 0x69, 0x70, 0x19, 0xc4, 0xc8, 0x36, 0xf3,
0x0f, 0x32, 0x0f, 0x6f, 0x2b, 0x75, 0xac, 0x0e, 0x9d, 0x91,
0x1f, 0x06, 0xba, 0xe3, 0x9c, 0x7f, 0xde, 0x16, 0x3a, 0x3f,
0xfd, 0x7d, 0x88, 0x61, 0x90, 0xca, 0x98, 0xc1, 0xcf, 0xa5,
0x50, 0x1f, 0xb3, 0x8c, 0xf9, 0x8c, 0xe9, 0x9f, 0xa3, 0xd3,
0xd7, 0xce, 0x7f, 0xdf, 0xd2, 0x8e, 0x84, 0x9c, 0x24, 0xc3,
0x85, 0xb1, 0xc6, 0x94, 0x8f, 0xbb, 0x55, 0x83, 0x8e, 0xa3,
0xc7, 0xf5, 0x8e, 0x7e, 0xe6, 0x30, 0x13, 0x06, 0x61, 0x9e,
0x63, 0x24, 0x27, 0x03, 0x01, 0xef, 0xec, 0x6d, 0xb1, 0x56,
0x86, 0xd9, 0xf3, 0x2e, 0xfc, 0xe2, 0xbb, 0xa5, 0xa7, 0xaa,
0x9c, 0x06, 0xf3, 0x36, 0x04, 0xae, 0xbd, 0x0f, 0x6f, 0xb9,
0xc7, 0x42, 0x79, 0xfd, 0xac, 0x8f, 0x1c, 0xcc, 0x01, 0x9f,
0x45, 0x3a, 0x52, 0xa2, 0x20, 0x31, 0xf6, 0x5d, 0xea, 0x4e,
0xe7, 0x13, 0x9d, 0x79, 0xe8, 0x81, 0x62, 0xcd, 0xaf, 0x2e,
0x6b, 0xb5, 0x1b, 0x75, 0xfe, 0x61, 0xf7, 0xcf, 0x4d, 0x90,
0xdf, 0xe8, 0x56, 0x23, 0x96, 0xe4, 0xab, 0x5d, 0xa5, 0xd8,
0x2e, 0x9e, 0x0c, 0x30, 0x27, 0xa3, 0x2c, 0x10, 0xda, 0x79,
0xaf, 0xb9, 0x16, 0x6a, 0x89, 0x33, 0xe7, 0x46, 0xef, 0x43,
0xe5, 0x5e, 0xb6, 0x38, 0xaa, 0x07, 0xb6, 0x5d, 0xd8, 0x57,
0x4b, 0x94, 0xbd, 0xd0, 0x73, 0x9c, 0xf9, 0xa9, 0x31, 0x8a,
0x71, 0xe5, 0xf0, 0xe6, 0xfb, 0x4e, 0xc4, 0xc7, 0x4b, 0xfe,
0xe2, 0x1e, 0xbc, 0x77, 0xba, 0x3b, 0x2c, 0xa2, 0x71, 0x2e,
0xf1, 0xd7, 0x33, 0xa2, 0xae, 0x2d, 0x89, 0x6a, 0xcb, 0x63,
0xed, 0x8d, 0x83, 0x10, 0x96, 0xb4, 0x43, 0xef, 0xc2, 0xe6,
0x49, 0x13, 0x2f, 0x0a, 0x09, 0xae, 0xca, 0xa8, 0x01, 0xff,
0xc9, 0x65, 0x87, 0x8d, 0x20, 0x98, 0x5f, 0xfb, 0x25, 0xe0,
0x7a, 0x3a, 0xcb, 0xf8, 0x48, 0x7e, 0x18, 0xcc, 0x4c, 0x66,
0xd3, 0x76, 0x10, 0x93, 0xa2, 0x7d, 0x3b, 0x0d, 0x49, 0xca,
0xa9, 0x18, 0x2a, 0x50, 0xe2, 0xb3, 0xdc, 0x77, 0x3c, 0x23,
0x84, 0xfe, 0xe7, 0x86, 0x39, 0x7f, 0xc7, 0x18, 0xca, 0xae,
0x79, 0xfc, 0x44, 0x27, 0xf9, 0xbc, 0xce, 0xdb, 0xda, 0xe9,
0xd5, 0x83, 0x90, 0xfb, 0x8c, 0x79, 0x4b, 0xc9, 0x1b, 0x6b,
0x57, 0x0a, 0x88, 0xfc, 0x80, 0x7d, 0x17, 0x10, 0x32, 0x7d,
0xf5, 0x87, 0xf7, 0x18, 0xd6, 0x7a, 0x60, 0x5c, 0x2b, 0x4a,
0x19, 0x0a, 0xea, 0x3f, 0xd1, 0x5b, 0x5e, 0x93, 0x38, 0x9f,
0xc9, 0xfc, 0x6c, 0x67, 0x91, 0xd6, 0x0c, 0x3b, 0x1e, 0xa6,
0x2d, 0x1a, 0x71, 0x74, 0x57, 0x67, 0x46, 0xa2, 0x93, 0xaf,
0x9d, 0x85, 0x0e, 0x0b, 0x1d, 0x39, 0x84, 0xe1, 0x7c, 0x8a,
0x11, 0xed, 0x7b, 0xfe, 0x98, 0xaf, 0x2b, 0x7a, 0xe6, 0xc6,
0x70, 0xf7, 0xce, 0x13, 0xe6, 0x5a, 0x96, 0x7e, 0x5d, 0x76,
0x30, 0xfc, 0x22, 0xdc, 0x4e, 0xb2, 0xd5, 0x59, 0x66, 0x54,
0x70, 0x25, 0x83, 0x1f, 0x16, 0xf0, 0x0a, 0x72, 0xd5, 0xb1,
0x69, 0x86, 0x13, 0xb8, 0x6c, 0x0f, 0xe0, 0x5a, 0xdd, 0x5e,
0x26, 0x9a, 0x9e, 0xbc, 0x94, 0xdf, 0xd0, 0x08, 0x4f, 0xc9,
0x87, 0xf3, 0xd5, 0x6d, 0xad, 0x65, 0xbd, 0x52, 0xd2, 0x10,
0x71, 0xca, 0x4b, 0xe5, 0x72, 0xcd, 0xae, 0xa7, 0x9c, 0x51,
0x52, 0x04, 0xe5, 0xcb, 0x80, 0xfa, 0x23, 0x1b, 0x4a, 0x0d,
0x83, 0x8a, 0xa6, 0x91, 0xef, 0x10, 0x08, 0x05, 0x2a, 0x39,
0x14, 0x2f, 0xdb, 0x1f, 0x96, 0x8d, 0xe1, 0x58, 0x08, 0xd0,
0x65, 0x6d, 0x83, 0x8f, 0x71, 0xe0, 0x87, 0x90, 0x96, 0xce,
0xa4, 0xa0, 0x30, 0xf7, 0x56, 0xd4, 0x88, 0x61, 0x08, 0x61,
0xda, 0xd1, 0x36, 0x8a, 0x92, 0x3f, 0xb1, 0xd4, 0xd0, 0x6f,
0x57, 0x9b, 0xb4, 0xe2, 0x96, 0x12, 0xad, 0x93, 0x4b, 0xd6,
0x59, 0x37, 0x08, 0x4f, 0x7a, 0xc8, 0x7f, 0x37, 0x8e, 0x11,
0x5f, 0x07, 0xd2, 0x5e, 0xbe, 0x54, 0xcb, 0xa8, 0xc6, 0x2e,
0xfc, 0x23, 0x7e, 0xab, 0x40, 0x24, 0x19, 0x4c, 0x51, 0x19,
0x52, 0xcc, 0xc2, 0x70, 0x63, 0xc6, 0x34, 0x1c, 0x97, 0x14,
0xb1, 0xfe, 0xd3, 0xe6, 0x98, 0xf2, 0xd7, 0x77, 0x5a, 0x69,
0xc6, 0xf6, 0x0f, 0xb9, 0x62, 0xae, 0x4a, 0xb0, 0x33, 0x3a,
0x43, 0x16, 0x2b, 0x66, 0xbf, 0xc6, 0x8c, 0x41, 0x8d, 0x0f,
0x94, 0x79, 0x77, 0x81, 0x01, 0x23, 0xd9, 0x5e, 0x81, 0x74,
0x1d, 0x87, 0x11, 0x76, 0xc6, 0x0f, 0x40, 0x91, 0x72, 0xe9,
0x7d, 0x51, 0xb8, 0x72, 0xa9, 0x6f, 0x23, 0x1d, 0x32, 0x33,
0xde, 0xd8, 0xf7, 0x9c, 0x52, 0xa4, 0x6d, 0x4f, 0x3f, 0x9e,
0xe4, 0xfa, 0x25, 0x8f, 0x27, 0x78, 0x8d, 0xde, 0x39, 0xa2,
0xfd, 0xd1, 0x39, 0x01, 0xeb, 0xce, 0xac, 0x60, 0xe4, 0x9f,
0x69, 0x8b, 0xf8, 0xd1, 0x85, 0x70, 0x74, 0xad, 0x1e, 0x30,
0x89, 0x9f, 0x84, 0x58, 0xff, 0xd5, 0x84, 0x41, 0xa6, 0x68,
0x16, 0xc8, 0x07, 0x9b, 0x7a, 0x33, 0x29, 0x05, 0x5c, 0x0e,
0x08, 0x94, 0x4d, 0x18, 0x80, 0xba, 0x10, 0x82, 0x4e, 0x92,
0x60, 0xa8, 0xff, 0x1a, 0x0e, 0x46, 0x57, 0x1e, 0x65, 0x67,
0x25, 0x8d, 0x28, 0xb1, 0xdb, 0x66, 0xca, 0xc0, 0xbc, 0xa9,
0x90, 0x8a, 0x74, 0x52, 0x97, 0x68, 0x32, 0x34, 0x60, 0xb0,
0x30, 0x60, 0xd5, 0x89, 0x15, 0x09, 0x1f, 0x95, 0xc5, 0x41,
0xe2, 0x02, 0x7a, 0x81, 0x7d, 0x49, 0xdd, 0x8c, 0x26, 0x05,
0xfe, 0xed, 0xa8, 0x12, 0xa4, 0x3d, 0x82, 0x65, 0x3d, 0x87,
0xed, 0x95, 0x86, 0x80, 0x3f, 0xc6, 0xcd, 0x27, 0x58, 0x56,
0xca, 0x23, 0xca, 0xa4, 0xd8, 0x06, 0x11, 0xb4, 0x24, 0xc8,
0x8a, 0xc5, 0x36, 0x42, 0xe3, 0xd4, 0xf7, 0xaf, 0x74, 0xac,
0x89, 0xee, 0x47, 0x2e, 0x8b, 0xde, 0xd0, 0x85, 0xd4, 0x2e,
0xb4, 0xae, 0x99, 0x96, 0x88, 0xe2, 0x60, 0x99, 0xfb, 0x62,
0x5f, 0x8b, 0xa7, 0x24, 0xe2, 0xc3, 0x72, 0x4c, 0x6f, 0x1d,
0xcd, 0xc1, 0x3a, 0x32, 0x06, 0x98, 0xb5, 0x92, 0x82, 0x98,
0xb1, 0x7d, 0xca, 0xa1, 0xe1, 0x4d, 0xe1, 0xe5, 0xaf, 0x3a,
0x08, 0x0d, 0x68, 0x33, 0xb8, 0xc0, 0xc3, 0xfd, 0xb9, 0x90,
0x47, 0x58, 0xca, 0xb2, 0x8d, 0x2d, 0x75, 0x7d, 0xbb, 0xd3,
0xc3, 0x0f, 0x7d, 0xa7, 0x5a, 0x5a, 0x25, 0x6f, 0x12, 0xd8,
0x69, 0xd4, 0xc1, 0x20, 0x19, 0x65, 0x4d, 0x36, 0x7c, 0x7f,
0xc4, 0x47, 0x00, 0xcb, 0x2c, 0x64, 0x13, 0x06, 0x0a, 0x37,
0x1d, 0x1d, 0x7d, 0x89, 0x9c, 0x21, 0xd0, 0xaa, 0xa9, 0x01,
0xee, 0xb2, 0x70, 0xc7, 0xc3, 0x11, 0x60, 0xd9, 0x73, 0xc9,
0xea, 0x6d, 0x8a, 0x1b, 0x0f, 0x69, 0x1d, 0xb3, 0x95, 0x82,
0x52, 0xf4, 0xa9, 0x4e, 0x25, 0x85, 0x75, 0xde, 0x12, 0x3c,
0x11, 0x71, 0x06, 0x88, 0xf0, 0x39, 0x93, 0x29, 0x3a, 0x94,
0x7c, 0x73, 0x42, 0xea, 0x59, 0x7c, 0x1d, 0x93, 0x1a, 0x14,
0x10, 0x4c, 0x5e, 0x92, 0x1a, 0x9e, 0x71, 0xf1, 0x42, 0xb9,
0x72, 0x13, 0x7d, 0x99, 0x4a, 0x28, 0x8b, 0x92, 0x48, 0x1d,
0x78, 0x19, 0x04, 0xf8, 0xc4, 0xf3, 0xb1, 0x1c, 0x2f, 0x56,
0xb6, 0xf6, 0x87, 0x00, 0xbd, 0x8c, 0x8c, 0x56, 0xe1, 0x38,
0xf8, 0x6d, 0x19, 0xe7, 0x7e, 0x30, 0x52, 0xc6, 0x47, 0x72,
0xc9, 0xa1, 0x30, 0xef, 0x8c, 0xf6, 0x23, 0xbf, 0xfb, 0xd0,
0xbb, 0x51, 0xa9, 0xf6, 0x1d, 0xa7, 0xd2, 0xc7, 0xaa, 0xa6,
0xc8, 0xa6, 0xa6, 0x61, 0x8f, 0x8c, 0x22, 0xee, 0x6e, 0xb5,
0x21, 0x89, 0x72, 0x0e, 0xbe, 0x00, 0xcf, 0x08, 0x80, 0x09,
0x06, 0x4d, 0xd4, 0xd4, 0xea, 0xb6, 0xa0, 0x8e, 0x71, 0xc8,
0x73, 0x16, 0xdb, 0x55, 0x0f, 0xed, 0xbf, 0xb7, 0x40, 0x41,
0x9a, 0x47, 0xfc, 0xad, 0x5b, 0xf4, 0x86, 0x3c, 0x98, 0xd1,
0xaa, 0x51, 0x15, 0xc3, 0x10, 0x55, 0x8e, 0x5d, 0xf7, 0x9d,
0xd4, 0x11, 0x35, 0xe7, 0x05, 0x11, 0x7d, 0x0f, 0x2b, 0x44,
0xfe, 0x12, 0x7f, 0x39, 0xa6, 0x19, 0x91, 0x8b, 0xd0, 0xac,
0x2c, 0x18, 0x63, 0x6a, 0x33, 0xc2, 0x75, 0xd2, 0xcd, 0xf7,
0x22, 0x46, 0xca, 0xd1, 0xf9, 0xc0, 0x15, 0x08, 0xc7, 0x10,
0x67, 0xd1, 0x42, 0x13, 0x27, 0x22, 0xc3, 0xe3, 0x94, 0x66,
0x00, 0xbf, 0x2f, 0x7d, 0xfb, 0xc5, 0x6f, 0xb9, 0x03, 0x24,
0xce, 0xfb, 0xf4, 0x6b, 0xad, 0xe0, 0x47, 0xda, 0x5f, 0xea,
0x61, 0xfd, 0x6a, 0x76, 0x98, 0x15, 0x76, 0x72, 0xef, 0x95,
0x77, 0x93, 0x3b, 0x23, 0xde, 0x09, 0x38, 0x1c, 0x7b, 0xd5,
0xd1, 0x5c, 0xc5, 0xc4, 0x34, 0x0c, 0xd8, 0xc2, 0x05, 0xb7,
0xe5, 0xb5, 0xc9, 0x7b, 0xc1, 0x28, 0xea, 0xc8, 0x07, 0x98,
0xe2, 0xab, 0x73, 0x24, 0xfb, 0xef, 0xce, 0x0a, 0xa7, 0xb9,
0x8d, 0xeb, 0x31, 0x09, 0x82, 0xf2, 0x9c, 0x4d, 0xf1, 0x1a,
0x4a, 0x79, 0x35, 0xa7, 0x7b, 0x7b, 0xf0, 0xa9, 0xe7, 0xb9,
0xf9, 0x52, 0x63, 0x73, 0x29, 0xe4, 0xd4, 0x13, 0x19, 0x2a,
0xf2, 0x9d, 0x4e, 0xcc, 0x2a, 0xb3, 0xdf, 0x95, 0xc5, 0xb6,
0x91, 0x34, 0xf4, 0x10, 0x2e, 0xe7, 0x0d, 0xf8, 0x3a, 0x6d,
0xdd, 0x30, 0x57, 0xec, 0x05, 0x70, 0xef, 0x80, 0x8c, 0x8a,
0xe1, 0x2e, 0x9e, 0xd4, 0xd1, 0xb4, 0xdc, 0x14, 0x87, 0xf5,
0x97, 0x4b, 0x2c, 0xd9, 0x93, 0x71, 0x3a, 0x15, 0x25, 0xa0,
0x8a, 0xb2, 0x93, 0xb5, 0x62, 0xf7, 0x81, 0x09, 0x9c, 0x8d,
0xe5, 0x09, 0xb2, 0xda, 0x07, 0xf2, 0x33, 0xf6, 0x5c, 0xd2,
0x71, 0xb1, 0xaf, 0xea, 0x62, 0x05, 0xf3, 0x5f, 0xd9, 0xb1,
0x8e, 0xd1, 0x5d, 0xf9, 0x89, 0x85, 0x78, 0xd5, 0x54, 0x56,
0x6c, 0xd4, 0x20, 0x45, 0xe7, 0x03, 0xcc, 0x25, 0x7e, 0xde,
0x40, 0x3d, 0xb2, 0x46, 0x90, 0x59, 0xc2, 0xfc, 0xdc, 0x15,
0xd4, 0x80, 0x5b, 0xd8, 0xec, 0x2e, 0x49, 0xd7, 0xd8, 0x45,
0x0e, 0x7d, 0xba, 0x09, 0x32, 0x60, 0xdb, 0x64, 0xd6, 0x44,
0xd7, 0xea, 0xb4, 0xb1, 0xb6, 0xfc, 0x1b, 0xde, 0x4a, 0x48,
0xa1, 0x6c, 0x5b, 0x5a, 0x1f, 0x35, 0x55, 0x18, 0xd2, 0xae,
0x88, 0x46, 0x5f, 0x2d, 0x25, 0xb0, 0xd9, 0x4f, 0x40, 0xbb,
0x23, 0x40, 0x9f, 0x85, 0x19, 0x4e, 0xd4, 0xfc, 0xcd, 0xc4,
0x59, 0x98, 0x27, 0xe2, 0x7e, 0xab, 0x36, 0x52, 0x51, 0x30,
0xf4, 0xb4, 0xf3, 0xa1, 0x8d, 0x87, 0x01, 0xe5, 0x2d, 0x42,
0x4b, 0x87, 0x70, 0x95, 0xde, 0x9d, 0x80, 0x36, 0x4e, 0x8a,
0x14, 0x40, 0x1c, 0x27, 0x89, 0xe1, 0x42, 0xee, 0x77, 0x87,
0x4f, 0x4d, 0xb0, 0x38, 0x3f, 0x05, 0x67, 0xe3, 0x9c, 0x88,
0xd8, 0x68, 0x75, 0xf3, 0xf9, 0x92, 0x8e, 0x78, 0xbe, 0x43,
0xb9, 0x28, 0xa9, 0x2e, 0xde, 0xc9, 0xbd, 0x48, 0x99, 0x4d,
0x7d, 0xb6, 0xba, 0x3b, 0x31, 0x20, 0x9f, 0x0c, 0xc4, 0x90,
0xae, 0x4a, 0x33, 0x17, 0x58, 0x13, 0xb5, 0xfd, 0xec, 0xef,
0x87, 0x21, 0x0c, 0xce, 0xbd, 0xbd, 0x85, 0x61, 0x07, 0xb8,
0x7f, 0x93, 0xaa, 0xbd, 0xc6, 0xae, 0x63, 0x2c, 0x12, 0x6a,
0xaa, 0xe2, 0x9d, 0xf8, 0x55, 0xac, 0xc3, 0xa3, 0x40, 0xf8,
0xad, 0xfb, 0x21, 0x89, 0x5c, 0x90, 0x21, 0x40, 0x57, 0xfb,
0x08, 0x5d, 0x28, 0x83, 0xcc, 0x46, 0x76, 0x44, 0x2e, 0xe4,
0x5b, 0xe7, 0x37, 0x79, 0xc7, 0xc8, 0x0a, 0x0b, 0xc2, 0xb6,
0x17, 0x48, 0x8c, 0x2b, 0x67, 0xd6, 0xf9, 0x33, 0xe0, 0xbd,
0x6b, 0xea, 0x79, 0x7d, 0x6d, 0x5b, 0x23, 0x7e, 0x5e, 0x5d,
0x53, 0xcf, 0x01, 0xea, 0x86, 0x5f, 0x8a, 0x4b, 0x1f, 0x32,
0xcd, 0xdb, 0x30, 0xe3, 0x27, 0x3f, 0x10, 0x4b, 0xba, 0x3c,
0xf9, 0x42, 0x78, 0x52, 0x01, 0x87, 0xed, 0xf4, 0x15, 0xa4,
0x8d, 0xa0, 0x1d, 0xc7, 0x89, 0xf5, 0x4f, 0x99, 0x28, 0x04,
0xa7, 0x87, 0xf8, 0x9b, 0x77, 0x18, 0x0a, 0xb8, 0x59, 0xf3,
0xcd, 0x74, 0xf1, 0xd5, 0x13, 0x61, 0xca, 0x02, 0x95, 0xe6,
0x50, 0x30, 0x96, 0x83, 0x35, 0xf8, 0xd2, 0xea, 0xd7, 0xd6,
0x5f, 0xbf, 0xab, 0x9b, 0x91, 0xc9, 0xc4, 0x93, 0x57, 0xb5,
0x55, 0xb6, 0x83, 0xb0, 0x83, 0x17, 0x78, 0xc9, 0xb6, 0xa5,
0x55, 0x9b, 0x2d, 0x08, 0x1f, 0x09, 0x37, 0x1c, 0x0a, 0x3a,
0xdc, 0x32, 0xeb, 0x20
};
const uint8_t *key = &static_keys_a[(nonce[0] >> 3) * 0x70];
for(size_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
{
uint8_t v = nonce[i];
v += 0x36;
v += i;
v ^= key[i];
ambassador[i] = v;
}
key = &static_keys_b[(nonce[7] >> 3) * 0x70];
for(size_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
{
uint8_t v = (key[i] ^ morning[i]);
v += 0x21;
v += i;
v ^= nonce[i];
bright[i] = v;
}
}
CHIAKI_EXPORT void chiaki_rpcrypt_bright_ambassador(ChiakiTarget target, uint8_t *bright, uint8_t *ambassador, const uint8_t *nonce, const uint8_t *morning)
{
switch(target)
{
case CHIAKI_TARGET_PS4_8:
case CHIAKI_TARGET_PS4_9:
bright_ambassador_ps4_pre10(bright, ambassador, nonce, morning);
break;
default:
bright_ambassador(bright, ambassador, nonce, morning);
break;
}
}
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause_ps4_pre10(uint8_t *aeropause, const uint8_t *ambassador)
{
for(size_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
{
@ -67,14 +828,81 @@ CHIAKI_EXPORT void chiaki_rpcrypt_aeropause(uint8_t *aeropause, const uint8_t *a
}
}
CHIAKI_EXPORT void chiaki_rpcrypt_init_auth(ChiakiRPCrypt *rpcrypt, const uint8_t *nonce, const uint8_t *morning)
CHIAKI_EXPORT void chiaki_rpcrypt_aeropause(size_t key_1_off, uint8_t *aeropause, const uint8_t *ambassador)
{
chiaki_rpcrypt_bright_ambassador(rpcrypt->bright, rpcrypt->ambassador, nonce, morning);
const uint8_t keys_1[] = {
0xc8, 0x48, 0xc2, 0xb4, 0x08, 0xeb, 0x88, 0xf7, 0x5f, 0x4a,
0x09, 0x2d, 0x59, 0x1f, 0x09, 0xcd, 0x1c, 0x18, 0xf4, 0x7a,
0x28, 0x4a, 0x96, 0x6d, 0xb3, 0x59, 0x71, 0x53, 0x75, 0x7e,
0x82, 0x50, 0x57, 0xe4, 0x59, 0xb3, 0xf4, 0x49, 0x69, 0x40,
0xeb, 0x17, 0xc9, 0x9f, 0x17, 0x97, 0x71, 0xae, 0xc9, 0x60,
0x7f, 0xf8, 0x2e, 0x08, 0x94, 0xe8, 0x43, 0xea, 0xda, 0x6b,
0xe5, 0x19, 0x59, 0x33, 0x1f, 0x89, 0xae, 0x47, 0x57, 0x7b,
0x1c, 0x66, 0xfe, 0xff, 0x95, 0xbf, 0x55, 0x6b, 0xd5, 0x93,
0x27, 0xea, 0xa6, 0x24, 0x67, 0x39, 0x9f, 0xd3, 0x0c, 0xaa,
0x26, 0x42, 0xe7, 0x66, 0x4d, 0xd8, 0x18, 0x75, 0xfe, 0x44,
0x03, 0x46, 0xee, 0x3e, 0xf8, 0x3c, 0xb7, 0x85, 0x97, 0x03,
0x07, 0x06, 0x92, 0xff, 0x59, 0x17, 0x27, 0x0b, 0x21, 0xf7,
0x05, 0x7f, 0x69, 0x90, 0x0e, 0x38, 0x91, 0xc6, 0x67, 0x23,
0x48, 0xba, 0x08, 0x8e, 0x57, 0xdd, 0x91, 0xd0, 0x40, 0x47,
0x1c, 0x5b, 0xbf, 0xc8, 0x06, 0x3f, 0x96, 0xa0, 0xdc, 0x00,
0xe5, 0x9a, 0xf5, 0x3b, 0x90, 0x80, 0x66, 0xbb, 0x0f, 0x93,
0x30, 0x07, 0x2b, 0x56, 0x45, 0xa0, 0x9a, 0xb1, 0xb0, 0x72,
0x0c, 0xe4, 0xdd, 0x70, 0xdd, 0x7c, 0x5a, 0xbf, 0xd4, 0xe8,
0x0d, 0xca, 0x37, 0xe5, 0x0e, 0xfd, 0x12, 0xee, 0x79, 0x9a,
0x5e, 0xa7, 0x1e, 0x31, 0xaf, 0x1f, 0x46, 0x52, 0xca, 0xf3,
0x42, 0x00, 0x3d, 0xf2, 0x89, 0x7c, 0x1c, 0x77, 0x60, 0xb7,
0x4a, 0x80, 0x76, 0x47, 0x4b, 0x3f, 0xb6, 0x91, 0x2f, 0x9c,
0xc2, 0xf1, 0xad, 0x44, 0x29, 0xcb, 0x32, 0x8c, 0x0a, 0x8d,
0x05, 0x75, 0x46, 0xa1, 0xf8, 0xda, 0x1a, 0xa7, 0x20, 0xde,
0x32, 0x59, 0xfe, 0x70, 0xb5, 0x87, 0xf3, 0x92, 0xfd, 0xb4,
0xdf, 0xf4, 0xa6, 0xe3, 0x7d, 0x98, 0x3b, 0xe1, 0xba, 0x18,
0xdb, 0x61, 0xd1, 0xc2, 0xa6, 0xee, 0x08, 0x25, 0xfa, 0x86,
0x8a, 0x7b, 0xfe, 0xbc, 0x02, 0xbd, 0x22, 0x5f, 0x25, 0x30,
0x51, 0x5d, 0x28, 0x36, 0x5a, 0x29, 0x8e, 0x52, 0xeb, 0x49,
0x14, 0x28, 0x7f, 0x0a, 0xc4, 0x69, 0x25, 0x85, 0x6b, 0xec,
0x33, 0x33, 0x57, 0xab, 0x50, 0x13, 0xcf, 0xe7, 0x73, 0x78,
0x23, 0x06, 0x4d, 0x1f, 0xbb, 0x38, 0x11, 0xb1, 0x6e, 0x6c,
0x6f, 0xcd, 0x4b, 0x0e, 0x42, 0x85, 0x80, 0xbb, 0xa8, 0x39,
0x68, 0xc9, 0x5b, 0xbb, 0x46, 0x58, 0x86, 0x88, 0x57, 0x88,
0x5e, 0xea, 0x7c, 0x37, 0xdf, 0xfd, 0x02, 0x39, 0x45, 0x89,
0x2e, 0xf2, 0xe4, 0xf0, 0x08, 0xc0, 0xb6, 0xeb, 0x9c, 0x6e,
0x7a, 0x81, 0xa3, 0x26, 0x46, 0xfe, 0xe1, 0x70, 0x3c, 0x3e,
0x11, 0x7a, 0x32, 0xce, 0x45, 0x02, 0x7d, 0x32, 0xcd, 0x08,
0x07, 0x06, 0xa3, 0xa8, 0xf7, 0x34, 0xfe, 0xee, 0x06, 0xb0,
0x14, 0xd6, 0x6b, 0x2d, 0x2e, 0x01, 0xaf, 0x77, 0x11, 0xec,
0x1f, 0x31, 0x38, 0x17, 0x9c, 0xd0, 0xe0, 0xc5, 0x4d, 0xa4,
0xd6, 0xad, 0xb9, 0xe6, 0xe1, 0xe3, 0xe2, 0x9e, 0x44, 0x91,
0x9a, 0x5e, 0x26, 0xca, 0xcc, 0xda, 0x4d, 0xd7, 0x78, 0x6a,
0x75, 0xa6, 0x19, 0xad, 0xcc, 0x62, 0xc7, 0xb6, 0x0d, 0x14,
0xb1, 0xbe, 0xeb, 0xcb, 0x10, 0xcf, 0xa9, 0xee, 0xe2, 0x42,
0x08, 0x35, 0x8a, 0x5c, 0xbc, 0xf1, 0x49, 0xfe, 0x64, 0x78,
0x03, 0x49, 0x0c, 0x85, 0xf0, 0xe4, 0x77, 0x26, 0xd2, 0x5e,
0xf5, 0xc1, 0x3b, 0x3d, 0x2d, 0xcc, 0xcf, 0x2a, 0xac, 0xed,
0x88, 0x52, 0x74, 0x6d, 0xbf, 0xb2, 0xb9, 0xf7, 0x58, 0x51,
0x1c, 0x50, 0xf6, 0x3d, 0xf2, 0xc4, 0x47, 0x0a, 0x21, 0x30,
0x47, 0x81, 0x2d, 0xe4, 0x75, 0x0d, 0x8f, 0x2d, 0x22, 0xb0,
0x63, 0x27
};
for(size_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
{
uint8_t k = keys_1[i*0x20 + key_1_off];
aeropause[i] = (ambassador[i] ^ k) + 0x29 + (uint8_t)i;
}
}
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, uint32_t pin)
CHIAKI_EXPORT void chiaki_rpcrypt_init_auth(ChiakiRPCrypt *rpcrypt, ChiakiTarget target, const uint8_t *nonce, const uint8_t *morning)
{
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 };
rpcrypt->target = target;
chiaki_rpcrypt_bright_ambassador(target, rpcrypt->bright, rpcrypt->ambassador, nonce, morning);
}
CHIAKI_EXPORT void chiaki_rpcrypt_init_regist_ps4_pre10(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, uint32_t pin)
{
rpcrypt->target = CHIAKI_TARGET_PS4_9; // representative, might not be the actual version
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);
@ -83,10 +911,101 @@ CHIAKI_EXPORT void chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint
rpcrypt->bright[3] ^= (uint8_t)((pin >> 0x00) & 0xff);
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_init_regist(ChiakiRPCrypt *rpcrypt, const uint8_t *ambassador, size_t key_0_off, uint32_t pin)
{
static const uint8_t keys_0[] = {
0xbe, 0xce, 0x5d, 0xf0, 0xc1, 0x7d, 0xb5, 0xd0, 0xcb, 0x30,
0x13, 0x5d, 0xaa, 0x56, 0x23, 0xfb, 0xc4, 0xbc, 0xf1, 0x8f,
0x38, 0x57, 0xfb, 0xd4, 0xd4, 0x3f, 0x26, 0x38, 0xb5, 0xce,
0xed, 0x6a, 0x21, 0xbc, 0x38, 0xd0, 0x1e, 0x68, 0xcc, 0x7b,
0x45, 0xd1, 0xbe, 0x42, 0x1a, 0x08, 0xaa, 0x16, 0xfd, 0xb0,
0xc0, 0xf4, 0xda, 0x35, 0xe9, 0x12, 0xfd, 0x21, 0x07, 0x48,
0x34, 0xc1, 0xfc, 0x9f, 0x8c, 0xb6, 0xcb, 0x5d, 0xb2, 0x9c,
0x84, 0xe0, 0x1a, 0xfa, 0xa0, 0xc7, 0xeb, 0x3a, 0x93, 0xb3,
0xb3, 0xf1, 0x15, 0xaf, 0x13, 0xbd, 0x21, 0xab, 0xea, 0x5b,
0x80, 0x50, 0x6b, 0x31, 0x1d, 0x7c, 0x1d, 0x40, 0xba, 0x3c,
0x56, 0x0e, 0xe7, 0x94, 0x3a, 0x5b, 0xa1, 0x40, 0x80, 0x74,
0x0a, 0xad, 0x28, 0xcf, 0x47, 0xdf, 0x42, 0xa6, 0x69, 0xe9,
0x5e, 0xbb, 0xc0, 0xc0, 0x0e, 0xb2, 0xc5, 0x8a, 0xee, 0x08,
0x03, 0xd2, 0x84, 0xe5, 0x91, 0x00, 0x1d, 0x46, 0x06, 0x55,
0x09, 0x9d, 0x39, 0x9f, 0xd8, 0xe7, 0xfd, 0xad, 0x9e, 0x93,
0x97, 0xc5, 0xea, 0xe7, 0xa3, 0x10, 0xa7, 0xf2, 0xa2, 0x93,
0x7f, 0x07, 0x04, 0xb4, 0xee, 0xbb, 0xbf, 0x88, 0x23, 0x9c,
0x6e, 0xa7, 0x62, 0xb1, 0x4b, 0x67, 0x1e, 0xb8, 0x3b, 0x1f,
0x64, 0x93, 0x5a, 0x99, 0xec, 0xda, 0xfd, 0x0c, 0x6a, 0xb7,
0xfe, 0xe4, 0x12, 0x76, 0x32, 0x65, 0xb8, 0x41, 0x23, 0xd1,
0x17, 0x09, 0x9c, 0x24, 0x2d, 0x5c, 0x9d, 0x12, 0x79, 0xde,
0xa1, 0xce, 0x69, 0xac, 0xa4, 0xbc, 0x39, 0x2f, 0x57, 0x38,
0x84, 0x61, 0x2d, 0x2a, 0xe8, 0x04, 0xf8, 0xd5, 0x9d, 0x0b,
0xff, 0x7e, 0x56, 0x0c, 0xec, 0x87, 0x0a, 0x1e, 0xab, 0xdf,
0x93, 0x81, 0x13, 0xee, 0xcf, 0x32, 0x02, 0x5a, 0xbf, 0xb0,
0x17, 0xb7, 0xba, 0xb5, 0x7f, 0xf0, 0x01, 0x7b, 0xe1, 0xcb,
0x39, 0x7e, 0x60, 0x6d, 0xa4, 0x75, 0x6e, 0x29, 0x92, 0x45,
0xa6, 0x4f, 0x74, 0x00, 0x86, 0x78, 0x73, 0xbe, 0xfd, 0x3e,
0xe0, 0xd1, 0x0c, 0x6c, 0x0b, 0x49, 0x09, 0x83, 0x6c, 0x85,
0x8a, 0x1d, 0xcb, 0x16, 0xce, 0x81, 0x7c, 0x49, 0xc9, 0x2c,
0x63, 0x61, 0xde, 0xe2, 0x3f, 0x98, 0xb2, 0x73, 0xf0, 0x9a,
0xec, 0x7b, 0x7c, 0xf1, 0xc9, 0xe1, 0x7f, 0xa5, 0x19, 0x8b,
0x4b, 0xe8, 0x38, 0xa4, 0x34, 0x7d, 0xf4, 0x28, 0xfe, 0x0d,
0x4d, 0x11, 0x57, 0x0c, 0x95, 0xf1, 0xaf, 0xd7, 0x34, 0x80,
0xf4, 0xeb, 0x9b, 0x50, 0xe6, 0x6a, 0x5d, 0xea, 0xce, 0x0c,
0x85, 0x4e, 0xc5, 0x5b, 0x93, 0x44, 0xc4, 0x24, 0x98, 0x80,
0xfc, 0xf7, 0x72, 0x9c, 0x31, 0x0b, 0xee, 0x89, 0x67, 0xb3,
0xa2, 0x69, 0x4f, 0xb3, 0x79, 0x5a, 0x14, 0x02, 0x70, 0xed,
0x50, 0x13, 0x75, 0x00, 0x6a, 0xf3, 0xc6, 0x05, 0x1a, 0x00,
0x33, 0x34, 0xf5, 0xac, 0x9e, 0x04, 0xdb, 0xc2, 0x00, 0xb0,
0x1b, 0xc4, 0xf3, 0x97, 0x9d, 0x7f, 0xbe, 0xb8, 0x23, 0x8d,
0x99, 0xe7, 0xcb, 0x74, 0x37, 0x4c, 0x57, 0xec, 0xd2, 0x69,
0x49, 0x46, 0x75, 0x74, 0xaf, 0x51, 0x40, 0xa4, 0x11, 0x7b,
0xb3, 0x2f, 0x51, 0xda, 0xe2, 0xef, 0x33, 0x73, 0x12, 0x18,
0x25, 0x39, 0x03, 0x09, 0xca, 0x49, 0xdc, 0x8e, 0xf1, 0x94,
0xd7, 0x80, 0x17, 0x9e, 0x87, 0x46, 0xc1, 0x04, 0x78, 0xd1,
0xe5, 0x3d, 0x25, 0x88, 0xec, 0x72, 0x3a, 0x28, 0x41, 0x68,
0x14, 0x6e, 0x10, 0xe4, 0xc9, 0x57, 0x75, 0x90, 0xfe, 0x22,
0x1a, 0x63, 0x8e, 0xf4, 0xb8, 0x8d, 0x1a, 0x36, 0xfd, 0xb6,
0xcb, 0x72, 0xc2, 0x97, 0x52, 0x9f, 0x91, 0x72, 0x1b, 0x75,
0x57, 0x90, 0x3b, 0xfd, 0x5a, 0x93, 0x8c, 0xdb, 0xfc, 0xa3,
0x03, 0xdf
};
if(key_0_off >= 0x20)
return CHIAKI_ERR_INVALID_DATA;
rpcrypt->target = CHIAKI_TARGET_PS4_10; // representative, might not be the actual version
memcpy(rpcrypt->ambassador, ambassador, sizeof(rpcrypt->ambassador));
for(size_t i=0; i<CHIAKI_RPCRYPT_KEY_SIZE; i++)
rpcrypt->bright[i] = keys_0[i*0x20 + key_0_off];
rpcrypt->bright[0xc] ^= (uint8_t)((pin >> 0x18) & 0xff);
rpcrypt->bright[0xd] ^= (uint8_t)((pin >> 0x10) & 0xff);
rpcrypt->bright[0xe] ^= (uint8_t)((pin >> 0x08) & 0xff);
rpcrypt->bright[0xf] ^= (uint8_t)((pin >> 0x00) & 0xff);
return CHIAKI_ERR_SUCCESS;
}
#define HMAC_KEY_SIZE 0x10
static const uint8_t hmac_key[HMAC_KEY_SIZE] = { 0x20, 0xd6, 0x6f, 0x59, 0x04, 0xea, 0x7c, 0x14, 0xe5, 0x57, 0xff, 0xc5, 0x2e, 0x48, 0x8a, 0xc8 };
static const uint8_t hmac_key_ps4_pre10[HMAC_KEY_SIZE] = { 0xac, 0x07, 0x88, 0x83, 0xc8, 0x3a, 0x1f, 0xe8, 0x11, 0x46, 0x3a, 0xf3, 0x9e, 0xe3, 0xe3, 0x77 };
static const uint8_t *rpcrypt_hmac_key(ChiakiRPCrypt *rpcrypt)
{
switch(rpcrypt->target)
{
case CHIAKI_TARGET_PS4_8:
case CHIAKI_TARGET_PS4_9:
return hmac_key_ps4_pre10;
default:
return hmac_key;
}
}
#ifdef 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 };
const uint8_t *hmac_key = rpcrypt_hmac_key(rpcrypt);
uint8_t buf[CHIAKI_RPCRYPT_KEY_SIZE + 8];
memcpy(buf, rpcrypt->ambassador, CHIAKI_RPCRYPT_KEY_SIZE);
@ -114,7 +1033,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_rpcrypt_generate_iv(ChiakiRPCrypt *rpcrypt,
} 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_starts(&ctx, hmac_key, HMAC_KEY_SIZE));
GOTO_ERROR(mbedtls_md_hmac_update(&ctx, (const unsigned char *) buf, sizeof(buf)));
GOTO_ERROR(mbedtls_md_hmac_finish(&ctx, hmac));
#undef GOTO_ERROR
@ -172,7 +1091,7 @@ error:
#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 };
const uint8_t *hmac_key = rpcrypt_hmac_key(rpcrypt);
uint8_t buf[CHIAKI_RPCRYPT_KEY_SIZE + 8];
memcpy(buf, rpcrypt->ambassador, CHIAKI_RPCRYPT_KEY_SIZE);

View file

@ -46,7 +46,7 @@
#define SESSION_EXPECT_TIMEOUT_MS 5000
static void *session_thread_func(void *arg);
static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersion *server_version_out);
static bool session_thread_request_session(ChiakiSession *session, ChiakiTarget *target_out);
const char *chiaki_rp_application_reason_string(uint32_t reason)
{
@ -67,26 +67,30 @@ const char *chiaki_rp_application_reason_string(uint32_t reason)
}
}
const char *chiaki_rp_version_string(ChiakiRpVersion version)
const char *chiaki_rp_version_string(ChiakiTarget version)
{
switch(version)
{
case CHIAKI_RP_VERSION_8_0:
case CHIAKI_TARGET_PS4_8:
return "8.0";
case CHIAKI_RP_VERSION_9_0:
case CHIAKI_TARGET_PS4_9:
return "9.0";
case CHIAKI_TARGET_PS4_10:
return "10.0";
default:
return NULL;
}
}
CHIAKI_EXPORT ChiakiRpVersion chiaki_rp_version_parse(const char *rp_version_str)
CHIAKI_EXPORT ChiakiTarget chiaki_rp_version_parse(const char *rp_version_str)
{
if(strcmp(rp_version_str, "8.0") == 0)
return CHIAKI_RP_VERSION_8_0;
return CHIAKI_TARGET_PS4_8;
if(strcmp(rp_version_str, "9.0") == 0)
return CHIAKI_RP_VERSION_9_0;
return CHIAKI_RP_VERSION_UNKNOWN;
return CHIAKI_TARGET_PS4_9;
if(strcmp(rp_version_str, "10.0") == 0)
return CHIAKI_TARGET_PS4_10;
return CHIAKI_TARGET_PS4_UNKNOWN;
}
CHIAKI_EXPORT void chiaki_connect_video_profile_preset(ChiakiConnectVideoProfile *profile, ChiakiVideoResolutionPreset resolution, ChiakiVideoFPSPreset fps)
@ -174,7 +178,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, Chiaki
session->log = log;
session->quit_reason = CHIAKI_QUIT_REASON_NONE;
session->rp_version = CHIAKI_RP_VERSION_9_0;
session->target = CHIAKI_TARGET_PS4_10;
ChiakiErrorCode err = chiaki_cond_init(&session->state_cond);
if(err != CHIAKI_ERR_SUCCESS)
@ -369,13 +373,20 @@ static void *session_thread_func(void *arg)
CHIAKI_LOGI(session->log, "Starting session request");
ChiakiRpVersion server_rp_version = CHIAKI_RP_VERSION_UNKNOWN;
success = session_thread_request_session(session, &server_rp_version);
ChiakiTarget server_target = CHIAKI_TARGET_PS4_UNKNOWN;
success = session_thread_request_session(session, &server_target);
if(!success && server_rp_version != CHIAKI_RP_VERSION_UNKNOWN)
if(!success && server_target != CHIAKI_TARGET_PS4_UNKNOWN)
{
CHIAKI_LOGI(session->log, "Attempting to re-request session with Server's RP-Version");
session->rp_version = server_rp_version;
session->target = server_target;
success = session_thread_request_session(session, &server_target);
}
if(!success && server_target != CHIAKI_TARGET_PS4_UNKNOWN)
{
CHIAKI_LOGI(session->log, "Attempting to re-request session even harder with Server's RP-Version!!!");
session->target = server_target;
success = session_thread_request_session(session, NULL);
}
@ -384,7 +395,7 @@ static void *session_thread_func(void *arg)
CHIAKI_LOGI(session->log, "Session request successful");
chiaki_rpcrypt_init_auth(&session->rpcrypt, session->nonce, session->connect_info.morning);
chiaki_rpcrypt_init_auth(&session->rpcrypt, session->target, session->nonce, session->connect_info.morning);
// PS4 doesn't always react right away, sleep a bit
chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, 10, session_check_state_pred, session);
@ -584,9 +595,9 @@ static void parse_session_response(SessionResponse *response, ChiakiHttpResponse
/**
* @param server_version_out if NULL, version mismatch means to fail the entire session, otherwise report the version here
* @param target_out if NULL, version mismatch means to fail the entire session, otherwise report the target here
*/
static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersion *server_version_out)
static bool session_thread_request_session(ChiakiSession *session, ChiakiTarget *target_out)
{
chiaki_socket_t session_sock = CHIAKI_INVALID_SOCKET;
for(struct addrinfo *ai=session->connect_info.host_addrinfos; ai; ai=ai->ai_next)
@ -676,7 +687,7 @@ static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersi
CHIAKI_LOGI(session->log, "Connected to %s:%d", session->connect_info.hostname, SESSION_PORT);
static const char session_request_fmt[] =
"GET /sce/rp/session HTTP/1.1\r\n"
"GET %s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"User-Agent: remoteplay Windows\r\n"
"Connection: close\r\n"
@ -684,6 +695,9 @@ static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersi
"RP-Registkey: %s\r\n"
"Rp-Version: %s\r\n"
"\r\n";
const char *path = (session->target == CHIAKI_TARGET_PS4_8 || session->target == CHIAKI_TARGET_PS4_9)
? "/sce/rp/session"
: "/sie/ps4/rp/sess/init";
size_t regist_key_len = sizeof(session->connect_info.regist_key);
for(size_t i=0; i<regist_key_len; i++)
@ -703,11 +717,11 @@ static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersi
return false;
}
const char *rp_version_str = chiaki_rp_version_string(session->rp_version);
const char *rp_version_str = chiaki_rp_version_string(session->target);
char buf[512];
int request_len = snprintf(buf, sizeof(buf), session_request_fmt,
session->connect_info.hostname, SESSION_PORT, regist_key_hex, rp_version_str ? rp_version_str : "");
path, session->connect_info.hostname, SESSION_PORT, regist_key_hex, rp_version_str ? rp_version_str : "");
if(request_len < 0 || request_len >= sizeof(buf))
{
CHIAKI_SOCKET_CLOSE(session_sock);
@ -774,12 +788,20 @@ static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersi
session->quit_reason = CHIAKI_QUIT_REASON_SESSION_REQUEST_UNKNOWN;
}
}
else if(response.error_code == CHIAKI_RP_APPLICATION_REASON_RP_VERSION && server_version_out && response.rp_version)
else if((response.error_code == CHIAKI_RP_APPLICATION_REASON_RP_VERSION
|| response.error_code == CHIAKI_RP_APPLICATION_REASON_UNKNOWN)
&& target_out && response.rp_version && strcmp(rp_version_str, response.rp_version))
{
CHIAKI_LOGI(session->log, "Reported RP-Version mismatch. ours = %s, server = %s", rp_version_str ? rp_version_str : "", response.rp_version);
*server_version_out = chiaki_rp_version_parse(response.rp_version);
if(*server_version_out != CHIAKI_RP_VERSION_UNKNOWN)
CHIAKI_LOGI(session->log, "Detected Server RP-Version %s", chiaki_rp_version_string(*server_version_out));
CHIAKI_LOGI(session->log, "Reported RP-Version mismatch. ours = %s, server = %s",
rp_version_str ? rp_version_str : "", response.rp_version);
*target_out = chiaki_rp_version_parse(response.rp_version);
if(*target_out != CHIAKI_TARGET_PS4_UNKNOWN)
CHIAKI_LOGI(session->log, "Detected Server RP-Version %s", chiaki_rp_version_string(*target_out));
else if(!strcmp(response.rp_version, "5.0"))
{
CHIAKI_LOGI(session->log, "Reported Server RP-Version is 5.0. This is probably nonsense, let's try with 9.0");
*target_out = CHIAKI_TARGET_PS4_9;
}
else
{
CHIAKI_LOGE(session->log, "Server RP-Version is unknown");

View file

@ -24,25 +24,25 @@ static const uint8_t ambassador[CHIAKI_RPCRYPT_KEY_SIZE] = { 0x13, 0x37, 0xde, 0
static const uint32_t pin = 13374201;
static const char * const psn_id = "ChiakiNanami1337";
static MunitResult test_aeropause(const MunitParameter params[], void *user)
static MunitResult test_aeropause_ps4_pre10(const MunitParameter params[], void *user)
{
uint8_t expected[CHIAKI_RPCRYPT_KEY_SIZE] = { 0x0b, 0xe1, 0x2f, 0xbb, 0x4c, 0x7c, 0x99, 0x4a, 0x41, 0x1e, 0x2d, 0x4c, 0xa4, 0x19, 0xf4, 0x35 };
uint8_t aeropause[CHIAKI_RPCRYPT_KEY_SIZE];
chiaki_rpcrypt_aeropause(aeropause, ambassador);
chiaki_rpcrypt_aeropause_ps4_pre10(aeropause, ambassador);
munit_assert_memory_equal(sizeof(expected), aeropause, expected);
return MUNIT_OK;
}
static MunitResult test_pin_bright(const MunitParameter params[], void *user)
static MunitResult test_pin_bright_ps4_pre10(const MunitParameter params[], void *user)
{
uint8_t expected[CHIAKI_RPCRYPT_KEY_SIZE] = { 0x3f, 0xd0, 0xd6, 0x4f, 0xdc, 0xbb, 0x3e, 0xcc, 0x50, 0xba, 0xed, 0xef, 0x97, 0x34, 0xc7, 0xc9 };
ChiakiRPCrypt rpcrypt;
chiaki_rpcrypt_init_regist(&rpcrypt, ambassador, pin);
chiaki_rpcrypt_init_regist_ps4_pre10(&rpcrypt, ambassador, pin);
munit_assert_memory_equal(sizeof(expected), rpcrypt.bright, expected);
return MUNIT_OK;
}
static MunitResult test_request_payload(const MunitParameter params[], void *user)
static MunitResult test_request_payload_ps4_pre10(const MunitParameter params[], void *user)
{
uint8_t expected[] = {
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
@ -65,11 +65,10 @@ static MunitResult test_request_payload(const MunitParameter params[], void *use
};
ChiakiRPCrypt rpcrypt;
chiaki_rpcrypt_init_regist(&rpcrypt, ambassador, pin);
uint8_t payload[0x400];
size_t payload_size = sizeof(payload);
ChiakiErrorCode err = chiaki_regist_request_payload_format(payload, &payload_size, &rpcrypt, psn_id, NULL);
ChiakiErrorCode err = chiaki_regist_request_payload_format(CHIAKI_TARGET_PS4_9, ambassador, payload, &payload_size, &rpcrypt, psn_id, NULL, pin);
munit_assert_int(err, ==, CHIAKI_ERR_SUCCESS);
munit_assert_size(payload_size, ==, sizeof(expected));
munit_assert_memory_equal(sizeof(expected), payload, expected);
@ -78,28 +77,28 @@ static MunitResult test_request_payload(const MunitParameter params[], void *use
MunitTest tests_regist[] = {
{
"/aeropause",
test_aeropause,
"/aeropause_ps4_pre10",
test_aeropause_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/pin_bright",
test_pin_bright,
"/pin_bright_ps4_pre10",
test_pin_bright_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/request_payload",
test_request_payload,
"/request_payload_ps4_pre10",
test_request_payload_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
};

View file

@ -19,19 +19,16 @@
#include <chiaki/rpcrypt.h>
static const uint8_t nonce[] = { 0x43, 0x9, 0x67, 0xae, 0x36, 0x4b, 0x1c, 0x45, 0x26, 0x62, 0x37, 0x7a, 0xbf, 0x3f, 0xe9, 0x39 };
static const uint8_t morning[] = { 0xd2, 0x78, 0x9f, 0x51, 0x85, 0xa7, 0x99, 0xa2, 0x44, 0x52, 0x77, 0x9c, 0x2b, 0x83, 0xcf, 0x7 };
static MunitResult test_bright_ambassador(const MunitParameter params[], void *user)
static MunitResult test_bright_ambassador_ps4_pre10(const MunitParameter params[], void *user)
{
static const uint8_t nonce[] = { 0x43, 0x9, 0x67, 0xae, 0x36, 0x4b, 0x1c, 0x45, 0x26, 0x62, 0x37, 0x7a, 0xbf, 0x3f, 0xe9, 0x39 };
static const uint8_t morning[] = { 0xd2, 0x78, 0x9f, 0x51, 0x85, 0xa7, 0x99, 0xa2, 0x44, 0x52, 0x77, 0x9c, 0x2b, 0x83, 0xcf, 0x7 };
static const uint8_t bright_expected[] = { 0xa4, 0x4e, 0x2a, 0x16, 0x5e, 0x20, 0xd3, 0xf, 0xaa, 0x11, 0x8b, 0xc7, 0x7c, 0xa7, 0xdc, 0x11 };
static const uint8_t ambassador_expected[] = { 0x1d, 0xa8, 0xb9, 0x1f, 0x6e, 0x26, 0x64, 0x2e, 0xbc, 0x8, 0x8b, 0x0, 0x4f, 0x1, 0x5b, 0x52 };
uint8_t bright[CHIAKI_RPCRYPT_KEY_SIZE];
uint8_t ambassador[CHIAKI_RPCRYPT_KEY_SIZE];
chiaki_rpcrypt_bright_ambassador(bright, ambassador, nonce, morning);
chiaki_rpcrypt_bright_ambassador(CHIAKI_TARGET_PS4_9, bright, ambassador, nonce, morning);
munit_assert_memory_equal(CHIAKI_RPCRYPT_KEY_SIZE, bright, bright_expected);
munit_assert_memory_equal(CHIAKI_RPCRYPT_KEY_SIZE, ambassador, ambassador_expected);
@ -39,15 +36,34 @@ static MunitResult test_bright_ambassador(const MunitParameter params[], void *u
return MUNIT_OK;
}
static MunitResult test_iv(const MunitParameter params[], void *user)
static MunitResult test_bright_ambassador(const MunitParameter params[], void *user)
{
static const uint8_t nonce_local[] = { 0xAE, 0x92, 0xE7, 0x64, 0x88, 0x26, 0x51, 0xEF, 0x89, 0x01, 0x8C, 0xFA, 0x69, 0x6C, 0x69, 0x38 };
static const uint8_t morning_local[] = { 0x74, 0xA5, 0x9C, 0x96, 0x93, 0xC2, 0x08, 0x3B, 0xA6, 0xA8, 0x4B, 0xA0, 0x50, 0xFA, 0x8E, 0x5A };
static const uint8_t ambassador_expected[] = { 0x92, 0xBE, 0xE2, 0x19, 0xB9, 0xD5, 0xB1, 0xAB, 0xC6, 0x49, 0x45, 0x77, 0xA4, 0x21, 0xE9, 0xBD };
static const uint8_t bright_expected[] = { 0x67, 0x40, 0x8C, 0x5E, 0x65, 0x66, 0x5A, 0xD2, 0x91, 0xA8, 0x32, 0xEB, 0xE2, 0xD9, 0x0A, 0xBB };
uint8_t bright[CHIAKI_RPCRYPT_KEY_SIZE];
uint8_t ambassador[CHIAKI_RPCRYPT_KEY_SIZE];
chiaki_rpcrypt_bright_ambassador(CHIAKI_TARGET_PS4_10, bright, ambassador, nonce_local, morning_local);
munit_assert_memory_equal(CHIAKI_RPCRYPT_KEY_SIZE, ambassador, ambassador_expected);
munit_assert_memory_equal(CHIAKI_RPCRYPT_KEY_SIZE, bright, bright_expected);
return MUNIT_OK;
}
static MunitResult test_iv_ps4_pre10(const MunitParameter params[], void *user)
{
static const uint8_t nonce[] = { 0x43, 0x9, 0x67, 0xae, 0x36, 0x4b, 0x1c, 0x45, 0x26, 0x62, 0x37, 0x7a, 0xbf, 0x3f, 0xe9, 0x39 };
static const uint8_t morning[] = { 0xd2, 0x78, 0x9f, 0x51, 0x85, 0xa7, 0x99, 0xa2, 0x44, 0x52, 0x77, 0x9c, 0x2b, 0x83, 0xcf, 0x7 };
static const uint8_t iv_a_expected[] = { 0x6, 0x29, 0xbe, 0x4, 0xe9, 0x91, 0x1c, 0x48, 0xb4, 0x5c, 0x2, 0x6d, 0xb7, 0xb7, 0x88, 0x46 };
static const uint8_t iv_b_expected[] = { 0x3f, 0xd0, 0x83, 0xa, 0xc7, 0x30, 0xfc, 0x56, 0x75, 0x2d, 0xbe, 0xb8, 0x2c, 0x68, 0xa7, 0x4 };
ChiakiRPCrypt rpcrypt;
ChiakiErrorCode err;
chiaki_rpcrypt_init_auth(&rpcrypt, nonce, morning);
chiaki_rpcrypt_init_auth(&rpcrypt, CHIAKI_TARGET_PS4_9, nonce, morning);
uint8_t iv[CHIAKI_RPCRYPT_KEY_SIZE];
@ -74,14 +90,49 @@ static MunitResult test_iv(const MunitParameter params[], void *user)
return MUNIT_OK;
}
#include <stdio.h>
static MunitResult test_encrypt(const MunitParameter params[], void *user)
static MunitResult test_iv_regist(const MunitParameter params[], void *user)
{
static const uint8_t ambassador[] = { 0x3e, 0x7e, 0x7a, 0x82, 0x59, 0x73, 0xad, 0xab, 0x2f, 0x69, 0x43, 0x46, 0xbd, 0x44, 0xda, 0xb5 };
static const uint8_t iv_expected[] = { 0xac, 0x48, 0x99, 0x77, 0xf9, 0x2a, 0xc5, 0x5b, 0xb9, 0x09, 0x3c, 0x33, 0xb6, 0x11, 0x3c, 0x46 };
ChiakiRPCrypt rpcrypt;
ChiakiErrorCode err;
chiaki_rpcrypt_init_auth(&rpcrypt, nonce, morning);
chiaki_rpcrypt_init_regist(&rpcrypt, ambassador, 0, 0);
uint8_t iv[CHIAKI_RPCRYPT_KEY_SIZE];
err = chiaki_rpcrypt_generate_iv(&rpcrypt, iv, 0);
if(err != CHIAKI_ERR_SUCCESS)
return MUNIT_ERROR;
munit_assert_memory_equal(CHIAKI_RPCRYPT_KEY_SIZE, iv, iv_expected);
return MUNIT_OK;
}
static MunitResult test_bright_regist(const MunitParameter params[], void *user)
{
static const uint8_t ambassador[] = { 0xdc, 0xa1, 0xc8, 0x4d, 0xfe, 0x50, 0xd6, 0x57, 0x22, 0xda, 0x09, 0x65, 0x42, 0x31, 0xe7, 0xc2 };
static const uint8_t bright_expected[] = { 0xed, 0xfc, 0x1d, 0xc5, 0xa2, 0xfe, 0x2d, 0x7f, 0x09, 0x19, 0x85, 0x75, 0x33, 0x6c, 0x13, 0x16 };
size_t key_0_off = 0x1e;
ChiakiRPCrypt rpcrypt;
ChiakiErrorCode err;
chiaki_rpcrypt_init_regist(&rpcrypt, ambassador, key_0_off, 78703893);
munit_assert_memory_equal(CHIAKI_RPCRYPT_KEY_SIZE, rpcrypt.bright, bright_expected);
return MUNIT_OK;
}
static MunitResult test_encrypt_ps4_pre10(const MunitParameter params[], void *user)
{
static const uint8_t nonce[] = { 0x43, 0x9, 0x67, 0xae, 0x36, 0x4b, 0x1c, 0x45, 0x26, 0x62, 0x37, 0x7a, 0xbf, 0x3f, 0xe9, 0x39 };
static const uint8_t morning[] = { 0xd2, 0x78, 0x9f, 0x51, 0x85, 0xa7, 0x99, 0xa2, 0x44, 0x52, 0x77, 0x9c, 0x2b, 0x83, 0xcf, 0x7 };
ChiakiRPCrypt rpcrypt;
ChiakiErrorCode err;
chiaki_rpcrypt_init_auth(&rpcrypt, CHIAKI_TARGET_PS4_9, nonce, morning);
// less than block size
uint8_t buf_a[] = { 0x13, 0x37, 0xc0, 0xff, 0xee };
@ -118,12 +169,14 @@ static MunitResult test_encrypt(const MunitParameter params[], void *user)
return MUNIT_OK;
}
static MunitResult test_decrypt(const MunitParameter params[], void *user)
static MunitResult test_decrypt_ps4_pre10(const MunitParameter params[], void *user)
{
static const uint8_t nonce[] = { 0x43, 0x9, 0x67, 0xae, 0x36, 0x4b, 0x1c, 0x45, 0x26, 0x62, 0x37, 0x7a, 0xbf, 0x3f, 0xe9, 0x39 };
static const uint8_t morning[] = { 0xd2, 0x78, 0x9f, 0x51, 0x85, 0xa7, 0x99, 0xa2, 0x44, 0x52, 0x77, 0x9c, 0x2b, 0x83, 0xcf, 0x7 };
ChiakiRPCrypt rpcrypt;
ChiakiErrorCode err;
chiaki_rpcrypt_init_auth(&rpcrypt, nonce, morning);
chiaki_rpcrypt_init_auth(&rpcrypt, CHIAKI_TARGET_PS4_9, nonce, morning);
// less than block size
uint8_t buf_a[] = { 0x8d, 0xd2, 0x1d, 0xfb };
@ -162,6 +215,14 @@ static MunitResult test_decrypt(const MunitParameter params[], void *user)
MunitTest tests_rpcrypt[] = {
{
"/bright_ambassador_ps4_pre10",
test_bright_ambassador_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/bright_ambassador",
test_bright_ambassador,
@ -171,28 +232,44 @@ MunitTest tests_rpcrypt[] = {
NULL
},
{
"/iv",
test_iv,
"/iv_ps4_pre10",
test_iv_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/encrypt",
test_encrypt,
"/iv_regist",
test_iv_regist,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/decrypt",
test_decrypt,
"/bright_regist",
test_bright_regist,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/encrypt_ps4_pre10",
test_encrypt_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{
"/decrypt_ps4_pre10",
test_decrypt_ps4_pre10,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
};