mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Certificate provide signature verification call
This commit is contained in:
parent
be289b4c55
commit
4b5ac1a8e0
@ -1,5 +1,6 @@
|
|||||||
#include "cert.h"
|
#include "cert.h"
|
||||||
#include "disadiff.h"
|
#include "disadiff.h"
|
||||||
|
#include "rsa.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char magic[4]; // "CERT"
|
char magic[4]; // "CERT"
|
||||||
@ -230,6 +231,73 @@ u32 Certificate_GetFullSize(const Certificate* cert, u32* size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 _Certificate_KeytypeSignatureSize(u32 keytype) {
|
||||||
|
if (keytype == 0)
|
||||||
|
return 0x200;
|
||||||
|
else if (keytype == 1)
|
||||||
|
return 0x100;
|
||||||
|
else if (keytype == 2)
|
||||||
|
return 0x3C;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 _Certificate_VerifyRSA4096(const Certificate* cert, const void* sig, const void* data, u32 data_size, bool sha256) {
|
||||||
|
(void)cert; (void)sig; (void)data; (void)data_size; (void)sha256;
|
||||||
|
return 2; // not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// noipa, to avoid form of inlining, cloning, etc, to avoid the extra stack usage when unneeded
|
||||||
|
static __attribute__((noipa)) bool _Certificate_SetKey2048Misaligned(const Certificate* cert) {
|
||||||
|
u32 mod[2048/8];
|
||||||
|
u32 exp;
|
||||||
|
|
||||||
|
memcpy(mod, cert->data->pub_key_data, 2048/8);
|
||||||
|
exp = getle32(&cert->data->pub_key_data[2048/8]);
|
||||||
|
|
||||||
|
return RSA_setKey2048(3, mod, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 _Certificate_VerifyRSA2048(const Certificate* cert, const void* sig, const void* data, u32 data_size, bool sha256) {
|
||||||
|
if (!sha256)
|
||||||
|
return 2; // not implemented
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (((u32)&cert->data->pub_key_data[0]) & 0x3)
|
||||||
|
ret = !_Certificate_SetKey2048Misaligned(cert);
|
||||||
|
else
|
||||||
|
ret = !RSA_setKey2048(3, (const u32*)(const void*)&cert->data->pub_key_data[0], getle32(&cert->data->pub_key_data[2048/8]));
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return !RSA_verify2048(sig, data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 _Certificate_VerifyECC(const Certificate* cert, const void* sig, const void* data, u32 data_size, bool sha256) {
|
||||||
|
(void)cert; (void)sig; (void)data; (void)data_size; (void)sha256;
|
||||||
|
return 2; // not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Certificate_VerifySignatureBlock(const Certificate* cert, const void* sig, u32 sig_size, const void* data, u32 data_size, bool sha256) {
|
||||||
|
if (!sig || !sig_size || (!data && data_size) || !Certificate_IsValid(cert))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
u32 keytype = getbe32(cert->data->keytype);
|
||||||
|
u32 _sig_size = _Certificate_KeytypeSignatureSize(keytype);
|
||||||
|
|
||||||
|
if (sig_size != _sig_size)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (keytype == 0)
|
||||||
|
return _Certificate_VerifyRSA4096(cert, sig, data, data_size, sha256);
|
||||||
|
if (keytype == 1)
|
||||||
|
return _Certificate_VerifyRSA2048(cert, sig, data, data_size, sha256);
|
||||||
|
if (keytype == 2)
|
||||||
|
return _Certificate_VerifyECC(cert, sig, data, data_size, sha256);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 _Certificate_AllocCopyOutImpl(const Certificate* cert, Certificate* out_cert) {
|
static u32 _Certificate_AllocCopyOutImpl(const Certificate* cert, Certificate* out_cert) {
|
||||||
u32 sig_size = _Certificate_GetSignatureChunkSizeFromType(getbe32(cert->sig->sig_type));
|
u32 sig_size = _Certificate_GetSignatureChunkSizeFromType(getbe32(cert->sig->sig_type));
|
||||||
u32 data_size = _Certificate_GetDataChunkSizeFromType(getbe32(cert->data->keytype));
|
u32 data_size = _Certificate_GetDataChunkSizeFromType(getbe32(cert->data->keytype));
|
||||||
|
@ -43,6 +43,7 @@ u32 Certificate_GetEccXY(const Certificate* cert, void* X, void* Y);
|
|||||||
u32 Certificate_GetSignatureChunkSize(const Certificate* cert, u32* size);
|
u32 Certificate_GetSignatureChunkSize(const Certificate* cert, u32* size);
|
||||||
u32 Certificate_GetDataChunkSize(const Certificate* cert, u32* size);
|
u32 Certificate_GetDataChunkSize(const Certificate* cert, u32* size);
|
||||||
u32 Certificate_GetFullSize(const Certificate* cert, u32* size);
|
u32 Certificate_GetFullSize(const Certificate* cert, u32* size);
|
||||||
|
u32 Certificate_VerifySignatureBlock(const Certificate* cert, const void* sig, u32 sig_size, const void* data, u32 data_size, bool sha256);
|
||||||
u32 Certificate_AllocCopyOut(const Certificate* cert, Certificate* out_cert);
|
u32 Certificate_AllocCopyOut(const Certificate* cert, Certificate* out_cert);
|
||||||
u32 Certificate_RawCopy(const Certificate* cert, void* raw);
|
u32 Certificate_RawCopy(const Certificate* cert, void* raw);
|
||||||
u32 Certificate_Cleanup(Certificate* cert);
|
u32 Certificate_Cleanup(Certificate* cert);
|
||||||
|
@ -29,30 +29,16 @@ u32 ValidateTwlTicket(Ticket* ticket) {
|
|||||||
|
|
||||||
u32 ValidateTicketSignature(Ticket* ticket) {
|
u32 ValidateTicketSignature(Ticket* ticket) {
|
||||||
Certificate cert;
|
Certificate cert;
|
||||||
u32 mod[2048/8];
|
|
||||||
u32 exp = 0;
|
|
||||||
|
|
||||||
// grab cert from certs.db
|
// grab cert from certs.db
|
||||||
if (LoadCertFromCertDb(&cert, (char*)(ticket->issuer)) != 0)
|
if (LoadCertFromCertDb(&cert, (char*)(ticket->issuer)) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// current code only expects RSA2048
|
int ret = Certificate_VerifySignatureBlock(&cert, &(ticket->signature), 0x100, (void*)&(ticket->issuer), GetTicketSize(ticket) - 0x140, true);
|
||||||
u32 mod_size;
|
|
||||||
if (Certificate_GetModulusSize(&cert, &mod_size) != 0 ||
|
|
||||||
mod_size != 2048/8 ||
|
|
||||||
Certificate_GetModulus(&cert, &mod) != 0 ||
|
|
||||||
Certificate_GetExponent(&cert, &exp) != 0) {
|
|
||||||
Certificate_Cleanup(&cert);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Certificate_Cleanup(&cert);
|
Certificate_Cleanup(&cert);
|
||||||
|
|
||||||
if (!RSA_setKey2048(3, mod, exp) ||
|
return ret;
|
||||||
!RSA_verify2048((void*) &(ticket->signature), (void*) &(ticket->issuer), GetTicketSize(ticket) - 0x140))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 BuildFakeTicket(Ticket* ticket, u8* title_id) {
|
u32 BuildFakeTicket(Ticket* ticket, u8* title_id) {
|
||||||
|
@ -25,30 +25,16 @@ u32 ValidateTwlTmd(TitleMetaData* tmd) {
|
|||||||
|
|
||||||
u32 ValidateTmdSignature(TitleMetaData* tmd) {
|
u32 ValidateTmdSignature(TitleMetaData* tmd) {
|
||||||
Certificate cert;
|
Certificate cert;
|
||||||
u32 mod[2048/8];
|
|
||||||
u32 exp = 0;
|
|
||||||
|
|
||||||
// grab cert from certs.db
|
// grab cert from certs.db
|
||||||
if (LoadCertFromCertDb(&cert, (char*)(tmd->issuer)) != 0)
|
if (LoadCertFromCertDb(&cert, (char*)(tmd->issuer)) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// current code only expects RSA2048
|
int ret = Certificate_VerifySignatureBlock(&cert, &(tmd->signature), 0x100, (void*)&(tmd->issuer), 0xC4, true);
|
||||||
u32 mod_size;
|
|
||||||
if (Certificate_GetModulusSize(&cert, &mod_size) != 0 ||
|
|
||||||
mod_size != 2048/8 ||
|
|
||||||
Certificate_GetModulus(&cert, &mod) != 0 ||
|
|
||||||
Certificate_GetExponent(&cert, &exp) != 0) {
|
|
||||||
Certificate_Cleanup(&cert);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Certificate_Cleanup(&cert);
|
Certificate_Cleanup(&cert);
|
||||||
|
|
||||||
if (!RSA_setKey2048(3, mod, exp) ||
|
return ret;
|
||||||
!RSA_verify2048((void*) &(tmd->signature), (void*) &(tmd->issuer), 0xC4))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 VerifyTmd(TitleMetaData* tmd) {
|
u32 VerifyTmd(TitleMetaData* tmd) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user