void cia_save_blob(cia_context *ctx, char *out_path, u32 offset, u32 size, int do_cbc) { FILE *fout = 0; u8 buffer[16*1024]; fseek(ctx->file, ctx->offset + offset, SEEK_SET); fout = fopen(out_path, "wb"); if (fout == NULL) { fprintf(stdout, "Error opening out file %s\n", out_path); goto clean; } while(size) { u32 max = sizeof(buffer); if (max > size) max = size; if (max != fread(buffer, 1, max, ctx->file)) { fprintf(stdout, "Error reading file\n"); goto clean; } if (do_cbc == 1) ctr_decrypt_cbc(&ctx->aes, buffer, buffer, max); if (max != fwrite(buffer, 1, max, fout)) { fprintf(stdout, "Error writing file\n"); goto clean; } size -= max; } clean: if (fout) fclose(fout); }
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++; }
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); } }