// Copyright 2022 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include "core/hle/service/nfc/nfc_types.h" namespace CryptoPP { class SHA256; template class HMAC; } // namespace CryptoPP namespace HW::AES { struct NfcSecret; } // namespace HW::AES namespace Service::NFC::AmiiboCrypto { // Byte locations in Service::NFC::NTAG215File constexpr std::size_t HMAC_DATA_START = 0x8; constexpr std::size_t SETTINGS_START = 0x2c; constexpr std::size_t WRITE_COUNTER_START = 0x29; constexpr std::size_t HMAC_TAG_START = 0x1B4; constexpr std::size_t UUID_START = 0x1D4; constexpr std::size_t DYNAMIC_LOCK_START = 0x208; using DrgbOutput = std::array; struct HashSeed { u16_be magic; std::array padding; UniqueSerialNumber uid_1; u8 nintendo_id_1; UniqueSerialNumber uid_2; u8 nintendo_id_2; std::array keygen_salt; }; static_assert(sizeof(HashSeed) == 0x40, "HashSeed is an invalid size"); struct CryptoCtx { std::array buffer; bool used; std::size_t buffer_size; s16 counter; }; struct DerivedKeys { std::array aes_key; std::array aes_iv; std::array hmac_key; }; static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size"); /// Validates that the amiibo file is not corrupted bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); /// Validates that the amiibo file is not corrupted bool IsAmiiboValid(const NTAG215File& ntag_file); /// Converts from encrypted file format to encoded file format NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); /// Converts from encoded file format to encrypted file format EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data); // Generates Seed needed for key derivation HashSeed GetSeed(const NTAG215File& data); // Middle step on the generation of derived keys std::vector GenerateInternalKey(const HW::AES::NfcSecret& secret, const HashSeed& seed); // Initializes mbedtls context void CryptoInit(CryptoCtx& ctx, CryptoPP::HMAC& hmac_ctx, std::span hmac_key, std::span seed); // Feeds data to mbedtls context to generate the derived key void CryptoStep(CryptoCtx& ctx, CryptoPP::HMAC& hmac_ctx, DrgbOutput& output); // Generates the derived key from amiibo data DerivedKeys GenerateKey(const HW::AES::NfcSecret& secret, const NTAG215File& data); // Encodes or decodes amiibo data void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& out_data); /// Decodes encripted amiibo data returns true if output is valid bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data); /// Encodes plain amiibo data returns true if output is valid bool EncodeAmiibo(const NTAG215File& tag_data, EncryptedNTAG215File& encrypted_tag_data); } // namespace Service::NFC::AmiiboCrypto