Beispiel #1
0
int SetCardInfoNotes(cardinfo_hdr *hdr, cci_settings *set)
{
	u64_to_u8(hdr->notes.mediaSizeUsed,set->romInfo.usedSize,LE);
	u32_to_u8(hdr->notes.unknown,0,LE);
	
	if(set->options.tmdHdr){
		u64_to_u8(hdr->notes.cverTitleId,GetTmdTitleId(set->options.tmdHdr),LE);
		u16_to_u8(hdr->notes.cverTitleId,GetTmdVersion(set->options.tmdHdr),LE);
	}
		
	return 0;
}
Beispiel #2
0
int GenCciHdr(cci_settings *set)
{
	set->headers.ccihdr.size = sizeof(cci_hdr);
	set->headers.ccihdr.buffer = calloc(1,set->headers.ccihdr.size);
	if(!set->headers.ccihdr.buffer){
		set->headers.ccihdr.size = 0;
		fprintf(stderr,"[CCI ERROR] Not enough memory\n");
		return MEM_ERROR;
	}
	
	cci_hdr *hdr = (cci_hdr*)set->headers.ccihdr.buffer;
	
	// Magic & TitleId
	memcpy(hdr->magic,"NCSD",4);
	u64_to_u8(hdr->titleId,set->content.titleId[0],LE);
	
	
	if(SetMediaSize(hdr->mediaSize,set))
		return GEN_HDR_FAIL;
	if(SetCciFlags(hdr->flags,set))
		return GEN_HDR_FAIL;
	SetCciNcchInfo(hdr,set);
	
	// Sign Header
	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;
}
Beispiel #3
0
void GetNewNcchIdForCci(u8 *newTid, u8 *srcTid, u8 index, tmd_hdr *tmdHdr)
{
	u64 titleId = u8_to_u64(srcTid,LE) & 0xffffffffffff;
	if(tmdHdr && index == 7)
		titleId |= (u64)(GetTmdVersion(tmdHdr)) << 48;
	else
		titleId |= (u64)(index+4) << 48;
		
	u64_to_u8(newTid,titleId,LE);
}
Beispiel #4
0
int SetupTMDContentRecord(u8 *content_record, cia_settings *ciaset)
{
	for(int i = 0; i < ciaset->content.count; i++){
		tmd_content_chunk *ptr = (tmd_content_chunk*)(content_record+sizeof(tmd_content_chunk)*i);
		u32_to_u8(ptr->contentID,ciaset->content.id[i],BE);
		u16_to_u8(ptr->contentIndex,ciaset->content.index[i],BE);
		u16_to_u8(ptr->contentFlags,ciaset->content.flags[i],BE);
		u64_to_u8(ptr->contentSize,ciaset->content.size[i],BE);
		memcpy(ptr->contentHash,ciaset->content.hash[i],0x20);
	}
	return 0;
}
Beispiel #5
0
void SetCciNcchInfo(cci_hdr *hdr, cci_settings *set)
{
	u64 ncchSize,ncchOffset;
	
	ncchOffset = NCCH0_OFFSET;
	
	for(int i = 0; i < CCI_MAX_CONTENT; i++){
		if(set->content.active[i]){
			set->content.cOffset[i] = ncchOffset;
			ncchSize = align(set->content.dSize[i],set->romInfo.blockSize);
			
			u32_to_u8(hdr->offset_sizeTable[i].offset,(ncchOffset/set->romInfo.blockSize),LE);
			u32_to_u8(hdr->offset_sizeTable[i].size,(ncchSize/set->romInfo.blockSize),LE);
			u64_to_u8(hdr->ncchIdTable[i],set->content.titleId[i],LE);
			
			ncchOffset += ncchSize;
		}
	}
	
	set->romInfo.usedSize = ncchOffset;
	
	return;
}
Beispiel #6
0
void SetAesCtrOffset(u8 *ctr, u64 offset)
{
	u64_to_u8(ctr+8,u8_to_u64(ctr+8,BE)|align(offset,16)/16,BE);
}
Beispiel #7
0
int SetCommonHeaderBasicData(ncch_settings *set, ncch_hdr *hdr)
{
	/* NCCH Magic */
	memcpy(hdr->magic,"NCCH",4);

	/* NCCH Format Version */
	if(!set->options.IsCfa)
		u16_to_u8(hdr->formatVersion,0x2,LE);

	
	/* Setting ProgramId/TitleId */
	u64 programId = 0;
	int result = GetProgramID(&programId,set->rsfSet,false); 
	if(result) return result;

	u64_to_u8(hdr->programId,programId,LE);
	u64_to_u8(hdr->titleId,programId,LE);

	/* Get Product Code and Maker Code */
	if(set->rsfSet->BasicInfo.ProductCode){
		if(!IsValidProductCode((char*)set->rsfSet->BasicInfo.ProductCode,set->options.FreeProductCode)){
			fprintf(stderr,"[NCCH ERROR] Invalid Product Code\n");
			return NCCH_BAD_RSF_SET;
		}
		memcpy(hdr->productCode,set->rsfSet->BasicInfo.ProductCode,strlen((char*)set->rsfSet->BasicInfo.ProductCode));
	}
	else memcpy(hdr->productCode,"CTR-P-CTAP",10);

	if(set->rsfSet->BasicInfo.CompanyCode){
		if(strlen((char*)set->rsfSet->BasicInfo.CompanyCode) != 2){
			fprintf(stderr,"[NCCH ERROR] CompanyCode length must be 2\n");
			return NCCH_BAD_RSF_SET;
		}
		memcpy(hdr->makerCode,set->rsfSet->BasicInfo.CompanyCode,2);
	}
	else memcpy(hdr->makerCode,"00",2);

	// Setting Encryption Settings
	if(!set->options.Encrypt)
		hdr->flags[ncchflag_OTHER_FLAG] = (otherflag_NoCrypto|otherflag_FixedCryptoKey);
	else if(set->options.useSecCrypto){
		hdr->flags[ncchflag_OTHER_FLAG] = otherflag_Clear;
		hdr->flags[ncchflag_CONTENT_KEYX] = set->options.keyXID;
	}
	else
		hdr->flags[ncchflag_OTHER_FLAG] = otherflag_FixedCryptoKey;	
		
	if(!SetNcchKeys(set->keys,hdr) && set->options.Encrypt){
		hdr->flags[ncchflag_OTHER_FLAG] = (otherflag_NoCrypto|otherflag_FixedCryptoKey);
		hdr->flags[ncchflag_CONTENT_KEYX] = 0;
		set->options.Encrypt = false;
		fprintf(stderr,"[NCCH WARNING] NCCH AES Key could not be loaded, NCCH will not be encrypted\n");
	}

	/* Set ContentUnitSize */
	hdr->flags[ncchflag_CONTENT_BLOCK_SIZE] = GetCtrBlockSizeFlag(set->options.blockSize);

	/* Setting ContentPlatform */
	hdr->flags[ncchflag_CONTENT_PLATFORM] = 1; // CTR

	/* Setting OtherFlag */
	if(!set->options.UseRomFS) 
		hdr->flags[ncchflag_OTHER_FLAG] |= otherflag_NoMountRomFs;


	/* Setting ContentType */
	hdr->flags[ncchflag_CONTENT_TYPE] = 0;
	if(set->options.UseRomFS) hdr->flags[ncchflag_CONTENT_TYPE] |= content_Data;
	if(!set->options.IsCfa) hdr->flags[ncchflag_CONTENT_TYPE] |= content_Executable;
	if(set->rsfSet->BasicInfo.ContentType){
		if(strcmp(set->rsfSet->BasicInfo.ContentType,"Application") == 0) hdr->flags[ncchflag_CONTENT_TYPE] |= 0;
		else if(strcmp(set->rsfSet->BasicInfo.ContentType,"SystemUpdate") == 0) hdr->flags[ncchflag_CONTENT_TYPE] |= content_SystemUpdate;
		else if(strcmp(set->rsfSet->BasicInfo.ContentType,"Manual") == 0) hdr->flags[ncchflag_CONTENT_TYPE] |= content_Manual;
		else if(strcmp(set->rsfSet->BasicInfo.ContentType,"Child") == 0) hdr->flags[ncchflag_CONTENT_TYPE] |= content_Child;
		else if(strcmp(set->rsfSet->BasicInfo.ContentType,"Trial") == 0) hdr->flags[ncchflag_CONTENT_TYPE] |= content_Trial;
		else{
			fprintf(stderr,"[NCCH ERROR] Invalid ContentType '%s'\n",set->rsfSet->BasicInfo.ContentType);
			return NCCH_BAD_RSF_SET;
		}
	}

	return 0;
}
Beispiel #8
0
void GetNcchAesCounter(u8 ctr[16], u64 titleId, u8 type)
{
	clrmem(ctr,16);	
	u64_to_u8(ctr,titleId,BE);
	ctr[8] = type;
}