Atmosphere/stratosphere/spl/source/spl_secure_monitor_manager.cpp
2024-03-29 02:41:14 -07:00

201 lines
9.8 KiB
C++

/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "spl_secure_monitor_manager.hpp"
namespace ams::spl {
void SecureMonitorManager::Initialize() {
return impl::Initialize();
}
Result SecureMonitorManager::ModularExponentiate(void *out, size_t out_size, const void *base, size_t base_size, const void *exp, size_t exp_size, const void *mod, size_t mod_size) {
R_RETURN(impl::ModularExponentiate(out, out_size, base, base_size, exp, exp_size, mod, mod_size));
}
Result SecureMonitorManager::GenerateAesKek(AccessKey *out_access_key, const KeySource &key_source, u32 generation, u32 option) {
R_RETURN(impl::GenerateAesKek(out_access_key, key_source, generation, option));
}
Result SecureMonitorManager::LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source) {
R_TRY(this->TestAesKeySlot(nullptr, keyslot, owner));
R_RETURN(impl::LoadAesKey(keyslot, access_key, key_source));
}
Result SecureMonitorManager::GenerateAesKey(AesKey *out_key, const AccessKey &access_key, const KeySource &key_source) {
R_RETURN(impl::GenerateAesKey(out_key, access_key, key_source));
}
Result SecureMonitorManager::DecryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
R_RETURN(impl::DecryptDeviceUniqueData(dst, dst_size, src, src_size, access_key, key_source, option));
}
Result SecureMonitorManager::ReencryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option) {
R_RETURN(impl::ReencryptDeviceUniqueData(dst, dst_size, src, src_size, access_key_dec, source_dec, access_key_enc, source_enc, option));
}
Result SecureMonitorManager::GetConfig(u64 *out, spl::ConfigItem key) {
R_RETURN(impl::GetConfig(out, key));
}
Result SecureMonitorManager::SetConfig(spl::ConfigItem key, u64 value) {
R_RETURN(impl::SetConfig(key, value));
}
Result SecureMonitorManager::GetPackage2Hash(void *dst, const size_t size) {
R_RETURN(impl::GetPackage2Hash(dst, size));
}
Result SecureMonitorManager::GenerateRandomBytes(void *out, size_t size) {
R_RETURN(impl::GenerateRandomBytes(out, size));
}
Result SecureMonitorManager::DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
R_RETURN(impl::DecryptAndStoreGcKey(src, src_size, access_key, key_source, option));
}
Result SecureMonitorManager::DecryptGcMessage(u32 *out_size, void *dst, size_t dst_size, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size) {
R_RETURN(impl::DecryptGcMessage(out_size, dst, dst_size, base, base_size, mod, mod_size, label_digest, label_digest_size));
}
Result SecureMonitorManager::DecryptAndStoreSslClientCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
R_RETURN(impl::DecryptAndStoreSslClientCertKey(src, src_size, access_key, key_source));
}
Result SecureMonitorManager::ModularExponentiateWithSslClientCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
R_RETURN(impl::ModularExponentiateWithSslClientCertKey(out, out_size, base, base_size, mod, mod_size));
}
Result SecureMonitorManager::DecryptAndStoreDrmDeviceCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
R_RETURN(impl::DecryptAndStoreDrmDeviceCertKey(src, src_size, access_key, key_source));
}
Result SecureMonitorManager::ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
R_RETURN(impl::ModularExponentiateWithDrmDeviceCertKey(out, out_size, base, base_size, mod, mod_size));
}
Result SecureMonitorManager::IsDevelopment(bool *out) {
R_RETURN(impl::IsDevelopment(out));
}
Result SecureMonitorManager::GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which) {
R_RETURN(impl::GenerateSpecificAesKey(out_key, key_source, generation, which));
}
Result SecureMonitorManager::DecryptAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 option) {
R_RETURN(impl::DecryptAesKey(out_key, key_source, generation, option));
}
Result SecureMonitorManager::ComputeCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr) {
R_TRY(this->TestAesKeySlot(nullptr, keyslot, owner));
R_RETURN(impl::ComputeCtr(dst, dst_size, keyslot, src, src_size, iv_ctr));
}
Result SecureMonitorManager::ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size) {
R_TRY(this->TestAesKeySlot(nullptr, keyslot, owner));
R_RETURN(impl::ComputeCmac(out_cmac, keyslot, data, size));
}
Result SecureMonitorManager::LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
R_RETURN(impl::LoadEsDeviceKey(src, src_size, access_key, key_source, option));
}
Result SecureMonitorManager::PrepareEsTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
R_RETURN(impl::PrepareEsTitleKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation));
}
Result SecureMonitorManager::PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
R_RETURN(impl::PrepareEsArchiveKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation));
}
Result SecureMonitorManager::PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
R_RETURN(impl::PrepareEsUnknown2Key(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation));
}
Result SecureMonitorManager::PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) {
R_RETURN(impl::PrepareCommonEsTitleKey(out_access_key, key_source, generation));
}
Result SecureMonitorManager::LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
R_TRY(this->TestAesKeySlot(nullptr, keyslot, owner));
R_RETURN(impl::LoadPreparedAesKey(keyslot, access_key));
}
Result SecureMonitorManager::AllocateAesKeySlot(s32 *out_keyslot, const void *owner) {
/* Allocate a new virtual keyslot. */
s32 keyslot;
R_TRY(impl::AllocateAesKeySlot(std::addressof(keyslot)));
/* Get the keyslot's index. */
s32 index;
bool virt;
R_ABORT_UNLESS(impl::TestAesKeySlot(std::addressof(index), std::addressof(virt), keyslot));
/* All allocated keyslots must be virtual. */
AMS_ABORT_UNLESS(virt);
m_aes_keyslot_owners[index] = owner;
*out_keyslot = keyslot;
R_SUCCEED();
}
Result SecureMonitorManager::DeallocateAesKeySlot(s32 keyslot, const void *owner) {
s32 index;
R_TRY(this->TestAesKeySlot(std::addressof(index), keyslot, owner));
m_aes_keyslot_owners[index] = nullptr;
R_RETURN(impl::DeallocateAesKeySlot(keyslot));
}
void SecureMonitorManager::DeallocateAesKeySlots(const void *owner) {
for (auto i = 0; i < impl::AesKeySlotCount; ++i) {
if (m_aes_keyslot_owners[i] == owner) {
m_aes_keyslot_owners[i] = nullptr;
impl::DeallocateAesKeySlot(impl::AesKeySlotMin + i);
}
}
}
Result SecureMonitorManager::SetBootReason(BootReasonValue boot_reason) {
R_RETURN(impl::SetBootReason(boot_reason));
}
Result SecureMonitorManager::GetBootReason(BootReasonValue *out) {
R_RETURN(impl::GetBootReason(out));
}
os::SystemEvent *SecureMonitorManager::GetAesKeySlotAvailableEvent() {
return impl::GetAesKeySlotAvailableEvent();
}
Result SecureMonitorManager::TestAesKeySlot(s32 *out_index, s32 keyslot, const void *owner) {
/* Validate the keyslot (and get the index). */
s32 index;
bool virt;
R_TRY(impl::TestAesKeySlot(std::addressof(index), std::addressof(virt), keyslot));
/* Check that the keyslot is physical (for legacy compat) or owned by the request maker. */
R_UNLESS(!virt || m_aes_keyslot_owners[index] == owner, spl::ResultInvalidKeySlot());
/* Set output index. */
if (out_index != nullptr) {
*out_index = index;
}
R_SUCCEED();
}
}