예제 #1
0
파일: ncsd.c 프로젝트: enler/Project_CTR
int SetMediaSize(u8 *mediaSize, cci_settings *set)
{	
	char *str = set->rsf->CardInfo.MediaSize;
	if(!str) 
		set->romInfo.mediaSize = (u64)GB*2;
	else{
		if(strcasecmp(str,"128MB") == 0) set->romInfo.mediaSize = (u64)MB*128;
		else if(strcasecmp(str,"256MB") == 0) set->romInfo.mediaSize = (u64)MB*256;
		else if(strcasecmp(str,"512MB") == 0) set->romInfo.mediaSize = (u64)MB*512;
		else if(strcasecmp(str,"1GB") == 0) set->romInfo.mediaSize = (u64)GB*1;
		else if(strcasecmp(str,"2GB") == 0) set->romInfo.mediaSize = (u64)GB*2;
		else if(strcasecmp(str,"4GB") == 0) set->romInfo.mediaSize = (u64)GB*4;
		else if(strcasecmp(str,"8GB") == 0) set->romInfo.mediaSize = (u64)GB*8;
		//else if(strcasecmp(str,"16GB") == 0) set->romInfo.mediaSize = (u64)GB*16;
		//else if(strcasecmp(str,"32GB") == 0) set->romInfo.mediaSize = (u64)GB*32;
		else {
			fprintf(stderr,"[CCI ERROR] Invalid MediaSize: %s\n",str);
			return INVALID_RSF_OPT;
		}
	}
		
	u32_to_u8(mediaSize,(set->romInfo.mediaSize/set->romInfo.blockSize),LE);

	return 0;
}
예제 #2
0
int GenerateExeFS_Header(exefs_buildctx *ctx, u8 *outbuff)
{
	for(int i = 0; i < ctx->fileCount; i++){
		if(i == 0)
			ctx->fileOffset[i] = 0;
		else
			ctx->fileOffset[i] = align((ctx->fileOffset[i-1]+ctx->fileSize[i-1]),ctx->blockSize);
		
		memcpy(ctx->fileHdr[i].name,ctx->fileName[i],8);
		u32_to_u8(ctx->fileHdr[i].offset,ctx->fileOffset[i],LE);
		u32_to_u8(ctx->fileHdr[i].size,ctx->fileSize[i],LE);
		ctr_sha(ctx->file[i],ctx->fileSize[i],ctx->fileHashes[9-i],CTR_SHA_256);
	}
	memcpy(outbuff,ctx->fileHdr,sizeof(exefs_filehdr)*10);
	memcpy(outbuff+0xc0,ctx->fileHashes,0x20*10);
	return 0;
}
예제 #3
0
int GenerateTicket(USER_CONTEXT *ctx)
{
	if(ctx->flags[verbose]) { printf("[+] Generating Ticket\n"); }
	ctx->cia_section[tik].size = (sizeof(TICKET_STRUCTURE)+ sizeof(TIK_2048_SIG_CONTEXT));
	ctx->cia_section[tik].buffer = malloc(ctx->cia_section[tik].size);
	if(ctx->cia_section[tik].buffer == NULL){
		printf("[!] Failed to allocated memory for ticket\n");
		return 1;
	}
	
	TICKET_STRUCTURE ticket;
	TIK_2048_SIG_CONTEXT sig;
	memset(&sig,0x0,sizeof(TIK_2048_SIG_CONTEXT));
	memset(&ticket,0x0,sizeof(TICKET_STRUCTURE));
	
	if(ctx->flags[verbose]) { printf(" > Collecting Data\n"); }
	ticket.TicketFormatVersion = ctx->core.ticket_format_ver;
	ticket.ca_crl_version = ctx->core.ca_crl_version;
	ticket.signer_crl_version = ctx->core.signer_crl_version;
	ticket.CommonKeyID = ctx->keys.common_key_id;
	
	memcpy(ticket.Issuer,ctx->core.TicketIssuer,0x40);
	memcpy(ticket.TicketID,ctx->core.TicketID,0x8);
	memcpy(ticket.DeviceID,ctx->core.DeviceID,0x4);
	memcpy(ticket.TitleID,ctx->core.TitleID,0x8);
	memcpy(ticket.TicketVersion,ctx->core.TicketVersion,0x2);
	
	if(ctx->flags[verbose]) { printf(" > Encrypting Titlekey\n"); }
	if(EncryptTitleKey(ticket.EncryptedTitleKey,ctx->keys.title_key,ctx->keys.common_key,ctx->core.TitleID) != 0){
		printf("[!] Failed to encrypt titlekey\n");
		return Fail;
	}
	if(ctx->flags[showkeys])
		memdump(stdout,"\n[+] Encrypted Title Key:   ",ticket.EncryptedTitleKey,0x10);
	
	if(SetStaticData(dev,ticket.StaticData) != 0){
		printf("[!] ERROR in Generating Ticket\n");
		return Fail;
	}
	if(ctx->flags[verbose]) { printf(" > Signing Ticket\n"); }
	u32_to_u8(sig.sig_type,RSA_2048_SHA256,BE);
	u8 hash[0x20];
	ctr_sha(&ticket,sizeof(TICKET_STRUCTURE),hash,CTR_SHA_256);
	if(ctr_rsa(hash,sig.data,ctx->keys.ticket.n,ctx->keys.ticket.d,RSA_2048_SHA256,CTR_RSA_SIGN) != Good){
		printf("[!] Failed to sign ticket\n");
		return ticket_gen_fail;
	}
	
	if(ctx->flags[info]){
		memdump(stdout,"[+] Ticket Signature:   ",sig.data,0x100);
	}
	
	memcpy(ctx->cia_section[tik].buffer,&sig,sizeof(TIK_2048_SIG_CONTEXT));
	memcpy((ctx->cia_section[tik].buffer + sizeof(TIK_2048_SIG_CONTEXT)),&ticket,sizeof(TICKET_STRUCTURE));
	return 0;
}
예제 #4
0
static char *
print_chars(const widechar *buffer, int length) {
	static uint8_t result_buf[BUFSIZE];
	size_t result_len = BUFSIZE - 1;
#ifdef WIDECHARS_ARE_UCS4
	u32_to_u8(buffer, length, result_buf, &result_len);
#else
	u16_to_u8(buffer, length, result_buf, &result_len);
#endif
	result_buf[result_len] = 0;
	return result_buf;
}
예제 #5
0
파일: tmd.c 프로젝트: bkifft/Project_CTR
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;
}
예제 #6
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;
}
예제 #7
0
int SetWriteableAddress(cardinfo_hdr *hdr, cci_settings *set)
{
	if(set->romInfo.mediaType != mediatype_CARD2){ // Can only be set for Card2 Media
		u32_to_u8(hdr->writableAddress,(u32)-1,LE);
		return 0;
	} 
	
	char *str = set->rsf->CardInfo.WritableAddress;
	set->romInfo.card2SaveOffset = -1;
	
	if(str){
		if(strncmp(str,"0x",2) != 0){
			fprintf(stderr,"[CCI ERROR] WritableAddress requires a Hexadecimal value\n");
			return INVALID_RSF_OPT;
		}	
		set->romInfo.card2SaveOffset = strtoull(str,NULL,16);
	}
	else{
		if ((set->romInfo.mediaSize / 2) < set->romInfo.saveSize || set->romInfo.saveSize > (u64)(2047*MB)){
			u64 saveDataSize = set->romInfo.saveSize / KB;
			fprintf(stderr,"[CCI ERROR] Too large SavedataSize %"PRIu64"K\n",saveDataSize);
			return SAVE_DATA_TOO_LARGE;
		}
		if(set->options.closeAlignWR)
			set->romInfo.card2SaveOffset = align(set->romInfo.usedSize, set->romInfo.blockSize); // invalid for "real" chips
		else{
			u64 unusedSize = GetCciUnusedSize(set->romInfo.mediaSize,set->romInfo.mediaType); // Some value related to the physical implementation of gamecards
			if(unusedSize > 0)
				set->romInfo.card2SaveOffset = set->romInfo.mediaSize - unusedSize - set->romInfo.saveSize; // Nintendo's method for calculating writable region offset
			else{
				fprintf(stderr,"[CCI WARNING] Nintendo does not support CARD2 for the current MediaSize, aligning save offset after last NCCH\n");
				set->romInfo.card2SaveOffset = align(set->romInfo.usedSize, set->romInfo.blockSize); // invalid for "real" chips
			}
		}
	}
	
	u32_to_u8(hdr->writableAddress,(u32)(set->romInfo.card2SaveOffset/set->romInfo.blockSize),LE);
	
	return 0;
}
예제 #8
0
static void
print_widechars(widechar *buffer, int length) {
	uint8_t *result_buf;
	size_t result_len;

#ifdef WIDECHARS_ARE_UCS4
	result_buf = u32_to_u8(buffer, length, NULL, &result_len);
#else
	result_buf = u16_to_u8(buffer, length, NULL, &result_len);
#endif
	fprintf(stderr, "%.*s", (int)result_len, result_buf);
	free(result_buf);
}
예제 #9
0
파일: ncsd.c 프로젝트: enler/Project_CTR
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;
}
예제 #10
0
int SetCardInfoBitmask(cardinfo_hdr *hdr, cci_settings *set)
{
	u32 bitmask = 0;

	char *str = set->rsf->CardInfo.CardType;
	if(!str) 
		bitmask |= 0;
	else{
		if(strcasecmp(str,"s1") == 0) 
			bitmask |= 0;
		else if(strcasecmp(str,"s2") == 0) 
			bitmask |= 0x20;
		else {
			fprintf(stderr,"[CCI ERROR] Invalid CardType: %s\n",str);
			return INVALID_RSF_OPT;
		}
	}
	
	str = set->rsf->CardInfo.CryptoType;
	if(!str) {
		if(set->options.useExternalSdkCardInfo)
			bitmask |= (3*0x40);
		else
			bitmask |= 0;
	}
	else{
		int val = strtol(str,NULL,10);
		if(val < 0 || val > 3) {
			fprintf(stderr,"[CCI ERROR] Invalid CryptoType: %s\n",str);
			return INVALID_RSF_OPT;
		}
		if(val != 3)
			fprintf(stderr,"[CCI WARNING] Card crypto type = '%d'\n",val);
		bitmask |= val * 0x40;
	}
	
	u32_to_u8(hdr->cardInfoBitmask,bitmask,BE);
	
	return 0;
}
예제 #11
0
int
main(int argc, char **argv) {
	uint8_t *charbuf;
	size_t charlen;
	widechar inbuf[BUFSIZE];
	widechar transbuf[BUFSIZE];
	widechar outbuf[BUFSIZE];
	int outputPos[BUFSIZE];
	int inputPos[BUFSIZE];
	int inlen;
	int translen;
	int outlen;
	int cursorPos = -1;
	int realInlen = 0;
	int optc;

	set_program_name(argv[0]);

	while ((optc = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) {
		switch (optc) {
		/* --help and --version exit immediately, per GNU coding standards. */
		case 'v':
			version_etc(
					stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *)NULL);
			exit(EXIT_SUCCESS);
			break;
		case 'h':
			print_help();
			exit(EXIT_SUCCESS);
			break;
		default:
			fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (optind < argc) {
		/* Print error message and exit. */
		fprintf(stderr, "%s: extra operand: %s\n", program_name, argv[optind]);
		fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
		exit(EXIT_FAILURE);
	}

	validTable = NULL;
	enteredCursorPos = -1;
	mode = 0;
	while (1) {
		getCommands();
		printf("Type something, press enter, and view the results.\n");
		printf("A blank line returns to command entry.\n");
		if (minimalist)
			while (1) {
				translen = outputSize;
				outlen = outputSize;
				inlen = getInput();
				if (inlen == 0) break;
				if (!(realInlen = _lou_extParseChars(inputBuffer, inbuf))) break;
				inlen = realInlen;
				if (!lou_translateString(
							table, inbuf, &inlen, transbuf, &translen, NULL, NULL, 0))
					break;
				transbuf[translen] = 0;
				printf("Translation:\n");
#ifdef WIDECHARS_ARE_UCS4
				charbuf = u32_to_u8(transbuf, translen, NULL, &charlen);
#else
				charbuf = u16_to_u8(transbuf, translen, NULL, &charlen);
#endif
				printf("%.*s\n", (int)charlen, charbuf);
				free(charbuf);
				if (showSizes)
					printf("input length = %d; output length = %d\n", inlen, translen);
				lou_backTranslateString(
						table, transbuf, &translen, outbuf, &outlen, NULL, NULL, 0);
				printf("Back-translation:\n");
#ifdef WIDECHARS_ARE_UCS4
				charbuf = u32_to_u8(outbuf, outlen, NULL, &charlen);
#else
				charbuf = u16_to_u8(outbuf, outlen, NULL, &charlen);
#endif
				printf("%.*s\n", (int)charlen, charbuf);
				free(charbuf);
				if (showSizes)
					printf("input length = %d; output length = %d.\n", translen, outlen);
				if (outlen == realInlen) {
					int k;
					for (k = 0; k < realInlen; k++)
						if (inbuf[k] != outbuf[k]) break;
					if (k == realInlen) printf("Perfect roundtrip!\n");
				}
			}
		else
			while (1) {
				memset(emphasis, 0, sizeof(formtype) * BUFSIZE);
				{
					size_t k = 0;
					for (k = 0; k < strlen(enteredEmphasis); k++)
						emphasis[k] = (formtype)enteredEmphasis[k] - '0';
					emphasis[k] = 0;
				}
				strcpy(spacing, enteredSpacing);
				cursorPos = enteredCursorPos;
				inlen = getInput();
				if (inlen == 0) break;
				outlen = outputSize;
				if (backOnly) {
					if (!(translen = _lou_extParseChars(inputBuffer, transbuf))) break;
					inlen = realInlen;
				} else {
					translen = outputSize;
					if (!(realInlen = _lou_extParseChars(inputBuffer, inbuf))) break;
					inlen = realInlen;
					if (!lou_translate(table, inbuf, &inlen, transbuf, &translen,
								emphasis, spacing, &outputPos[0], &inputPos[0],
								&cursorPos, mode))
						break;
					transbuf[translen] = 0;
					if (mode & dotsIO) {
						printf("Translation dot patterns:\n");
						printf("%s\n", _lou_showDots(transbuf, translen));
					} else {
						printf("Translation:\n");
#ifdef WIDECHARS_ARE_UCS4
						charbuf = u32_to_u8(transbuf, translen, NULL, &charlen);
#else
						charbuf = u16_to_u8(transbuf, translen, NULL, &charlen);
#endif
						printf("%.*s\n", (int)charlen, charbuf);
						free(charbuf);
						if (showSizes)
							printf("input length = %d; output length = %d\n", inlen,
									translen);
					}
				}
				if (cursorPos != -1) printf("Cursor position: %d\n", cursorPos);
				if (enteredSpacing[0]) printf("Returned spacing: %s\n", spacing);
				if (showPositions) {
					printf("Output positions:\n");
					for (int k = 0; k < inlen; k++) printf("%d ", outputPos[k]);
					printf("\n");
					printf("Input positions:\n");
					for (int k = 0; k < translen; k++) printf("%d ", inputPos[k]);
					printf("\n");
				}
				if (!forwardOnly) {
					if (!lou_backTranslate(table, transbuf, &translen, outbuf, &outlen,
								emphasis, spacing, &outputPos[0], &inputPos[0],
								&cursorPos, mode))
						break;
					printf("Back-translation:\n");
#ifdef WIDECHARS_ARE_UCS4
					charbuf = u32_to_u8(outbuf, outlen, NULL, &charlen);
#else
					charbuf = u16_to_u8(outbuf, outlen, NULL, &charlen);
#endif
					printf("%.*s\n", (int)charlen, charbuf);
					free(charbuf);
					if (showSizes)
						printf("input length = %d; output length = %d\n", translen,
								outlen);
					if (cursorPos != -1) printf("Cursor position: %d\n", cursorPos);
					if (enteredSpacing[0]) printf("Returned spacing: %s\n", spacing);
					if (showPositions) {
						printf("Output positions:\n");
						for (int k = 0; k < translen; k++) printf("%d ", outputPos[k]);
						printf("\n");
						printf("Input positions:\n");
						for (int k = 0; k < outlen; k++) printf("%d ", inputPos[k]);
						printf("\n");
					}
				}
				if (!(forwardOnly || backOnly)) {
					if (outlen == realInlen) {
						int k;
						for (k = 0; k < realInlen; k++)
							if (inbuf[k] != outbuf[k]) break;
						if (k == realInlen) printf("Perfect roundtrip!\n");
					}
				}
			}
	}
	lou_free();
	exit(EXIT_SUCCESS);
}
예제 #12
0
파일: ncch.c 프로젝트: enler/Project_CTR
int SetupNcch(ncch_settings *set, romfs_buildctx *romfs)
{
	u64 ncchSize = 0;
	u64 exhdrSize,acexSize,logoSize,plnRgnSize,exefsSize,romfsSize;
	u64 exhdrOffset,acexOffset,logoOffset,plnRgnOffset,exefsOffset,romfsOffset;
	u32 exefsHashSize,romfsHashSize;

	ncchSize += sizeof(ncch_hdr); // Sig+Hdr
	
	// Sizes for NCCH hdr
	if(set->sections.exhdr.size){
		exhdrSize = set->sections.exhdr.size;
		exhdrOffset = ncchSize;
		ncchSize += exhdrSize;
	}
	else
		exhdrSize = 0;
		
	if(set->sections.acexDesc.size){
		acexSize = set->sections.acexDesc.size;
		acexOffset = ncchSize;
		ncchSize += acexSize;
	}
	else
		acexSize = 0;

	if(set->sections.logo.size){
		logoSize = set->sections.logo.size;
		logoOffset = align(ncchSize,set->options.blockSize);
		ncchSize = logoOffset + logoSize;
	}
	else
		logoSize = 0;

	if(set->sections.plainRegion.size){
		plnRgnSize = align(set->sections.plainRegion.size,set->options.blockSize);
		plnRgnOffset = align(ncchSize,set->options.blockSize);
		ncchSize = plnRgnOffset + plnRgnSize;
	}
	else
		plnRgnSize = 0;

	if(set->sections.exeFs.size){
		exefsHashSize = align(sizeof(exefs_hdr),set->options.blockSize);
		exefsSize = align(set->sections.exeFs.size,set->options.blockSize);
		exefsOffset = align(ncchSize,set->options.blockSize);
		ncchSize = exefsOffset + exefsSize;
	}
	else
		exefsSize = 0;

	if(romfs->romfsSize){
		romfsHashSize = align(romfs->romfsHeaderSize,set->options.blockSize);
		romfsSize = align(romfs->romfsSize,set->options.blockSize);
		//romfsOffset = align(ncchSize,set->options.blockSize); // Old makerom method, SDK 2.x and prior
		romfsOffset = align(ncchSize,0x1000);
		ncchSize = romfsOffset + romfsSize;
	}
	else
		romfsSize = 0;



	// Aligning Total NCCH Size
	ncchSize = align(ncchSize,set->options.blockSize);
	
	u8 *ncch = calloc(1,ncchSize);
	if(!ncch){
		fprintf(stderr,"[NCCH ERROR] Not enough memory\n");
		return MEM_ERROR;
	}
	
	// Setting up hdr\n");
	ncch_hdr *hdr = (ncch_hdr*)ncch;
	int ret = SetCommonHeaderBasicData(set,hdr);
	if(ret != 0){
		free(ncch);
		return ret;
	}
	u32_to_u8(hdr->ncchSize,ncchSize/set->options.blockSize,LE);


	// Copy already built sections to ncch
	if(exhdrSize){
		memcpy((u8*)(ncch+exhdrOffset),set->sections.exhdr.buffer,set->sections.exhdr.size);
		free(set->sections.exhdr.buffer);
		set->sections.exhdr.buffer = NULL;
		u32_to_u8(hdr->exhdrSize,exhdrSize,LE);
	}
	if(acexSize){
		memcpy((u8*)(ncch+acexOffset),set->sections.acexDesc.buffer,set->sections.acexDesc.size);
		free(set->sections.acexDesc.buffer);
		set->sections.acexDesc.buffer = NULL;
	}

	if(logoSize){
		memcpy((u8*)(ncch+logoOffset),set->sections.logo.buffer,set->sections.logo.size);
		free(set->sections.logo.buffer);
		set->sections.logo.buffer = NULL;
		u32_to_u8(hdr->logoOffset,logoOffset/set->options.blockSize,LE);
		u32_to_u8(hdr->logoSize,logoSize/set->options.blockSize,LE);
	}

	if(plnRgnSize){		
		memcpy((u8*)(ncch+plnRgnOffset),set->sections.plainRegion.buffer,set->sections.plainRegion.size);
		free(set->sections.plainRegion.buffer);
		set->sections.plainRegion.buffer = NULL;
		u32_to_u8(hdr->plainRegionOffset,plnRgnOffset/set->options.blockSize,LE);
		u32_to_u8(hdr->plainRegionSize,plnRgnSize/set->options.blockSize,LE);
	}

	if(exefsSize){	
		memcpy((u8*)(ncch+exefsOffset),set->sections.exeFs.buffer,set->sections.exeFs.size);
		free(set->sections.exeFs.buffer);
		
		set->sections.exeFs.buffer = NULL;
		
		u32_to_u8(hdr->exefsOffset,exefsOffset/set->options.blockSize,LE);
		
		u32_to_u8(hdr->exefsSize,exefsSize/set->options.blockSize,LE);
		
		u32_to_u8(hdr->exefsHashSize,exefsHashSize/set->options.blockSize,LE);
		
	}

	// Point Romfs CTX to output buffer, if exists\n");
	if(romfsSize){
		romfs->output = ncch + romfsOffset;
		u32_to_u8(hdr->romfsOffset,romfsOffset/set->options.blockSize,LE);
		u32_to_u8(hdr->romfsSize,romfsSize/set->options.blockSize,LE);
		u32_to_u8(hdr->romfsHashSize,romfsHashSize/set->options.blockSize,LE);
	}
	
	set->out->buffer = ncch;
	set->out->size = ncchSize;

	GetNcchInfo(&set->cryptoDetails,hdr);

	return 0;
}
예제 #13
0
int
check_base(const char *tableList, const char *input, const char *expected,
		optional_test_params in) {

	int i, retval = 0;
	int direction = in.direction;
	const int *expected_inputPos = in.expected_inputPos;
	const int *expected_outputPos = in.expected_outputPos;
	if (in.direction < 0 || in.direction > 2) {
		fprintf(stderr, "Invalid direction.\n");
		return 1;
	}
	if (in.direction != 0 && in.typeform != NULL) {
		// Currently, in backward translation, nothing is done with the initial value of
		// the typeform argument, and on return it always contains all zeros, so it
		// doesn't make any sense to use typeforms in backward translation tests.
		fprintf(stderr, "typeforms only supported with testmode 'forward'\n");
		return 1;
	}
	if (in.direction == 2 && in.cursorPos >= 0) {
		fprintf(stderr, "cursorPos not supported with testmode 'bothDirections'\n");
		return 1;
	}
	if (in.direction == 2 && in.max_outlen >= 0) {
		fprintf(stderr, "maxOutputLength not supported with testmode 'bothDirections'\n");
		return 1;
	}
	if (in.real_inlen >= 0 && in.max_outlen < 0) {
		fprintf(stderr,
				"realInputLength not supported when maxOutputLength is not specified\n");
		return 1;
	}
	while (1) {
		widechar *inbuf, *outbuf, *expectedbuf;
		int inlen = strlen(input);
		int actualInlen;
		const int outlen_multiplier = 4 + sizeof(widechar) * 2;
		int outlen = inlen * outlen_multiplier;
		int expectedlen = strlen(expected);
		int funcStatus = 0;
		formtype *typeformbuf = NULL;
		int *inputPos = NULL;
		int *outputPos = NULL;
		int cursorPos = 0;
		inbuf = malloc(sizeof(widechar) * inlen);
		outbuf = malloc(sizeof(widechar) * outlen);
		expectedbuf = malloc(sizeof(widechar) * expectedlen);
		if (in.typeform != NULL) {
			typeformbuf = malloc(outlen * sizeof(formtype));
			memcpy(typeformbuf, in.typeform, inlen * sizeof(formtype));
		}
		if (in.cursorPos >= 0) {
			cursorPos = in.cursorPos;
		}
		if (in.max_outlen >= 0) {
			outlen = in.max_outlen;
		}
		inlen = _lou_extParseChars(input, inbuf);
		if (!inlen) {
			fprintf(stderr, "Cannot parse input string.\n");
			retval = 1;
			goto fail;
		}
		if (in.real_inlen > inlen) {
			fprintf(stderr,
					"expected realInputLength (%d) may not exceed total input length "
					"(%d)\n",
					in.real_inlen, inlen);
			return 1;
		}
		if (expected_inputPos) {
			inputPos = malloc(sizeof(int) * outlen);
		}
		if (expected_outputPos) {
			outputPos = malloc(sizeof(int) * inlen);
		}
		actualInlen = inlen;
		// Note that this loop is not strictly needed to make the current tests pass, but
		// in the general case it is needed because it is theoretically possible that we
		// provided a too short output buffer.
		for (int k = 1; k <= 3; k++) {
			if (direction == 1) {
				funcStatus = lou_backTranslate(tableList, inbuf, &actualInlen, outbuf,
						&outlen, typeformbuf, NULL, outputPos, inputPos, &cursorPos,
						in.mode);
			} else {
				funcStatus = lou_translate(tableList, inbuf, &actualInlen, outbuf,
						&outlen, typeformbuf, NULL, outputPos, inputPos, &cursorPos,
						in.mode);
			}
			if (!funcStatus) {
				fprintf(stderr, "Translation failed.\n");
				retval = 1;
				goto fail;
			}
			if (in.max_outlen >= 0 || inlen == actualInlen) {
				break;
			} else if (k < 3) {
				// Hm, something is not quite right. Try again with a larger outbuf
				free(outbuf);
				outlen = inlen * outlen_multiplier * (k + 1);
				outbuf = malloc(sizeof(widechar) * outlen);
				if (expected_inputPos) {
					free(inputPos);
					inputPos = malloc(sizeof(int) * outlen);
				}
				fprintf(stderr,
						"Warning: For %s: returned inlen (%d) differs from passed inlen "
						"(%d) "
						"using outbuf of size %d. Trying again with bigger outbuf "
						"(%d).\n",
						input, actualInlen, inlen, inlen * outlen_multiplier * k, outlen);
				actualInlen = inlen;
			}
		}
		expectedlen = _lou_extParseChars(expected, expectedbuf);
		for (i = 0; i < outlen && i < expectedlen && expectedbuf[i] == outbuf[i]; i++)
			;
		if (i < outlen || i < expectedlen) {
			retval = 1;
			if (in.diagnostics) {
				outbuf[outlen] = 0;
				fprintf(stderr, "Input:    '%s'\n", input);
				/* Print the original typeform not the typeformbuf, as the
				 * latter has been modified by the translation and contains some
				 * information about outbuf */
				if (in.typeform != NULL) print_typeform(in.typeform, inlen);
				if (in.cursorPos >= 0) fprintf(stderr, "Cursor:   %d\n", in.cursorPos);
				fprintf(stderr, "Expected: '%s' (length %d)\n", expected, expectedlen);
				fprintf(stderr, "Received: '");
				print_widechars(outbuf, outlen);
				fprintf(stderr, "' (length %d)\n", outlen);

				uint8_t *expected_utf8;
				uint8_t *out_utf8;
				size_t expected_utf8_len;
				size_t out_utf8_len;
#ifdef WIDECHARS_ARE_UCS4
				expected_utf8 = u32_to_u8(&expectedbuf[i], 1, NULL, &expected_utf8_len);
				out_utf8 = u32_to_u8(&outbuf[i], 1, NULL, &out_utf8_len);
#else
				expected_utf8 = u16_to_u8(&expectedbuf[i], 1, NULL, &expected_utf8_len);
				out_utf8 = u16_to_u8(&outbuf[i], 1, NULL, &out_utf8_len);
#endif

				if (i < outlen && i < expectedlen) {
					fprintf(stderr,
							"Diff:     Expected '%.*s' but received '%.*s' in index %d\n",
							(int)expected_utf8_len, expected_utf8, (int)out_utf8_len,
							out_utf8, i);
				} else if (i < expectedlen) {
					fprintf(stderr,
							"Diff:     Expected '%.*s' but received nothing in index "
							"%d\n",
							(int)expected_utf8_len, expected_utf8, i);
				} else {
					fprintf(stderr,
							"Diff:     Expected nothing but received '%.*s' in index "
							"%d\n",
							(int)out_utf8_len, out_utf8, i);
				}
				free(expected_utf8);
				free(out_utf8);
			}
		}
		if (expected_inputPos) {
			int error_printed = 0;
			for (i = 0; i < outlen; i++) {
				if (expected_inputPos[i] != inputPos[i]) {
					if (!error_printed) {  // Print only once
						fprintf(stderr, "Input position failure:\n");
						error_printed = 1;
					}
					fprintf(stderr, "Expected %d, received %d in index %d\n",
							expected_inputPos[i], inputPos[i], i);
					retval = 1;
				}
			}
		}
		if (expected_outputPos) {
			int error_printed = 0;
			for (i = 0; i < inlen; i++) {
				if (expected_outputPos[i] != outputPos[i]) {
					if (!error_printed) {  // Print only once
						fprintf(stderr, "Output position failure:\n");
						error_printed = 1;
					}
					fprintf(stderr, "Expected %d, received %d in index %d\n",
							expected_outputPos[i], outputPos[i], i);
					retval = 1;
				}
			}
		}
		if ((in.expected_cursorPos >= 0) && (cursorPos != in.expected_cursorPos)) {
			fprintf(stderr, "Cursor position failure:\n");
			fprintf(stderr, "Initial:%d Expected:%d Actual:%d \n", in.cursorPos,
					in.expected_cursorPos, cursorPos);
			retval = 1;
		}
		if (in.max_outlen < 0 && inlen != actualInlen) {
			fprintf(stderr,
					"Unexpected error happened: input length is not the same before as "
					"after the translation:\n");
			fprintf(stderr, "Before: %d After: %d \n", inlen, actualInlen);
			retval = 1;
		} else if (actualInlen > inlen) {
			fprintf(stderr,
					"Unexpected error happened: returned input length (%d) exceeds "
					"total input length (%d)\n",
					actualInlen, inlen);
			retval = 1;
		} else if (in.real_inlen >= 0 && in.real_inlen != actualInlen) {
			fprintf(stderr, "Real input length failure:\n");
			fprintf(stderr, "Expected: %d, received: %d\n", in.real_inlen, actualInlen);
			retval = 1;
		}

	fail:
		free(inbuf);
		free(outbuf);
		free(expectedbuf);
		free(typeformbuf);
		free(inputPos);
		free(outputPos);

		if (direction == 2) {
			const char *tmp = input;
			input = expected;
			expected = tmp;
			expected_inputPos = in.expected_outputPos;
			expected_outputPos = in.expected_inputPos;
			direction = 1;
			continue;
		} else {
			break;
		}
	}

	return retval;
}
예제 #14
0
/** Check if a string is hyphenated as expected.
 *
 * @return 0 if the hyphenation is as expected and 1 otherwise.
 */
int
check_hyphenation(const char *tableList, const char *str, const char *expected) {
	widechar *inbuf;
	widechar *hyphenatedbuf = NULL;
	uint8_t *hyphenated = NULL;
	char *hyphens = NULL;
	int inlen = strlen(str);
	size_t hyphenatedlen = inlen * 2;
	int retval = 0;

	inbuf = malloc(sizeof(widechar) * inlen);
	inlen = _lou_extParseChars(str, inbuf);
	if (!inlen) {
		fprintf(stderr, "Cannot parse input string.\n");
		retval = 1;
		goto fail;
	}
	hyphens = calloc(inlen + 1, sizeof(char));

	if (!lou_hyphenate(tableList, inbuf, inlen, hyphens, 0)) {
		fprintf(stderr, "Hyphenation failed.\n");
		retval = 1;
		goto fail;
	}
	if (hyphens[0] != '0') {
		fprintf(stderr, "Unexpected output from lou_hyphenate.\n");
		retval = 1;
		goto fail;
	}

	hyphenatedbuf = malloc(sizeof(widechar) * hyphenatedlen);
	int i = 0;
	int j = 0;
	hyphenatedbuf[i++] = inbuf[j++];
	for (; j < inlen; j++) {
		if (hyphens[j] != '0') hyphenatedbuf[i++] = (widechar)'-';
		hyphenatedbuf[i++] = inbuf[j];
	}

#ifdef WIDECHARS_ARE_UCS4
	hyphenated = u32_to_u8(hyphenatedbuf, i, NULL, &hyphenatedlen);
#else
	hyphenated = u16_to_u8(hyphenatedbuf, i, NULL, &hyphenatedlen);
#endif

	if (!hyphenated) {
		fprintf(stderr, "Unexpected error during UTF-8 encoding\n");
		free(hyphenatedbuf);
		retval = 2;
		goto fail;
	}

	if (strlen(expected) != hyphenatedlen ||
			strncmp(expected, (const char *)hyphenated, hyphenatedlen)) {
		fprintf(stderr, "Input:    '%s'\n", str);
		fprintf(stderr, "Expected: '%s'\n", expected);
		fprintf(stderr, "Received: '%.*s'\n", (int)hyphenatedlen, hyphenated);
		retval = 1;
	}

	free(hyphenatedbuf);
	free(hyphenated);

fail:
	free(inbuf);
	free(hyphens);
	return retval;
}
예제 #15
0
파일: tmd.c 프로젝트: bkifft/Project_CTR
int SignTMDHeader(tmd_hdr *hdr, tmd_signature *sig, keys_struct *keys)
{
	memset(sig,0,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);
}
예제 #16
0
int main(int argc, char *argv[])
{
	if(argc < 2){
		help(argv[0]);
		return 1;
	}
	int action = 0;
	int i = 1;
	while(!action){
		if(i == argc) break; 
		if(strcmp(argv[i],"-i") == 0 || strncmp(argv[i],"--image=",8) == 0) action = image;
		if(strcmp(argv[i],"-d") == 0 || strncmp(argv[i],"--FSdir=",8) == 0) action = fs;
		if(strcmp(argv[i],"-g") == 0 || strncmp(argv[i],"--genextdata=",13) == 0) action = generate;
		i++;
	}	
	if(action == 0){
		printf("[!] Nothing to do\n");
		help(argv[0]);
		return ARG_ERROR;
	}
	
	if(action == image){
		ExtdataContext *extdata = malloc(sizeof(ExtdataContext));
		InitaliseExtdataContext(extdata);
		char *input = NULL;
		char *output = NULL;
		int DB_Mode = -1;
		u8 Extract = False;
		extdata->PrintInfo = False;
		extdata->Verbose = False;
		extdata->OverrideActiveDIFI = False;
		u8 result = 0;
		
		for(i = 1; i < argc; i++){
			if(strcmp(argv[i],"-i") == 0 && input == NULL && i < argc-1){
				input = argv[i+1];
			}
			else if(strncmp(argv[i],"--image=",8) == 0 && input == NULL){
				input = (char*)(argv[i]+8);
			}
			else if(strcmp(argv[i],"-x") == 0 && output == NULL && i < argc-1 && Extract == False){
				Extract = True;
				output = argv[i+1];
			}
			else if(strncmp(argv[i],"--extract=",10) == 0 && output == NULL && Extract == False){
				Extract = True;
				output = (char*)(argv[i]+10);
			}
			else if(strcmp(argv[i],"-a") == 0 && i < argc-1){
				extdata->OverrideActiveDIFI = True;
				extdata->DIFIPartition = strtol(argv[i+1],NULL,10);
			}
			else if(strncmp(argv[i],"--forcedifi=",12) == 0){
				extdata->OverrideActiveDIFI = True;
				extdata->DIFIPartition = strtol((argv[i]+12),NULL,10);
			}
			else if(strcmp(argv[i],"-p") == 0 || strcmp(argv[i],"--info") == 0){
				extdata->PrintInfo = True;
			}
			else if(strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--verbose") == 0){
				extdata->Verbose = True;
			}
			else if(strcmp(argv[i],"-l") == 0 || strcmp(argv[i],"--listDB") == 0){
				DB_Mode = DB_Normal;
			}
			else if(strcmp(argv[i],"-0") == 0 || strcmp(argv[i],"--listTID") == 0){
				DB_Mode = DB_ByTID;
			}
		}
		
		if(input == NULL){
			printf("[!] No input extdata image was specified\n");
			FreeExtdataContext(extdata);
			help(argv[0]);
			return ARG_ERROR;
		}
		if(Extract == False && extdata->PrintInfo == False && extdata->Verbose == False && DB_Mode == -1){
			printf("[!] Nothing to do\n");
			FreeExtdataContext(extdata);
			help(argv[0]);
			return ARG_ERROR;
		}
		
		if(extdata->OverrideActiveDIFI && extdata->DIFIPartition != 0 && extdata->DIFIPartition != 1){
			printf("[!] Invalid DIFI partition: %d\n",extdata->DIFIPartition);
			FreeExtdataContext(extdata);
			help(argv[0]);
			return ARG_ERROR;
		}
		FILE *fp = fopen(input,"rb");
		if(fp == NULL){
			printf("[!] Failed to open '%s'\n",input);
			FreeExtdataContext(extdata);
			return IO_ERROR;
		}
		fclose(fp);
		extdata->extdata.size = GetFileSize_u64(input);
		extdata->extdata.buffer = malloc(extdata->extdata.size);
		if(extdata->extdata.buffer == NULL){
			printf("[!] Failed to allocate memory for extdata image\n");
			FreeExtdataContext(extdata);
			return MEM_ERROR;
		}
		fp = fopen(input,"rb");
		ReadFile_64(extdata->extdata.buffer,extdata->extdata.size,0,fp);
		fclose(fp);
		result = GetExtdataContext(extdata);
		if(result != 0){
			printf("[!] Failed to interprete extdata image (%d)\n",result);
			FreeExtdataContext(extdata);
			return 1;
		}
		
		if(extdata->Files.Count > 0){
			u8* embedded_data = extdata->extdata.buffer + extdata->Files.Data[0].offset;
		
			// Extracting Data
			if(extdata->Files.Count == 1 && Extract){
				fp = fopen(output,"wb");
				if(fp == NULL){
					printf("[!] Failed to create '%s'\n",output);
					FreeExtdataContext(extdata);
					return IO_ERROR;
				}
				if(extdata->Verbose) printf("[+] Writing data to '%s'\n",output);
				WriteBuffer(embedded_data,extdata->Files.Data[0].size,0,fp);
				fclose(fp);
			}
		
			// Displaying DB... if possible
			if(DB_Mode >= 0){
				if(extdata->ExtdataType == RawIVFC && extdata->Files.Count == 1 && IsTitleDB(embedded_data)){
					result = ProcessTitleDB(embedded_data,DB_Mode);
					if(result){
						printf("[!] Failed to read DB (%d)\n",result);
					}
				}
				else{
					printf("[!] No valid Title Database in extdata\n"); 
				}
			
			}
		}
		else{
			printf("[!] No data exists embedded in extdata\n"); 
		}
		FreeExtdataContext(extdata);
	}
	
	else if(action == fs){
		VSXEContext *vsxe_ctx = malloc(sizeof(VSXEContext));
		ExtdataContext *vsxe = malloc(sizeof(ExtdataContext));
		char *input = NULL;
		char *output = NULL;
		char cwd[IO_PATH_LEN];
		char VSXE_image_path[IO_PATH_LEN];
		memset(vsxe_ctx,0,sizeof(VSXEContext));
		memset(&cwd,0,IO_PATH_LEN);
		memset(&VSXE_image_path,0,IO_PATH_LEN);
		memset(vsxe,0,sizeof(ExtdataContext));
		
		if(getcwdir(cwd,IO_PATH_LEN) == NULL){
			printf("[!] Could not store Current Working Directory\n");
			return IO_ERROR;
		}
		
		
		for(i = 1; i < argc; i++){
			if(strcmp(argv[i],"-d") == 0 && input == NULL && i < argc-1){
				input = argv[i+1];
			}
			else if(strncmp(argv[i],"--FSdir=",8) == 0 && input == NULL){
				input = (char*)(argv[i]+8);
			}
			else if(strcmp(argv[i],"-x") == 0 && output == NULL && i < argc-1){
				vsxe_ctx->Flags[vsxe_extract] = True;
				output = argv[i+1];
			}
			else if(strncmp(argv[i],"--extractFS=",12) == 0 && output == NULL){
				vsxe_ctx->Flags[vsxe_extract] = True;
				output = (char*)(argv[i]+12);
			}
			else if(strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"--showFS") == 0){
				vsxe_ctx->Flags[vsxe_show_fs] = True;
			}
			else if(strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--verbose") == 0){
				vsxe_ctx->Flags[vsxe_verbose] = True;
			}
			else if(strcmp(argv[i],"-f") == 0 || strcmp(argv[i],"--FStable") == 0){
				vsxe_ctx->Flags[vsxe_fstable] = True;
			}
			else if(strcmp(argv[i],"-a") == 0 && i < argc-1){
				vsxe->OverrideActiveDIFI = True;
				vsxe->DIFIPartition = strtol(argv[i+1],NULL,10);
			}
			else if(strncmp(argv[i],"--forcedifi=",12) == 0){
				vsxe->OverrideActiveDIFI = True;
				vsxe->DIFIPartition = strtol((argv[i]+12),NULL,10);
			}
		}
		
		if(input == NULL){
			printf("[!] No Extdata FS directory was specified\n");
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return ARG_ERROR;
		}
		
		if(vsxe_ctx->Flags[vsxe_extract] && output == NULL){
			printf("[!] No Output directory was specified\n");
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return ARG_ERROR;
		}
		
		if(vsxe_ctx->Flags[vsxe_show_fs] == False && vsxe_ctx->Flags[vsxe_extract] == False && vsxe_ctx->Flags[vsxe_fstable] == False){
			printf("[!] Nothing to do\n");
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return ARG_ERROR;
		}
		
#ifdef _WIN32
		vsxe_ctx->platform = WIN_32;
#else
		vsxe_ctx->platform = UNIX;
#endif
		
		// Storing Input Directory
		vsxe_ctx->input = malloc(IO_PATH_LEN);
		if(vsxe_ctx->input == NULL){
			printf("[!] Failed to allocate memory for input path\n");
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return MEM_ERROR;
		}
		chdir(input);
		if(getcwdir(vsxe_ctx->input,IO_PATH_LEN) == NULL){
			printf("[!] Could not store input Directory\n");
			free(vsxe_ctx->input);
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return IO_ERROR;
		}
		chdir(cwd);
		
		// Storing Output Directory
		vsxe_ctx->output = malloc(IO_PATH_LEN);
		if(vsxe_ctx->output == NULL){
			printf("[!] Failed to allocate memory for output path\n");
			free(vsxe_ctx->input);
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return MEM_ERROR;
		}
		chdir(output);
		if(getcwdir(vsxe_ctx->output,IO_PATH_LEN) == NULL){
			printf("[!] Could not store output Directory\n");
			free(vsxe_ctx->input);
			free(vsxe_ctx->output);
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return IO_ERROR;
		}
		chdir(cwd);
		
		// Getting path to VSXE FS Image
		sprintf(VSXE_image_path,"%s%c00000001.dec",vsxe_ctx->input,vsxe_ctx->platform);
		
		FILE *fp = fopen(VSXE_image_path,"rb");
		if(fp == NULL){
			printf("[!] Could not open '%s'\n",VSXE_image_path);
			free(vsxe_ctx->input);
			free(vsxe_ctx->output);
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return IO_ERROR;
		}
		
		fclose(fp);
		vsxe->extdata.size = GetFileSize_u64(VSXE_image_path);
		vsxe->extdata.buffer = malloc(vsxe->extdata.size);
		if(vsxe->extdata.buffer == NULL){
			printf("[!] Failed to allocate memory for VSXE FST Image\n");
			free(vsxe_ctx->input);
			free(vsxe_ctx->output);
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return MEM_ERROR;
		}
		
		// Getting VSXE FST Image
		fp = fopen(VSXE_image_path,"rb");
		ReadFile_64(vsxe->extdata.buffer,vsxe->extdata.size,0,fp);
		fclose(fp);
		
		u8 result = GetExtdataContext(vsxe);
		if(result){
			printf("[!] Failed to obtain VSXE FST from image '%s' (%d)\n",VSXE_image_path,result);
			free(vsxe_ctx->input);
			free(vsxe_ctx->output);
			free(vsxe_ctx);
			FreeExtdataContext(vsxe);
			return result;
		}
		
		if(vsxe->Files.Count > 0){
			u8 *vsxe_offset = vsxe->extdata.buffer + vsxe->Files.Data[0].offset;
			if(vsxe->ExtdataType == RawIVFC && vsxe->Files.Count == 1 && IsVSXEFileSystem(vsxe_offset)){
				vsxe_ctx->vsxe = vsxe_offset;
				result = ProcessExtData_FS(vsxe_ctx);
				if(result){
					printf("[!] Failed to read VSXE FST (%d)\n",result);
				}
			}
			else{
				printf("[!] No valid VSXE FST exists in '%s'\n",output); 
			}
		}
		else{
			printf("[!] No data exists embedded in extdata\n"); 
		}
		free(vsxe_ctx->input);
		free(vsxe_ctx->output);
		free(vsxe_ctx);
		FreeExtdataContext(vsxe);
	}
	
	else if(action == generate){
		// Extdata Gen
		COMPONENT_STRUCT sourcedata;
		memset(&sourcedata,0,sizeof(COMPONENT_STRUCT));
		COMPONENT_STRUCT outdata;
		memset(&outdata,0,sizeof(COMPONENT_STRUCT));
		
		char *input = NULL;
		char *output = NULL;
		char *extdatatype = NULL;
		u32 activeDIFI = 0;
		u8 type = 0;
		u8 Verbose = False;
		u8 UniqueExtdataID[8];
		memset(&UniqueExtdataID,0,8);
		
		u8 GenMAC = False;
		
		for(i = 1; i < argc; i++){
			if(strcmp(argv[i],"-1") == 0 || strcmp(argv[i],"-2") == 0 || strncmp(argv[i],"--keyX=",6) == 0 || strncmp(argv[i],"--keyY=",6) == 0){
				GenMAC = True;
			}
			else if(strcmp(argv[i],"-g") == 0 && input == NULL && i < argc-1){
				input = argv[i+1];
			}
			else if(strncmp(argv[i],"--genextdata=",13) == 0 && input == NULL){
				input = (char*)(argv[i]+13);
			}
			else if(strcmp(argv[i],"-o") == 0 && output == NULL && i < argc-1){
				output = argv[i+1];
			}
			else if(strncmp(argv[i],"--outimage=",11) == 0 && output == NULL){
				output = (char*)(argv[i]+11);
			}
			else if(strcmp(argv[i],"-t") == 0 && extdatatype == NULL && i < argc-1){
				extdatatype = argv[i+1];
			}
			else if(strncmp(argv[i],"--type=",7) == 0 && extdatatype == NULL){
				extdatatype = (char*)(argv[i]+7);
			}
			else if(strcmp(argv[i],"-a") == 0 && i < argc-1){
				activeDIFI = strtol(argv[i+1],NULL,10);
			}
			else if(strncmp(argv[i],"--activedifi=",13) == 0){
				activeDIFI = strtol((argv[i]+13),NULL,10);
			}
			else if(strcmp(argv[i],"-u") == 0 && i < argc-1){
				if(strlen(argv[i+1]) == 16)
					char_to_u8_array(UniqueExtdataID,argv[i+1],8,BE,16);
				else
					printf("[!] Invalid length for Extdata Unique ID (expected 16 hex characters)\n"); 
			}
			else if(strncmp(argv[i],"--uniqueID=",11) == 0){
				if(strlen((argv[i]+11)) == 16)
					char_to_u8_array(UniqueExtdataID,(argv[i]+11),8,BE,16);
				else
					printf("[!] Invalid length for Extdata Unique ID (expected 16 hex characters)\n"); 
			}
			else if(strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--verbose") == 0){
				Verbose = True;
			}
		}
		
		if(input == NULL){
			printf("[!] No input image was specified\n");
			help(argv[0]);
			return ARG_ERROR;
		}
		
		if(output == NULL){
			printf("[!] No output extdata image was specified\n");
			help(argv[0]);
			return ARG_ERROR;
		}
		
		if(extdatatype == NULL){
			printf("[!] No extdata type was specified\n");
			help(argv[0]);
			return ARG_ERROR;
		}
		
		// MAC Gen
		AESMAC_CTX *aes_ctx = malloc(sizeof(AESMAC_CTX));
		memset(aes_ctx,0,sizeof(AESMAC_CTX));
		u8 KeyX[0x10];
		u8 KeyY[0x10];
		memset(&KeyX,0,0x10);
		memset(&KeyY,0,0x10);
		
		aes_ctx->Verbose = Verbose;

		if(strcmp(extdatatype,"DATA") == 0){
			type = BUILD_DATA;
			aes_ctx->type = mac_extdata;	
		}
		else if(strcmp(extdatatype,"FS") == 0){
			type = BUILD_FS;
			aes_ctx->type = mac_extdata;	
		}
		else if(strcmp(extdatatype,"TDB") == 0){
			type = BUILD_DB;
			aes_ctx->type = mac_title_db;	
		}
		else if(strcmp(extdatatype,"IDB") == 0){
			type = BUILD_DB;
			aes_ctx->type = mac_import_db;	
		}
			
		if(type == 0){
			printf("[!] Invalid Extdata type '%s'\n",extdatatype);
			help(argv[0]);
			free(aes_ctx);
			return ARG_ERROR;
		}
			
		if(GenMAC){
			for(i = 1; i < argc; i++){
				if(strcmp(argv[i],"-1") == 0 && i < argc-1){
					if(strlen(argv[i+1]) == 32)
						char_to_u8_array(KeyX,argv[i+1],16,BE,16);
					else{
						printf("[!] Invalid length for KeyX (expected 32 hex characters)\n"); 
						help(argv[0]);
						free(aes_ctx);
						return ARG_ERROR;
					}
				}
				else if(strncmp(argv[i],"--keyX=",7) == 0){
					if(strlen((argv[i]+7)) == 32)
						char_to_u8_array(KeyX,(argv[i]+7),16,BE,16);
					else{
						printf("[!] Invalid length for KeyX (expected 32 hex characters)\n"); 
						help(argv[0]);
						free(aes_ctx);
						return ARG_ERROR;
					}
				}
				else if(strcmp(argv[i],"-2") == 0 && i < argc-1){
					if(strlen(argv[i+1]) == 32)
						char_to_u8_array(KeyY,argv[i+1],16,BE,16);
					else{
						printf("[!] Invalid length for KeyY (expected 32 hex characters)\n"); 
						help(argv[0]);
						free(aes_ctx);
						return ARG_ERROR;
					}
				}
				else if(strncmp(argv[i],"--keyY=",7) == 0){
					if(strlen((argv[i]+7)) == 32)
						char_to_u8_array(KeyY,(argv[i]+7),16,BE,16);
					else{
						printf("[!] Invalid length for KeyY (expected 32 hex characters)\n"); 
						help(argv[0]);
						free(aes_ctx);
						return ARG_ERROR;
					}
				}
				else if(strcmp(argv[i],"-3") == 0 && i < argc-1){
					u32_to_u8(aes_ctx->subdir_id,strtol(argv[i+1],NULL,16),BE);
				}
				else if(strncmp(argv[i],"--SubDirID=",11) == 0){
					u32_to_u8(aes_ctx->subdir_id,strtol((argv[i]+11),NULL,16),BE);
				}
				else if(strcmp(argv[i],"-4") == 0 && i < argc-1){
					u32_to_u8(aes_ctx->image_id,strtol(argv[i+1],NULL,16),BE);				
				}
				else if(strncmp(argv[i],"--ImageID=",10) == 0){
					u32_to_u8(aes_ctx->image_id,strtol((argv[i]+11),NULL,16),BE);
				}
				else if(strcmp(argv[i],"-5") == 0 || strcmp(argv[i],"--IsQuotaDat") == 0){
					aes_ctx->is_quote_dat = 1;
				}
			}
			if(aes_ctx->is_quote_dat == 1){
				memset(aes_ctx->image_id,0,4);
				memset(aes_ctx->subdir_id,0,4);
			}
		}
	
		//Extdata creation
		FILE *outfile = fopen(output,"wb");
		if(outfile == NULL){
			printf("[!] Failed to create '%s'\n",output);
			free(aes_ctx);
			return IO_ERROR;
		}
		FILE *infile = fopen(input,"rb");
		if(infile == NULL){
			printf("[!] Failed to open '%s'\n",input);
			free(aes_ctx);
			free(sourcedata.buffer);
			return IO_ERROR;
		}
		fclose(infile);
		sourcedata.size = GetFileSize_u64(input);
		sourcedata.buffer = malloc(sourcedata.size);
		if(sourcedata.buffer == NULL){
			printf("[!] Failed to allocate memory to generate Extdata\n");
			free(aes_ctx);
			return MEM_ERROR;
		}
		infile = fopen(input,"rb");
		ReadFile_64(sourcedata.buffer,sourcedata.size,0,infile);
		fclose(infile);
		
		u8 result = CreateExtdata(&outdata,&sourcedata,type,activeDIFI,UniqueExtdataID);
		if(result){
			free(aes_ctx);
			free(sourcedata.buffer);
			if(outdata.size > 0){ free(outdata.buffer); }
			return result;
		}
		if(GenMAC){
			if(Verbose) printf("[+] Generating AES MAC\n");
			memcpy(aes_ctx->header,(outdata.buffer+0x100),0x100);
			GenAESMAC(KeyX,KeyY,aes_ctx);
			memcpy(outdata.buffer,aes_ctx->aesmac,16);
		}
		if(Verbose) printf("[+] Writing '%s'\n",output);
		WriteBuffer(outdata.buffer,outdata.size,0,outfile);
		if(outdata.size > 0) free(outdata.buffer);
		if(sourcedata.size > 0)free(sourcedata.buffer);
		free(aes_ctx);
		fclose(outfile);
	}
	return 0;
}
예제 #17
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);
예제 #18
0
int PrepAESMAC(AESMAC_CTX *ctx)
{
	u8 savegame_type[6][8] = {"CTR-EXT0","CTR-SYS0","CTR-NOR0","CTR-SAV0","CTR-SIGN","CTR-9DB0"};
	memset(ctx->hash,0,0x20);
	
	if(ctx->type == 0)
		return Fail;
	else if(ctx->type == mac_import_db){
		db_sha256_block finalblock;
		memset(&finalblock,0,sizeof(db_sha256_block));
		memcpy(finalblock.savegame_type,savegame_type[CTR_9DB0],8);
		u32_to_u8(finalblock.db_id,0x3,LE);
		memcpy(finalblock.diff_header,ctx->header,0x100);
		ctr_sha(&finalblock,sizeof(db_sha256_block),ctx->hash,CTR_SHA_256);
	}
	else if(ctx->type == mac_title_db){
		db_sha256_block finalblock;
		memset(&finalblock,0,sizeof(db_sha256_block));
		memcpy(finalblock.savegame_type,savegame_type[CTR_9DB0],8);
		u32_to_u8(finalblock.db_id,0x2,LE);
		memcpy(finalblock.diff_header,ctx->header,0x100);
		ctr_sha(&finalblock,sizeof(db_sha256_block),ctx->hash,CTR_SHA_256);
	}
	else if(ctx->type == mac_extdata){
		extdata_sha256_block finalblock;
		memset(&finalblock,0,sizeof(extdata_sha256_block));
		memcpy(finalblock.savegame_type,savegame_type[CTR_EXT0],8);
		endian_memcpy(finalblock.image_id,ctx->image_id,4,LE);
		endian_memcpy(finalblock.subdir_id,ctx->subdir_id,4,LE);
		u32_to_u8(finalblock.unknown,ctx->is_quote_dat,LE);
		endian_memcpy(finalblock.image_id_dup,ctx->image_id,4,LE);
		endian_memcpy(finalblock.subdir_id_dup,ctx->subdir_id,4,LE);
		memcpy(finalblock.diff_header,ctx->header,0x100);
		ctr_sha(&finalblock,sizeof(extdata_sha256_block),ctx->hash,CTR_SHA_256);
	}
	else if(ctx->type == mac_sys_save){
		sys_savedata_sha256_block finalblock;
		memset(&finalblock,0,sizeof(sys_savedata_sha256_block));
		memcpy(finalblock.savegame_type,savegame_type[CTR_SYS0],8);
		endian_memcpy(finalblock.save_id,ctx->saveid,8,LE);
		memcpy(finalblock.disa_header,ctx->header,0x100);
		ctr_sha(&finalblock,sizeof(sys_savedata_sha256_block),ctx->hash,CTR_SHA_256);
	}
	else if(ctx->type == mac_sd_save){
		sdcard_savegame_sha256_block finalblock;
		memset(&finalblock,0,sizeof(sdcard_savegame_sha256_block));
		memcpy(finalblock.savegame_type,savegame_type[CTR_SIGN],8);
		endian_memcpy(finalblock.program_id,ctx->programid,8,LE);
		// Generating CTR_SAV0 hash
		ctr_sav0_sha256_block pre_block;
		memset(&pre_block,0,sizeof(ctr_sav0_sha256_block));
		memcpy(pre_block.savegame_type,savegame_type[CTR_SAV0],8);
		memcpy(pre_block.disa_header,ctx->header,0x100);
		ctr_sha(&pre_block,sizeof(ctr_sav0_sha256_block),finalblock.ctr_sav0_block_hash,CTR_SHA_256);
		//
		ctr_sha(&finalblock,sizeof(sdcard_savegame_sha256_block),ctx->hash,CTR_SHA_256);
	}
	else if(ctx->type == mac_card_save){
		gamecard_savegame_sha256_block finalblock;
		memset(&finalblock,0,sizeof(gamecard_savegame_sha256_block));
		memcpy(finalblock.savegame_type,savegame_type[CTR_SAV0],8);
		// Generating CTR_NOR0 hash
		ctr_nor0_sha256_block pre_block;
		memset(&pre_block,0,sizeof(ctr_nor0_sha256_block));
		memcpy(pre_block.savegame_type,savegame_type[CTR_NOR0],8);
		memcpy(pre_block.disa_header,ctx->header,0x100);
		ctr_sha(&pre_block,sizeof(ctr_nor0_sha256_block),finalblock.ctr_nor0_block_hash,CTR_SHA_256);
		//
		ctr_sha(&finalblock,sizeof(gamecard_savegame_sha256_block),ctx->hash,CTR_SHA_256);
	}
	else
		return Fail;
	
	return 0;
}
예제 #19
0
static inline u8 dispatch_t192(t192 a193, u32 a194)
{
    return u32_to_u8(a194);
}