Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add support for Personalised eTickets #102

Open
jakcron opened this issue Jun 4, 2023 · 0 comments
Open

[Feature] Add support for Personalised eTickets #102

jakcron opened this issue Jun 4, 2023 · 0 comments

Comments

@jakcron
Copy link
Owner

jakcron commented Jun 4, 2023

About

NSTool doesn't currently support personalised tickets, these are generated for paid content usually, and are locked to the device they were downloaded on.

Can support for this please be added to:

  • processing tickets directly
  • implicitly processing tickets to decrypt NCAs

Technical Details

Ticket Data

Only the Ticket Body is different, for reference included here:

struct sTicketBody_v2
{
	tc::bn::string<ticket::kIssuerSize> issuer;
	std::array<byte_t, ticket::kEncTitleKeySize> enc_title_key;
	byte_t format_version;
	byte_t title_key_enc_type;
	tc::bn::le16<uint16_t> ticket_version;
	byte_t license_type;
	byte_t common_key_id;
	tc::bn::bitarray<sizeof(uint16_t)> property_mask;
	std::array<byte_t, ticket::kReservedRegionSize> reserved_region; // explicitly reserved
	tc::bn::le64<uint64_t> ticket_id;
	tc::bn::le64<uint64_t> device_id;
	std::array<byte_t, ticket::kRightsIdSize> rights_id;
	tc::bn::le32<uint32_t> account_id;
	tc::bn::le32<uint32_t> sect_total_size;
	tc::bn::le32<uint32_t> sect_header_offset;
	tc::bn::le16<uint16_t> sect_num;
	tc::bn::le16<uint16_t> sect_entry_size;
};

When comparing personalised tickets with common tickets, these are the differences:

  • title_key_enc_type == 1
  • enc_title_key has an RSA2048-OAEP-SHA2256 encryption layer on top of the regular AES128-CBC, this RSA key is device specific, and is required
    • No label is used for the OAEP layer.
  • account_id should be non-zero
    • I believe this links it to the originating Nintendo Account
  • device_id should be non-zero
    • My understanding is each Nintendo Switch has it's own unique eTicket Personalisation RSA key
    • The device ID links the ticket to originating Nintendo Switch, and may be usable for selecting the correct Device RSA key if multiple are loaded at once into NSTool Key Manager.

How does the user get the RSA key?

Currently if the user generates prod.keys using LockPick_RCM, the RSA Key Pair is dumped with the name eticket_rsa_keypair.

It appears to be the raw decrypted structure from the Switch OS:

{
	std::array<byte_t, 0x100> private_exponent;
	std::array<byte_t, 0x100> modulus;
	std::array<byte_t, 0x004> public_exponent;
	tc::bn::pad<0xC>          reserved;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant