diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp index e0cc70dea3..158eebd7f0 100644 --- a/Source/Core/Core/IOS/ES/Formats.cpp +++ b/Source/Core/Core/IOS/ES/Formats.cpp @@ -375,7 +375,7 @@ s32 TicketReader::Unpersonalise() return ret; const auto public_key_iter = ticket_begin + offsetof(Ticket, server_public_key); - ret = iosc.ImportPublicKey(public_handle, &*public_key_iter, PID_ES); + ret = iosc.ImportPublicKey(public_handle, &*public_key_iter, nullptr, PID_ES); if (ret != IPC_SUCCESS) return ret; diff --git a/Source/Core/Core/IOS/IOSC.cpp b/Source/Core/Core/IOS/IOSC.cpp index 6a23a0e2b4..e4bd241f0a 100644 --- a/Source/Core/Core/IOS/IOSC.cpp +++ b/Source/Core/Core/IOS/IOSC.cpp @@ -101,8 +101,8 @@ ReturnCode IOSC::ImportSecretKey(Handle dest_handle, Handle decrypt_handle, u8* return Decrypt(decrypt_handle, iv, encrypted_key, AES128_KEY_SIZE, dest_entry->data.data(), pid); } -constexpr size_t ECC233_PUBLIC_KEY_SIZE = 0x3c; -ReturnCode IOSC::ImportPublicKey(Handle dest_handle, const u8* public_key, u32 pid) +ReturnCode IOSC::ImportPublicKey(Handle dest_handle, const u8* public_key, + const u8* public_key_exponent, u32 pid) { if (!HasOwnership(dest_handle, pid) || IsDefaultHandle(dest_handle)) return IOSC_EACCES; @@ -111,11 +111,20 @@ ReturnCode IOSC::ImportPublicKey(Handle dest_handle, const u8* public_key, u32 p if (!dest_entry) return IOSC_EINVAL; - // TODO: allow other public key subtypes - if (dest_entry->type != TYPE_PUBLIC_KEY || dest_entry->subtype != SUBTYPE_ECC233) + if (dest_entry->type != TYPE_PUBLIC_KEY) return IOSC_INVALID_OBJTYPE; - dest_entry->data.assign(public_key, public_key + ECC233_PUBLIC_KEY_SIZE); + const size_t size = GetSizeForType(dest_entry->type, dest_entry->subtype); + if (size == 0) + return IOSC_INVALID_OBJTYPE; + + dest_entry->data.assign(public_key, public_key + size); + + if (dest_entry->subtype == SUBTYPE_RSA2048 || dest_entry->subtype == SUBTYPE_RSA4096) + { + _assert_(public_key_exponent); + std::copy_n(public_key_exponent, 4, dest_entry->misc_data.begin()); + } return IPC_SUCCESS; } diff --git a/Source/Core/Core/IOS/IOSC.h b/Source/Core/Core/IOS/IOSC.h index 080b9942f3..17a43e9b5f 100644 --- a/Source/Core/Core/IOS/IOSC.h +++ b/Source/Core/Core/IOS/IOSC.h @@ -172,8 +172,9 @@ public: // Import a secret, encrypted key into dest_handle, which will be decrypted using decrypt_handle. ReturnCode ImportSecretKey(Handle dest_handle, Handle decrypt_handle, u8* iv, const u8* encrypted_key, u32 pid); - // Import a public key. - ReturnCode ImportPublicKey(Handle dest_handle, const u8* public_key, u32 pid); + // Import a public key. public_key_exponent must be passed for RSA keys. + ReturnCode ImportPublicKey(Handle dest_handle, const u8* public_key, + const u8* public_key_exponent, u32 pid); // Compute an AES key from an ECDH shared secret. ReturnCode ComputeSharedKey(Handle dest_handle, Handle private_handle, Handle public_handle, u32 pid);