Ejemplo n.º 1
0
int elf_ProcessHeader(elf_context *elf)
{
	const elf_hdr *hdr = (const elf_hdr*)elf->file;

	/* Check conditions for valid CTR ELF */
	if (u8_to_u32(hdr->magic, BE) != ELF_MAGIC)
		return NOT_ELF_FILE;
	if (hdr->bitFormat != elf_32_bit)
		return NOT_CTR_ARM_ELF;
	if (hdr->endianness != elf_little_endian)
		return NOT_CTR_ARM_ELF;
	if (u8_to_u16(hdr->targetArchitecture, LE) != elf_arm)
		return NOT_CTR_ARM_ELF;
	if (u8_to_u16(hdr->type, LE) != elf_executeable)
		return NON_EXECUTABLE_ELF;

	elf->phdrOffset = u8_to_u32(hdr->programHeaderTableOffset, LE);
	elf->segmentNum = u8_to_u16(hdr->programHeaderEntryCount, LE);
	elf->segments = calloc(elf->segmentNum, sizeof(elf_segment));
	if (!elf->segments) {
		fprintf(stderr, "[ELF ERROR] Not enough memory\n");
		return MEM_ERROR;
	}

	elf->shdrOffset = u8_to_u32(hdr->sectionHeaderTableOffset, LE);
	elf->shdrNameIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex, LE);
	elf->sectionNum = u8_to_u16(hdr->sectionHeaderEntryCount, LE);
	elf->sections = calloc(elf->sectionNum, sizeof(elf_section));
	if (!elf->sections) {
		fprintf(stderr, "[ELF ERROR] Not enough memory\n");
		return MEM_ERROR;
	}

	return 0;
}
Ejemplo n.º 2
0
static int
check (const uint8_t *input, size_t input_length,
       const uint32_t *expected, size_t expected_length)
{
  size_t length;
  uint32_t *result;

  /* Test return conventions with resultbuf == NULL.  */
  result = u8_to_u32 (input, input_length, NULL, &length);
  if (!(result != NULL))
    return 1;
  if (!(length == expected_length))
    return 2;
  if (!(u32_cmp (result, expected, expected_length) == 0))
    return 3;
  free (result);

  /* Test return conventions with resultbuf too small.  */
  if (expected_length > 0)
    {
      uint32_t *preallocated;

      length = expected_length - 1;
      preallocated = (uint32_t *) malloc (length * sizeof (uint32_t));
      result = u8_to_u32 (input, input_length, preallocated, &length);
      if (!(result != NULL))
        return 4;
      if (!(result != preallocated))
        return 5;
      if (!(length == expected_length))
        return 6;
      if (!(u32_cmp (result, expected, expected_length) == 0))
        return 7;
      free (result);
      free (preallocated);
    }

  /* Test return conventions with resultbuf large enough.  */
  {
    uint32_t *preallocated;

    length = expected_length;
    preallocated = (uint32_t *) malloc (length * sizeof (uint32_t));
    result = u8_to_u32 (input, input_length, preallocated, &length);
    if (!(result != NULL))
      return 8;
    if (!(preallocated == NULL || result == preallocated))
      return 9;
    if (!(length == expected_length))
      return 10;
    if (!(u32_cmp (result, expected, expected_length) == 0))
      return 11;
    free (preallocated);
  }

  return 0;
}
Ejemplo n.º 3
0
void GetCertSigSectionSizes(u32 *SigSize, u32 *SigPadding, u8 *cert)
{
	sig_types sig = (sig_types)u8_to_u32(cert,BE);
	switch(sig){
		case RSA_4096_SHA1 :
			*SigSize = 0x200;
			*SigPadding = 0x3C;
			break;
		case RSA_2048_SHA1 :
			*SigSize = 0x100;
			*SigPadding = 0x3C;
			break;
		case ECC_SHA1 :
			*SigSize = 0x3C;
			*SigPadding = 0x40;
			break;
		case RSA_4096_SHA256 :
			*SigSize = 0x200;
			*SigPadding = 0x3C;
			break;
		case RSA_2048_SHA256 :
			*SigSize = 0x100;
			*SigPadding = 0x3C;
			break;
		case ECC_SHA256 :
			*SigSize = 0x3C;
			*SigPadding = 0x40;
			break;
		default :
			*SigSize = 0;
			*SigPadding = 0;
			break;
	}
	return;
}
Ejemplo n.º 4
0
// Cert Sizes
void GetCertSigSectionSizes(u32 *sign_size, u32 *sign_padlen, u8 *cert)
{
	u32 sig = u8_to_u32(cert,BE);
	switch(sig){
		case RSA_4096_SHA1 :
			*sign_size = 0x200;
			*sign_padlen = 0x3C;
			break;
		case RSA_2048_SHA1 :
			*sign_size = 0x100;
			*sign_padlen = 0x3C;
			break;
		case ECC_SHA1 :
			*sign_size = 0x3C;
			*sign_padlen = 0x40;
			break;
		case RSA_4096_SHA256 :
			*sign_size = 0x200;
			*sign_padlen = 0x3C;
			break;
		case RSA_2048_SHA256 :
			*sign_size = 0x100;
			*sign_padlen = 0x3C;
			break;
		case ECC_SHA256 :
			*sign_size = 0x3C;
			*sign_padlen = 0x40;
			break;
		default :
			*sign_size = 0;
			*sign_padlen = 0;
			break;
	}
	return;
}
Ejemplo n.º 5
0
void GetCUPVersion(/*char *FW_STRING, */CARD_INFO_HEADER *card_info)
{
	u8 MAJOR = 0;
	u8 MINOR = 0;
	u8 BUILD = 0;
	char REGION_CHAR = ' ';

	u16 CVer_ver = u8_to_u16(card_info->cver_title_version,LE);
	u32 CVer_UID = u8_to_u32(card_info->cver_title_id,LE);
		
	switch(CVer_UID){
		case EUR_UPDATE : REGION_CHAR = 'E'; break;
		case JPN_UPDATE : REGION_CHAR = 'J'; break;
		case USA_UPDATE : REGION_CHAR = 'U'; break;
		case CHN_UPDATE : REGION_CHAR = 'C'; break;
		case KOR_UPDATE : REGION_CHAR = 'K'; break;
		case TWN_UPDATE : REGION_CHAR = 'T'; break;
	}
	
	
	switch(CVer_ver){
		case 3088 : MAJOR = 3; MINOR = 0; BUILD = 0; break;
		default ://This tends to work most of the time, use above for manual overrides
			MAJOR = (CVer_ver & 0x7f00) >> 10;
			MINOR = (CVer_ver & 0x3f0) >> 4;
			//BUILD = CVer_ver & 0xf; 
			break;	
	}
	printf(" CUP Version:           %d.%d.%d%c\n",MAJOR,MINOR,BUILD,REGION_CHAR);
}
Ejemplo n.º 6
0
void GetMin3DSFW(char *FW_STRING, CARD_INFO_HEADER *card_info)
{
	u8 MAJOR = 0;
	u8 MINOR = 0;
	u8 BUILD = 0;
	char REGION_CHAR = 'X';

	u16 CVer_ver = u8_to_u16(card_info->cver_title_version,LE);
	u32 CVer_UID = u8_to_u32(card_info->cver_title_id,LE);
		
	switch(CVer_UID){
		case EUR_ROM : REGION_CHAR = 'E'; break;
		case JPN_ROM : REGION_CHAR = 'J'; break;
		case USA_ROM : REGION_CHAR = 'U'; break;
		case CHN_ROM : REGION_CHAR = 'C'; break;
		case KOR_ROM : REGION_CHAR = 'K'; break;
		case TWN_ROM : REGION_CHAR = 'T'; break;
	}
	
	
	switch(CVer_ver){
		case 3088 : MAJOR = 3; MINOR = 0; BUILD = 0; break;
		default : MAJOR = CVer_ver/1024; MINOR = (CVer_ver - 1024*(CVer_ver/1024))/0x10; break;//This tends to work 98% of the time, use above for manual overides
	}
	sprintf(FW_STRING,"%d.%d.%d-X%c",MAJOR,MINOR,BUILD,REGION_CHAR);
}
Ejemplo n.º 7
0
void PrintNCSDHeaderData(NCSD_STRUCT *ctx, NCSD_HEADER *header, CARD_INFO_HEADER *card_info, DEV_CARD_INFO_HEADER *dev_card_info)
{
	printf("[+] CCI Image Details\n");
	u8 CardDevice = header->partition_flags[MEDIA_CARD_DEVICE_OLD] + header->partition_flags[MEDIA_CARD_DEVICE];
	switch (header->partition_flags[MEDIA_TYPE_INDEX]){
		case INNER_DEVICE: printf(" Media Type:            INTERNAL_DEVICE\n"); break;
		case CARD1: printf(" Media Type:            CARD1\n"); break;
		case CARD2: printf(" Media Type:            CARD2\n  > Writable Region:\n   - Offset:            0x%llx\n   - Size:              0x%llx (%lld MB)\n",ctx->WRITABLE_ADDRESS,ctx->CARD2_MAX_SAVEDATA_SIZE,(ctx->CARD2_MAX_SAVEDATA_SIZE/MB)); break;
		case EXTENDED_DEVICE: printf(" Media Type:            EXTENDED_DEVICE\n"); break;
	}
	GetCHIPFullSize(ctx->MEDIA_SIZE,ctx->type);
	GetCCIDataSize(ctx->CCI_IMAGE_SIZE,ctx->type);
	GetCCIFileStatus(ctx->CCI_FILE_SIZE,ctx->CCI_FILE_STATUS,ctx->type);
	switch (CardDevice){
		case CARD_DEVICE_NOR_FLASH: printf(" Additional Device:     EEPROM\n"); break;
		case CARD_DEVICE_NONE: printf(" Additional Device:     None\n"); break;
		case CARD_DEVICE_BT: printf(" Additional Device:     BT\n"); break;
	}
	printf(" Partition Count:       %d\n",ctx->partition_count);
	if(u8_to_u64(card_info->cver_title_id,LE) && u8_to_u16(card_info->cver_title_version,LE)){
		//printf("CVer Title ID:          %016llx\n",u8_to_u64(card_info->cver_title_id,LE));
		//printf("CVer Title Ver:         v%d\n",u8_to_u16(card_info->cver_title_version,LE));
		GetCUPVersion(card_info);
	}
	if(!header->partition_flags[MEDIA_6X_SAVE_CRYPTO] && !header->partition_flags[MEDIA_CARD_DEVICE] && !header->partition_flags[MEDIA_CARD_DEVICE_OLD]){
		printf(" Save Crypto:           Repeating CTR Fail\n");
	}
	else if(!header->partition_flags[MEDIA_6X_SAVE_CRYPTO] && (header->partition_flags[MEDIA_CARD_DEVICE] || header->partition_flags[MEDIA_CARD_DEVICE_OLD])){
		printf(" Save Crypto:           2.2.0 KeyY Method\n");
	}
	else if(header->partition_flags[MEDIA_6X_SAVE_CRYPTO] == 1 && !header->partition_flags[MEDIA_CARD_DEVICE_OLD]){
		if(!header->partition_flags[MEDIA_CARD_DEVICE]){
			printf(" Save Crypto:           2.2.0 KeyY Method\n");
		}
		else if(header->partition_flags[MEDIA_CARD_DEVICE]){
			printf(" Save Crypto:           6.0.0 KeyY Method\n");
		}
	}
	
	printf("[+] CXI Partition\n");
	printf(" Product Code:          %.16s\n",card_info->partition_0_header.product_code);
	printf(" Company Code:          %.2s\n",card_info->partition_0_header.maker_code);
	u32 UniqueID = u8_to_u32(&card_info->partition_0_header.program_id[1],LE)&0xffffff;
	printf(" Unique ID:             %05x\n",UniqueID);
	printf(" Build Type:            %s\n",ctx->BUILD_TYPE? "Debug or Development" : "Release");
	printf(" SDK Version:           %d.%d.%d %s\n",ctx->SDK_VER[0],ctx->SDK_VER[1],ctx->SDK_VER[2],ctx->SDK_PATCH);
	if(ctx->FW_VER[0] || ctx->FW_VER[1]) printf(" Req. Kernel Version:   %d.%d-%d\n",ctx->FW_VER[0],ctx->FW_VER[1],ctx->FW_VER[2]);
	printf("[+] CFA Partitions\n");
	for(int i = 1; i < 8; i++){
		if(i == 1) printf(" E-Manual:              %s\n",ctx->partition_data[i].active? "Yes" : "No"); 
		else if(i == 2) printf(" DLP Child:             %s\n",ctx->partition_data[i].active? "Yes" : "No"); 
		else if(i == 7) printf(" Update Data:           %s\n",ctx->partition_data[i].active? "Yes" : "No"); 
		else{
			if(ctx->partition_data[i].active) printf(" CFA %d:                %s\n",i,ctx->partition_data[i].active? "Yes" : "No"); 
		}
	}
	
	
	
}
Ejemplo n.º 8
0
u32 GetExeFsSectionOffset(char *section, u8 *ExeFs)
{
	exefs_hdr *hdr = (exefs_hdr*) ExeFs;
	for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
		if(strncmp(hdr->fileHdr[i].name,section,8) == 0){ 
			return u8_to_u32(hdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
		}
	}
	return 0;
}
Ejemplo n.º 9
0
bool VerifyCert(u8 *cert, u8 *pubk)
{
	if(!GetCertHdr(cert)) 
		return false;
	u8 *signature = (cert+sizeof(u32));
	u8 *data = (u8*)GetCertHdr(cert);
	u32 datasize = sizeof(cert_hdr) + GetCertPubkSectionSize(GetCertPubkType(cert));

	return RsaSignVerify(data,datasize,signature,pubk,NULL,u8_to_u32(cert,BE),CTR_RSA_VERIFY);
}
Ejemplo n.º 10
0
u8* GetExeFsSection(char *section, u8 *ExeFs)
{
	exefs_hdr *hdr = (exefs_hdr*) ExeFs;
	for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
		if(strncmp(hdr->fileHdr[i].name,section,8) == 0){ 
			u32 offset = u8_to_u32(hdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
			return (u8*)(ExeFs+offset);
		}
	}
	return NULL;
}
Ejemplo n.º 11
0
// Pubk
pubk_types GetCertPubkType(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 (pubk_types)u8_to_u32(certcore->KeyType,BE);
}
Ejemplo n.º 12
0
u32 GetCertSize(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);
}
Ejemplo n.º 13
0
void elf_PopulateSegments(elf_context *elf)
{
	const elf_phdr *phdr = (const elf_phdr *)(elf->file + elf->phdrOffset);

	for (int i = 0; i < elf->segmentNum; i++) {
		elf->segments[i].type = u8_to_u32(phdr[i].type, LE);
		elf->segments[i].flags = u8_to_u32(phdr[i].flags, LE);
		elf->segments[i].fileOffset = u8_to_u32(phdr[i].offset, LE);
		elf->segments[i].fileSize = u8_to_u32(phdr[i].filesz, LE);
		elf->segments[i].ptr = elf->file + elf->segments[i].fileOffset;
		elf->segments[i].pAddr = u8_to_u32(phdr[i].paddr, LE);
		elf->segments[i].vAddr = u8_to_u32(phdr[i].vaddr, LE);
		elf->segments[i].memSize = u8_to_u32(phdr[i].memsz, LE);
		elf->segments[i].alignment = u8_to_u32(phdr[i].align, LE);
	}
}
Ejemplo n.º 14
0
void elf_PopulateSections(elf_context *elf)
{
	const elf_shdr *shdr = (const elf_shdr *)(elf->file + elf->shdrOffset);
	const char *nameTable = (const char*)(elf->file + u8_to_u32(shdr[elf->shdrNameIndex].offset, LE));

	for (int i = 0; i < elf->sectionNum; i++) {
		elf->sections[i].name = nameTable + u8_to_u32(shdr[i].name, LE);
		elf->sections[i].type = u8_to_u32(shdr[i].type, LE);
		elf->sections[i].flags = u8_to_u32(shdr[i].flags, LE);
		elf->sections[i].fileOffset = u8_to_u32(shdr[i].offset, LE);
		elf->sections[i].size = u8_to_u32(shdr[i].size, LE);
		elf->sections[i].ptr = elf->file + elf->sections[i].fileOffset;
		elf->sections[i].vAddr = u8_to_u32(shdr[i].addr, LE);
		elf->sections[i].alignment = u8_to_u32(shdr[i].addralign, LE);
	}
}
Ejemplo n.º 15
0
bool VerifyCert(u8 *cert, u8 *pubk)
{
	u32 SigSize = 0;
	u32 SigPadding = 0;
	GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
	if(!SigSize || !SigPadding) return 0;


	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;
}
Ejemplo n.º 16
0
int PrepareImportRomFsBinaryFromFile(ncch_settings *ncchset, romfs_buildctx *ctx)
{
	ctx->ImportRomfsBinary = true;
	ctx->romfsSize = ncchset->componentFilePtrs.romfsSize;
	ctx->romfsBinary = ncchset->componentFilePtrs.romfs;

	ivfc_hdr *hdr = calloc(1,sizeof(ivfc_hdr));

	ReadFile64(hdr,sizeof(ivfc_hdr),0,ctx->romfsBinary);
	if(memcmp(hdr->magic,"IVFC",4) != 0){
		fprintf(stderr,"[ROMFS ERROR] Invalid RomFS Binary.\n");
		return INVALID_ROMFS_FILE;
	}

	ctx->romfsHeaderSize = align(sizeof(ivfc_hdr),0x10) + (u64)u8_to_u32(hdr->masterHashSize,LE);

	return 0;
}
Ejemplo n.º 17
0
static inline u32 dispatch_t207(t207 a208, u8 a209)
{
    return u8_to_u32(a209);
}
Ejemplo n.º 18
0
/**
 * gnutls_utf8_password_normalize:
 * @password: contain the UTF-8 formatted password
 * @plen: the length of the provided password
 * @out: the result in an null-terminated allocated string
 * @flags: should be zero
 *
 * This function will convert the provided UTF-8 password according
 * to the normalization rules in RFC7613.
 *
 * If the flag %GNUTLS_UTF8_IGNORE_ERRS is specified, any UTF-8 encoding
 * errors will be ignored, and in that case the output will be a copy of the input.
 *
 * Returns: %GNUTLS_E_INVALID_UTF8_STRING on invalid UTF-8 data, or 0 on success.
 *
 * Since: 3.5.7
 **/
