2018-07-28 05:55:23 +02:00
|
|
|
// Copyright 2018 yuzu emulator team
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2018-07-30 01:00:09 +02:00
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
2018-08-04 22:41:17 +02:00
|
|
|
#include "common/common_types.h"
|
2018-07-28 05:55:23 +02:00
|
|
|
#include "core/file_sys/vfs.h"
|
|
|
|
|
2018-07-28 22:23:00 +02:00
|
|
|
namespace Core::Crypto {
|
2018-07-28 05:55:23 +02:00
|
|
|
|
2018-07-30 01:00:09 +02:00
|
|
|
struct CipherContext;
|
|
|
|
|
2018-07-28 05:55:23 +02:00
|
|
|
enum class Mode {
|
2018-07-28 22:23:00 +02:00
|
|
|
CTR = 11,
|
|
|
|
ECB = 2,
|
|
|
|
XTS = 70,
|
2018-07-28 05:55:23 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class Op {
|
2018-07-28 22:23:00 +02:00
|
|
|
Encrypt,
|
|
|
|
Decrypt,
|
2018-07-28 05:55:23 +02:00
|
|
|
};
|
|
|
|
|
2018-09-15 15:21:06 +02:00
|
|
|
template <typename Key, std::size_t KeySize = sizeof(Key)>
|
2018-07-28 22:23:00 +02:00
|
|
|
class AESCipher {
|
2018-07-28 05:55:23 +02:00
|
|
|
static_assert(std::is_same_v<Key, std::array<u8, KeySize>>, "Key must be std::array of u8.");
|
|
|
|
static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256.");
|
|
|
|
|
2018-07-28 22:23:00 +02:00
|
|
|
public:
|
|
|
|
AESCipher(Key key, Mode mode);
|
|
|
|
~AESCipher();
|
2018-07-28 05:55:23 +02:00
|
|
|
|
2020-08-03 20:14:39 +02:00
|
|
|
template <typename ContiguousContainer>
|
|
|
|
void SetIV(const ContiguousContainer& container) {
|
|
|
|
SetIVImpl(std::data(container), std::size(container));
|
|
|
|
}
|
2018-07-28 05:55:23 +02:00
|
|
|
|
|
|
|
template <typename Source, typename Dest>
|
2018-09-15 15:21:06 +02:00
|
|
|
void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const {
|
2018-08-04 22:56:26 +02:00
|
|
|
static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
|
|
|
|
"Transcode source and destination types must be trivially copyable.");
|
2018-07-28 22:23:00 +02:00
|
|
|
Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op);
|
2018-07-28 05:55:23 +02:00
|
|
|
}
|
|
|
|
|
2018-09-15 15:21:06 +02:00
|
|
|
void Transcode(const u8* src, std::size_t size, u8* dest, Op op) const;
|
2018-07-28 22:23:00 +02:00
|
|
|
|
2018-07-28 05:55:23 +02:00
|
|
|
template <typename Source, typename Dest>
|
2018-09-15 15:21:06 +02:00
|
|
|
void XTSTranscode(const Source* src, std::size_t size, Dest* dest, std::size_t sector_id,
|
|
|
|
std::size_t sector_size, Op op) {
|
2018-08-04 22:56:26 +02:00
|
|
|
static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
|
|
|
|
"XTSTranscode source and destination types must be trivially copyable.");
|
2018-07-29 03:39:42 +02:00
|
|
|
XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id,
|
|
|
|
sector_size, op);
|
2018-07-28 05:55:23 +02:00
|
|
|
}
|
|
|
|
|
2018-09-15 15:21:06 +02:00
|
|
|
void XTSTranscode(const u8* src, std::size_t size, u8* dest, std::size_t sector_id,
|
|
|
|
std::size_t sector_size, Op op);
|
2018-07-28 22:23:00 +02:00
|
|
|
|
2018-07-28 05:55:23 +02:00
|
|
|
private:
|
2020-08-03 20:14:39 +02:00
|
|
|
void SetIVImpl(const u8* data, std::size_t size);
|
|
|
|
|
2018-07-29 03:39:42 +02:00
|
|
|
std::unique_ptr<CipherContext> ctx;
|
2018-07-28 05:55:23 +02:00
|
|
|
};
|
2018-07-29 03:39:42 +02:00
|
|
|
} // namespace Core::Crypto
|