Example #1
0
uint8_t* decryptFirmTitleNcch(uint8_t* title, unsigned int size){
	ctr_ncchheader NCCH;
	uint8_t CTR[16];
	PartitionInfo INFO;
	NCCH = *((ctr_ncchheader*)title);
	if(memcmp(NCCH.magic, "NCCH", 4) != 0) return NULL;
	ncch_get_counter(NCCH, CTR, 2);
	INFO.ctr = CTR; INFO.buffer = title + getle32(NCCH.exefsoffset)*0x200; INFO.keyY = NCCH.signature; INFO.size = size; INFO.keyslot = 0x2C;
	DecryptPartition(&INFO);
	uint8_t* firm = (uint8_t*)(INFO.buffer + 0x200);
	return firm;
}
Example #2
0
int VerifyNCCHSection(USER_CONTEXT *ctx, u8 cxi_key[0x10], u32 offset, FILE *ncch)
{
	NCCH_STRUCT *cxi_ctx = malloc(sizeof(NCCH_STRUCT));
	if(cxi_ctx == NULL){
		printf("[!] Memory Allocation Failure\n");
		return Fail;
	}
	memset(cxi_ctx,0x0,sizeof(NCCH_STRUCT));
	GetCXIStruct(cxi_ctx,offset,ncch);
	
	u8 HeaderSignature[0x100];
	u8 Header[0x100];
	u8 HeaderSHAHash[0x20];
	u8 ExHeader[0x800];
	memset(&HeaderSignature,0x0,0x100);
	memset(&Header,0x0,0x100);
	memset(&HeaderSHAHash,0x0,0x20);
	fseek(ncch,offset+0x0,SEEK_SET);
	fread(HeaderSignature,0x100,1,ncch);
	fread(Header,0x100,1,ncch);
	ctr_sha(&Header,0x100,HeaderSHAHash,CTR_SHA_256);
	
	RSA_2048_KEY HeaderRSA;
	memset(&HeaderRSA,0x0,sizeof(RSA_2048_KEY));
	u8 Exponent[0x3] = {0x01,0x00,0x01};
	memcpy(HeaderRSA.e,Exponent,0x3);
		
	if(cxi_ctx->is_cfa == True)
		memcpy(HeaderRSA.n,ctx->keys.NcsdCfa.n,0x100);
		
	else{
		memset(&ExHeader,0x0,0x800);
		fseek(ncch,offset+cxi_ctx->exheader_offset,SEEK_SET);
		fread(&ExHeader,0x800,1,ncch);
		if(cxi_ctx->encrypted == True){
			u8 counter[0x10];
			ncch_get_counter(cxi_ctx,counter,NCCHTYPE_EXHEADER);
			ctr_aes_context aes_ctx;
			memset(&aes_ctx,0x0,sizeof(ctr_aes_context));
			ctr_init_counter(&aes_ctx, cxi_key, counter);
			ctr_crypt_counter(&aes_ctx, ExHeader, ExHeader, 0x800);
			if(memcmp((ExHeader+0x200),cxi_ctx->programID,8) != 0){
				printf("[!] CXI decryption failed\n");
				return Fail;
			}
		}
		memcpy(HeaderRSA.n,ExHeader+0x500,0x100);
	}
		
	return ctr_rsa(HeaderSHAHash,HeaderSignature,HeaderRSA.n,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
}
Example #3
0
uint8_t* decryptFirmTitleNcch(uint8_t* title, size_t *size)
{
	const size_t sector = 512;
	const size_t header = 512;
	ctr_ncchheader NCCH;
	uint8_t CTR[16];
	PartitionInfo INFO;
	NCCH = *((ctr_ncchheader*)title);
	if(memcmp(NCCH.magic, "NCCH", 4) != 0) return NULL;
	ncch_get_counter(NCCH, CTR, 2);
	INFO.ctr = CTR; INFO.buffer = title + getle32(NCCH.exefsoffset)*sector; INFO.keyY = NCCH.signature; INFO.size = getle32(NCCH.exefssize)*sector; INFO.keyslot = 0x2C;
	DecryptPartition(&INFO);

	if (size != NULL)
		*size = INFO.size - header;

	uint8_t* firm = (uint8_t*)(INFO.buffer + header);

	if (getMpInfo() == MPINFO_KTR)
	    if (decryptFirmKtrArm9(firm))
			return NULL;

	return firm;
}
Example #4
0
int ProcessCTR(char* path){
	PartitionInfo myInfo;
	File myFile;
	char myString[256];  //In case it is needed...
	if(FileOpen(&myFile, path, 0)){
		ConsoleInit();
		ConsoleAddText(TITLE);
		unsigned int ncch_base = 0x100;
		unsigned char magic[] = { 0, 0, 0, 0, 0};
		FileRead(&myFile, magic, 4, ncch_base);
		if(magic[0] == 'N' && magic[1] == 'C' && magic[2] == 'S' && magic[3] == 'D'){
			ncch_base = 0x4000;
			FileRead(&myFile, magic, 4, ncch_base+0x100);
			if(!(magic[0] == 'N' && magic[1] == 'C' && magic[2] == 'C' && magic[3] == 'H')){
				FileClose(&myFile);
				return 2;
			}
		}else if(magic[0] == 'N' && magic[1] == 'C' && magic[2] == 'C' && magic[3] == 'H'){
			ncch_base = 0x0;
		}else{
			FileClose(&myFile);
			return 2;
		}
		ctr_ncchheader NCCH; unsigned int mediaunitsize = 0x200;
		FileRead(&myFile, &NCCH, 0x200, ncch_base);

		//ConsoleAddText(path);
		ConsoleAddText(NCCH.productcode);
		unsigned int NEWCRYPTO = 0, CRYPTO = 1;
		if(NCCH.flags[3] != 0) NEWCRYPTO = 1;
		if(NCCH.flags[7] & 4) CRYPTO = 0;
		if(NEWCRYPTO){
			ConsoleAddText("\nCryptoType : 7.X Key security");
		}else if(CRYPTO){
			ConsoleAddText("\nCryptoType : Secure");
		}else{
			ConsoleAddText("\nCryptoType : None");
			ConsoleAddText("Decryption completed!");
			FileClose(&myFile);
			ConsoleShow();
			return 3;
		}

		ConsoleShow();
		u8 CTR[16];
		if(getle32(NCCH.extendedheadersize) > 0){
			ConsoleAddText("Decrypting ExHeader..."); ConsoleShow();
			ncch_get_counter(NCCH, CTR, 1);
			FileRead(&myFile, BUFFER_ADDR, 0x800, ncch_base + 0x200);
			myInfo.buffer = BUFFER_ADDR;
			myInfo.size = 0x800;
			myInfo.keyslot = 0x2C;
			myInfo.ctr = CTR;
			myInfo.keyY = NCCH.signature;
			DecryptPartition(&myInfo);
			FileWrite(&myFile, BUFFER_ADDR, 0x800, ncch_base + 0x200);
		}
		if(getle32(NCCH.exefssize) > 0){
			ConsoleAddText("Decrypting ExeFS..."); ConsoleShow();
			ncch_get_counter(NCCH, CTR, 2);
			myInfo.buffer = BUFFER_ADDR;
			myInfo.keyslot = NEWCRYPTO ? 0x25 : 0x2C;
			myInfo.ctr = CTR;
			myInfo.keyY = NCCH.signature;

			size_t bytesRead = FileRead(&myFile, BUFFER_ADDR, getle32(NCCH.exefssize) * mediaunitsize, ncch_base + getle32(NCCH.exefsoffset) * mediaunitsize);
			myInfo.size = bytesRead;
			ProcessExeFS(&myInfo); //Explanation at function definition
			FileWrite(&myFile, BUFFER_ADDR, getle32(NCCH.exefssize) * mediaunitsize, ncch_base + getle32(NCCH.exefsoffset) * mediaunitsize);
		}
		if(getle32(NCCH.romfssize) > 0){
			ConsoleAddText("Decrypting RomFS..."); ConsoleShow();
			ncch_get_counter(NCCH, CTR, 3);
			myInfo.buffer = BUFFER_ADDR;
			myInfo.keyslot = NEWCRYPTO ? 0x25 : 0x2C;
			myInfo.ctr = CTR;
			myInfo.keyY = NCCH.signature;
			for(int i = 0; i < getle32(NCCH.romfssize) * mediaunitsize / BLOCK_SIZE; i++){
				sprintf(myString, "%i%%", (int)((i*BLOCK_SIZE)/(getle32(NCCH.romfssize) * mediaunitsize/ 100)));
				int x, y; ConsoleGetXY(&x, &y); y += CHAR_WIDTH * 4; x += CHAR_WIDTH*22;
				DrawString(TOP_SCREEN, myString, x, y, ConsoleGetTextColor(),  ConsoleGetBackgroundColor());
				size_t bytesRead = FileRead(&myFile, BUFFER_ADDR, BLOCK_SIZE, ncch_base + getle32(NCCH.romfsoffset) * mediaunitsize + i*BLOCK_SIZE);
				myInfo.size = bytesRead;
				DecryptPartition(&myInfo);
				add_ctr(myInfo.ctr, bytesRead/16);
				FileWrite(&myFile, BUFFER_ADDR, BLOCK_SIZE, ncch_base + getle32(NCCH.romfsoffset) * mediaunitsize + i*BLOCK_SIZE);
			}
		}
		NCCH.flags[7] |= 4; //Disable encryption
		NCCH.flags[3] = 0;  //Disable 7.XKey usage
		FileWrite(&myFile, &NCCH, 0x200, ncch_base);
		if(ncch_base == 0x4000) FileWrite(&myFile, ((u8*)&NCCH) + 0x100, 0x100, 0x1100);   //Only for NCSD
		FileClose(&myFile);
		ConsoleAddText("Decryption completed!"); ConsoleShow();
		return 0;
	}else return 1;
}