int gnutls_utf8_password_normalize(const unsigned char *password, unsigned plen,
				   gnutls_datum_t *out, unsigned flags)
{
	size_t ucs4_size = 0, nrm_size = 0;
	size_t final_size = 0;
	uint8_t *final = NULL;
	uint32_t *ucs4 = NULL;
	uint32_t *nrm = NULL;
	uint8_t *nrmu8 = NULL;
	int ret;

	if (plen == 0) {
		out->data = (uint8_t*)gnutls_strdup("");
		out->size = 0;
		if (out->data == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
		return 0;
	}

	/* check for invalid UTF-8 */
	if (u8_check((uint8_t*)password, plen) != NULL) {
		gnutls_assert();
		if (flags & GNUTLS_UTF8_IGNORE_ERRS) {
 raw_copy:
			out->data = gnutls_malloc(plen+1);
			if (out->data == NULL)
				return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
			out->size = plen;
			memcpy(out->data, password, plen);
			out->data[plen] = 0;
			return 0;
		} else {
			return GNUTLS_E_INVALID_UTF8_STRING;
		}
	}

	/* convert to UTF-32 */
	ucs4 = u8_to_u32((uint8_t*)password, plen, NULL, &ucs4_size);
	if (ucs4 == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto fail;
	}

	ret = check_for_valid_freeformclass(ucs4, ucs4_size);
	if (ret < 0) {
		gnutls_assert();
		if (flags & GNUTLS_UTF8_IGNORE_ERRS) {
			free(ucs4);
			goto raw_copy;
		}
		if (ret == GNUTLS_E_INVALID_UTF8_STRING)
			ret = GNUTLS_E_INVALID_PASSWORD_STRING;
		goto fail;
	}

	/* normalize to NFC */
	nrm = u32_normalize(UNINORM_NFC, ucs4, ucs4_size, NULL, &nrm_size);
	if (nrm == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_INVALID_PASSWORD_STRING;
		goto fail;
	}

	/* convert back to UTF-8 */
	final_size = 0;
	nrmu8 = u32_to_u8(nrm, nrm_size, NULL, &final_size);
	if (nrmu8 == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_INVALID_PASSWORD_STRING;
		goto fail;
	}

	/* copy to output with null terminator */
	final = gnutls_malloc(final_size+1);
Ejemplo n.º 19
0
void PrintNCSDData(NCSD_STRUCT *ctx, NCSD_HEADER *header, CARD_INFO_HEADER *card_info, DEV_CARD_INFO_HEADER *dev_card_info)
{
	if(ctx->valid != True){
		printf("[!] NCSD Corrupt\n");
		return;
	}
	printf("[+] NCSD\n");
	switch(ctx->sig_valid){
		case Good : memdump(stdout,"Signature(Good):        ",ctx->signature,0x100); break;
		case Fail : memdump(stdout,"Signature(Fail):        ",ctx->signature,0x100); break;
		case NotChecked: memdump(stdout,"Signature:              ",ctx->signature,0x100); break;
	}
	switch(ctx->type){
		case retail : 
			printf("Target:                 Retail/Production\n"); 
			printf("CVer Title ID:          %016llx\n",u8_to_u64(card_info->cver_title_id,LE));
			printf("CVer Title Ver:         v%d\n",u8_to_u16(card_info->cver_title_version,LE));
			char *FW_STRING = malloc(10);
			memset(FW_STRING,0,10);
			GetMin3DSFW(FW_STRING,card_info);
			printf("Min 3DS Firm:           %s\n",FW_STRING);
			_free(FW_STRING);
			break;
		case dev_internal_SDK :
			printf("Target:                 Debug/Development\n");
			printf("SDK Type:               Nintendo Internal SDK\n");
			memdump(stdout,"Title Key:              ",dev_card_info->TitleKey,0x10);
			break;
		case dev_external_SDK :
			printf("Target:                 Debug/Development\n");
			printf("SDK Type:               Nintendo 3RD Party SDK\n");
			memdump(stdout,"Title Key:              ",dev_card_info->TitleKey,0x10);
			break;
	}
	if(ctx->rom_size >= GB){
		printf("ROM Cart Size:          %lld GB",ctx->rom_size/GB); printf(" (%lld Gbit)\n",(ctx->rom_size/GB)*8);
	}
	else{
		printf("ROM Cart Size:          %lld MB",ctx->rom_size/MB); 
		u32 tmp = (ctx->rom_size/MB)*8;
		if(tmp >= 1024)
			printf(" (%d Gbit)\n",tmp/1024);
		else
			printf(" (%d Mbit)\n",tmp);
	}
	if(ctx->used_rom_size >= MB){
		printf("ROM Used Size:          %lld MB",ctx->used_rom_size/MB); printf(" (0x%llx bytes)\n",ctx->used_rom_size);
	}
	else if(ctx->used_rom_size >= KB){
		printf("ROM Used Size:          %lld KB",ctx->used_rom_size/KB); printf(" (0x%llx bytes)\n",ctx->used_rom_size);
	}
	printf("NCSD Title ID:          %016llx\n",u8_to_u64(header->title_id,LE));
	memdump(stdout,"ExHeader Hash:          ",header->exheader_hash,0x20);
	printf("AddHeader Size:         0x%x\n",u8_to_u32(header->additional_header_size,LE));
	printf("Sector 0 Offset:        0x%x\n",u8_to_u32(header->sector_zero_offset,LE));
	memdump(stdout,"Flags:                  ",header->partition_flags,8);
	printf("\n");
	for(int i = 0; i < 8; i++){
		if(ctx->partition_data[i].active == True){
			printf("Partition %d\n",i);
			printf(" Title ID:              %016llx\n",ctx->partition_data[i].title_id);
			printf(" Content Type:          ");
			switch(ctx->partition_data[i].content_type){
				case _unknown : printf("Unknown\n"); break;
				case CXI : printf("Application\n"); break;
				case CFA_Manual : printf("Electronic Manual\n"); break;
				case CFA_DLPChild : printf("Download Play Child\n"); break;
				case CFA_Update : printf("Software Update Partition\n"); break;
			}
			
			printf(" FS Type:               %x\n",ctx->partition_data[i].fs_type);
			printf(" Crypto Type:           %x\n",ctx->partition_data[i].crypto_type);
			printf(" Offset:                0x%x\n",ctx->partition_data[i].offset);
			printf(" Size:                  0x%x\n",ctx->partition_data[i].size);
			printf("\n");
		}
	}
}
Ejemplo n.º 20
0
void LazyText::setText(std::string new_text)
{
	setText(u8_to_u32(new_text));
}
Ejemplo n.º 21
0
int GetNCSDData(CCI_CONTEXT *ctx)
{
	// Opening CCI
	FILE *cci = fopen(ctx->cci_file.argument,"rb");
	if(ctx->ncsd_struct == NULL)
		return Fail;
	memset(ctx->ncsd_struct,0x0,sizeof(NCSD_STRUCT));
	
	// Getting File Size of CCI File
	ctx->ncsd_struct->CCI_FILE_SIZE = GetFileSize_u64(ctx->cci_file.argument);

	NCSD_HEADER header;
	CARD_INFO_HEADER card_info;
	DEV_CARD_INFO_HEADER dev_card_info;
	
	// Reading CCI Header Sections
	fseek(cci,0x0,SEEK_SET);
	fread(&ctx->ncsd_struct->signature,0x100,1,cci);
	fseek(cci,0x100,SEEK_SET);
	fread(&header,sizeof(NCSD_HEADER),1,cci);
	fseek(cci,0x200,SEEK_SET);
	fread(&card_info,sizeof(CARD_INFO_HEADER),1,cci);
	fseek(cci,0x1200,SEEK_SET);
	fread(&dev_card_info,sizeof(DEV_CARD_INFO_HEADER),1,cci);
	
	// Checking CCI Magic
	if(u8_to_u32(header.magic,BE) != NCSD_MAGIC){
		printf("[!] NCSD File is corrupt\n");
		goto fail;
	}
	
	// Checking Media Type to see if suitable for CCI
	if(header.partition_flags[MEDIA_TYPE_INDEX] != CARD1 && header.partition_flags[MEDIA_TYPE_INDEX] != CARD2){
		printf("[!] NCSD File is not CCI\n");
		goto fail;
	}	
	
	// Determining Media Unit Size
	ctx->ncsd_struct->MEDIA_UNIT_SIZE = 0x200*pow(2,header.partition_flags[MEDIA_UNIT_SIZE]);
	
	// Media Size
	ctx->ncsd_struct->MEDIA_SIZE = u8_to_u32(header.media_size,LE)*(ctx->ncsd_struct->MEDIA_UNIT_SIZE);
	
	// Get Writable Address
	ctx->ncsd_struct->WRITABLE_ADDRESS = u8_to_u32(card_info.writable_address,LE)*(ctx->ncsd_struct->MEDIA_UNIT_SIZE);
	ctx->ncsd_struct->CARD2_MAX_SAVEDATA_SIZE = ctx->ncsd_struct->MEDIA_SIZE - ctx->ncsd_struct->WRITABLE_ADDRESS;
	// Getting CCI Image Size by summing total size of NCSD Partitions
	u32 tmp = u8_to_u32(header.offsetsize_table[0].offset,LE);
	for(int i = 0; i < 8; i++){
		tmp += u8_to_u32(header.offsetsize_table[i].size,LE);
		if (i == 6) ctx->ncsd_struct->CCI_S_TRIM_SIZE = tmp*ctx->ncsd_struct->MEDIA_UNIT_SIZE; // The Update Partition is always in Partition 7, so this size doesn't include Partition 7
	}
	ctx->ncsd_struct->CCI_IMAGE_SIZE = tmp*ctx->ncsd_struct->MEDIA_UNIT_SIZE;
	
	// Comparing CCI File Size, with calculated size
	ctx->ncsd_struct->CCI_FILE_STATUS = 0;
	if(ctx->ncsd_struct->CCI_FILE_SIZE == ctx->ncsd_struct->MEDIA_SIZE) ctx->ncsd_struct->CCI_FILE_STATUS = IS_FULL;
	else if(ctx->ncsd_struct->CCI_FILE_SIZE == ctx->ncsd_struct->CCI_IMAGE_SIZE) ctx->ncsd_struct->CCI_FILE_STATUS = IS_TRIM;
	else if(ctx->ncsd_struct->CCI_FILE_SIZE == ctx->ncsd_struct->CCI_S_TRIM_SIZE) ctx->ncsd_struct->CCI_FILE_STATUS = IS_S_TRIM;
	else {
		/*
		printf("CCI_FILE_SIZE = 0x%llx\n",ctx->ncsd_struct->CCI_FILE_SIZE);
		printf("MEDIA_SIZE = 0x%llx\n",ctx->ncsd_struct->MEDIA_SIZE);
		printf("CCI_IMAGE_SIZE = 0x%llx\n",ctx->ncsd_struct->CCI_IMAGE_SIZE);
		printf("CCI_S_TRIM_SIZE = 0x%llx\n",ctx->ncsd_struct->CCI_S_TRIM_SIZE);
		*/
		ctx->ncsd_struct->CCI_FILE_STATUS = IS_MALFORMED;
		goto fail;
	}
	
	// Storing Partition Offsets
	ctx->ncsd_struct->partition_count = 0;
	for(int i = 0; i < 8; i++){
		ctx->ncsd_struct->partition_data[i].offset = u8_to_u32(header.offsetsize_table[i].offset,LE)*ctx->ncsd_struct->MEDIA_UNIT_SIZE;
		ctx->ncsd_struct->partition_data[i].size = u8_to_u32(header.offsetsize_table[i].size,LE)*ctx->ncsd_struct->MEDIA_UNIT_SIZE;
		if(ctx->ncsd_struct->partition_data[i].offset != 0 && ctx->ncsd_struct->partition_data[i].size != 0)
			ctx->ncsd_struct->partition_data[i].active = True;
		ctx->ncsd_struct->partition_data[i].title_id = u8_to_u64(header.partition_id_table[i],LE);
		ctx->ncsd_struct->partition_data[i].fs_type = header.partitions_fs_type[i];
		ctx->ncsd_struct->partition_data[i].crypto_type = header.partitions_crypto_type[i];
		
		// Checking to see if partition actually exists
		if(ctx->ncsd_struct->partition_data[i].offset >= ctx->ncsd_struct->CCI_FILE_SIZE){
			ctx->ncsd_struct->partition_data[i].active = False;
			break;
		}
		if(ctx->ncsd_struct->partition_data[i].active) ctx->ncsd_struct->partition_count++;
	}
	
	// Exit if no CXI found
	if(!ctx->ncsd_struct->partition_data[0].active){
		printf("[!] CXI Not Found\n");
		goto fail;
	}
	
	// Getting Data from CXI
	NCCH_HEADER cxi_header;
	fseek_64(cci,(ctx->ncsd_struct->partition_data[0].offset + 0x100),SEEK_SET);
	fread(&cxi_header,sizeof(NCCH_HEADER),1,cci);
	if(u8_to_u32(cxi_header.magic,BE) != NCCH_MAGIC){
		printf("[!] CXI is Corrupt\n");
		goto fail;
	}
	// Must have ExeFS region to be CXI
	if((cxi_header.flags[MEDIA_TYPE_INDEX] & ExeFS) != ExeFS){
		printf("[!] CXI Not Found\n");
		goto fail;
	}
	ctx->ncsd_struct->partition_data[0].content_type = CXI;
	
	// Getting Product Code
	fseek_64(cci,(ctx->ncsd_struct->partition_data[0].offset + 0x150),SEEK_SET);
	fread(ctx->ncsd_struct->partition_data[0].product_code,16,1,cci);
	
	// Checking 'other flag' for crypto settings
	if((cxi_header.flags[OtherFlag] & 1) == 1){
		if((cxi_header.flags[OtherFlag] & 4) == 4) ctx->ncsd_struct->partition_data[0].ncch_crypto_key = no_crypto;	
		else if ((cxi_header.program_id[4] && 0x10) == 0x10) ctx->ncsd_struct->partition_data[0].ncch_crypto_key = fixed_system;
		else ctx->ncsd_struct->partition_data[0].ncch_crypto_key = fixed_zeros;
	}
	else if(!cxi_header.flags[OtherFlag]){
		ctx->ncsd_struct->partition_data[0].ncch_crypto_key = secure_key;
		if(cxi_header.flags[SecureCryptoType2Flag]) ctx->ncsd_struct->partition_data[0].ncch_crypto_key = secure_key2;
	}
	
	// Getting SDK Version
	u32 CXI_Media_Unit_Size = 0x200*pow(2,cxi_header.flags[MEDIA_UNIT_SIZE]);
	u64 plain_region_offset = ctx->ncsd_struct->partition_data[0].offset + u8_to_u32(cxi_header.plain_region_offset,LE)*CXI_Media_Unit_Size;
	u64 plain_region_size = u8_to_u32(cxi_header.plain_region_size,LE)*CXI_Media_Unit_Size;
	int result = GetSDKVersion(cci,plain_region_offset,plain_region_size,ctx->ncsd_struct);
	// If that failed, attempt to guess SDK version
	if(result){
		strcpy(ctx->ncsd_struct->SDK_PATCH,"Release");
		memset(&ctx->ncsd_struct->SDK_VER,0,3);
		ctx->ncsd_struct->SDK_VER[0] = 1;
		if(header.partition_flags[MEDIA_CARD_DEVICE_OLD]) ctx->ncsd_struct->SDK_VER[0] = 2;
		if(header.partition_flags[MEDIA_CARD_DEVICE]) ctx->ncsd_struct->SDK_VER[0] = 3;
		if(u8_to_u32(cxi_header.logo_region_offset,LE) || u8_to_u32(cxi_header.logo_region_size,LE)) ctx->ncsd_struct->SDK_VER[0] = 5;
		if(cxi_header.flags[SecureCryptoType2Flag])  ctx->ncsd_struct->SDK_VER[0] = 6;
	}
	
	
	// Getting Data from remaining CFA partitions	
	for(int i = 1; i < 8; i++){
		u8 magic[4];
		fseek_64(cci,(ctx->ncsd_struct->partition_data[i].offset + 0x100),SEEK_SET);
		fread(&magic,4,1,cci);
		if(u8_to_u32(magic,BE) == NCCH_MAGIC){
			u8 flags[8];
			u8 ProgramID[8];
			fseek_64(cci,(ctx->ncsd_struct->partition_data[i].offset + 0x188),SEEK_SET);
			fread(&flags,8,1,cci);
			fseek_64(cci,(ctx->ncsd_struct->partition_data[i].offset + 0x118),SEEK_SET);
			fread(&ProgramID,8,1,cci);
			if( (flags[NCCH_Type] & ExeFS) != ExeFS && (flags[NCCH_Type] & RomFS) == RomFS ){
				if((flags[NCCH_Type] & Manual) == Manual && (flags[NCCH_Type] & SystemUpdate) != SystemUpdate)
					ctx->ncsd_struct->partition_data[i].content_type = CFA_Manual;
				else if((flags[NCCH_Type] & Child) == Child)
					ctx->ncsd_struct->partition_data[i].content_type = CFA_DLPChild;
				else if((flags[NCCH_Type] & SystemUpdate) == SystemUpdate && (flags[NCCH_Type] & Manual) != Manual)
					ctx->ncsd_struct->partition_data[i].content_type = CFA_Update;
				else
					ctx->ncsd_struct->partition_data[i].content_type = CFA_Simple;
			}
			else if((flags[NCCH_Type] & ExeFS) == ExeFS)
				ctx->ncsd_struct->partition_data[i].content_type = CXI;
			else
				ctx->ncsd_struct->partition_data[i].content_type = _unknown;


			// Checking 'other flag' for crypto settings
			if((flags[OtherFlag] & 1) == 1){
				if((flags[OtherFlag] & 4) == 4) ctx->ncsd_struct->partition_data[i].ncch_crypto_key = no_crypto;	
				else if ((ProgramID[4] && 0x10) == 0x10) ctx->ncsd_struct->partition_data[i].ncch_crypto_key = fixed_system;
				else ctx->ncsd_struct->partition_data[i].ncch_crypto_key = fixed_zeros;
			}
			else if(!flags[OtherFlag]){
				ctx->ncsd_struct->partition_data[i].ncch_crypto_key = secure_key;
				if(flags[SecureCryptoType2Flag]) ctx->ncsd_struct->partition_data[i].ncch_crypto_key = secure_key2;
			}

			fseek_64(cci,(ctx->ncsd_struct->partition_data[i].offset + 0x150),SEEK_SET);
			fread(ctx->ncsd_struct->partition_data[i].product_code,16,1,cci);
		}
		else
			ctx->ncsd_struct->partition_data[i].content_type = _unknown;
	} 
		
	if(ctx->flags[info])
		PrintNCSDHeaderData(ctx->ncsd_struct,&header,&card_info,&dev_card_info);
	if(ctx->flags[part_info])
		PrintCCIPartitionData(ctx->ncsd_struct,&header,&card_info,&dev_card_info);
	fclose(cci);
	return 0;
fail:
	fclose(cci);
	return Fail;

}
Ejemplo n.º 22
0
int GetNCSDData(USER_CONTEXT *ctx, NCSD_STRUCT *ncsd_struct, FILE *ncsd)
{
	if(ncsd_struct == NULL)
		return Fail;
	memset(ncsd_struct,0x0,sizeof(NCSD_STRUCT));
	
	NCSD_HEADER header;
	CARD_INFO_HEADER card_info;
	DEV_CARD_INFO_HEADER dev_card_info;
	
	fseek(ncsd,0x0,SEEK_SET);
	fread(&ncsd_struct->signature,0x100,1,ncsd);
	fseek(ncsd,0x100,SEEK_SET);
	fread(&header,sizeof(NCSD_HEADER),1,ncsd);
	fseek(ncsd,0x200,SEEK_SET);
	fread(&card_info,sizeof(CARD_INFO_HEADER),1,ncsd);
	fseek(ncsd,0x1200,SEEK_SET);
	fread(&dev_card_info,sizeof(DEV_CARD_INFO_HEADER),1,ncsd);
	
	ctr_sha(&header,sizeof(NCSD_HEADER),ncsd_struct->ncsd_header_hash,CTR_SHA_256);
	
	if(u8_to_u32(header.magic,BE) != NCSD_MAGIC){
		printf("[!] ROM is Corrupt\n");
		return Fail;
	}
	
	ncsd_struct->sig_valid = ctr_rsa(ncsd_struct->ncsd_header_hash,ncsd_struct->signature,ctx->keys.NcsdCfa.n,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
	
	u32 media_size = ((header.partition_flags[6] + 1)*0x200);
	
	ncsd_struct->rom_size = u8_to_u32(header.rom_size,LE)*media_size;
	ncsd_struct->used_rom_size = 0;
	if(ncsd_struct->used_rom_size == 0){
		u32 tmp = u8_to_u32(header.offsetsize_table[0].offset,LE);
		for(int i = 0; i < 8; i++){
			tmp += u8_to_u32(header.offsetsize_table[i].size,LE);
		}
		ncsd_struct->used_rom_size = tmp*media_size;
	}
		
	
	for(int i = 0; i < 8; i++){
		ncsd_struct->partition_data[i].offset = u8_to_u32(header.offsetsize_table[i].offset,LE)*media_size;
		ncsd_struct->partition_data[i].size = u8_to_u32(header.offsetsize_table[i].size,LE)*media_size;
		if(ncsd_struct->partition_data[i].offset != 0 && ncsd_struct->partition_data[i].size != 0)
			ncsd_struct->partition_data[i].active = True;
		ncsd_struct->partition_data[i].title_id = u8_to_u64(header.partition_id_table[i],LE);
		ncsd_struct->partition_data[i].fs_type = header.partitions_fs_type[i];
		ncsd_struct->partition_data[i].crypto_type = header.partitions_crypto_type[i];
		
		u8 magic[4];
		fseek_64(ncsd,(ncsd_struct->partition_data[i].offset + 0x100),SEEK_SET);
		fread(&magic,4,1,ncsd);
		if(u8_to_u32(magic,BE) == NCCH_MAGIC){
			u8 flags[8];
			u8 flag_bool[8];
			fseek_64(ncsd,(ncsd_struct->partition_data[i].offset + 0x188),SEEK_SET);
			fread(&flags,8,1,ncsd);
			resolve_flag(flags[5],flag_bool);
			if(flag_bool[1] == False && flag_bool[0] == True){
				if(flag_bool[2] == False && flag_bool[3] == True)
					ncsd_struct->partition_data[i].content_type = CFA_Manual;
				else if(flag_bool[2] == True && flag_bool[3] == True)
					ncsd_struct->partition_data[i].content_type = CFA_DLPChild;
				else if(flag_bool[2] == True && flag_bool[3] == False)
					ncsd_struct->partition_data[i].content_type = CFA_Update;
				else
					ncsd_struct->partition_data[i].content_type = _unknown;
			}
			else if(flag_bool[1] == True)
				ncsd_struct->partition_data[i].content_type = CXI;
			else
				ncsd_struct->partition_data[i].content_type = _unknown;
		}
		else
			ncsd_struct->partition_data[i].content_type = _unknown;
	}
	
	if(u8_to_u64(card_info.cver_title_id,LE) == 0){
		u8 stock_title_key[0x10] = {0x6E, 0xC7, 0x5F, 0xB2, 0xE2, 0xB4, 0x87, 0x46, 0x1E, 0xDD, 0xCB, 0xB8, 0x97, 0x11, 0x92, 0xBA};
		if(memcmp(dev_card_info.TitleKey,stock_title_key,0x10) == 0)
			ncsd_struct->type = dev_external_SDK;
		else
			ncsd_struct->type = dev_internal_SDK;
	}
	else
		ncsd_struct->type = retail;
	
	/**
	if(ncsd_struct->type != retail){
		u8 iv[16];
		u8 key[16];
		memset(&iv,0x0,16);
		memset(&key,0x0,16);
		//iv[0] = header.partition_flags[7];
		//memcpy(iv+11,header.partition_flags,5);
		u8 tmp[16] = {0xB2, 0x57, 0xA7, 0xC0, 0x24, 0xC8, 0xC1, 0xB0, 0x75, 0x91, 0xC4, 0xC5, 0x1D, 0x96, 0x67, 0x4F};
		
		memcpy(iv,tmp,16);
		memcpy(key,common_dpki_aesKey,16);
		
		ctr_aes_context aes;
		memset(&aes,0x0,sizeof(ctr_aes_context));
		
		memdump(stdout,"ENC Title Key:   ",dev_card_info.TitleKey,0x10);
		
		ctr_init_aes_cbc(&aes,key,iv,DEC);
		ctr_aes_cbc(&aes,dev_card_info.TitleKey,dev_card_info.TitleKey,0x10,DEC);
		
		memdump(stdout,"DEC Title Key:   ",dev_card_info.TitleKey,0x10);
	}
	**/
	/**
	for(int i = 0; i < 8; i++){
		if(ncsd_struct->partition_data[i].active == True){
			ncsd_struct->partition_data[i].sig_valid = VerifyNCCHSection(ctx,dev_card_info.TitleKey,ncsd_struct->partition_data[i].offset,ncsd);
		}
	}
	**/
	ncsd_struct->valid = True;
	if(ctx->flags[info])
		PrintNCSDData(ncsd_struct,&header,&card_info,&dev_card_info);
	return 0;
}
Ejemplo n.º 23
0
int GetNcchInfo(ncch_info *info, ncch_hdr *hdr)
{
	clrmem(info, sizeof(ncch_info));

	info->titleId = u8_to_u64(hdr->titleId,LE);
	info->programId = u8_to_u64(hdr->programId,LE);

	u32 block_size = GetNcchBlockSize(hdr);
	
	info->formatVersion = u8_to_u16(hdr->formatVersion,LE);
	if(!IsCfa(hdr)){
		info->exhdrOffset = sizeof(ncch_hdr);
		info->exhdrSize = u8_to_u32(hdr->exhdrSize,LE);
		info->acexOffset = (info->exhdrOffset + info->exhdrSize);
		info->acexSize = sizeof(access_descriptor);
		info->plainRegionOffset = (u64)(u8_to_u32(hdr->plainRegionOffset,LE)*block_size);
		info->plainRegionSize = (u64)(u8_to_u32(hdr->plainRegionSize,LE)*block_size);
	}

	info->logoOffset = (u64)(u8_to_u32(hdr->logoOffset,LE)*block_size);
	info->logoSize = (u64)(u8_to_u32(hdr->logoSize,LE)*block_size);
	info->exefsOffset = (u64)(u8_to_u32(hdr->exefsOffset,LE)*block_size);
	info->exefsSize = (u64)(u8_to_u32(hdr->exefsSize,LE)*block_size);
	info->exefsHashDataSize = (u64)(u8_to_u32(hdr->exefsHashSize,LE)*block_size);
	info->romfsOffset = (u64) (u8_to_u32(hdr->romfsOffset,LE)*block_size);
	info->romfsSize = (u64) (u8_to_u32(hdr->romfsSize,LE)*block_size);
	info->romfsHashDataSize = (u64)(u8_to_u32(hdr->romfsHashSize,LE)*block_size);
	return 0;
}
Ejemplo n.º 24
0
u64 GetNcchSize(ncch_hdr* hdr)
{
	return (u64)u8_to_u32(hdr->ncchSize,LE) * (u64)GetNcchBlockSize(hdr);
}
Ejemplo n.º 25
0
int
main ()
{
  /* Empty string.  */
  ASSERT (check (NULL, 0, NULL, 0) == 0);

  /* Simple string.  */
  { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a)  日本語,中文,한글" */
    static const uint8_t input[] =
      { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
        0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
        0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
        '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
        'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
        ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
        0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
        0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
      };
    static const uint32_t expected[] =
      { 'G', 'r', 0x00FC, 0x00DF, ' ', 'G', 'o', 't', 't', '.', ' ',
        0x0417, 0x0434, 0x0440, 0x0430, 0x0432, 0x0441, 0x0442, 0x0432, 0x0443,
        0x0439, 0x0442, 0x0435, '!', ' ',
        'x', '=', '(', '-', 'b', 0x00B1, 's', 'q', 'r', 't', '(', 'b', 0x00B2,
        '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')', ' ', ' ',
        0x65E5, 0x672C, 0x8A9E, ',', 0x4E2D, 0x6587, ',', 0xD55C, 0xAE00, '\n'
      };
    ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
  }

  /* String with characters outside the BMP.  */
  {
    static const uint8_t input[] =
      { '-', '(', 0xF0, 0x9D, 0x94, 0x9E, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9F,
        ')', '=', 0xF0, 0x9D, 0x94, 0x9F, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9E
      };
    static const uint32_t expected[] =
      { '-', '(', 0x1D51E, 0x00D7, 0x1D51F, ')', '=',
        0x1D51F, 0x00D7, 0x1D51E
      };
    ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
  }

  /* Invalid input.  */
  {
    static const uint8_t input[] = { 'x', 0xC2, 0xC3, 'y' };
#if 0 /* Currently invalid input is rejected, not accommodated.  */
    static const uint32_t expected[] = { 'x', 0xFFFD, 0xFFFD, 'y' };
    ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
#else
    size_t length;
    uint32_t *result;
    uint32_t preallocated[10];

    /* Test return conventions with resultbuf == NULL.  */
    result = u8_to_u32 (input, SIZEOF (input), NULL, &length);
    ASSERT (result == NULL);
    ASSERT (errno == EILSEQ);

    /* Test return conventions with resultbuf too small.  */
    length = 1;
    result = u8_to_u32 (input, SIZEOF (input), preallocated, &length);
    ASSERT (result == NULL);
    ASSERT (errno == EILSEQ);

    /* Test return conventions with resultbuf large enough.  */
    length = SIZEOF (preallocated);
    result = u8_to_u32 (input, SIZEOF (input), preallocated, &length);
    ASSERT (result == NULL);
    ASSERT (errno == EILSEQ);
#endif
  }

  return 0;
}
Ejemplo n.º 26
0
// Pubk
pubk_types GetCertPubkType(u8 *cert)
{
	cert_hdr *hdr = GetCertHdr(cert);

	return (pubk_types)u8_to_u32(hdr->keyType,BE);
}
Ejemplo n.º 27
0
int FinaliseNcch(ncch_settings *set)
{
	u8 *ncch = set->out->buffer;

	ncch_hdr *hdr = (ncch_hdr*)ncch;
	u8 *exhdr = (u8*)(ncch + set->cryptoDetails.exhdrOffset);
	u8 *acexDesc = (u8*)(ncch + set->cryptoDetails.acexOffset);
	u8 *logo = (u8*)(ncch + set->cryptoDetails.logoOffset);
	u8 *exefs = (u8*)(ncch + set->cryptoDetails.exefsOffset);
	u8 *romfs = (u8*)(ncch + set->cryptoDetails.romfsOffset);

	// Taking Hashes
	if(set->cryptoDetails.exhdrSize)
		ShaCalc(exhdr,set->cryptoDetails.exhdrSize,hdr->exhdrHash,CTR_SHA_256);
	if(set->cryptoDetails.logoSize)
		ShaCalc(logo,set->cryptoDetails.logoSize,hdr->logoHash,CTR_SHA_256);
	if(set->cryptoDetails.exefsHashDataSize)
		ShaCalc(exefs,set->cryptoDetails.exefsHashDataSize,hdr->exefsHash,CTR_SHA_256);
	if(set->cryptoDetails.romfsHashDataSize)
		ShaCalc(romfs,set->cryptoDetails.romfsHashDataSize,hdr->romfsHash,CTR_SHA_256);

	// Signing NCCH
	int sig_result = Good;
	if(set->options.IsCfa) 
		sig_result = SignCFA(hdr,set->keys);
	else 
		sig_result = SignCXI(hdr,set->keys);
	if(sig_result != Good){
		fprintf(stderr,"[NCCH ERROR] Failed to sign %s header\n",set->options.IsCfa ? "CFA" : "CXI");
		return sig_result;
	}


	// Crypting NCCH\n");
	if(IsNcchEncrypted(hdr)){
		if(!SetNcchKeys(set->keys, hdr)){
			fprintf(stderr,"[NCCH ERROR] Failed to load NCCH AES key\n");
			return -1;
		}

		if(set->options.verbose){
			printf("[NCCH] NCCH AES keys:\n");
			memdump(stdout," > key0: ",set->keys->aes.ncchKey0,AES_128_KEY_SIZE);
			memdump(stdout," > key1: ",set->keys->aes.ncchKey1,AES_128_KEY_SIZE);
		}

		// Crypting Exheader/AcexDesc
		if(set->cryptoDetails.exhdrSize){
			CryptNcchRegion(exhdr,set->cryptoDetails.exhdrSize,0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exhdr);
			CryptNcchRegion(acexDesc,set->cryptoDetails.acexSize,set->cryptoDetails.exhdrSize,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exhdr);
		}			

		// Crypting ExeFs Files
		if(set->cryptoDetails.exefsSize){
			exefs_hdr *exefsHdr = (exefs_hdr*)exefs;
			for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
				u8 *key = NULL;
				if(strncmp(exefsHdr->fileHdr[i].name,"icon",8) == 0 || strncmp(exefsHdr->fileHdr[i].name,"banner",8) == 0)
					key = set->keys->aes.ncchKey0;
				else
					key = set->keys->aes.ncchKey1;
								
				u32 offset = u8_to_u32(exefsHdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
				u32 size = u8_to_u32(exefsHdr->fileHdr[i].size,LE);

				if(size)
					CryptNcchRegion((exefs+offset),align(size,set->options.blockSize),offset,set->cryptoDetails.titleId,key,ncch_exefs);

			}
			// Crypting ExeFs Header
			CryptNcchRegion(exefs,sizeof(exefs_hdr),0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exefs);
		}

		// Crypting RomFs
		if(set->cryptoDetails.romfsSize)
			CryptNcchRegion(romfs,set->cryptoDetails.romfsSize,0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey1,ncch_romfs);
	}

	return 0;
}