Esempio n. 1
0
void cia_verify_contents(cia_context *ctx, u32 actions)
{
	u16 contentflags;
	ctr_tmd_body *body;
	ctr_tmd_contentchunk *chunk;
	u8 *verify_buf;
	u32 content_size=0;
	int i;

	// verify TMD content hashes, requires decryption ..
	body  = tmd_get_body(&ctx->tmd);
	chunk = (ctr_tmd_contentchunk*)(body->contentinfo + (sizeof(ctr_tmd_contentinfo) * TMD_MAX_CONTENTS));

	fseek(ctx->file, ctx->offset + ctx->offsetcontent, SEEK_SET);
	for(i = 0; i < getbe16(body->contentcount); i++) 
	{
		content_size = getbe64(chunk->size) & 0xffffffff;

		contentflags = getbe16(chunk->type);

		verify_buf = malloc(content_size);
		fread(verify_buf, content_size, 1, ctx->file);

		if(contentflags & 1 && !(actions & PlainFlag)) // Decrypt if needed
		{
			ctx->iv[0] = (getbe16(chunk->index) >> 8) & 0xff;
			ctx->iv[1] = getbe16(chunk->index) & 0xff;

			ctr_init_cbc_decrypt(&ctx->aes, ctx->titlekey, ctx->iv);
		
			ctr_decrypt_cbc(&ctx->aes, verify_buf, verify_buf, content_size);
		}

		if (ctr_sha_256_verify(verify_buf, content_size, chunk->hash) == Good)
			ctx->tmd.content_hash_stat[i] = 1;
		else
			ctx->tmd.content_hash_stat[i] = 2;

		free(verify_buf);

		chunk++;
	}
Esempio n. 2
0
void tik_decrypt_titlekey(tik_context* ctx, u8 decryptedkey[0x10]) 
{
	u8 iv[16];
	u8* keyX = settings_get_common_keyX(ctx->usersettings);
	u8* keyY = settings_get_common_keyY(ctx->usersettings, ctx->tik.commonkey_idx);
	u8 key[16];

	memset(decryptedkey, 0, 0x10);

	if (!keyX)
	{
		fprintf(stdout, "Warning, could not read common key.\n");
	}
	else
	{
		ctr_aes_keygen(keyX, keyY, key);
		memset(iv, 0, 0x10);
		memcpy(iv, ctx->tik.title_id, 8);

		ctr_init_cbc_decrypt(&ctx->aes, key, iv);
		ctr_decrypt_cbc(&ctx->aes, ctx->tik.encrypted_title_key, decryptedkey, 0x10);
	}
}
Esempio n. 3
0
void cia_save(cia_context* ctx, u32 type, u32 flags)
{
	u32 offset;
	u32 size;
	u16 contentflags;
	u8 docrypto;
	filepath* path = 0;
	ctr_tmd_body *body;
	ctr_tmd_contentchunk *chunk;
	int i;
	char tmpname[255];

	switch(type)
	{
		case CIATYPE_CERTS:
			offset = ctx->offsetcerts;
			size = ctx->sizecert;
			path = settings_get_certs_path(ctx->usersettings);
		break;

		case CIATYPE_TIK:
			offset = ctx->offsettik;
			size = ctx->sizetik;
			path = settings_get_tik_path(ctx->usersettings);
		break;

		case CIATYPE_TMD:
			offset = ctx->offsettmd;
			size = ctx->sizetmd;
			path = settings_get_tmd_path(ctx->usersettings);
		break;
		
		case CIATYPE_CONTENT:
			offset = ctx->offsetcontent;
			size = ctx->sizecontent;
			path = settings_get_content_path(ctx->usersettings);
			
		break;

		case CIATYPE_META:
			offset = ctx->offsetmeta;
			size = ctx->sizemeta;
			path = settings_get_meta_path(ctx->usersettings);;
		break;

		default:
			fprintf(stderr, "Error, unknown CIA type specified\n");
			return;	
		break;
	}

	if (path == 0 || path->valid == 0)
		return;

	switch(type)
	{
		case CIATYPE_CERTS: fprintf(stdout, "Saving certs to %s\n", path->pathname); break;
		case CIATYPE_TIK: fprintf(stdout, "Saving tik to %s\n", path->pathname); break;
		case CIATYPE_TMD: fprintf(stdout, "Saving tmd to %s\n", path->pathname); break;
		case CIATYPE_CONTENT:

			body  = tmd_get_body(&ctx->tmd);
			chunk = (ctr_tmd_contentchunk*)(body->contentinfo + (sizeof(ctr_tmd_contentinfo) * TMD_MAX_CONTENTS));

			for(i = 0; i < getbe16(body->contentcount); i++) {
				sprintf(tmpname, "%s.%04x.%08x", path->pathname, getbe16(chunk->index), getbe32(chunk->id));
				fprintf(stdout, "Saving content #%04x to %s\n", getbe16(chunk->index), tmpname);
				
				contentflags = getbe16(chunk->type);
				docrypto = contentflags & 1 && !(flags & PlainFlag);

				if(docrypto) // Decrypt if needed
				{
					ctx->iv[0] = (getbe16(chunk->index) >> 8) & 0xff;
					ctx->iv[1] = getbe16(chunk->index) & 0xff;

					ctr_init_cbc_decrypt(&ctx->aes, ctx->titlekey, ctx->iv);
				}

				cia_save_blob(ctx, tmpname, offset, getbe64(chunk->size) & 0xffffffff, docrypto);

				offset += getbe64(chunk->size) & 0xffffffff;
				chunk++;
			}

			memset(ctx->iv, 0, 16);

			return;
		break;

		case CIATYPE_META: fprintf(stdout, "Saving meta to %s\n", path->pathname); break;
	}

	cia_save_blob(ctx, path->pathname, offset, size, 0);
}