2018-07-27 23:55:23 -04:00
|
|
|
// Copyright 2018 yuzu emulator team
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2018-07-29 19:00:09 -04:00
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <vector>
|
2018-08-04 16:41:17 -04:00
|
|
|
#include "common/common_types.h"
|
2018-07-27 23:55:23 -04:00
|
|
|
#include "core/file_sys/vfs.h"
|
|
|
|
|
2018-07-28 16:23:00 -04:00
|
|
|
namespace Core::Crypto {
|
2018-07-27 23:55:23 -04:00
|
|
|
|
2018-07-29 19:00:09 -04:00
|
|
|
struct CipherContext;
|
|
|
|
|
2018-07-27 23:55:23 -04:00
|
|
|
enum class Mode {
|
2018-07-28 16:23:00 -04:00
|
|
|
CTR = 11,
|
|
|
|
ECB = 2,
|
|
|
|
XTS = 70,
|
2018-07-27 23:55:23 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class Op {
|
2018-07-28 16:23:00 -04:00
|
|
|
Encrypt,
|
|
|
|
Decrypt,
|
2018-07-27 23:55:23 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Key, size_t KeySize = sizeof(Key)>
|
2018-07-28 16:23:00 -04:00
|
|
|
class AESCipher {
|
2018-07-27 23:55:23 -04: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 16:23:00 -04:00
|
|
|
public:
|
|
|
|
AESCipher(Key key, Mode mode);
|
2018-07-27 23:55:23 -04:00
|
|
|
|
2018-07-28 16:23:00 -04:00
|
|
|
~AESCipher();
|
2018-07-27 23:55:23 -04:00
|
|
|
|
2018-07-28 16:23:00 -04:00
|
|
|
void SetIV(std::vector<u8> iv);
|
2018-07-27 23:55:23 -04:00
|
|
|
|
|
|
|
template <typename Source, typename Dest>
|
|
|
|
void Transcode(const Source* src, size_t size, Dest* dest, Op op) {
|
2018-07-28 16:23:00 -04:00
|
|
|
Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op);
|
2018-07-27 23:55:23 -04:00
|
|
|
}
|
|
|
|
|
2018-07-28 16:23:00 -04:00
|
|
|
void Transcode(const u8* src, size_t size, u8* dest, Op op);
|
|
|
|
|
2018-07-27 23:55:23 -04:00
|
|
|
template <typename Source, typename Dest>
|
|
|
|
void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id,
|
|
|
|
size_t sector_size, Op op) {
|
2018-07-28 21:39:42 -04:00
|
|
|
XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id,
|
|
|
|
sector_size, op);
|
2018-07-27 23:55:23 -04:00
|
|
|
}
|
|
|
|
|
2018-07-28 21:39:42 -04:00
|
|
|
void XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size,
|
|
|
|
Op op);
|
2018-07-28 16:23:00 -04:00
|
|
|
|
2018-07-27 23:55:23 -04:00
|
|
|
private:
|
2018-07-28 21:39:42 -04:00
|
|
|
std::unique_ptr<CipherContext> ctx;
|
2018-07-28 16:23:00 -04:00
|
|
|
|
|
|
|
static std::vector<u8> CalculateNintendoTweak(size_t sector_id);
|
2018-07-27 23:55:23 -04:00
|
|
|
};
|
2018-07-28 21:39:42 -04:00
|
|
|
} // namespace Core::Crypto
|