makerom: fixes

Moved away from ctrtool's polarssl api completely. Brought certs.c/h
inline with code style, fixed bugs relating to tmd savedata field
generation and not recording savedata size from rsf (ncsd.c)
This commit is contained in:
applestash
2014-09-16 19:15:55 +10:00
parent b4b22944a4
commit c7c2c3f73e
12 changed files with 243 additions and 323 deletions
+55 -87
View File
@@ -2,57 +2,64 @@
#include "certs.h"
// Cert Sizes
u32 GetCertSize(u8 *cert)
void GetCertSigSectionSizes(u32 *sign_size, u32 *sign_padlen, u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
u32 PubKSectionSize = GetCertPubkSectionSize((pubk_types)u8_to_u32(certcore->KeyType,BE));
return (4+SigSize+SigPadding+sizeof(Cert_Struct)+PubKSectionSize);
}
void GetCertSigSectionSizes(u32 *SigSize, u32 *SigPadding, u8 *cert)
{
sig_types sig = (sig_types)u8_to_u32(cert,BE);
u32 sig = u8_to_u32(cert,BE);
switch(sig){
case RSA_4096_SHA1 :
*SigSize = 0x200;
*SigPadding = 0x3C;
*sign_size = 0x200;
*sign_padlen = 0x3C;
break;
case RSA_2048_SHA1 :
*SigSize = 0x100;
*SigPadding = 0x3C;
*sign_size = 0x100;
*sign_padlen = 0x3C;
break;
case ECC_SHA1 :
*SigSize = 0x3C;
*SigPadding = 0x40;
*sign_size = 0x3C;
*sign_padlen = 0x40;
break;
case RSA_4096_SHA256 :
*SigSize = 0x200;
*SigPadding = 0x3C;
*sign_size = 0x200;
*sign_padlen = 0x3C;
break;
case RSA_2048_SHA256 :
*SigSize = 0x100;
*SigPadding = 0x3C;
*sign_size = 0x100;
*sign_padlen = 0x3C;
break;
case ECC_SHA256 :
*SigSize = 0x3C;
*SigPadding = 0x40;
*sign_size = 0x3C;
*sign_padlen = 0x40;
break;
default :
*SigSize = 0;
*SigPadding = 0;
*sign_size = 0;
*sign_padlen = 0;
break;
}
return;
}
u32 GetCertSize(u8 *cert)
{
u32 sign_size = 0;
u32 sign_padlen = 0;
GetCertSigSectionSizes(&sign_size,&sign_padlen,cert);
if(!sign_size || !sign_padlen)
return 0;
return sizeof(u32) + sign_size + sign_padlen + sizeof(cert_hdr) + GetCertPubkSectionSize(GetCertPubkType(cert));
}
cert_hdr* GetCertHdr(u8 *cert)
{
u32 sign_size = 0;
u32 sign_padlen = 0;
GetCertSigSectionSizes(&sign_size,&sign_padlen,cert);
if(!sign_size || !sign_padlen) return NULL;
return (cert_hdr*)(cert+4+sign_size+sign_padlen);
}
u32 GetCertPubkSectionSize(pubk_types type)
{
switch(type){
@@ -66,80 +73,41 @@ u32 GetCertPubkSectionSize(pubk_types type)
// Issuer/Name Functions
u8 *GetCertIssuer(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
return certcore->Issuer;
cert_hdr *hdr = GetCertHdr(cert);
return hdr->issuer;
}
u8 *GetCertName(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
return certcore->Name;
cert_hdr *hdr = GetCertHdr(cert);
return hdr->name;
}
int GenCertChildIssuer(u8 *dest, u8 *cert)
void GenCertChildIssuer(u8 *dest, u8 *cert)
{
u8 *issuer = GetCertIssuer(cert);
u8 *name = GetCertName(cert);
/*
u32 out_size = strlen((char*)issuer) + strlen((char*)name) + 1;
if(out_size > 0x40) return MEM_ERROR;
*/
snprintf((char*)dest,0x40,"%s-%s",issuer,name);
/*
strcat((char*)dest,(char*)issuer);
strcat((char*)dest,"-");
strcat((char*)dest,(char*)name);
*/
return 0;
snprintf((char*)dest,0x40,"%s-%s",GetCertIssuer(cert),GetCertName(cert));
}
// Pubk
pubk_types GetCertPubkType(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
cert_hdr *hdr = GetCertHdr(cert);
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
return (pubk_types)u8_to_u32(certcore->KeyType,BE);
return (pubk_types)u8_to_u32(hdr->keyType,BE);
}
u8 *GetCertPubk(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
return (cert+4+SigSize+SigPadding+sizeof(Cert_Struct));
if(!GetCertHdr(cert))
return NULL;
return ((u8*)GetCertHdr(cert)) + sizeof(cert_hdr);
}
bool VerifyCert(u8 *cert, u8 *pubk)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
if(!GetCertHdr(cert))
return false;
u8 *signature = (cert+sizeof(u32));
u8 *data = (u8*)GetCertHdr(cert);
u32 datasize = sizeof(cert_hdr) + GetCertPubkSectionSize(GetCertPubkType(cert));
u8 *signature = (cert+4);
u8 *data = (cert+4+SigSize+SigPadding);
u32 datasize = sizeof(Cert_Struct) + GetCertPubkSectionSize(GetCertPubkType(cert));
int result = ctr_sig(data,datasize,signature,pubk,NULL,u8_to_u32(cert,BE),CTR_RSA_VERIFY);
if(result == 0) return true;
else return false;
return RsaSignVerify(data,datasize,signature,pubk,NULL,u8_to_u32(cert,BE),CTR_RSA_VERIFY);
}
+14 -15
View File
@@ -2,41 +2,40 @@
typedef struct
{
u8 Issuer[0x40];
u8 KeyType[4];
u8 Name[0x40];
u8 Unknown[4];
} Cert_Struct;
u8 issuer[0x40];
u8 keyType[4];
u8 name[0x40];
u8 id[4];
} cert_hdr;
typedef struct
{
u8 Modulus[0x200];
u8 PubExponent[4];
u8 Padding[0x34];
u8 modulus[0x200];
u8 pubExponent[4];
u8 padding[0x34];
} rsa_4096_pubk_struct;
typedef struct
{
u8 Modulus[0x100];
u8 PubExponent[4];
u8 Padding[0x34];
u8 modulus[0x100];
u8 pubExponent[4];
u8 padding[0x34];
} rsa_2048_pubk_struct;
typedef struct
{
u8 PubK[0x3C];
u8 Padding[0x3C];
u8 pubK[0x3C];
u8 padding[0x3C];
} ecc_pubk_struct;
// Cert Sizes
u32 GetCertSize(u8 *cert);
void GetCertSigSectionSizes(u32 *SigSize, u32 *SigPadding, u8 *cert);
u32 GetCertPubkSectionSize(pubk_types type);
// Issuer/Name Functions
u8 *GetCertIssuer(u8 *cert);
u8 *GetCertName(u8 *cert);
int GenCertChildIssuer(u8 *dest, u8 *cert);
void GenCertChildIssuer(u8 *dest, u8 *cert);
// Pubk
pubk_types GetCertPubkType(u8 *cert);
+10 -16
View File
@@ -17,7 +17,6 @@ const int CIA_ALIGN_SIZE = 0x40;
const int CIA_CONTENT_ALIGN = 0x10;
// Private Prototypes
void InitCiaSettings(cia_settings *set);
void FreeCiaSettings(cia_settings *set);
int GetCiaSettings(cia_settings *ciaset, user_settings *usrset);
@@ -53,7 +52,6 @@ int build_CIA(user_settings *usrset)
}
// Get Settings
InitCiaSettings(ciaset);
result = GetCiaSettings(ciaset,usrset);
if(result) goto finish;
@@ -96,11 +94,6 @@ finish:
return result;
}
void InitCiaSettings(cia_settings *set)
{
memset(set,0,sizeof(cia_settings));
}
void FreeCiaSettings(cia_settings *set)
{
if(set->content.filePtrs){
@@ -198,8 +191,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
ciaset->tik.formatVersion = 1;
int result = GenCertChildIssuer(ciaset->tik.issuer,ciaset->keys->certs.xsCert);
if(result) return result;
GenCertChildIssuer(ciaset->tik.issuer,ciaset->keys->certs.xsCert);
// Tmd Stuff
if(usrset->cia.contentId[0] > MAX_U32)
@@ -209,7 +201,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
ciaset->tmd.formatVersion = 1;
ciaset->tmd.accessRights = 0;
result = GenCertChildIssuer(ciaset->tmd.issuer,ciaset->keys->certs.cpCert);
GenCertChildIssuer(ciaset->tmd.issuer,ciaset->keys->certs.cpCert);
return 0;
}
@@ -293,14 +285,16 @@ int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *
if(IsPatch(GetTidCategory(ciaset->common.titleId))||ciaset->content.IsCfa)
ciaset->tmd.savedataSize = 0;
else if(ciaset->content.keyNotFound && ciaset->rsf->SystemControlInfo.SaveDataSize){ // if it's a title which can have save data, but save data size could not be read from exhdr
else if(!ciaset->content.keyNotFound)
ciaset->tmd.savedataSize = (u32)(GetSaveDataSize_frm_exhdr(exhdr) & MAX_U32);
else if(ciaset->rsf->SystemControlInfo.SaveDataSize){ // if it's a title which can have save data, but save data size could not be read from exhdr
u64 size = 0;
GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA");
ciaset->tmd.savedataSize = (u32)(size & MAX_U32);
}
else
ciaset->tmd.savedataSize = (u32)(GetSaveDataSize_frm_exhdr(exhdr) & MAX_U32);
else
ciaset->tmd.savedataSize = 0;
if(ciaset->content.IsCfa||ciaset->content.keyNotFound){
if(ciaset->common.titleVersion[VER_MAJOR] == MAX_U16){ // '-major' wasn't set
if(ciaset->content.IsCfa){ // Is a CFA and can be decrypted
@@ -569,7 +563,7 @@ u16 SetupVersion(u16 major, u16 minor, u16 micro)
void GetContentHashes(cia_settings *ciaset)
{
for(int i = 0; i < ciaset->content.count; i++)
ctr_sha(ciaset->ciaSections.content.buffer+ciaset->content.offset[i],ciaset->content.size[i],ciaset->content.hash[i],CTR_SHA_256);
ShaCalc(ciaset->ciaSections.content.buffer+ciaset->content.offset[i],ciaset->content.size[i],ciaset->content.hash[i],CTR_SHA_256);
}
void EncryptContent(cia_settings *ciaset)
@@ -653,7 +647,7 @@ int CryptContent(u8 *input, u8 *output, u64 size, u8 *title_key, u16 index, u8 m
iv[0] = (index >> 8) & 0xff;
iv[1] = index & 0xff;
//Crypting content
AesCbc(title_key,iv,input,output,size,mode);
AesCbcCrypt(title_key,iv,input,output,size,mode);
return 0;
}
+114 -134
View File
@@ -1,14 +1,24 @@
#include "lib.h"
#include "crypto.h"
const u8 RSA_PUB_EXP[0x3] = {0x01,0x00,0x01};
const int HASH_MAX_LEN = 0x20;
int ctr_rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
bool VerifySha256(void *data, u64 size, u8 hash[32])
{
u8 calchash[32];
ctr_sha(data, size, calchash, CTR_SHA_256);
ShaCalc(data, size, calchash, CTR_SHA_256);
return memcmp(hash,calchash,32) == 0;
}
void ctr_sha(void *data, u64 size, u8 *hash, int mode)
void ShaCalc(void *data, u64 size, u8 *hash, int mode)
{
switch(mode){
case(CTR_SHA_1): sha1((u8*)data, size, hash); break;
@@ -21,7 +31,7 @@ void SetAesCtrOffset(u8 *ctr, u64 offset)
u64_to_u8(ctr+8,u8_to_u64(ctr+8,BE)|align(offset,16)/16,BE);
}
void AesCtr(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset)
void AesCtrCrypt(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset)
{
u8 stream[16];
aes_context aes;
@@ -37,7 +47,7 @@ void AesCtr(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset)
return;
}
void AesCbc(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode)
void AesCbcCrypt(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode)
{
aes_context aes;
clrmem(&aes,sizeof(aes_context));
@@ -56,168 +66,138 @@ void AesCbc(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode)
}
}
void ctr_rsa_free(ctr_rsa_context* ctx)
{
rsa_free(&ctx->rsa);
}
int ctr_rsa_init(ctr_rsa_context* ctx, u8 *modulus, u8 *private_exp, u8 *exponent, u8 rsa_type, u8 mode)
bool RsaKeyInit(rsa_context* ctx, u8 *modulus, u8 *private_exp, u8 *exponent, u8 rsa_type)
{
// Sanity Check
if(ctx == NULL || modulus == NULL ||(private_exp == NULL && mode == RSAKEY_PRIV) || (exponent == NULL && mode == RSAKEY_PUB))
return Fail;
rsa_init(&ctx->rsa, RSA_PKCS_V15, 0);
if(!ctx)
return false;
rsa_init(ctx, RSA_PKCS_V15, 0);
u16 n_size = 0;
u16 d_size = 0;
u16 e_size = 0;
switch(rsa_type){
case RSA_2048:
ctx->rsa.len = 0x100;
ctx->len = 0x100;
n_size = 0x100;
d_size = 0x100;
e_size = 3;
break;
case RSA_4096:
ctx->rsa.len = 0x200;
ctx->len = 0x200;
n_size = 0x200;
d_size = 0x200;
e_size = 3;
break;
default: return Fail;
}
switch(mode){
case(RSAKEY_PUB):
if (mpi_read_binary(&ctx->rsa.N, modulus, n_size))
goto clean;
if (mpi_read_binary(&ctx->rsa.E, exponent, e_size))
goto clean;
break;
case(RSAKEY_PRIV):
if (mpi_read_binary(&ctx->rsa.N, modulus, n_size))
goto clean;
if (mpi_read_binary(&ctx->rsa.D, private_exp, d_size))
goto clean;
break;
default: return Fail;
default: return false;
}
if (modulus && mpi_read_binary(&ctx->N, modulus, n_size))
goto clean;
if (exponent && mpi_read_binary(&ctx->E, exponent, e_size))
goto clean;
if (private_exp && mpi_read_binary(&ctx->D, private_exp, d_size))
goto clean;
return Good;
return true;
clean:
ctr_rsa_free(ctx);
return Fail;
rsa_free(ctx);
return false;
}
int ctr_sig(void *data, u64 size, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode)
u8 GetRsaType(u32 sig_type)
{
int result = 0;
int hashtype, hashlen, sigtype;
if(data == NULL || signature == NULL || modulus == NULL ||(private_exp == NULL && mode == CTR_RSA_SIGN))
return Fail;
switch(type){
switch(sig_type){
case RSA_4096_SHA1:
hashtype = CTR_SHA_1;
hashlen = 0x14;
sigtype = RSA_4096;
case RSA_4096_SHA256:
hashtype = CTR_SHA_256;
hashlen = 0x20;
sigtype = RSA_4096;
break;
return RSA_4096;
case RSA_2048_SHA1:
hashtype = CTR_SHA_1;
hashlen = 0x14;
sigtype = RSA_2048;
case RSA_2048_SHA256:
hashtype = CTR_SHA_256;
hashlen = 0x20;
sigtype = RSA_2048;
break;
case ECC_SHA1:
hashtype = CTR_SHA_1;
hashlen = 0x14;
sigtype = ECC;
case ECC_SHA256:
hashtype = CTR_SHA_256;
hashlen = 0x20;
sigtype = ECC;
break;
default: return Fail;
return RSA_2048;
}
u8 hash[hashlen];
memset(hash,0,hashlen);
ctr_sha(data,size,hash,hashtype);
//memdump(stdout,"Data: ",data,size);
//memdump(stdout,"HashFor Sig: ",hash,hashlen);
if(sigtype == RSA_2048 || sigtype == RSA_4096)
result = ctr_rsa(hash,signature,modulus,private_exp,type,mode);
else if(sigtype == ECC){
printf("[!] ECC is not yet implemented\n");
result = Fail;
}
return result;
return INVALID_SIG_TYPE;
}
int ctr_rsa(u8 *hash, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode)
u32 GetSigHashType(u32 sig_type)
{
int result = 0;
// Sanity Check
if(hash == NULL || signature == NULL || modulus == NULL ||(private_exp == NULL && mode == CTR_RSA_SIGN))
return Fail;
// Getting details from sig type
int hashtype;
int hashlen;
int sigtype;
switch(type){
case RSA_4096_SHA1:
hashtype = SIG_RSA_SHA1;
hashlen = 0x14;
sigtype = RSA_4096;
break;
case RSA_4096_SHA256:
hashtype = SIG_RSA_SHA256;
hashlen = 0x14;
sigtype = RSA_4096;
break;
case RSA_2048_SHA1:
hashtype = SIG_RSA_SHA1;
hashlen = 0x20;
sigtype = RSA_2048;
break;
case RSA_2048_SHA256:
hashtype = SIG_RSA_SHA256;
hashlen = 0x20;
sigtype = RSA_2048;
break;
default: return Fail;
switch(sig_type){
case RSA_4096_SHA1:
case RSA_2048_SHA1:
case ECC_SHA1:
return CTR_SHA_1;
case RSA_4096_SHA256:
case RSA_2048_SHA256:
case ECC_SHA256:
return CTR_SHA_256;
}
// Setting up
ctr_rsa_context ctx;
u8 exponent[3] = {0x01,0x00,0x01};
switch(mode){
case CTR_RSA_VERIFY:
result = ctr_rsa_init(&ctx,modulus,NULL,(u8*)exponent,sigtype,RSAKEY_PUB);
break;
case CTR_RSA_SIGN:
result = ctr_rsa_init(&ctx,modulus,private_exp,NULL,sigtype,RSAKEY_PRIV);
break;
}
if(result)return result;
switch(mode){
case CTR_RSA_VERIFY:
return rsa_pkcs1_verify(&ctx.rsa,RSA_PUBLIC,hashtype,hashlen,hash,signature);
case CTR_RSA_SIGN:
return ctr_rsa_rsassa_pkcs1_v15_sign(&ctx.rsa,RSA_PRIVATE,hashtype,hashlen,hash,signature);
}
return Fail;
}
return 0;
}
int GetRsaHashType(u32 sig_type)
{
switch(sig_type){
case RSA_4096_SHA1:
case RSA_2048_SHA1:
return SIG_RSA_SHA1;
case RSA_4096_SHA256:
case RSA_2048_SHA256:
return SIG_RSA_SHA256;
}
return 0;
}
u32 GetSigHashLen(u32 sig_type)
{
switch(sig_type){
case RSA_4096_SHA1:
return 0x14;
case RSA_4096_SHA256:
return 0x20;
case RSA_2048_SHA1:
return 0x14;
case RSA_2048_SHA256:
return 0x20;
case ECC_SHA1:
return 0x14;
case ECC_SHA256:
return 0x20;
}
return 0;
}
bool CalcHashForSign(void *data, u64 len, u8 *hash, u32 sig_type)
{
if(GetSigHashType(sig_type) == 0)
return false;
ShaCalc(data, len, hash, GetSigHashType(sig_type));
return true;
}
int RsaSignVerify(void *data, u64 len, u8 *sign, u8 *mod, u8 *priv_exp, u32 sig_type, u8 rsa_mode)
{
int rsa_result = 0;
rsa_context ctx;
u8 hash[HASH_MAX_LEN];
if(!RsaKeyInit(&ctx, mod, priv_exp, (u8*)RSA_PUB_EXP, GetRsaType(sig_type)))
return -1;
if(!CalcHashForSign(data, len, hash, sig_type))
return -1;
if(rsa_mode == CTR_RSA_VERIFY)
rsa_result = rsa_pkcs1_verify(&ctx, RSA_PUBLIC, GetRsaHashType(sig_type), 0, hash, sign);
else // CTR_RSA_SIGN
rsa_result = ctr_rsa_rsassa_pkcs1_v15_sign(&ctx, RSA_PRIVATE, GetRsaHashType(sig_type), 0, hash, sign);
rsa_free(&ctx);
return rsa_result;
}
/**
* Hacked from rsa.c, polarssl doesn't like generating signatures when only D and N are present
+19 -38
View File
@@ -14,25 +14,26 @@ typedef enum
RSA_4096_SHA256 = 0x00010003,
RSA_2048_SHA256 = 0x00010004,
ECC_SHA256 = 0x00010005
} sig_types;
typedef enum
{
RSA_2048 = 0,
RSA_4096 = 1,
ECC = 2,
} ctr_sig_types;
typedef enum
{
CTR_RSA_VERIFY = 0,
CTR_RSA_SIGN = 1,
} ctr_rsa_functions;
CTR_RSA_VERIFY,
CTR_RSA_SIGN,
} ctr_rsa_mode;
typedef enum
{
CTR_SHA_1 = 1,
CTR_SHA_256 = 256,
RSA_4096,
RSA_2048,
ECC,
INVALID_SIG_TYPE,
} sig_types;
typedef enum
{
CTR_SHA_1,
CTR_SHA_256,
} ctr_sha_modes;
typedef enum
@@ -46,42 +47,22 @@ typedef enum
{
ENC,
DEC
} aescbcmode;
} aes_mode;
typedef enum
{
RSAKEY_INVALID,
RSAKEY_PRIV,
RSAKEY_PUB
} rsakeytype;
typedef struct
{
rsa_context rsa;
} ctr_rsa_context;
#ifdef __cplusplus
extern "C" {
#endif
// SHA
bool VerifySha256(void *data, u64 size, u8 hash[32]);
void ctr_sha(void *data, u64 size, u8 *hash, int mode);
void ShaCalc(void *data, u64 size, u8 *hash, int mode);
// AES
void AesCtr(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset);
void AesCbc(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode);
void AesCtrCrypt(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset);
void AesCbcCrypt(u8 *key, u8 *iv, u8 *input, u8 *output, u64 length, u8 mode);
// RSA
void ctr_rsa_free(ctr_rsa_context* ctx);
int ctr_rsa_init(ctr_rsa_context* ctx, u8 *modulus, u8 *private_exp, u8 *exponent, u8 rsa_type, u8 mode);
int ctr_rsa(u8 *hash, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode);
int ctr_rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
int RsaSignVerify(void *data, u64 len, u8 *sign, u8 *mod, u8 *priv_exp, u32 sig_type, u8 rsa_mode);
// Signature Functions
int ctr_sig(void *data, u64 size, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode);
#ifdef __cplusplus
}
+1 -1
View File
@@ -75,7 +75,7 @@ int GenerateExeFS_Header(exefs_buildctx *ctx, u8 *outbuff)
memcpy(exefs->fileHdr[i].name,ctx->fileName[i],8);
u32_to_u8(exefs->fileHdr[i].offset,ctx->fileOffset[i],LE);
u32_to_u8(exefs->fileHdr[i].size,ctx->fileSize[i],LE);
ctr_sha(ctx->file[i],ctx->fileSize[i],exefs->fileHashes[MAX_EXEFS_SECTIONS-1-i],CTR_SHA_256);
ShaCalc(ctx->file[i],ctx->fileSize[i],exefs->fileHashes[MAX_EXEFS_SECTIONS-1-i],CTR_SHA_256);
}
return 0;
}
+6 -6
View File
@@ -53,16 +53,16 @@ int get_ExHeaderARM9AccessControlInfo(exhdr_ARM9AccessControlInfo *arm9, rsf_set
/* ExHeader Signature Functions */
int SignAccessDesc(access_descriptor *acexDesc, keys_struct *keys)
{
u8 *AccessDesc = (u8*) &acexDesc->ncchRsaPubKey;
u8 *Signature = (u8*) &acexDesc->signature;
return ctr_sig(AccessDesc,0x300,Signature,keys->rsa.acexPub,keys->rsa.acexPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
u8 *data = (u8*) &acexDesc->ncchRsaPubKey;
u8 *sign = (u8*) &acexDesc->signature;
return RsaSignVerify(data,0x300,sign,keys->rsa.acexPub,keys->rsa.acexPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int CheckAccessDescSignature(access_descriptor *acexDesc, keys_struct *keys)
{
u8 *AccessDesc = (u8*) &acexDesc->ncchRsaPubKey;
u8 *Signature = (u8*) &acexDesc->signature;
return ctr_sig(AccessDesc,0x300,Signature,keys->rsa.acexPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
u8 *data = (u8*) &acexDesc->ncchRsaPubKey;
u8 *sign = (u8*) &acexDesc->signature;
return RsaSignVerify(data,0x300,sign,keys->rsa.acexPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
}
/* ExHeader Build Functions */
+9 -9
View File
@@ -34,22 +34,22 @@ bool IsValidProductCode(char *ProductCode, bool FreeProductCode);
// Code
int SignCFA(ncch_hdr *hdr, keys_struct *keys)
{
return ctr_sig(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfaPub,keys->rsa.cciCfaPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfaPub,keys->rsa.cciCfaPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int CheckCFASignature(ncch_hdr *hdr, keys_struct *keys)
{
return ctr_sig(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfaPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfaPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
}
int SignCXI(ncch_hdr *hdr, keys_struct *keys)
{
return ctr_sig(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cxiHdrPub,keys->rsa.cxiHdrPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cxiHdrPub,keys->rsa.cxiHdrPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int CheckCXISignature(ncch_hdr *hdr, u8 *pubk)
{
int result = ctr_sig(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),pubk,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
int result = RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),pubk,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
return result;
}
@@ -500,13 +500,13 @@ int FinaliseNcch(ncch_settings *set)
// Taking Hashes
if(set->cryptoDetails.exhdrSize)
ctr_sha(exhdr,set->cryptoDetails.exhdrSize,hdr->exhdrHash,CTR_SHA_256);
ShaCalc(exhdr,set->cryptoDetails.exhdrSize,hdr->exhdrHash,CTR_SHA_256);
if(set->cryptoDetails.logoSize)
ctr_sha(logo,set->cryptoDetails.logoSize,hdr->logoHash,CTR_SHA_256);
ShaCalc(logo,set->cryptoDetails.logoSize,hdr->logoHash,CTR_SHA_256);
if(set->cryptoDetails.exefsHashDataSize)
ctr_sha(exefs,set->cryptoDetails.exefsHashDataSize,hdr->exefsHash,CTR_SHA_256);
ShaCalc(exefs,set->cryptoDetails.exefsHashDataSize,hdr->exefsHash,CTR_SHA_256);
if(set->cryptoDetails.romfsHashDataSize)
ctr_sha(romfs,set->cryptoDetails.romfsHashDataSize,hdr->romfsHash,CTR_SHA_256);
ShaCalc(romfs,set->cryptoDetails.romfsHashDataSize,hdr->romfsHash,CTR_SHA_256);
// Signing NCCH
int sig_result = Good;
@@ -1048,6 +1048,6 @@ void CryptNcchRegion(u8 *buffer, u64 size, u64 src_pos, u64 titleId, u8 key[16],
{
u8 ctr[0x10];
GetNcchAesCounter(ctr,titleId,type);
AesCtr(key,ctr,buffer,buffer,size,src_pos);
AesCtrCrypt(key,ctr,buffer,buffer,size,src_pos);
return;
}
+5 -6
View File
@@ -10,7 +10,6 @@
#include "cardinfo.h"
#include "titleid.h"
const int NCCH0_OFFSET = 0x4000;
const int CCI_BLOCK_SIZE = 0x200;
@@ -288,15 +287,15 @@ int ProcessCiaForCci(cci_settings *set)
int ImportCciNcch(cci_settings *set)
{
if(set->rsf->SystemControlInfo.SaveDataSize)
GetSaveDataSizeFromString(&set->romInfo.saveSize,set->rsf->SystemControlInfo.SaveDataSize,"CCI");
if(set->content.dataType == infile_ncch)
return ImportNcchForCci(set);
else if(set->content.dataType == infile_cia)
return ProcessCiaForCci(set);
else
fprintf(stderr,"[CCI ERROR] Unrecognised input data type\n");
if(set->rsf->SystemControlInfo.SaveDataSize)
GetSaveDataSizeFromString(&set->romInfo.saveSize,set->rsf->SystemControlInfo.SaveDataSize,"CCI");
fprintf(stderr,"[CCI ERROR] Unrecognised input data type\n");
return FAILED_TO_IMPORT_FILE;
}
@@ -594,7 +593,7 @@ int GenCciHdr(cci_settings *set)
SetCciNcchInfo(hdr,set);
// Sign Header
ctr_sig(&hdr->magic,sizeof(cci_hdr)-RSA_2048_KEY_SIZE,hdr->signature,set->keys->rsa.cciCfaPub,set->keys->rsa.cciCfaPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
RsaSignVerify(&hdr->magic,sizeof(cci_hdr)-RSA_2048_KEY_SIZE,hdr->signature,set->keys->rsa.cciCfaPub,set->keys->rsa.cciCfaPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
return 0;
}
+1 -1
View File
@@ -467,7 +467,7 @@ void GenIvfcHashTree(romfs_buildctx *ctx)
for(u32 j = 0; j < numHashes; j++){
u8 *datapos = (u8*)(ctx->level[i+1].pos + ROMFS_BLOCK_SIZE * j);
u8 *hashpos = (u8*)(ctx->level[i].pos + 0x20 * j);
ctr_sha(datapos, ROMFS_BLOCK_SIZE, hashpos, CTR_SHA_256);
ShaCalc(datapos, ROMFS_BLOCK_SIZE, hashpos, CTR_SHA_256);
}
}
+5 -7
View File
@@ -15,9 +15,8 @@ int CryptTitleKey(u8 *input, u8 *output, u8 *titleId, keys_struct *keys, u8 mode
int BuildTicket(cia_settings *set)
{
int result = 0;
result = SetupTicketBuffer(set);
if(result) return result;
if(SetupTicketBuffer(set))
return MEM_ERROR;
// Setting Ticket Struct Ptrs
buffer_struct *tik = &set->ciaSections.tik;
@@ -31,8 +30,7 @@ int BuildTicket(cia_settings *set)
SetContentIndexHeader(idxHdr,set);
SetContentIndexData(idxData,set);
result = SignTicketHeader(tik,set->keys);
return 0;
return SignTicketHeader(tik,set->keys);
}
int SetupTicketBuffer(cia_settings *set)
@@ -83,7 +81,7 @@ int SignTicketHeader(buffer_struct *tik, keys_struct *keys)
clrmem(sig,sizeof(tik_signature));
u32_to_u8(sig->sigType,RSA_2048_SHA256,BE);
return ctr_sig(data,len,sig->data,keys->rsa.xsPub,keys->rsa.xsPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
return RsaSignVerify(data,len,sig->data,keys->rsa.xsPub,keys->rsa.xsPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int CryptTitleKey(u8 *input, u8 *output, u8 *titleId, keys_struct *keys, u8 mode)
@@ -94,7 +92,7 @@ int CryptTitleKey(u8 *input, u8 *output, u8 *titleId, keys_struct *keys, u8 mode
memcpy(iv,titleId,0x8);
//Crypting TitleKey
AesCbc(keys->aes.commonKey[keys->aes.currentCommonKey],iv,input,output,0x10,mode);
AesCbcCrypt(keys->aes.commonKey[keys->aes.currentCommonKey],iv,input,output,0x10,mode);
// Return
return 0;
+4 -3
View File
@@ -62,7 +62,7 @@ int SetupTMDHeader(tmd_hdr *hdr, tmd_content_info_record *info_record, cia_setti
u32_to_u8(hdr->accessRights,ciaset->tmd.accessRights,BE);
u16_to_u8(hdr->titleVersion,ciaset->tmd.version,BE);
u16_to_u8(hdr->contentCount,ciaset->content.count,BE);
ctr_sha(info_record,sizeof(tmd_content_info_record)*64,hdr->infoRecordHash,CTR_SHA_256);
ShaCalc(info_record,sizeof(tmd_content_info_record)*64,hdr->infoRecordHash,CTR_SHA_256);
return 0;
}
@@ -70,7 +70,8 @@ int SignTMDHeader(tmd_hdr *hdr, tmd_signature *sig, keys_struct *keys)
{
clrmem(sig,sizeof(tmd_signature));
u32_to_u8(sig->sigType,RSA_2048_SHA256,BE);
return ctr_sig((u8*)hdr,sizeof(tmd_hdr),sig->data,keys->rsa.cpPub,keys->rsa.cpPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
return RsaSignVerify((u8*)hdr,sizeof(tmd_hdr),sig->data,keys->rsa.cpPub,keys->rsa.cpPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int SetupTMDInfoRecord(tmd_content_info_record *info_record, u8 *content_record, u16 ContentCount)
@@ -78,7 +79,7 @@ int SetupTMDInfoRecord(tmd_content_info_record *info_record, u8 *content_record,
clrmem(info_record,sizeof(tmd_content_info_record)*0x40);
u16_to_u8(info_record->contentIndexOffset,0x0,BE);
u16_to_u8(info_record->contentCommandCount,ContentCount,BE);
ctr_sha(content_record,sizeof(tmd_content_chunk)*ContentCount,info_record->contentChunkHash,CTR_SHA_256);
ShaCalc(content_record,sizeof(tmd_content_chunk)*ContentCount,info_record->contentChunkHash,CTR_SHA_256);
return 0;
}