From 721897d7b02ab01b1716cf9eefbbd6c7dbdfa40d Mon Sep 17 00:00:00 2001 From: QCDLZCLW3K <1329-33c17f40@users.noreply.dev.s-ul.net> Date: Thu, 12 May 2022 10:24:21 +0900 Subject: [PATCH] Separate key algorithm and core code for rp2 and rp3 --- src/main/security/rp2.c | 49 +++++++++++++++++++++++------------------ src/main/security/rp2.h | 24 +++++++++++--------- src/main/security/rp3.c | 21 +++++++++--------- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/main/security/rp2.c b/src/main/security/rp2.c index 65d9ed1..4741c9e 100644 --- a/src/main/security/rp2.c +++ b/src/main/security/rp2.c @@ -1,3 +1,5 @@ +#include + #include "security/rp2.h" #include "security/rp-util.h" #include "security/util.h" @@ -48,6 +50,19 @@ void security_rp2_create_signature( } } +void security_rp2_generate_signed_eeprom_data_core( + const uint8_t *sign_key, + const uint8_t *plug_mcode, + const uint8_t *plug_id, + uint8_t *signature, + uint8_t *packed_payload) +{ + uint8_t sign_key_tmp[8]; + security_util_8_to_6_encode(sign_key, sign_key_tmp); + security_rp2_create_signature(plug_id, sign_key_tmp, signature); + security_util_8_to_6_encode(plug_mcode, packed_payload); +} + void security_rp2_generate_signed_eeprom_data( enum security_rp_util_rp_type type, const struct security_rp_sign_key *sign_key, @@ -57,37 +72,29 @@ void security_rp2_generate_signed_eeprom_data( { uint8_t sign_key_tmp[8]; uint8_t plug_id_enc[8]; + const uint8_t *plug_mcode_raw = (const uint8_t *) plug_mcode; log_assert(sign_key); log_assert(plug_mcode); log_assert(plug_id); log_assert(out); - memcpy(sign_key_tmp, sign_key, sizeof(sign_key_tmp)); + for (int i = 0; i < sizeof(sign_key_tmp); i++) { + sign_key_tmp[i] = sign_key->data[i] ^ 0x40; - if (type == SECURITY_RP_UTIL_RP_TYPE_BLACK) { - for (int i = 0; i < sizeof(sign_key_tmp); i++) { - sign_key_tmp[i] ^= ((const uint8_t *) plug_mcode)[i]; + if (type == SECURITY_RP_UTIL_RP_TYPE_BLACK) { + sign_key_tmp[i] ^= plug_mcode_raw[i]; } } - for (uint8_t i = 0; i < sizeof(sign_key_tmp); i++) { - sign_key_tmp[i] ^= 0x40; - } - - security_util_8_to_6_encode(sign_key_tmp, sign_key_tmp); - plug_id_enc[0] = plug_id->checksum; - plug_id_enc[1] = plug_id->id[2]; - plug_id_enc[2] = plug_id->id[3]; - plug_id_enc[3] = plug_id->id[4]; - plug_id_enc[4] = plug_id->id[5]; - plug_id_enc[5] = plug_id->id[6]; - plug_id_enc[6] = plug_id->id[7]; + memcpy(&plug_id_enc[1], &plug_id->id[2], 6); plug_id_enc[7] = plug_id->id[1]; - security_rp2_create_signature(plug_id_enc, sign_key_tmp, (uint8_t *) out); - - security_util_8_to_6_encode( - (const uint8_t *) plug_mcode, out->packed_payload); -} \ No newline at end of file + security_rp2_generate_signed_eeprom_data_core( + sign_key_tmp, + plug_mcode_raw, + plug_id_enc, + out->signature, + out->packed_payload); +} diff --git a/src/main/security/rp2.h b/src/main/security/rp2.h index c68a155..b5284c7 100644 --- a/src/main/security/rp2.h +++ b/src/main/security/rp2.h @@ -20,16 +20,22 @@ struct security_rp2_eeprom { }; /** - * Generates the signature for the given plug id. Used by both rp2 and rp3. + * This is the core of the algorithm shared between rp2 and rp3 dongles. + * The keys passed to this function are assumed to already be mutated + * as required. * - * @param plug_id The scrambled form of the plug id stored on the plug. - * @param sign_key_packed The packed key to use for generating the signature. - * @param out Pointer to the buffer for the resulting data. + * @param sign_key The key to use for generating the signature. + * @param plug_mcode The mcode of the game to boot. + * @param plug_id The id stored on the plug. + * @param signature Pointer to the signature buffer for the resulting data. + * @param packed_payload Pointer to the payload buffer for the resulting data. */ -void security_rp2_create_signature( - const uint8_t *plug_id_enc, - const uint8_t *sign_key_packed, - uint8_t *out); +void security_rp2_generate_signed_eeprom_data_core( + const uint8_t *sign_key, + const uint8_t *plug_mcode, + const uint8_t *plug_id, + uint8_t *signature, + uint8_t *packed_payload); /** * Generate signed eeprom data from non encrypted and unobfuscated data required @@ -44,8 +50,6 @@ void security_rp2_create_signature( * @param sign_key The key to use for generating the signature. * This key can be extracted from the executables of the games and might * be re-used for multiple games of the same series or generation. - * @param boot_version The boot version mcode that is used for bootstrapping - * the security backend (of the ezusb.dll). * @param plug_mcode The mcode of the game to boot. Typically, this code is * printed onto the housing of the black dongle. For white * dongles, the "mcode" @@@@@@@@ is used. diff --git a/src/main/security/rp3.c b/src/main/security/rp3.c index e5f9421..77ecd05 100644 --- a/src/main/security/rp3.c +++ b/src/main/security/rp3.c @@ -1,10 +1,11 @@ +#include + #include "security/rp2.h" #include "security/rp3.h" #include "security/rp-util.h" #include "security/util.h" #include "util/crc.h" -#include "util/crypto.h" #include "util/log.h" void security_rp3_generate_signed_eeprom_data( @@ -16,6 +17,7 @@ void security_rp3_generate_signed_eeprom_data( { uint8_t sign_key_tmp[8]; uint8_t plug_id_reversed[8]; + const uint8_t *plug_mcode_raw = (const uint8_t *) plug_mcode; log_assert(sign_key); log_assert(plug_mcode); @@ -23,24 +25,23 @@ void security_rp3_generate_signed_eeprom_data( log_assert(out); memcpy(sign_key_tmp, sign_key, sizeof(sign_key_tmp)); - if (type == SECURITY_RP_UTIL_RP_TYPE_BLACK) { for (int i = 0; i < sizeof(sign_key_tmp); i++) { - sign_key_tmp[i] ^= ((const uint8_t *) plug_mcode)[i]; + sign_key_tmp[i] ^= plug_mcode_raw[i]; } } - security_util_8_to_6_encode(sign_key_tmp, sign_key_tmp); - for (int i = 0; i < sizeof(plug_id_reversed); i++) { plug_id_reversed[i] = plug_id->id[7 - i]; } - security_util_8_to_6_encode( - (const uint8_t *) plug_mcode, out->packed_payload); - memset(out->zeros, 0, sizeof(out->zeros)); + security_rp2_generate_signed_eeprom_data_core( + sign_key_tmp, + plug_mcode_raw, + plug_id_reversed, + out->signature, + out->packed_payload); - security_rp2_create_signature( - plug_id_reversed, sign_key_tmp, out->signature); + memset(out->zeros, 0, sizeof(out->zeros)); out->crc = crc8((uint8_t *) out, sizeof(*out) - 1, 0); }