// SPDX-License-Identifier: MPL-2.0 // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) #pragma once #include #include namespace skyline::crypto { /** * @brief Wrapper for mbedtls for AES decryption using a cipher * @note The IV state must be appropriately locked during multi-threaded usage */ class AesCipher { private: mbedtls_cipher_context_t decryptContext; std::vector buffer; //!< A buffer used to avoid constant memory allocation /** * @brief Calculates IV for XTS, basically just big to little endian conversion */ static std::array GetTweak(size_t sector) { std::array tweak{}; size_t le{util::SwapEndianness(sector)}; std::memcpy(tweak.data() + 8, &le, 8); return tweak; } public: AesCipher(span key, mbedtls_cipher_type_t type); ~AesCipher(); /** * @brief Sets the Initialization Vector */ void SetIV(const std::array &iv); /** * @brief Decrypts the supplied buffer and outputs the result into the destination buffer * @note The destination and source buffers can be the same */ void Decrypt(u8 *destination, u8 *source, size_t size); /** * @brief Decrypts the supplied data in-place */ void Decrypt(span data) { Decrypt(data.data(), data.data(), data.size()); } /** * @brief Decrypts data with XTS, IV will get calculated with the given sector */ void XtsDecrypt(u8 *destination, u8 *source, size_t size, size_t sector, size_t sectorSize); /** * @brief Decrypts data with XTS and writes back to it */ void XtsDecrypt(span data, size_t sector, size_t sectorSize) { XtsDecrypt(data.data(), data.data(), data.size(), sector, sectorSize); } }; }