mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-10 21:44:28 +00:00
IOSC: Implement VerifyPublicKeySign
Partial implementation which doesn't support ECC stuff, but good enough for our purposes.
This commit is contained in:
parent
a0392db833
commit
965773bf67
@ -8,12 +8,15 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mbedtls/md.h>
|
||||||
|
#include <mbedtls/rsa.h>
|
||||||
#include <mbedtls/sha1.h>
|
#include <mbedtls/sha1.h>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "Common/Crypto/AES.h"
|
#include "Common/Crypto/AES.h"
|
||||||
#include "Common/Crypto/ec.h"
|
#include "Common/Crypto/ec.h"
|
||||||
|
#include "Common/ScopeGuard.h"
|
||||||
#include "Core/IOS/Device.h"
|
#include "Core/IOS/Device.h"
|
||||||
#include "Core/IOS/IOSC.h"
|
#include "Core/IOS/IOSC.h"
|
||||||
#include "Core/ec_wii.h"
|
#include "Core/ec_wii.h"
|
||||||
@ -164,6 +167,54 @@ ReturnCode IOSC::Decrypt(Handle key_handle, u8* iv, const u8* input, size_t size
|
|||||||
return DecryptEncrypt(Common::AES::Mode::Decrypt, key_handle, iv, input, size, output, pid);
|
return DecryptEncrypt(Common::AES::Mode::Decrypt, key_handle, iv, input, size, output, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnCode IOSC::VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle signer_handle,
|
||||||
|
const u8* signature, u32 pid) const
|
||||||
|
{
|
||||||
|
if (!HasOwnership(signer_handle, pid))
|
||||||
|
return IOSC_EACCES;
|
||||||
|
|
||||||
|
const KeyEntry* entry = FindEntry(signer_handle, SearchMode::IncludeRootKey);
|
||||||
|
if (!entry)
|
||||||
|
return IOSC_EINVAL;
|
||||||
|
|
||||||
|
// TODO: add support for keypair entries.
|
||||||
|
if (entry->type != TYPE_PUBLIC_KEY)
|
||||||
|
return IOSC_INVALID_OBJTYPE;
|
||||||
|
|
||||||
|
switch (entry->subtype)
|
||||||
|
{
|
||||||
|
case SUBTYPE_RSA2048:
|
||||||
|
case SUBTYPE_RSA4096:
|
||||||
|
{
|
||||||
|
const size_t expected_key_size = entry->subtype == SUBTYPE_RSA2048 ? 0x100 : 0x200;
|
||||||
|
_assert_(entry->data.size() == expected_key_size);
|
||||||
|
|
||||||
|
mbedtls_rsa_context rsa;
|
||||||
|
mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
|
||||||
|
Common::ScopeGuard context_guard{[&rsa] { mbedtls_rsa_free(&rsa); }};
|
||||||
|
|
||||||
|
mbedtls_mpi_read_binary(&rsa.N, entry->data.data(), entry->data.size());
|
||||||
|
mbedtls_mpi_read_binary(&rsa.E, entry->misc_data.data(), entry->misc_data.size());
|
||||||
|
rsa.len = entry->data.size();
|
||||||
|
|
||||||
|
const int ret = mbedtls_rsa_pkcs1_verify(&rsa, nullptr, nullptr, MBEDTLS_RSA_PUBLIC,
|
||||||
|
MBEDTLS_MD_SHA1, 0, sha1.data(), signature);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
WARN_LOG(IOS, "VerifyPublicKeySign: RSA verification failed (error %d)", ret);
|
||||||
|
return IOSC_FAIL_CHECKVALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_SUCCESS;
|
||||||
|
}
|
||||||
|
case SUBTYPE_ECC233:
|
||||||
|
ERROR_LOG(IOS, "VerifyPublicKeySign: SUBTYPE_ECC233 is unimplemented");
|
||||||
|
// [[fallthrough]]
|
||||||
|
default:
|
||||||
|
return IOSC_INVALID_OBJTYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReturnCode IOSC::GetOwnership(Handle handle, u32* owner) const
|
ReturnCode IOSC::GetOwnership(Handle handle, u32* owner) const
|
||||||
{
|
{
|
||||||
const KeyEntry* entry = FindEntry(handle);
|
const KeyEntry* entry = FindEntry(handle);
|
||||||
|
@ -155,6 +155,7 @@ public:
|
|||||||
{
|
{
|
||||||
SUBTYPE_AES128 = 0,
|
SUBTYPE_AES128 = 0,
|
||||||
SUBTYPE_MAC = 1,
|
SUBTYPE_MAC = 1,
|
||||||
|
SUBTYPE_RSA2048 = 2,
|
||||||
SUBTYPE_RSA4096 = 3,
|
SUBTYPE_RSA4096 = 3,
|
||||||
SUBTYPE_ECC233 = 4,
|
SUBTYPE_ECC233 = 4,
|
||||||
SUBTYPE_DATA = 5,
|
SUBTYPE_DATA = 5,
|
||||||
@ -183,6 +184,9 @@ public:
|
|||||||
ReturnCode Decrypt(Handle key_handle, u8* iv, const u8* input, size_t size, u8* output,
|
ReturnCode Decrypt(Handle key_handle, u8* iv, const u8* input, size_t size, u8* output,
|
||||||
u32 pid) const;
|
u32 pid) const;
|
||||||
|
|
||||||
|
ReturnCode VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle signer_handle,
|
||||||
|
const u8* signature, u32 pid) const;
|
||||||
|
|
||||||
// Ownership
|
// Ownership
|
||||||
ReturnCode GetOwnership(Handle handle, u32* owner) const;
|
ReturnCode GetOwnership(Handle handle, u32* owner) const;
|
||||||
ReturnCode SetOwnership(Handle handle, u32 owner, u32 pid);
|
ReturnCode SetOwnership(Handle handle, u32 owner, u32 pid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user