/*
* 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 .
*/
#include
#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) {
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) {
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));
return impl::LoadAesKey(keyslot, access_key, key_source);
}
Result SecureMonitorManager::GenerateAesKey(AesKey *out_key, const AccessKey &access_key, const KeySource &key_source) {
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) {
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) {
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) {
return impl::GetConfig(out, key);
}
Result SecureMonitorManager::SetConfig(spl::ConfigItem key, u64 value) {
return impl::SetConfig(key, value);
}
Result SecureMonitorManager::GetPackage2Hash(void *dst, const size_t size) {
return impl::GetPackage2Hash(dst, size);
}
Result SecureMonitorManager::GenerateRandomBytes(void *out, size_t size) {
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) {
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) {
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) {
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) {
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) {
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) {
return impl::ModularExponentiateWithDrmDeviceCertKey(out, out_size, base, base_size, mod, mod_size);
}
Result SecureMonitorManager::IsDevelopment(bool *out) {
return impl::IsDevelopment(out);
}
Result SecureMonitorManager::GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which) {
return impl::GenerateSpecificAesKey(out_key, key_source, generation, which);
}
Result SecureMonitorManager::DecryptAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 option) {
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));
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));
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) {
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) {
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) {
return impl::PrepareEsArchiveKey(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) {
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));
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;
return ResultSuccess();
}
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;
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) {
return impl::SetBootReason(boot_reason);
}
Result SecureMonitorManager::GetBootReason(BootReasonValue *out) {
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;
}
return ResultSuccess();
}
}