mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-20 07:22:21 +02:00
sf: convert spl to new format
This commit is contained in:
parent
fb3b29516c
commit
4a3a6dec29
@ -16,6 +16,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "spl/spl_types.hpp"
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
#include "spl/spl_api.hpp"
|
#include <stratosphere/spl/spl_api.hpp>
|
||||||
#include "spl/smc/spl_smc.hpp"
|
#include <stratosphere/spl/smc/spl_smc.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_random_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_deprecated_general_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_general_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_crypto_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_device_unique_data_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_ssl_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_es_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_manu_interface.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_fs_interface.hpp>
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_general_interface.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_CRYPTO_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SPL_I_GENERAL_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 2, Result, GenerateAesKek, (sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, LoadAesKey, (s32 keyslot, AccessKey access_key, KeySource key_source)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 4, Result, GenerateAesKey, (sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 14, Result, DecryptAesKey, (sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 15, Result, ComputeCtr, (const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 16, Result, ComputeCmac, (sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 21, Result, AllocateAesKeySlot, (sf::Out<s32> out_keyslot)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 22, Result, DeallocateAesKeySlot, (s32 keyslot)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 23, Result, GetAesKeySlotAvailableEvent, (sf::OutCopyHandle out_hnd))
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(ICryptoInterface, AMS_SPL_I_CRYPTO_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_DEPRECATED_GENERAL_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 0, Result, GetConfig, (sf::Out<u64> out, u32 which)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 1, Result, ModularExponentiate, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 2, Result, GenerateAesKek, (sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 3, Result, LoadAesKey, (s32 keyslot, AccessKey access_key, KeySource key_source)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 4, Result, GenerateAesKey, (sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 5, Result, SetConfig, (u32 which, u64 value)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 7, Result, GenerateRandomBytes, (const sf::OutPointerBuffer &out)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 9, Result, DecryptAndStoreGcKey, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 10, Result, DecryptGcMessage, (sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 11, Result, IsDevelopment, (sf::Out<bool> is_dev)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 12, Result, GenerateSpecificAesKey, (sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 13, Result, DecryptDeviceUniqueData, (const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 14, Result, DecryptAesKey, (sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 15, Result, ComputeCtrDeprecated, (const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr), hos::Version_1_0_0, hos::Version_1_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 15, Result, ComputeCtr, (const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr), hos::Version_2_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 16, Result, ComputeCmac, (sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 17, Result, LoadEsDeviceKey, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 18, Result, PrepareEsTitleKeyDeprecated, (sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest), hos::Version_1_0_0, hos::Version_2_3_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 18, Result, PrepareEsTitleKey, (sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation), hos::Version_3_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 19, Result, LoadPreparedAesKey, (s32 keyslot, AccessKey access_key)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 20, Result, PrepareCommonEsTitleKeyDeprecated, (sf::Out<AccessKey> out_access_key, KeySource key_source), hos::Version_2_0_0, hos::Version_2_3_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 20, Result, PrepareCommonEsTitleKey, (sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation), hos::Version_3_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 22, Result, DeallocateAesKeySlot, (s32 keyslot)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 23, Result, GetAesKeySlotAvailableEvent, (sf::OutCopyHandle out_hnd)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 24, Result, SetBootReason, (spl::BootReasonValue boot_reason), hos::Version_3_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 25, Result, GetBootReason, (sf::Out<spl::BootReasonValue> out), hos::Version_3_0_0)
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IDeprecatedGeneralInterface, AMS_SPL_I_DEPRECATED_GENERAL_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_crypto_interface.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_DEVICE_UNIQUE_DATA_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SPL_I_CRYPTO_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 13, Result, DecryptDeviceUniqueDataDeprecated, (const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option), hos::Version_Min, hos::Version_4_1_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 13, Result, DecryptDeviceUniqueData, (const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source), hos::Version_5_0_0)
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IDeviceUniqueDataInterface, AMS_SPL_I_DEVICE_UNIQUE_DATA_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_device_unique_data_interface.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_ES_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SPL_I_DEVICE_UNIQUE_DATA_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 17, Result, LoadEsDeviceKeyDeprecated, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option), hos::Version_Min, hos::Version_4_1_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 17, Result, LoadEsDeviceKey, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source), hos::Version_5_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 18, Result, PrepareEsTitleKey, (sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 20, Result, PrepareCommonEsTitleKey, (sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation), hos::Version_2_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 28, Result, DecryptAndStoreDrmDeviceCertKey, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source), hos::Version_5_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 29, Result, ModularExponentiateWithDrmDeviceCertKey, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod), hos::Version_5_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 31, Result, PrepareEsArchiveKey, (sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation), hos::Version_6_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 32, Result, LoadPreparedAesKey, (s32 keyslot, AccessKey access_key), hos::Version_6_0_0)
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IEsInterface, AMS_SPL_I_ES_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_crypto_interface.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_FS_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SPL_I_CRYPTO_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 9, Result, DecryptAndStoreGcKeyDeprecated, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option), hos::Version_Min, hos::Version_4_1_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 9, Result, DecryptAndStoreGcKey, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source), hos::Version_5_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 10, Result, DecryptGcMessage, (sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 12, Result, GenerateSpecificAesKey, (sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 19, Result, LoadPreparedAesKey, (s32 keyslot, AccessKey access_key)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 31, Result, GetPackage2Hash, (const sf::OutPointerBuffer &dst), hos::Version_5_0_0)
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IFsInterface, AMS_SPL_I_FS_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_GENERAL_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 0, Result, GetConfig, (sf::Out<u64> out, u32 which)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 1, Result, ModularExponentiate, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 5, Result, SetConfig, (u32 which, u64 value)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 7, Result, GenerateRandomBytes, (const sf::OutPointerBuffer &out)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 11, Result, IsDevelopment, (sf::Out<bool> is_dev)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 24, Result, SetBootReason, (spl::BootReasonValue boot_reason), hos::Version_3_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 25, Result, GetBootReason, (sf::Out<spl::BootReasonValue> out), hos::Version_3_0_0)
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IGeneralInterface, AMS_SPL_I_GENERAL_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_device_unique_data_interface.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_MANU_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SPL_I_DEVICE_UNIQUE_DATA_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 30, Result, ReencryptDeviceUniqueData, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option)) \
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IManuInterface, AMS_SPL_I_MANU_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_RANDOM_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 0, Result, GenerateRandomBytes, (const sf::OutBuffer &out))
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(IRandomInterface, AMS_SPL_I_RANDOM_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <vapours.hpp>
|
||||||
|
#include <stratosphere/sf.hpp>
|
||||||
|
#include <stratosphere/spl/spl_types.hpp>
|
||||||
|
#include <stratosphere/spl/impl/spl_device_unique_data_interface.hpp>
|
||||||
|
|
||||||
|
namespace ams::spl::impl {
|
||||||
|
|
||||||
|
#define AMS_SPL_I_SSL_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SPL_I_DEVICE_UNIQUE_DATA_INTERFACE_INTERFACE_INFO(C, H) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 26, Result, DecryptAndStoreSslClientCertKey, (const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source), hos::Version_5_0_0) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 27, Result, ModularExponentiateWithSslClientCertKey, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod), hos::Version_5_0_0)
|
||||||
|
|
||||||
|
AMS_SF_DEFINE_INTERFACE(ISslInterface, AMS_SPL_I_SSL_INTERFACE_INTERFACE_INFO)
|
||||||
|
|
||||||
|
}
|
@ -20,54 +20,47 @@
|
|||||||
namespace ams::spl::smc {
|
namespace ams::spl::smc {
|
||||||
|
|
||||||
/* Helpers for converting arguments. */
|
/* Helpers for converting arguments. */
|
||||||
inline u32 GetCryptAesMode(CipherMode mode, u32 keyslot) {
|
inline u32 GetComputeAesMode(CipherMode mode, u32 keyslot) {
|
||||||
return static_cast<u32>((static_cast<u32>(mode) << 4) | (keyslot & 7));
|
return static_cast<u32>((static_cast<u32>(mode) << 4) | (keyslot & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 GetUnwrapEsKeyOption(EsKeyType type, u32 generation) {
|
inline u32 GetPrepareEsDeviceUniqueKeyOption(EsCommonKeyType type, u32 generation) {
|
||||||
return static_cast<u32>((static_cast<u32>(type) << 6) | (generation & 0x3F));
|
return static_cast<u32>((static_cast<u32>(type) << 6) | (generation & 0x3F));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions. */
|
/* Functions. */
|
||||||
Result SetConfig(SplConfigItem which, const u64 *value, size_t num_qwords);
|
Result SetConfig(spl::ConfigItem which, const u64 *value, size_t num_qwords);
|
||||||
Result GetConfig(u64 *out, size_t num_qwords, SplConfigItem which);
|
Result GetConfig(u64 *out, size_t num_qwords, spl::ConfigItem which);
|
||||||
Result CheckStatus(Result *out, AsyncOperationKey op);
|
Result GetResult(Result *out, AsyncOperationKey op);
|
||||||
Result GetResult(Result *out, void *out_buf, size_t out_buf_size, AsyncOperationKey op);
|
Result GetResultData(Result *out, void *out_buf, size_t out_buf_size, AsyncOperationKey op);
|
||||||
Result ExpMod(AsyncOperationKey *out_op, const void *base, const void *exp, size_t exp_size, const void *mod);
|
Result ModularExponentiate(AsyncOperationKey *out_op, const void *base, const void *exp, size_t exp_size, const void *mod);
|
||||||
Result GenerateRandomBytes(void *out, size_t size);
|
Result GenerateRandomBytes(void *out, size_t size);
|
||||||
Result GenerateAesKek(AccessKey *out, const KeySource &source, u32 generation, u32 option);
|
Result GenerateAesKek(AccessKey *out, const KeySource &source, u32 generation, u32 option);
|
||||||
Result LoadAesKey(u32 keyslot, const AccessKey &access_key, const KeySource &source);
|
Result LoadAesKey(u32 keyslot, const AccessKey &access_key, const KeySource &source);
|
||||||
Result CryptAes(AsyncOperationKey *out_op, u32 mode, const IvCtr &iv_ctr, u32 dst_addr, u32 src_addr, size_t size);
|
Result ComputeAes(AsyncOperationKey *out_op, u32 mode, const IvCtr &iv_ctr, u32 dst_addr, u32 src_addr, size_t size);
|
||||||
Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &source, u32 generation, u32 which);
|
Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &source, u32 generation, u32 which);
|
||||||
Result ComputeCmac(Cmac *out_mac, u32 keyslot, const void *data, size_t size);
|
Result ComputeCmac(Cmac *out_mac, u32 keyslot, const void *data, size_t size);
|
||||||
Result ReEncryptRsaPrivateKey(void *data, size_t size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option);
|
Result ReencryptDeviceUniqueData(void *data, size_t size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option);
|
||||||
Result DecryptOrImportRsaPrivateKey(void *data, size_t size, const AccessKey &access_key, const KeySource &source, DecryptOrImportMode mode);
|
Result DecryptDeviceUniqueData(void *data, size_t size, const AccessKey &access_key, const KeySource &source, DeviceUniqueDataMode mode);
|
||||||
Result SecureExpMod(AsyncOperationKey *out_op, const void *base, const void *mod, SecureExpModMode mode);
|
Result ModularExponentiateWithStorageKey(AsyncOperationKey *out_op, const void *base, const void *mod, ModularExponentiateWithStorageKeyMode mode);
|
||||||
Result UnwrapTitleKey(AsyncOperationKey *out_op, const void *base, const void *mod, const void *label_digest, size_t label_digest_size, u32 option);
|
Result PrepareEsDeviceUniqueKey(AsyncOperationKey *out_op, const void *base, const void *mod, const void *label_digest, size_t label_digest_size, u32 option);
|
||||||
Result LoadTitleKey(u32 keyslot, const AccessKey &access_key);
|
Result LoadPreparedAesKey(u32 keyslot, const AccessKey &access_key);
|
||||||
Result UnwrapCommonTitleKey(AccessKey *out, const KeySource &source, u32 generation);
|
Result PrepareCommonEsTitleKey(AccessKey *out, const KeySource &source, u32 generation);
|
||||||
|
|
||||||
/* Deprecated functions. */
|
/* Deprecated functions. */
|
||||||
Result ImportEsKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
|
Result LoadEsDeviceKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
|
||||||
Result DecryptRsaPrivateKey(size_t *out_size, void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
|
Result DecryptDeviceUniqueData(size_t *out_size, void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
|
||||||
Result ImportSecureExpModKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
|
Result DecryptAndStoreGcKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);
|
||||||
|
|
||||||
/* Atmosphere functions. */
|
/* Atmosphere functions. */
|
||||||
Result AtmosphereCopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size);
|
Result AtmosphereCopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size);
|
||||||
Result AtmosphereCopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size);
|
Result AtmosphereCopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size);
|
||||||
Result AtmosphereReadWriteRegister(uint64_t address, uint32_t mask, uint32_t value, uint32_t *out_value);
|
Result AtmosphereReadWriteRegister(uint64_t address, uint32_t mask, uint32_t value, uint32_t *out_value);
|
||||||
Result AtmosphereWriteAddress(void *dst, const void *src, size_t size);
|
|
||||||
Result AtmosphereGetEmummcConfig(void *out_config, void *out_paths, u32 storage_id);
|
Result AtmosphereGetEmummcConfig(void *out_config, void *out_paths, u32 storage_id);
|
||||||
|
|
||||||
/* Helpers. */
|
/* Helpers. */
|
||||||
inline Result SetConfig(SplConfigItem which, const u64 value) {
|
inline Result SetConfig(spl::ConfigItem which, const u64 value) {
|
||||||
return SetConfig(which, &value, 1);
|
return SetConfig(which, &value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline Result AtmosphereWriteAddress(void *dst, const T value) {
|
|
||||||
static_assert(std::is_integral<T>::value && sizeof(T) <= 8 && (sizeof(T) & (sizeof(T) - 1)) == 0, "AtmosphereWriteAddress requires integral type.");
|
|
||||||
return AtmosphereWriteAddress(dst, &value, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,35 +22,34 @@ namespace ams::spl {
|
|||||||
namespace smc {
|
namespace smc {
|
||||||
|
|
||||||
enum class FunctionId : u32 {
|
enum class FunctionId : u32 {
|
||||||
SetConfig = 0xC3000401,
|
SetConfig = 0xC3000401,
|
||||||
GetConfig = 0xC3000002,
|
GetConfig = 0xC3000002,
|
||||||
CheckStatus = 0xC3000003,
|
GetResult = 0xC3000003,
|
||||||
GetResult = 0xC3000404,
|
GetResultData = 0xC3000404,
|
||||||
ExpMod = 0xC3000E05,
|
ModularExponentiate = 0xC3000E05,
|
||||||
GenerateRandomBytes = 0xC3000006,
|
GenerateRandomBytes = 0xC3000006,
|
||||||
GenerateAesKek = 0xC3000007,
|
GenerateAesKek = 0xC3000007,
|
||||||
LoadAesKey = 0xC3000008,
|
LoadAesKey = 0xC3000008,
|
||||||
CryptAes = 0xC3000009,
|
ComputeAes = 0xC3000009,
|
||||||
GenerateSpecificAesKey = 0xC300000A,
|
GenerateSpecificAesKey = 0xC300000A,
|
||||||
ComputeCmac = 0xC300040B,
|
ComputeCmac = 0xC300040B,
|
||||||
ReEncryptRsaPrivateKey = 0xC300D60C,
|
ReencryptDeviceUniqueData = 0xC300D60C,
|
||||||
DecryptOrImportRsaPrivateKey = 0xC300100D,
|
DecryptDeviceUniqueData = 0xC300100D,
|
||||||
|
|
||||||
SecureExpMod = 0xC300060F,
|
ModularExponentiateWithStorageKey = 0xC300060F,
|
||||||
UnwrapTitleKey = 0xC3000610,
|
PrepareEsDeviceUniqueKey = 0xC3000610,
|
||||||
LoadTitleKey = 0xC3000011,
|
LoadPreparedAesKey = 0xC3000011,
|
||||||
UnwrapCommonTitleKey = 0xC3000012,
|
PrepareCommonEsTitleKey = 0xC3000012,
|
||||||
|
|
||||||
/* Deprecated functions. */
|
/* Deprecated functions. */
|
||||||
ImportEsKey = 0xC300100C,
|
LoadEsDeviceKey = 0xC300100C,
|
||||||
DecryptRsaPrivateKey = 0xC300100D,
|
DecryptAndStoreGcKey = 0xC300100E,
|
||||||
ImportSecureExpModKey = 0xC300100E,
|
|
||||||
|
|
||||||
/* Atmosphere functions. */
|
/* Atmosphere functions. */
|
||||||
AtmosphereIramCopy = 0xF0000201,
|
AtmosphereIramCopy = 0xF0000201,
|
||||||
AtmosphereReadWriteRegister = 0xF0000002,
|
AtmosphereReadWriteRegister = 0xF0000002,
|
||||||
AtmosphereWriteAddress = 0xF0000003,
|
|
||||||
AtmosphereGetEmummcConfig = 0xF0000404,
|
AtmosphereGetEmummcConfig = 0xF0000404,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Result {
|
enum class Result {
|
||||||
@ -61,6 +60,7 @@ namespace ams::spl {
|
|||||||
NoAsyncOperation = 4,
|
NoAsyncOperation = 4,
|
||||||
InvalidAsyncOperation = 5,
|
InvalidAsyncOperation = 5,
|
||||||
NotPermitted = 6,
|
NotPermitted = 6,
|
||||||
|
NotInitialized = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr inline ::ams::Result ConvertResult(Result smc_result) {
|
constexpr inline ::ams::Result ConvertResult(Result smc_result) {
|
||||||
@ -69,11 +69,10 @@ namespace ams::spl {
|
|||||||
|
|
||||||
/* Convert to the list of known SecureMonitorErrors. */
|
/* Convert to the list of known SecureMonitorErrors. */
|
||||||
const auto converted = R_MAKE_NAMESPACE_RESULT(::ams::spl, static_cast<u32>(smc_result));
|
const auto converted = R_MAKE_NAMESPACE_RESULT(::ams::spl, static_cast<u32>(smc_result));
|
||||||
if (spl::ResultSecureMonitorError::Includes(converted)) {
|
R_UNLESS(spl::ResultSecureMonitorError::Includes(converted), spl::ResultUnknownSecureMonitorError());
|
||||||
return converted;
|
|
||||||
}
|
|
||||||
|
|
||||||
return spl::ResultUnknownSecureMonitorError();
|
/* Return the error. */
|
||||||
|
return converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class CipherMode {
|
enum class CipherMode {
|
||||||
@ -82,23 +81,23 @@ namespace ams::spl {
|
|||||||
Ctr = 2,
|
Ctr = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DecryptOrImportMode {
|
enum class DeviceUniqueDataMode {
|
||||||
DecryptRsaPrivateKey = 0,
|
DecryptDeviceUniqueData = 0,
|
||||||
ImportLotusKey = 1,
|
DecryptAndStoreGcKey = 1,
|
||||||
ImportEsKey = 2,
|
DecryptAndStoreEsDeviceKey = 2,
|
||||||
ImportSslKey = 3,
|
DecryptAndStoreSslKey = 3,
|
||||||
ImportDrmKey = 4,
|
DecryptAndStoreDrmDeviceCertKey = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SecureExpModMode {
|
enum class ModularExponentiateWithStorageKeyMode {
|
||||||
Lotus = 0,
|
Gc = 0,
|
||||||
Ssl = 1,
|
Ssl = 1,
|
||||||
Drm = 2,
|
DrmDeviceCert = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EsKeyType {
|
enum class EsCommonKeyType {
|
||||||
TitleKey = 0,
|
TitleKey = 0,
|
||||||
ElicenseKey = 1,
|
ArchiveKey = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AsyncOperationKey {
|
struct AsyncOperationKey {
|
||||||
@ -196,23 +195,23 @@ namespace ams::spl {
|
|||||||
|
|
||||||
enum class ConfigItem : u32 {
|
enum class ConfigItem : u32 {
|
||||||
/* Standard config items. */
|
/* Standard config items. */
|
||||||
DisableProgramVerification = 1,
|
DisableProgramVerification = 1,
|
||||||
DramId = 2,
|
DramId = 2,
|
||||||
SecurityEngineIrqNumber = 3,
|
SecurityEngineInterruptNumber = 3,
|
||||||
FuseVersion = 4,
|
FuseVersion = 4,
|
||||||
HardwareType = 5,
|
HardwareType = 5,
|
||||||
HardwareState = 6,
|
HardwareState = 6,
|
||||||
IsRecoveryBoot = 7,
|
IsRecoveryBoot = 7,
|
||||||
DeviceId = 8,
|
DeviceId = 8,
|
||||||
BootReason = 9,
|
BootReason = 9,
|
||||||
MemoryMode = 10,
|
MemoryMode = 10,
|
||||||
IsDevelopmentFunctionEnabled = 11,
|
IsDevelopmentFunctionEnabled = 11,
|
||||||
KernelConfiguration = 12,
|
KernelConfiguration = 12,
|
||||||
IsChargerHiZModeEnabled = 13,
|
IsChargerHiZModeEnabled = 13,
|
||||||
IsQuest = 14,
|
QuestState = 14,
|
||||||
RegulatorType = 15,
|
RegulatorType = 15,
|
||||||
DeviceUniqueKeyGeneration = 16,
|
DeviceUniqueKeyGeneration = 16,
|
||||||
Package2Hash = 17,
|
Package2Hash = 17,
|
||||||
|
|
||||||
/* Extension config items for exosphere. */
|
/* Extension config items for exosphere. */
|
||||||
ExosphereApiVersion = 65000,
|
ExosphereApiVersion = 65000,
|
||||||
|
@ -21,7 +21,7 @@ namespace ams::exosphere {
|
|||||||
|
|
||||||
ApiInfo GetApiInfo() {
|
ApiInfo GetApiInfo() {
|
||||||
u64 exosphere_cfg;
|
u64 exosphere_cfg;
|
||||||
if (spl::smc::GetConfig(&exosphere_cfg, 1, SplConfigItem_ExosphereApiVersion) != spl::smc::Result::Success) {
|
if (spl::smc::GetConfig(&exosphere_cfg, 1, spl::ConfigItem::ExosphereApiVersion) != spl::smc::Result::Success) {
|
||||||
R_ABORT_UNLESS(ResultNotPresent());
|
R_ABORT_UNLESS(ResultNotPresent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,15 +29,15 @@ namespace ams::exosphere {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ForceRebootToRcm() {
|
void ForceRebootToRcm() {
|
||||||
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::SetConfig(SplConfigItem_ExosphereNeedsReboot, 1)));
|
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForceRebootToIramPayload() {
|
void ForceRebootToIramPayload() {
|
||||||
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::SetConfig(SplConfigItem_ExosphereNeedsReboot, 2)));
|
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForceShutdown() {
|
void ForceShutdown() {
|
||||||
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::SetConfig(SplConfigItem_ExosphereNeedsShutdown, 1)));
|
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::SetConfig(spl::ConfigItem::ExosphereNeedsShutdown, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size) {
|
void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size) {
|
||||||
@ -52,7 +52,7 @@ namespace ams::exosphere {
|
|||||||
|
|
||||||
inline u64 GetU64ConfigItem(spl::ConfigItem cfg) {
|
inline u64 GetU64ConfigItem(spl::ConfigItem cfg) {
|
||||||
u64 tmp;
|
u64 tmp;
|
||||||
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::GetConfig(std::addressof(tmp), 1, static_cast<::SplConfigItem>(cfg))));
|
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::GetConfig(std::addressof(tmp), 1, cfg)));
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
namespace ams::spl::smc {
|
namespace ams::spl::smc {
|
||||||
|
|
||||||
Result SetConfig(SplConfigItem which, const u64 *value, size_t num_qwords) {
|
Result SetConfig(spl::ConfigItem which, const u64 *value, size_t num_qwords) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::SetConfig);
|
args.X[0] = static_cast<u64>(FunctionId::SetConfig);
|
||||||
args.X[1] = which;
|
args.X[1] = static_cast<u64>(which);
|
||||||
args.X[2] = 0;
|
args.X[2] = 0;
|
||||||
for (size_t i = 0; i < std::min(size_t(4), num_qwords); i++) {
|
for (size_t i = 0; i < std::min(size_t(4), num_qwords); i++) {
|
||||||
args.X[3 + i] = value[i];
|
args.X[3 + i] = value[i];
|
||||||
@ -31,11 +31,11 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetConfig(u64 *out, size_t num_qwords, SplConfigItem which) {
|
Result GetConfig(u64 *out, size_t num_qwords, spl::ConfigItem which) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::GetConfig);
|
args.X[0] = static_cast<u64>(FunctionId::GetConfig);
|
||||||
args.X[1] = which;
|
args.X[1] = static_cast<u64>(which);
|
||||||
svcCallSecureMonitor(&args);
|
svcCallSecureMonitor(&args);
|
||||||
|
|
||||||
for (size_t i = 0; i < std::min(size_t(4), num_qwords); i++) {
|
for (size_t i = 0; i < std::min(size_t(4), num_qwords); i++) {
|
||||||
@ -44,10 +44,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheckStatus(Result *out, AsyncOperationKey op) {
|
Result GetResult(Result *out, AsyncOperationKey op) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::CheckStatus);
|
args.X[0] = static_cast<u64>(FunctionId::GetResult);
|
||||||
args.X[1] = op.value;
|
args.X[1] = op.value;
|
||||||
svcCallSecureMonitor(&args);
|
svcCallSecureMonitor(&args);
|
||||||
|
|
||||||
@ -55,10 +55,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetResult(Result *out, void *out_buf, size_t out_buf_size, AsyncOperationKey op) {
|
Result GetResultData(Result *out, void *out_buf, size_t out_buf_size, AsyncOperationKey op) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::GetResult);
|
args.X[0] = static_cast<u64>(FunctionId::GetResultData);
|
||||||
args.X[1] = op.value;
|
args.X[1] = op.value;
|
||||||
args.X[2] = reinterpret_cast<u64>(out_buf);
|
args.X[2] = reinterpret_cast<u64>(out_buf);
|
||||||
args.X[3] = out_buf_size;
|
args.X[3] = out_buf_size;
|
||||||
@ -68,10 +68,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ExpMod(AsyncOperationKey *out_op, const void *base, const void *exp, size_t exp_size, const void *mod) {
|
Result ModularExponentiate(AsyncOperationKey *out_op, const void *base, const void *exp, size_t exp_size, const void *mod) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::ExpMod);
|
args.X[0] = static_cast<u64>(FunctionId::ModularExponentiate);
|
||||||
args.X[1] = reinterpret_cast<u64>(base);
|
args.X[1] = reinterpret_cast<u64>(base);
|
||||||
args.X[2] = reinterpret_cast<u64>(exp);
|
args.X[2] = reinterpret_cast<u64>(exp);
|
||||||
args.X[3] = reinterpret_cast<u64>(mod);
|
args.X[3] = reinterpret_cast<u64>(mod);
|
||||||
@ -124,10 +124,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptAes(AsyncOperationKey *out_op, u32 mode, const IvCtr &iv_ctr, u32 dst_addr, u32 src_addr, size_t size) {
|
Result ComputeAes(AsyncOperationKey *out_op, u32 mode, const IvCtr &iv_ctr, u32 dst_addr, u32 src_addr, size_t size) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::CryptAes);
|
args.X[0] = static_cast<u64>(FunctionId::ComputeAes);
|
||||||
args.X[1] = mode;
|
args.X[1] = mode;
|
||||||
args.X[2] = iv_ctr.data64[0];
|
args.X[2] = iv_ctr.data64[0];
|
||||||
args.X[3] = iv_ctr.data64[1];
|
args.X[3] = iv_ctr.data64[1];
|
||||||
@ -169,10 +169,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReEncryptRsaPrivateKey(void *data, size_t size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option) {
|
Result ReencryptDeviceUniqueData(void *data, size_t size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::ReEncryptRsaPrivateKey);
|
args.X[0] = static_cast<u64>(FunctionId::ReencryptDeviceUniqueData);
|
||||||
args.X[1] = reinterpret_cast<u64>(&access_key_dec);
|
args.X[1] = reinterpret_cast<u64>(&access_key_dec);
|
||||||
args.X[2] = reinterpret_cast<u64>(&access_key_enc);
|
args.X[2] = reinterpret_cast<u64>(&access_key_enc);
|
||||||
args.X[3] = option;
|
args.X[3] = option;
|
||||||
@ -185,10 +185,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DecryptOrImportRsaPrivateKey(void *data, size_t size, const AccessKey &access_key, const KeySource &source, DecryptOrImportMode mode) {
|
Result DecryptDeviceUniqueData(void *data, size_t size, const AccessKey &access_key, const KeySource &source, DeviceUniqueDataMode mode) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::DecryptOrImportRsaPrivateKey);
|
args.X[0] = static_cast<u64>(FunctionId::DecryptDeviceUniqueData);
|
||||||
args.X[1] = access_key.data64[0];
|
args.X[1] = access_key.data64[0];
|
||||||
args.X[2] = access_key.data64[1];
|
args.X[2] = access_key.data64[1];
|
||||||
args.X[3] = static_cast<u32>(mode);
|
args.X[3] = static_cast<u32>(mode);
|
||||||
@ -201,10 +201,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SecureExpMod(AsyncOperationKey *out_op, const void *base, const void *mod, SecureExpModMode mode) {
|
Result ModularExponentiateWithStorageKey(AsyncOperationKey *out_op, const void *base, const void *mod, ModularExponentiateWithStorageKeyMode mode) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::SecureExpMod);
|
args.X[0] = static_cast<u64>(FunctionId::ModularExponentiateWithStorageKey);
|
||||||
args.X[1] = reinterpret_cast<u64>(base);
|
args.X[1] = reinterpret_cast<u64>(base);
|
||||||
args.X[2] = reinterpret_cast<u64>(mod);
|
args.X[2] = reinterpret_cast<u64>(mod);
|
||||||
args.X[3] = static_cast<u32>(mode);
|
args.X[3] = static_cast<u32>(mode);
|
||||||
@ -214,10 +214,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnwrapTitleKey(AsyncOperationKey *out_op, const void *base, const void *mod, const void *label_digest, size_t label_digest_size, u32 option) {
|
Result PrepareEsDeviceUniqueKey(AsyncOperationKey *out_op, const void *base, const void *mod, const void *label_digest, size_t label_digest_size, u32 option) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::UnwrapTitleKey);
|
args.X[0] = static_cast<u64>(FunctionId::PrepareEsDeviceUniqueKey);
|
||||||
args.X[1] = reinterpret_cast<u64>(base);
|
args.X[1] = reinterpret_cast<u64>(base);
|
||||||
args.X[2] = reinterpret_cast<u64>(mod);
|
args.X[2] = reinterpret_cast<u64>(mod);
|
||||||
std::memset(&args.X[3], 0, 4 * sizeof(args.X[3]));
|
std::memset(&args.X[3], 0, 4 * sizeof(args.X[3]));
|
||||||
@ -229,10 +229,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadTitleKey(u32 keyslot, const AccessKey &access_key) {
|
Result LoadPreparedAesKey(u32 keyslot, const AccessKey &access_key) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::LoadTitleKey);
|
args.X[0] = static_cast<u64>(FunctionId::LoadPreparedAesKey);
|
||||||
args.X[1] = keyslot;
|
args.X[1] = keyslot;
|
||||||
args.X[2] = access_key.data64[0];
|
args.X[2] = access_key.data64[0];
|
||||||
args.X[3] = access_key.data64[1];
|
args.X[3] = access_key.data64[1];
|
||||||
@ -241,10 +241,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnwrapCommonTitleKey(AccessKey *out, const KeySource &source, u32 generation) {
|
Result PrepareCommonEsTitleKey(AccessKey *out, const KeySource &source, u32 generation) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::UnwrapCommonTitleKey);
|
args.X[0] = static_cast<u64>(FunctionId::PrepareCommonEsTitleKey);
|
||||||
args.X[1] = source.data64[0];
|
args.X[1] = source.data64[0];
|
||||||
args.X[2] = source.data64[1];
|
args.X[2] = source.data64[1];
|
||||||
args.X[3] = generation;
|
args.X[3] = generation;
|
||||||
@ -257,10 +257,10 @@ namespace ams::spl::smc {
|
|||||||
|
|
||||||
|
|
||||||
/* Deprecated functions. */
|
/* Deprecated functions. */
|
||||||
Result ImportEsKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option) {
|
Result LoadEsDeviceKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::ImportEsKey);
|
args.X[0] = static_cast<u64>(FunctionId::LoadEsDeviceKey);
|
||||||
args.X[1] = access_key.data64[0];
|
args.X[1] = access_key.data64[0];
|
||||||
args.X[2] = access_key.data64[1];
|
args.X[2] = access_key.data64[1];
|
||||||
args.X[3] = option;
|
args.X[3] = option;
|
||||||
@ -273,10 +273,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DecryptRsaPrivateKey(size_t *out_size, void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option) {
|
Result DecryptDeviceUniqueData(size_t *out_size, void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::DecryptRsaPrivateKey);
|
args.X[0] = static_cast<u64>(FunctionId::DecryptDeviceUniqueData);
|
||||||
args.X[1] = access_key.data64[0];
|
args.X[1] = access_key.data64[0];
|
||||||
args.X[2] = access_key.data64[1];
|
args.X[2] = access_key.data64[1];
|
||||||
args.X[3] = option;
|
args.X[3] = option;
|
||||||
@ -290,10 +290,10 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ImportSecureExpModKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option) {
|
Result DecryptAndStoreGcKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::ImportSecureExpModKey);
|
args.X[0] = static_cast<u64>(FunctionId::DecryptAndStoreGcKey);
|
||||||
args.X[1] = access_key.data64[0];
|
args.X[1] = access_key.data64[0];
|
||||||
args.X[2] = access_key.data64[1];
|
args.X[2] = access_key.data64[1];
|
||||||
args.X[3] = option;
|
args.X[3] = option;
|
||||||
@ -348,19 +348,6 @@ namespace ams::spl::smc {
|
|||||||
return static_cast<Result>(args.X[0]);
|
return static_cast<Result>(args.X[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AtmosphereWriteAddress(void *dst, const void *src, size_t size) {
|
|
||||||
AMS_ABORT_UNLESS(size <= sizeof(u64));
|
|
||||||
|
|
||||||
SecmonArgs args;
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::AtmosphereWriteAddress);
|
|
||||||
args.X[1] = reinterpret_cast<uintptr_t>(dst);
|
|
||||||
__builtin_memcpy(&args.X[1], src, size);
|
|
||||||
args.X[3] = size;
|
|
||||||
svcCallSecureMonitor(&args);
|
|
||||||
|
|
||||||
return static_cast<Result>(args.X[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result AtmosphereGetEmummcConfig(void *out_config, void *out_paths, u32 storage_id) {
|
Result AtmosphereGetEmummcConfig(void *out_config, void *out_paths, u32 storage_id) {
|
||||||
const u64 paths = reinterpret_cast<u64>(out_paths);
|
const u64 paths = reinterpret_cast<u64>(out_paths);
|
||||||
AMS_ABORT_UNLESS(util::IsAligned(paths, os::MemoryPageSize));
|
AMS_ABORT_UNLESS(util::IsAligned(paths, os::MemoryPageSize));
|
||||||
|
@ -63,7 +63,7 @@ namespace ams::spl {
|
|||||||
auto is_event_initialized = false;
|
auto is_event_initialized = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
R_TRY_CATCH(static_cast<::ams::Result>(f())) {
|
R_TRY_CATCH(static_cast<::ams::Result>(f())) {
|
||||||
R_CATCH(spl::ResultOutOfKeyslots) {
|
R_CATCH(spl::ResultOutOfKeySlots) {
|
||||||
if (!is_event_initialized) {
|
if (!is_event_initialized) {
|
||||||
GetAesKeySlotAvailableEvent(std::addressof(event));
|
GetAesKeySlotAvailableEvent(std::addressof(event));
|
||||||
is_event_initialized = true;
|
is_event_initialized = true;
|
||||||
|
@ -28,13 +28,14 @@ namespace ams::spl {
|
|||||||
R_DEFINE_ERROR_RESULT(SecureMonitorNoAsyncOperation, 4);
|
R_DEFINE_ERROR_RESULT(SecureMonitorNoAsyncOperation, 4);
|
||||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidAsyncOperation, 5);
|
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidAsyncOperation, 5);
|
||||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotPermitted, 6);
|
R_DEFINE_ERROR_RESULT(SecureMonitorNotPermitted, 6);
|
||||||
|
R_DEFINE_ERROR_RESULT(SecureMonitorNotInitialized, 7);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(InvalidSize, 100);
|
R_DEFINE_ERROR_RESULT(InvalidSize, 100);
|
||||||
R_DEFINE_ERROR_RESULT(UnknownSecureMonitorError, 101);
|
R_DEFINE_ERROR_RESULT(UnknownSecureMonitorError, 101);
|
||||||
R_DEFINE_ERROR_RESULT(DecryptionFailed, 102);
|
R_DEFINE_ERROR_RESULT(DecryptionFailed, 102);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(OutOfKeyslots, 104);
|
R_DEFINE_ERROR_RESULT(OutOfKeySlots, 104);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidKeyslot, 105);
|
R_DEFINE_ERROR_RESULT(InvalidKeySlot, 105);
|
||||||
R_DEFINE_ERROR_RESULT(BootReasonAlreadySet, 106);
|
R_DEFINE_ERROR_RESULT(BootReasonAlreadySet, 106);
|
||||||
R_DEFINE_ERROR_RESULT(BootReasonNotSet, 107);
|
R_DEFINE_ERROR_RESULT(BootReasonNotSet, 107);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 108);
|
R_DEFINE_ERROR_RESULT(InvalidArgument, 108);
|
||||||
|
@ -24,39 +24,39 @@ namespace ams::spl::impl {
|
|||||||
|
|
||||||
/* Convenient defines. */
|
/* Convenient defines. */
|
||||||
constexpr size_t DeviceAddressSpaceAlign = 0x400000;
|
constexpr size_t DeviceAddressSpaceAlign = 0x400000;
|
||||||
constexpr u32 WorkBufferMapBase = 0x80000000u;
|
constexpr u32 WorkBufferMapBase = 0x80000000u;
|
||||||
constexpr u32 CryptAesInMapBase = 0x90000000u;
|
constexpr u32 ComputeAesInMapBase = 0x90000000u;
|
||||||
constexpr u32 CryptAesOutMapBase = 0xC0000000u;
|
constexpr u32 ComputeAesOutMapBase = 0xC0000000u;
|
||||||
constexpr size_t CryptAesSizeMax = static_cast<size_t>(CryptAesOutMapBase - CryptAesInMapBase);
|
constexpr size_t ComputeAesSizeMax = static_cast<size_t>(ComputeAesOutMapBase - ComputeAesInMapBase);
|
||||||
|
|
||||||
constexpr size_t RsaPrivateKeySize = 0x100;
|
constexpr size_t RsaPrivateKeySize = 0x100;
|
||||||
constexpr size_t RsaPrivateKeyMetaSize = 0x30;
|
constexpr size_t DeviceUniqueDataMetaSize = 0x30;
|
||||||
constexpr size_t LabelDigestSizeMax = 0x20;
|
constexpr size_t LabelDigestSizeMax = 0x20;
|
||||||
|
|
||||||
constexpr size_t WorkBufferSizeMax = 0x800;
|
constexpr size_t WorkBufferSizeMax = 0x800;
|
||||||
|
|
||||||
constexpr s32 MaxPhysicalAesKeyslots = 6;
|
constexpr s32 MaxPhysicalAesKeySlots = 6;
|
||||||
constexpr s32 MaxPhysicalAesKeyslotsDeprecated = 4;
|
constexpr s32 MaxPhysicalAesKeySlotsDeprecated = 4;
|
||||||
|
|
||||||
constexpr s32 MaxVirtualAesKeyslots = 9;
|
constexpr s32 MaxVirtualAesKeySlots = 9;
|
||||||
|
|
||||||
/* Keyslot management. */
|
/* KeySlot management. */
|
||||||
KeySlotCache g_keyslot_cache;
|
KeySlotCache g_keyslot_cache;
|
||||||
std::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeyslots];
|
std::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeySlots];
|
||||||
|
|
||||||
inline s32 GetMaxPhysicalKeyslots() {
|
inline s32 GetMaxPhysicalKeySlots() {
|
||||||
return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeyslots : MaxPhysicalAesKeyslotsDeprecated;
|
return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeySlots : MaxPhysicalAesKeySlotsDeprecated;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr s32 VirtualKeySlotMin = 16;
|
constexpr s32 VirtualKeySlotMin = 16;
|
||||||
constexpr s32 VirtualKeySlotMax = VirtualKeySlotMin + MaxVirtualAesKeyslots - 1;
|
constexpr s32 VirtualKeySlotMax = VirtualKeySlotMin + MaxVirtualAesKeySlots - 1;
|
||||||
|
|
||||||
constexpr inline bool IsVirtualKeySlot(s32 keyslot) {
|
constexpr inline bool IsVirtualKeySlot(s32 keyslot) {
|
||||||
return VirtualKeySlotMin <= keyslot && keyslot <= VirtualKeySlotMax;
|
return VirtualKeySlotMin <= keyslot && keyslot <= VirtualKeySlotMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsPhysicalKeySlot(s32 keyslot) {
|
inline bool IsPhysicalKeySlot(s32 keyslot) {
|
||||||
return keyslot < GetMaxPhysicalKeyslots();
|
return keyslot < GetMaxPhysicalKeySlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline s32 GetVirtualKeySlotIndex(s32 keyslot) {
|
constexpr inline s32 GetVirtualKeySlotIndex(s32 keyslot) {
|
||||||
@ -71,16 +71,16 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InitializeKeySlotCache() {
|
void InitializeKeySlotCache() {
|
||||||
for (s32 i = 0; i < MaxPhysicalAesKeyslots; i++) {
|
for (s32 i = 0; i < MaxPhysicalAesKeySlots; i++) {
|
||||||
g_keyslot_cache_entry[i].emplace(i);
|
g_keyslot_cache_entry[i].emplace(i);
|
||||||
g_keyslot_cache.AddEntry(std::addressof(g_keyslot_cache_entry[i].value()));
|
g_keyslot_cache.AddEntry(std::addressof(g_keyslot_cache_entry[i].value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class KeySlotContentType {
|
enum class KeySlotContentType {
|
||||||
None = 0,
|
None = 0,
|
||||||
AesKey = 1,
|
AesKey = 1,
|
||||||
TitleKey = 2,
|
PreparedKey = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KeySlotContents {
|
struct KeySlotContents {
|
||||||
@ -92,15 +92,15 @@ namespace ams::spl::impl {
|
|||||||
} aes_key;
|
} aes_key;
|
||||||
struct {
|
struct {
|
||||||
AccessKey access_key;
|
AccessKey access_key;
|
||||||
} title_key;
|
} prepared_key;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const void *g_keyslot_owners[MaxVirtualAesKeyslots];
|
const void *g_keyslot_owners[MaxVirtualAesKeySlots];
|
||||||
KeySlotContents g_keyslot_contents[MaxVirtualAesKeyslots];
|
KeySlotContents g_keyslot_contents[MaxVirtualAesKeySlots];
|
||||||
KeySlotContents g_physical_keyslot_contents_for_backwards_compatibility[MaxPhysicalAesKeyslots];
|
KeySlotContents g_physical_keyslot_contents_for_backwards_compatibility[MaxPhysicalAesKeySlots];
|
||||||
|
|
||||||
void ClearPhysicalKeyslot(s32 keyslot) {
|
void ClearPhysicalKeySlot(s32 keyslot) {
|
||||||
AMS_ASSERT(IsPhysicalKeySlot(keyslot));
|
AMS_ASSERT(IsPhysicalKeySlot(keyslot));
|
||||||
|
|
||||||
AccessKey access_key = {};
|
AccessKey access_key = {};
|
||||||
@ -139,13 +139,13 @@ namespace ams::spl::impl {
|
|||||||
if (load) {
|
if (load) {
|
||||||
switch (contents->type) {
|
switch (contents->type) {
|
||||||
case KeySlotContentType::None:
|
case KeySlotContentType::None:
|
||||||
ClearPhysicalKeyslot(phys_slot);
|
ClearPhysicalKeySlot(phys_slot);
|
||||||
break;
|
break;
|
||||||
case KeySlotContentType::AesKey:
|
case KeySlotContentType::AesKey:
|
||||||
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadAesKey(phys_slot, contents->aes_key.access_key, contents->aes_key.key_source)));
|
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadAesKey(phys_slot, contents->aes_key.access_key, contents->aes_key.key_source)));
|
||||||
break;
|
break;
|
||||||
case KeySlotContentType::TitleKey:
|
case KeySlotContentType::PreparedKey:
|
||||||
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadTitleKey(phys_slot, contents->title_key.access_key)));
|
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadPreparedAesKey(phys_slot, contents->prepared_key.access_key)));
|
||||||
break;
|
break;
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
}
|
}
|
||||||
@ -169,32 +169,32 @@ namespace ams::spl::impl {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadVirtualTitleKey(s32 keyslot, const AccessKey &access_key) {
|
Result LoadVirtualPreparedAesKey(s32 keyslot, const AccessKey &access_key) {
|
||||||
/* Ensure we can load into the slot. */
|
/* Ensure we can load into the slot. */
|
||||||
const s32 phys_slot = GetPhysicalKeySlot(keyslot, false);
|
const s32 phys_slot = GetPhysicalKeySlot(keyslot, false);
|
||||||
R_TRY(smc::ConvertResult(smc::LoadTitleKey(phys_slot, access_key)));
|
R_TRY(smc::ConvertResult(smc::LoadPreparedAesKey(phys_slot, access_key)));
|
||||||
|
|
||||||
/* Update our contents. */
|
/* Update our contents. */
|
||||||
const s32 index = GetVirtualKeySlotIndex(keyslot);
|
const s32 index = GetVirtualKeySlotIndex(keyslot);
|
||||||
|
|
||||||
g_keyslot_contents[index].type = KeySlotContentType::TitleKey;
|
g_keyslot_contents[index].type = KeySlotContentType::PreparedKey;
|
||||||
g_keyslot_contents[index].title_key.access_key = access_key;
|
g_keyslot_contents[index].prepared_key.access_key = access_key;
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
class ScopedAesKeyslot {
|
class ScopedAesKeySlot {
|
||||||
private:
|
private:
|
||||||
s32 slot;
|
s32 slot;
|
||||||
bool has_slot;
|
bool has_slot;
|
||||||
public:
|
public:
|
||||||
ScopedAesKeyslot() : slot(-1), has_slot(false) {
|
ScopedAesKeySlot() : slot(-1), has_slot(false) {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
~ScopedAesKeyslot() {
|
~ScopedAesKeySlot() {
|
||||||
if (this->has_slot) {
|
if (this->has_slot) {
|
||||||
FreeAesKeyslot(slot, this);
|
DeallocateAesKeySlot(slot, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result Allocate() {
|
Result Allocate() {
|
||||||
R_TRY(AllocateAesKeyslot(&this->slot, this));
|
R_TRY(AllocateAesKeySlot(&this->slot, this));
|
||||||
this->has_slot = true;
|
this->has_slot = true;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ namespace ams::spl::impl {
|
|||||||
|
|
||||||
void InitializeSeEvents() {
|
void InitializeSeEvents() {
|
||||||
u64 irq_num;
|
u64 irq_num;
|
||||||
AMS_ABORT_UNLESS(smc::GetConfig(&irq_num, 1, SplConfigItem_SecurityEngineIrqNumber) == smc::Result::Success);
|
AMS_ABORT_UNLESS(smc::GetConfig(&irq_num, 1, ConfigItem::SecurityEngineInterruptNumber) == smc::Result::Success);
|
||||||
os::InitializeInterruptEvent(std::addressof(g_se_event), irq_num, os::EventClearMode_AutoClear);
|
os::InitializeInterruptEvent(std::addressof(g_se_event), irq_num, os::EventClearMode_AutoClear);
|
||||||
|
|
||||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_se_keyslot_available_event), os::EventClearMode_AutoClear, true));
|
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_se_keyslot_available_event), os::EventClearMode_AutoClear, true));
|
||||||
@ -320,7 +320,7 @@ namespace ams::spl::impl {
|
|||||||
WaitSeOperationComplete();
|
WaitSeOperationComplete();
|
||||||
|
|
||||||
smc::Result op_res;
|
smc::Result op_res;
|
||||||
smc::Result res = smc::CheckStatus(&op_res, op_key);
|
smc::Result res = smc::GetResult(&op_res, op_key);
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ namespace ams::spl::impl {
|
|||||||
WaitSeOperationComplete();
|
WaitSeOperationComplete();
|
||||||
|
|
||||||
smc::Result op_res;
|
smc::Result op_res;
|
||||||
smc::Result res = smc::GetResult(&op_res, out_buf, out_buf_size, op_key);
|
smc::Result res = smc::GetResultData(&op_res, out_buf, out_buf_size, op_key);
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -340,17 +340,17 @@ namespace ams::spl::impl {
|
|||||||
return op_res;
|
return op_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Internal Keyslot utility. */
|
/* Internal KeySlot utility. */
|
||||||
Result ValidateAesKeyslot(s32 keyslot, const void *owner) {
|
Result ValidateAesKeySlot(s32 keyslot, const void *owner) {
|
||||||
/* Allow the use of physical keyslots on 1.0.0. */
|
/* Allow the use of physical keyslots on 1.0.0. */
|
||||||
if (hos::GetVersion() == hos::Version_1_0_0) {
|
if (hos::GetVersion() == hos::Version_1_0_0) {
|
||||||
R_SUCCEED_IF(IsPhysicalKeySlot(keyslot));
|
R_SUCCEED_IF(IsPhysicalKeySlot(keyslot));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeyslot());
|
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeySlot());
|
||||||
|
|
||||||
const s32 index = GetVirtualKeySlotIndex(keyslot);
|
const s32 index = GetVirtualKeySlotIndex(keyslot);
|
||||||
R_UNLESS(g_keyslot_owners[index] == owner, spl::ResultInvalidKeyslot());
|
R_UNLESS(g_keyslot_owners[index] == owner, spl::ResultInvalidKeySlot());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,11 +377,11 @@ namespace ams::spl::impl {
|
|||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
const IvCtr iv_ctr = {};
|
const IvCtr iv_ctr = {};
|
||||||
const u32 mode = smc::GetCryptAesMode(smc::CipherMode::CbcDecrypt, GetPhysicalKeySlot(keyslot, true));
|
const u32 mode = smc::GetComputeAesMode(smc::CipherMode::CbcDecrypt, GetPhysicalKeySlot(keyslot, true));
|
||||||
const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(DecryptAesBlockLayout, crypt_ctx.out);
|
const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(DecryptAesBlockLayout, crypt_ctx.out);
|
||||||
const u32 src_ll_addr = g_se_mapped_work_buffer_addr + offsetof(DecryptAesBlockLayout, crypt_ctx.in);
|
const u32 src_ll_addr = g_se_mapped_work_buffer_addr + offsetof(DecryptAesBlockLayout, crypt_ctx.in);
|
||||||
|
|
||||||
smc::Result res = smc::CryptAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, sizeof(layout->in_block));
|
smc::Result res = smc::ComputeAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, sizeof(layout->in_block));
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -397,33 +397,33 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation wrappers for API commands. */
|
/* Implementation wrappers for API commands. */
|
||||||
Result ImportSecureExpModKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
Result DecryptAndStoreDeviceUniqueKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||||
struct ImportSecureExpModKeyLayout {
|
struct DecryptAndStoreDeviceUniqueKeyLayout {
|
||||||
u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
u8 data[DeviceUniqueDataMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||||
};
|
};
|
||||||
ImportSecureExpModKeyLayout *layout = reinterpret_cast<ImportSecureExpModKeyLayout *>(g_work_buffer);
|
DecryptAndStoreDeviceUniqueKeyLayout *layout = reinterpret_cast<DecryptAndStoreDeviceUniqueKeyLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate size. */
|
/* Validate size. */
|
||||||
R_UNLESS(src_size <= sizeof(ImportSecureExpModKeyLayout), spl::ResultInvalidSize());
|
R_UNLESS(src_size <= sizeof(DecryptAndStoreDeviceUniqueKeyLayout), spl::ResultInvalidSize());
|
||||||
std::memcpy(layout, src, src_size);
|
std::memcpy(layout, src, src_size);
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
armDCacheFlush(layout, sizeof(*layout));
|
||||||
smc::Result smc_res;
|
smc::Result smc_res;
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||||
smc_res = smc::DecryptOrImportRsaPrivateKey(layout->data, src_size, access_key, key_source, static_cast<smc::DecryptOrImportMode>(option));
|
smc_res = smc::DecryptDeviceUniqueData(layout->data, src_size, access_key, key_source, static_cast<smc::DeviceUniqueDataMode>(option));
|
||||||
} else {
|
} else {
|
||||||
smc_res = smc::ImportSecureExpModKey(layout->data, src_size, access_key, key_source, option);
|
smc_res = smc::DecryptAndStoreGcKey(layout->data, src_size, access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
return smc::ConvertResult(smc_res);
|
return smc::ConvertResult(smc_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SecureExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size, smc::SecureExpModMode mode) {
|
Result ModularExponentiateWithStorageKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size, smc::ModularExponentiateWithStorageKeyMode mode) {
|
||||||
struct SecureExpModLayout {
|
struct ModularExponentiateWithStorageKeyLayout {
|
||||||
u8 base[0x100];
|
u8 base[0x100];
|
||||||
u8 mod[0x100];
|
u8 mod[0x100];
|
||||||
};
|
};
|
||||||
SecureExpModLayout *layout = reinterpret_cast<SecureExpModLayout *>(g_work_buffer);
|
ModularExponentiateWithStorageKeyLayout *layout = reinterpret_cast<ModularExponentiateWithStorageKeyLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate sizes. */
|
/* Validate sizes. */
|
||||||
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
||||||
@ -443,7 +443,7 @@ namespace ams::spl::impl {
|
|||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
|
||||||
smc::Result res = smc::SecureExpMod(&op_key, layout->base, layout->mod, mode);
|
smc::Result res = smc::ModularExponentiateWithStorageKey(&op_key, layout->base, layout->mod, mode);
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
@ -458,12 +458,12 @@ namespace ams::spl::impl {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnwrapEsRsaOaepWrappedKey(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, smc::EsKeyType type) {
|
Result PrepareEsDeviceUniqueKey(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, smc::EsCommonKeyType type) {
|
||||||
struct UnwrapEsKeyLayout {
|
struct PrepareEsDeviceUniqueKeyLayout {
|
||||||
u8 base[0x100];
|
u8 base[0x100];
|
||||||
u8 mod[0x100];
|
u8 mod[0x100];
|
||||||
};
|
};
|
||||||
UnwrapEsKeyLayout *layout = reinterpret_cast<UnwrapEsKeyLayout *>(g_work_buffer);
|
PrepareEsDeviceUniqueKeyLayout *layout = reinterpret_cast<PrepareEsDeviceUniqueKeyLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate sizes. */
|
/* Validate sizes. */
|
||||||
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
||||||
@ -483,7 +483,7 @@ namespace ams::spl::impl {
|
|||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
|
||||||
smc::Result res = smc::UnwrapTitleKey(&op_key, layout->base, layout->mod, label_digest, label_digest_size, smc::GetUnwrapEsKeyOption(type, generation));
|
smc::Result res = smc::PrepareEsDeviceUniqueKey(&op_key, layout->base, layout->mod, label_digest, label_digest_size, smc::GetPrepareEsDeviceUniqueKeyOption(type, generation));
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
@ -514,39 +514,45 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* General. */
|
/* General. */
|
||||||
Result GetConfig(u64 *out, SplConfigItem which) {
|
Result GetConfig(u64 *out, ConfigItem which) {
|
||||||
/* Nintendo explicitly blacklists package2 hash here, amusingly. */
|
/* Nintendo explicitly blacklists package2 hash here, amusingly. */
|
||||||
/* This is not blacklisted in safemode, but we're never in safe mode... */
|
/* This is not blacklisted in safemode, but we're never in safe mode... */
|
||||||
R_UNLESS(which != SplConfigItem_Package2Hash, spl::ResultInvalidArgument());
|
R_UNLESS(which != ConfigItem::Package2Hash, spl::ResultInvalidArgument());
|
||||||
|
|
||||||
smc::Result res = smc::GetConfig(out, 1, which);
|
smc::Result res = smc::GetConfig(out, 1, which);
|
||||||
|
|
||||||
/* Nintendo has some special handling here for hardware type/is_retail. */
|
/* Nintendo has some special handling here for hardware type/is_retail. */
|
||||||
if (which == SplConfigItem_HardwareType && res == smc::Result::InvalidArgument) {
|
if (res == smc::Result::InvalidArgument) {
|
||||||
*out = 0;
|
switch (which) {
|
||||||
res = smc::Result::Success;
|
case ConfigItem::HardwareType:
|
||||||
}
|
*out = static_cast<u64>(HardwareType::Icosa);
|
||||||
if (which == SplConfigItem_IsRetail && res == smc::Result::InvalidArgument) {
|
res = smc::Result::Success;
|
||||||
*out = 0;
|
break;
|
||||||
res = smc::Result::Success;
|
case ConfigItem::HardwareState:
|
||||||
|
*out = HardwareState_Development;
|
||||||
|
res = smc::Result::Success;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ExpMod(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) {
|
Result 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) {
|
||||||
struct ExpModLayout {
|
struct ModularExponentiateLayout {
|
||||||
u8 base[0x100];
|
u8 base[0x100];
|
||||||
u8 exp[0x100];
|
u8 exp[0x100];
|
||||||
u8 mod[0x100];
|
u8 mod[0x100];
|
||||||
};
|
};
|
||||||
ExpModLayout *layout = reinterpret_cast<ExpModLayout *>(g_work_buffer);
|
ModularExponentiateLayout *layout = reinterpret_cast<ModularExponentiateLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate sizes. */
|
/* Validate sizes. */
|
||||||
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
||||||
R_UNLESS(exp_size <= sizeof(layout->exp), spl::ResultInvalidSize());
|
R_UNLESS(exp_size <= sizeof(layout->exp), spl::ResultInvalidSize());
|
||||||
R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize());
|
R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize());
|
||||||
R_UNLESS(out_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
R_UNLESS(out_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||||
|
|
||||||
/* Copy data into work buffer. */
|
/* Copy data into work buffer. */
|
||||||
const size_t base_ofs = sizeof(layout->base) - base_size;
|
const size_t base_ofs = sizeof(layout->base) - base_size;
|
||||||
@ -562,7 +568,7 @@ namespace ams::spl::impl {
|
|||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
|
|
||||||
smc::Result res = smc::ExpMod(&op_key, layout->base, layout->exp, exp_size, layout->mod);
|
smc::Result res = smc::ModularExponentiate(&op_key, layout->base, layout->exp, exp_size, layout->mod);
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
@ -577,7 +583,7 @@ namespace ams::spl::impl {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetConfig(SplConfigItem which, u64 value) {
|
Result SetConfig(ConfigItem which, u64 value) {
|
||||||
return smc::ConvertResult(smc::SetConfig(which, &value, 1));
|
return smc::ConvertResult(smc::SetConfig(which, &value, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,10 +601,10 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IsDevelopment(bool *out) {
|
Result IsDevelopment(bool *out) {
|
||||||
u64 is_retail;
|
u64 hardware_state;
|
||||||
R_TRY(GetConfig(&is_retail, SplConfigItem_IsRetail));
|
R_TRY(impl::GetConfig(&hardware_state, ConfigItem::HardwareState));
|
||||||
|
|
||||||
*out = (is_retail == 0);
|
*out = (hardware_state == HardwareState_Development);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +629,7 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source) {
|
Result LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source) {
|
||||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||||
return LoadVirtualAesKey(keyslot, access_key, key_source);
|
return LoadVirtualAesKey(keyslot, access_key, key_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +638,7 @@ namespace ams::spl::impl {
|
|||||||
.data = {0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8}
|
.data = {0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8}
|
||||||
};
|
};
|
||||||
|
|
||||||
ScopedAesKeyslot keyslot_holder;
|
ScopedAesKeySlot keyslot_holder;
|
||||||
R_TRY(keyslot_holder.Allocate());
|
R_TRY(keyslot_holder.Allocate());
|
||||||
|
|
||||||
R_TRY(LoadVirtualAesKey(keyslot_holder.GetKeySlot(), access_key, s_generate_aes_key_source));
|
R_TRY(LoadVirtualAesKey(keyslot_holder.GetKeySlot(), access_key, s_generate_aes_key_source));
|
||||||
@ -651,8 +657,8 @@ namespace ams::spl::impl {
|
|||||||
return GenerateAesKey(out_key, access_key, key_source);
|
return GenerateAesKey(out_key, access_key, key_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptAesCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr) {
|
Result 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(ValidateAesKeyslot(keyslot, owner));
|
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||||
|
|
||||||
/* Succeed immediately if there's nothing to crypt. */
|
/* Succeed immediately if there's nothing to crypt. */
|
||||||
if (src_size == 0) {
|
if (src_size == 0) {
|
||||||
@ -670,14 +676,14 @@ namespace ams::spl::impl {
|
|||||||
const uintptr_t dst_addr_page_aligned = util::AlignDown(dst_addr, os::MemoryPageSize);
|
const uintptr_t dst_addr_page_aligned = util::AlignDown(dst_addr, os::MemoryPageSize);
|
||||||
const size_t src_size_page_aligned = util::AlignUp(src_addr + src_size, os::MemoryPageSize) - src_addr_page_aligned;
|
const size_t src_size_page_aligned = util::AlignUp(src_addr + src_size, os::MemoryPageSize) - src_addr_page_aligned;
|
||||||
const size_t dst_size_page_aligned = util::AlignUp(dst_addr + dst_size, os::MemoryPageSize) - dst_addr_page_aligned;
|
const size_t dst_size_page_aligned = util::AlignUp(dst_addr + dst_size, os::MemoryPageSize) - dst_addr_page_aligned;
|
||||||
const u32 src_se_map_addr = CryptAesInMapBase + (src_addr_page_aligned % DeviceAddressSpaceAlign);
|
const u32 src_se_map_addr = ComputeAesInMapBase + (src_addr_page_aligned % DeviceAddressSpaceAlign);
|
||||||
const u32 dst_se_map_addr = CryptAesOutMapBase + (dst_addr_page_aligned % DeviceAddressSpaceAlign);
|
const u32 dst_se_map_addr = ComputeAesOutMapBase + (dst_addr_page_aligned % DeviceAddressSpaceAlign);
|
||||||
const u32 src_se_addr = CryptAesInMapBase + (src_addr % DeviceAddressSpaceAlign);
|
const u32 src_se_addr = ComputeAesInMapBase + (src_addr % DeviceAddressSpaceAlign);
|
||||||
const u32 dst_se_addr = CryptAesOutMapBase + (dst_addr % DeviceAddressSpaceAlign);
|
const u32 dst_se_addr = ComputeAesOutMapBase + (dst_addr % DeviceAddressSpaceAlign);
|
||||||
|
|
||||||
/* Validate aligned sizes. */
|
/* Validate aligned sizes. */
|
||||||
R_UNLESS(src_size_page_aligned <= CryptAesSizeMax, spl::ResultInvalidSize());
|
R_UNLESS(src_size_page_aligned <= ComputeAesSizeMax, spl::ResultInvalidSize());
|
||||||
R_UNLESS(dst_size_page_aligned <= CryptAesSizeMax, spl::ResultInvalidSize());
|
R_UNLESS(dst_size_page_aligned <= ComputeAesSizeMax, spl::ResultInvalidSize());
|
||||||
|
|
||||||
/* Helpers for mapping/unmapping. */
|
/* Helpers for mapping/unmapping. */
|
||||||
DeviceAddressSpaceMapHelper in_mapper(g_se_das_hnd, src_se_map_addr, src_addr_page_aligned, src_size_page_aligned, 1);
|
DeviceAddressSpaceMapHelper in_mapper(g_se_das_hnd, src_se_map_addr, src_addr_page_aligned, src_size_page_aligned, 1);
|
||||||
@ -698,11 +704,11 @@ namespace ams::spl::impl {
|
|||||||
{
|
{
|
||||||
std::scoped_lock lk(g_async_op_lock);
|
std::scoped_lock lk(g_async_op_lock);
|
||||||
smc::AsyncOperationKey op_key;
|
smc::AsyncOperationKey op_key;
|
||||||
const u32 mode = smc::GetCryptAesMode(smc::CipherMode::Ctr, GetPhysicalKeySlot(keyslot, true));
|
const u32 mode = smc::GetComputeAesMode(smc::CipherMode::Ctr, GetPhysicalKeySlot(keyslot, true));
|
||||||
const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, out);
|
const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, out);
|
||||||
const u32 src_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, in);
|
const u32 src_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, in);
|
||||||
|
|
||||||
smc::Result res = smc::CryptAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, src_size);
|
smc::Result res = smc::ComputeAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, src_size);
|
||||||
if (res != smc::Result::Success) {
|
if (res != smc::Result::Success) {
|
||||||
return smc::ConvertResult(res);
|
return smc::ConvertResult(res);
|
||||||
}
|
}
|
||||||
@ -717,7 +723,7 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size) {
|
Result ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size) {
|
||||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||||
|
|
||||||
R_UNLESS(size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
R_UNLESS(size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||||
|
|
||||||
@ -725,9 +731,9 @@ namespace ams::spl::impl {
|
|||||||
return smc::ConvertResult(smc::ComputeCmac(out_cmac, GetPhysicalKeySlot(keyslot, true), g_work_buffer, size));
|
return smc::ConvertResult(smc::ComputeCmac(out_cmac, GetPhysicalKeySlot(keyslot, true), g_work_buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AllocateAesKeyslot(s32 *out_keyslot, const void *owner) {
|
Result AllocateAesKeySlot(s32 *out_keyslot, const void *owner) {
|
||||||
/* Find a virtual keyslot. */
|
/* Find a virtual keyslot. */
|
||||||
for (s32 i = 0; i < MaxVirtualAesKeyslots; i++) {
|
for (s32 i = 0; i < MaxVirtualAesKeySlots; i++) {
|
||||||
if (g_keyslot_owners[i] == nullptr) {
|
if (g_keyslot_owners[i] == nullptr) {
|
||||||
g_keyslot_owners[i] = owner;
|
g_keyslot_owners[i] = owner;
|
||||||
g_keyslot_contents[i] = { .type = KeySlotContentType::None };
|
g_keyslot_contents[i] = { .type = KeySlotContentType::None };
|
||||||
@ -737,20 +743,20 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
os::ClearSystemEvent(std::addressof(g_se_keyslot_available_event));
|
os::ClearSystemEvent(std::addressof(g_se_keyslot_available_event));
|
||||||
return spl::ResultOutOfKeyslots();
|
return spl::ResultOutOfKeySlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FreeAesKeyslot(s32 keyslot, const void *owner) {
|
Result DeallocateAesKeySlot(s32 keyslot, const void *owner) {
|
||||||
/* Only virtual keyslots can be freed. */
|
/* Only virtual keyslots can be freed. */
|
||||||
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeyslot());
|
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeySlot());
|
||||||
|
|
||||||
/* Ensure the keyslot is owned. */
|
/* Ensure the keyslot is owned. */
|
||||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||||
|
|
||||||
/* Clear the physical keyslot, if we're cached. */
|
/* Clear the physical keyslot, if we're cached. */
|
||||||
s32 phys_slot;
|
s32 phys_slot;
|
||||||
if (g_keyslot_cache.Release(std::addressof(phys_slot), keyslot)) {
|
if (g_keyslot_cache.Release(std::addressof(phys_slot), keyslot)) {
|
||||||
ClearPhysicalKeyslot(phys_slot);
|
ClearPhysicalKeySlot(phys_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the virtual keyslot. */
|
/* Clear the virtual keyslot. */
|
||||||
@ -763,15 +769,15 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RSA. */
|
/* RSA. */
|
||||||
Result DecryptRsaPrivateKey(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
Result DecryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||||
struct DecryptRsaPrivateKeyLayout {
|
struct DecryptDeviceUniqueDataLayout {
|
||||||
u8 data[RsaPrivateKeySize + RsaPrivateKeyMetaSize];
|
u8 data[RsaPrivateKeySize + DeviceUniqueDataMetaSize];
|
||||||
};
|
};
|
||||||
DecryptRsaPrivateKeyLayout *layout = reinterpret_cast<DecryptRsaPrivateKeyLayout *>(g_work_buffer);
|
DecryptDeviceUniqueDataLayout *layout = reinterpret_cast<DecryptDeviceUniqueDataLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate size. */
|
/* Validate size. */
|
||||||
R_UNLESS(src_size >= RsaPrivateKeyMetaSize, spl::ResultInvalidSize());
|
R_UNLESS(src_size >= DeviceUniqueDataMetaSize, spl::ResultInvalidSize());
|
||||||
R_UNLESS(src_size <= sizeof(DecryptRsaPrivateKeyLayout), spl::ResultInvalidSize());
|
R_UNLESS(src_size <= sizeof(DecryptDeviceUniqueDataLayout), spl::ResultInvalidSize());
|
||||||
|
|
||||||
std::memcpy(layout->data, src, src_size);
|
std::memcpy(layout->data, src, src_size);
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
armDCacheFlush(layout, sizeof(*layout));
|
||||||
@ -779,10 +785,10 @@ namespace ams::spl::impl {
|
|||||||
smc::Result smc_res;
|
smc::Result smc_res;
|
||||||
size_t copy_size = 0;
|
size_t copy_size = 0;
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||||
copy_size = std::min(dst_size, src_size - RsaPrivateKeyMetaSize);
|
copy_size = std::min(dst_size, src_size - DeviceUniqueDataMetaSize);
|
||||||
smc_res = smc::DecryptOrImportRsaPrivateKey(layout->data, src_size, access_key, key_source, static_cast<smc::DecryptOrImportMode>(option));
|
smc_res = smc::DecryptDeviceUniqueData(layout->data, src_size, access_key, key_source, static_cast<smc::DeviceUniqueDataMode>(option));
|
||||||
} else {
|
} else {
|
||||||
smc_res = smc::DecryptRsaPrivateKey(©_size, layout->data, src_size, access_key, key_source, option);
|
smc_res = smc::DecryptDeviceUniqueData(©_size, layout->data, src_size, access_key, key_source, option);
|
||||||
copy_size = std::min(dst_size, copy_size);
|
copy_size = std::min(dst_size, copy_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,71 +801,66 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* SSL */
|
/* SSL */
|
||||||
Result ImportSslKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
Result DecryptAndStoreSslClientCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
||||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportSslKey));
|
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreSslKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SslExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
Result ModularExponentiateWithSslClientCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
||||||
return SecureExpMod(out, out_size, base, base_size, mod, mod_size, smc::SecureExpModMode::Ssl);
|
return ModularExponentiateWithStorageKey(out, out_size, base, base_size, mod, mod_size, smc::ModularExponentiateWithStorageKeyMode::Ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ES */
|
/* ES */
|
||||||
Result ImportEsKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
Result LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, option);
|
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, option);
|
||||||
} else {
|
} else {
|
||||||
struct ImportEsKeyLayout {
|
struct LoadEsDeviceKeyLayout {
|
||||||
u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
u8 data[DeviceUniqueDataMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||||
};
|
};
|
||||||
ImportEsKeyLayout *layout = reinterpret_cast<ImportEsKeyLayout *>(g_work_buffer);
|
LoadEsDeviceKeyLayout *layout = reinterpret_cast<LoadEsDeviceKeyLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate size. */
|
/* Validate size. */
|
||||||
R_UNLESS(src_size <= sizeof(ImportEsKeyLayout), spl::ResultInvalidSize());
|
R_UNLESS(src_size <= sizeof(LoadEsDeviceKeyLayout), spl::ResultInvalidSize());
|
||||||
|
|
||||||
std::memcpy(layout, src, src_size);
|
std::memcpy(layout, src, src_size);
|
||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
armDCacheFlush(layout, sizeof(*layout));
|
||||||
return smc::ConvertResult(smc::ImportEsKey(layout->data, src_size, access_key, key_source, option));
|
return smc::ConvertResult(smc::LoadEsDeviceKey(layout->data, src_size, access_key, key_source, option));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnwrapTitleKey(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) {
|
Result 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 UnwrapEsRsaOaepWrappedKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsKeyType::TitleKey);
|
return PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsCommonKeyType::TitleKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnwrapCommonTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) {
|
Result PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) {
|
||||||
return smc::ConvertResult(smc::UnwrapCommonTitleKey(out_access_key, key_source, generation));
|
return smc::ConvertResult(smc::PrepareCommonEsTitleKey(out_access_key, key_source, generation));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ImportDrmKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
Result DecryptAndStoreDrmDeviceCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
||||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportDrmKey));
|
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreDrmDeviceCertKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DrmExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
Result ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
||||||
return SecureExpMod(out, out_size, base, base_size, mod, mod_size, smc::SecureExpModMode::Drm);
|
return ModularExponentiateWithStorageKey(out, out_size, base, base_size, mod, mod_size, smc::ModularExponentiateWithStorageKeyMode::DrmDeviceCert);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnwrapElicenseKey(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) {
|
Result 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 UnwrapEsRsaOaepWrappedKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsKeyType::ElicenseKey);
|
return PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsCommonKeyType::ArchiveKey);
|
||||||
}
|
|
||||||
|
|
||||||
Result LoadElicenseKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
|
|
||||||
/* Right now, this is just literally the same function as LoadTitleKey in N's impl. */
|
|
||||||
return LoadTitleKey(keyslot, owner, access_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FS */
|
/* FS */
|
||||||
Result ImportLotusKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, option);
|
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DecryptLotusMessage(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) {
|
Result 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) {
|
||||||
/* Validate sizes. */
|
/* Validate sizes. */
|
||||||
R_UNLESS(dst_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
R_UNLESS(dst_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||||
R_UNLESS(label_digest_size == LabelDigestSizeMax, spl::ResultInvalidSize());
|
R_UNLESS(label_digest_size == LabelDigestSizeMax, spl::ResultInvalidSize());
|
||||||
|
|
||||||
/* Nintendo doesn't check this result code, but we will. */
|
/* Nintendo doesn't check this result code, but we will. */
|
||||||
R_TRY(SecureExpMod(g_work_buffer, 0x100, base, base_size, mod, mod_size, smc::SecureExpModMode::Lotus));
|
R_TRY(ModularExponentiateWithStorageKey(g_work_buffer, 0x100, base, base_size, mod, mod_size, smc::ModularExponentiateWithStorageKeyMode::Gc));
|
||||||
|
|
||||||
size_t data_size = crypto::DecodeRsa2048OaepSha256(dst, dst_size, label_digest, label_digest_size, g_work_buffer, 0x100);
|
size_t data_size = crypto::DecodeRsa2048OaepSha256(dst, dst_size, label_digest, label_digest_size, g_work_buffer, 0x100);
|
||||||
R_UNLESS(data_size > 0, spl::ResultDecryptionFailed());
|
R_UNLESS(data_size > 0, spl::ResultDecryptionFailed());
|
||||||
@ -872,9 +873,9 @@ namespace ams::spl::impl {
|
|||||||
return smc::ConvertResult(smc::GenerateSpecificAesKey(out_key, key_source, generation, which));
|
return smc::ConvertResult(smc::GenerateSpecificAesKey(out_key, key_source, generation, which));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadTitleKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
|
Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
|
||||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||||
return LoadVirtualTitleKey(keyslot, access_key);
|
return LoadVirtualPreparedAesKey(keyslot, access_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetPackage2Hash(void *dst, const size_t size) {
|
Result GetPackage2Hash(void *dst, const size_t size) {
|
||||||
@ -882,7 +883,7 @@ namespace ams::spl::impl {
|
|||||||
R_UNLESS(size >= sizeof(hash), spl::ResultInvalidSize());
|
R_UNLESS(size >= sizeof(hash), spl::ResultInvalidSize());
|
||||||
|
|
||||||
smc::Result smc_res;
|
smc::Result smc_res;
|
||||||
if ((smc_res = smc::GetConfig(hash, 4, SplConfigItem_Package2Hash)) != smc::Result::Success) {
|
if ((smc_res = smc::GetConfig(hash, 4, ConfigItem::Package2Hash)) != smc::Result::Success) {
|
||||||
return smc::ConvertResult(smc_res);
|
return smc::ConvertResult(smc_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -891,19 +892,19 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Manu. */
|
/* Manu. */
|
||||||
Result ReEncryptRsaPrivateKey(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) {
|
Result 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) {
|
||||||
struct ReEncryptRsaPrivateKeyLayout {
|
struct ReencryptDeviceUniqueDataLayout {
|
||||||
u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
u8 data[DeviceUniqueDataMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||||
AccessKey access_key_dec;
|
AccessKey access_key_dec;
|
||||||
KeySource source_dec;
|
KeySource source_dec;
|
||||||
AccessKey access_key_enc;
|
AccessKey access_key_enc;
|
||||||
KeySource source_enc;
|
KeySource source_enc;
|
||||||
};
|
};
|
||||||
ReEncryptRsaPrivateKeyLayout *layout = reinterpret_cast<ReEncryptRsaPrivateKeyLayout *>(g_work_buffer);
|
ReencryptDeviceUniqueDataLayout *layout = reinterpret_cast<ReencryptDeviceUniqueDataLayout *>(g_work_buffer);
|
||||||
|
|
||||||
/* Validate size. */
|
/* Validate size. */
|
||||||
R_UNLESS(src_size >= RsaPrivateKeyMetaSize, spl::ResultInvalidSize());
|
R_UNLESS(src_size >= DeviceUniqueDataMetaSize, spl::ResultInvalidSize());
|
||||||
R_UNLESS(src_size <= sizeof(ReEncryptRsaPrivateKeyLayout), spl::ResultInvalidSize());
|
R_UNLESS(src_size <= sizeof(ReencryptDeviceUniqueDataLayout), spl::ResultInvalidSize());
|
||||||
|
|
||||||
std::memcpy(layout, src, src_size);
|
std::memcpy(layout, src, src_size);
|
||||||
layout->access_key_dec = access_key_dec;
|
layout->access_key_dec = access_key_dec;
|
||||||
@ -913,7 +914,7 @@ namespace ams::spl::impl {
|
|||||||
|
|
||||||
armDCacheFlush(layout, sizeof(*layout));
|
armDCacheFlush(layout, sizeof(*layout));
|
||||||
|
|
||||||
smc::Result smc_res = smc::ReEncryptRsaPrivateKey(layout->data, src_size, layout->access_key_dec, layout->source_dec, layout->access_key_enc, layout->source_enc, option);
|
smc::Result smc_res = smc::ReencryptDeviceUniqueData(layout->data, src_size, layout->access_key_dec, layout->source_dec, layout->access_key_enc, layout->source_enc, option);
|
||||||
if (smc_res == smc::Result::Success) {
|
if (smc_res == smc::Result::Success) {
|
||||||
size_t copy_size = std::min(dst_size, src_size);
|
size_t copy_size = std::min(dst_size, src_size);
|
||||||
armDCacheFlush(layout, copy_size);
|
armDCacheFlush(layout, copy_size);
|
||||||
@ -924,16 +925,16 @@ namespace ams::spl::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Helper. */
|
/* Helper. */
|
||||||
Result FreeAesKeyslots(const void *owner) {
|
Result DeallocateAllAesKeySlots(const void *owner) {
|
||||||
for (s32 slot = VirtualKeySlotMin; slot <= VirtualKeySlotMax; ++slot) {
|
for (s32 slot = VirtualKeySlotMin; slot <= VirtualKeySlotMax; ++slot) {
|
||||||
if (g_keyslot_owners[GetVirtualKeySlotIndex(slot)] == owner) {
|
if (g_keyslot_owners[GetVirtualKeySlotIndex(slot)] == owner) {
|
||||||
FreeAesKeyslot(slot, owner);
|
DeallocateAesKeySlot(slot, owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle GetAesKeyslotAvailableEventHandle() {
|
Handle GetAesKeySlotAvailableEventHandle() {
|
||||||
return os::GetReadableHandleOfSystemEvent(std::addressof(g_se_keyslot_available_event));
|
return os::GetReadableHandleOfSystemEvent(std::addressof(g_se_keyslot_available_event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ namespace ams::spl::impl {
|
|||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
/* General. */
|
/* General. */
|
||||||
Result GetConfig(u64 *out, SplConfigItem which);
|
Result GetConfig(u64 *out, spl::ConfigItem which);
|
||||||
Result ExpMod(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);
|
Result 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);
|
||||||
Result SetConfig(SplConfigItem which, u64 value);
|
Result SetConfig(spl::ConfigItem which, u64 value);
|
||||||
Result GenerateRandomBytes(void *out, size_t size);
|
Result GenerateRandomBytes(void *out, size_t size);
|
||||||
Result IsDevelopment(bool *out);
|
Result IsDevelopment(bool *out);
|
||||||
Result SetBootReason(BootReasonValue boot_reason);
|
Result SetBootReason(BootReasonValue boot_reason);
|
||||||
@ -35,39 +35,39 @@ namespace ams::spl::impl {
|
|||||||
Result LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source);
|
Result LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source);
|
||||||
Result GenerateAesKey(AesKey *out_key, const AccessKey &access_key, const KeySource &key_source);
|
Result GenerateAesKey(AesKey *out_key, const AccessKey &access_key, const KeySource &key_source);
|
||||||
Result DecryptAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 option);
|
Result DecryptAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 option);
|
||||||
Result CryptAesCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr);
|
Result ComputeCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr);
|
||||||
Result ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size);
|
Result ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size);
|
||||||
Result AllocateAesKeyslot(s32 *out_keyslot, const void *owner);
|
Result AllocateAesKeySlot(s32 *out_keyslot, const void *owner);
|
||||||
Result FreeAesKeyslot(s32 keyslot, const void *owner);
|
Result DeallocateAesKeySlot(s32 keyslot, const void *owner);
|
||||||
|
|
||||||
/* RSA. */
|
/* RSA. */
|
||||||
Result DecryptRsaPrivateKey(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
Result DecryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||||
|
|
||||||
/* SSL */
|
/* SSL */
|
||||||
Result ImportSslKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
Result DecryptAndStoreSslClientCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
||||||
Result SslExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
Result ModularExponentiateWithSslClientCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
||||||
|
|
||||||
/* ES */
|
/* ES */
|
||||||
Result ImportEsKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
Result LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||||
Result UnwrapTitleKey(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);
|
Result 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);
|
||||||
Result UnwrapCommonTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation);
|
Result PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation);
|
||||||
Result ImportDrmKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
Result DecryptAndStoreDrmDeviceCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
||||||
Result DrmExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
Result ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
||||||
Result UnwrapElicenseKey(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);
|
Result 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);
|
||||||
Result LoadElicenseKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
||||||
|
|
||||||
/* FS */
|
/* FS */
|
||||||
Result ImportLotusKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||||
Result DecryptLotusMessage(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);
|
Result 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);
|
||||||
Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which);
|
Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which);
|
||||||
Result LoadTitleKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
||||||
Result GetPackage2Hash(void *dst, const size_t size);
|
Result GetPackage2Hash(void *dst, const size_t size);
|
||||||
|
|
||||||
/* Manu. */
|
/* Manu. */
|
||||||
Result ReEncryptRsaPrivateKey(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);
|
Result 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);
|
||||||
|
|
||||||
/* Helper. */
|
/* Helper. */
|
||||||
Result FreeAesKeyslots(const void *owner);
|
Result DeallocateAllAesKeySlots(const void *owner);
|
||||||
Handle GetAesKeyslotAvailableEventHandle();
|
Handle GetAesKeySlotAvailableEventHandle();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace ams::spl {
|
|||||||
|
|
||||||
CryptoService::~CryptoService() {
|
CryptoService::~CryptoService() {
|
||||||
/* Free any keyslots this service is using. */
|
/* Free any keyslots this service is using. */
|
||||||
impl::FreeAesKeyslots(this);
|
impl::DeallocateAllAesKeySlots(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptoService::GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option) {
|
Result CryptoService::GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option) {
|
||||||
@ -40,24 +40,25 @@ namespace ams::spl {
|
|||||||
return impl::DecryptAesKey(out_key.GetPointer(), key_source, generation, option);
|
return impl::DecryptAesKey(out_key.GetPointer(), key_source, generation, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptoService::CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
Result CryptoService::ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
||||||
return impl::CryptAesCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
return impl::ComputeCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptoService::ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf) {
|
Result CryptoService::ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf) {
|
||||||
return impl::ComputeCmac(out_cmac.GetPointer(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize());
|
return impl::ComputeCmac(out_cmac.GetPointer(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptoService::AllocateAesKeyslot(sf::Out<s32> out_keyslot) {
|
Result CryptoService::AllocateAesKeySlot(sf::Out<s32> out_keyslot) {
|
||||||
return impl::AllocateAesKeyslot(out_keyslot.GetPointer(), this);
|
return impl::AllocateAesKeySlot(out_keyslot.GetPointer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CryptoService::FreeAesKeyslot(s32 keyslot) {
|
Result CryptoService::DeallocateAesKeySlot(s32 keyslot) {
|
||||||
return impl::FreeAesKeyslot(keyslot, this);
|
return impl::DeallocateAesKeySlot(keyslot, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryptoService::GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
Result CryptoService::GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
||||||
out_hnd.SetValue(impl::GetAesKeyslotAvailableEventHandle());
|
out_hnd.SetValue(impl::GetAesKeySlotAvailableEventHandle());
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,38 +20,19 @@ namespace ams::spl {
|
|||||||
|
|
||||||
class CryptoService : public GeneralService {
|
class CryptoService : public GeneralService {
|
||||||
public:
|
public:
|
||||||
CryptoService() : GeneralService() { /* ... */ }
|
|
||||||
virtual ~CryptoService();
|
virtual ~CryptoService();
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
|
||||||
virtual Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
|
||||||
virtual Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
|
||||||
virtual Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
|
||||||
virtual Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
|
||||||
virtual Result CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
|
||||||
virtual Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
|
||||||
virtual Result AllocateAesKeyslot(sf::Out<s32> out_keyslot);
|
|
||||||
virtual Result FreeAesKeyslot(s32 keyslot);
|
|
||||||
virtual void GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd);
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
/* Actual commands. */
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
Result ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
Result AllocateAesKeySlot(sf::Out<s32> out_keyslot);
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
Result DeallocateAesKeySlot(s32 keyslot);
|
||||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
Result GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd);
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
|
||||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
|
||||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsICryptoInterface<CryptoService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,17 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
Result DeprecatedService::GetConfig(sf::Out<u64> out, u32 which) {
|
DeprecatedService::~DeprecatedService() {
|
||||||
return impl::GetConfig(out.GetPointer(), static_cast<SplConfigItem>(which));
|
/* Free any keyslots this service is using. */
|
||||||
|
impl::DeallocateAllAesKeySlots(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
Result DeprecatedService::GetConfig(sf::Out<u64> out, u32 which) {
|
||||||
return impl::ExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
return impl::GetConfig(out.GetPointer(), static_cast<spl::ConfigItem>(which));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DeprecatedService::ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
||||||
|
return impl::ModularExponentiate(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option) {
|
Result DeprecatedService::GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option) {
|
||||||
@ -40,19 +45,19 @@ namespace ams::spl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::SetConfig(u32 which, u64 value) {
|
Result DeprecatedService::SetConfig(u32 which, u64 value) {
|
||||||
return impl::SetConfig(static_cast<SplConfigItem>(which), value);
|
return impl::SetConfig(static_cast<spl::ConfigItem>(which), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::GenerateRandomBytes(const sf::OutPointerBuffer &out) {
|
Result DeprecatedService::GenerateRandomBytes(const sf::OutPointerBuffer &out) {
|
||||||
return impl::GenerateRandomBytes(out.GetPointer(), out.GetSize());
|
return impl::GenerateRandomBytes(out.GetPointer(), out.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
Result DeprecatedService::DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||||
return impl::ImportLotusKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
return impl::DecryptAndStoreGcKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
Result DeprecatedService::DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||||
return impl::DecryptLotusMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
return impl::DecryptGcMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::IsDevelopment(sf::Out<bool> is_dev) {
|
Result DeprecatedService::IsDevelopment(sf::Out<bool> is_dev) {
|
||||||
@ -63,60 +68,61 @@ namespace ams::spl {
|
|||||||
return impl::GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which);
|
return impl::GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
Result DeprecatedService::DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||||
return impl::DecryptRsaPrivateKey(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
return impl::DecryptDeviceUniqueData(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option) {
|
Result DeprecatedService::DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option) {
|
||||||
return impl::DecryptAesKey(out_key.GetPointer(), key_source, generation, option);
|
return impl::DecryptAesKey(out_key.GetPointer(), key_source, generation, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::CryptAesCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr) {
|
Result DeprecatedService::ComputeCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr) {
|
||||||
return impl::CryptAesCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
return impl::ComputeCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
Result DeprecatedService::ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
||||||
return impl::CryptAesCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
return impl::ComputeCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf) {
|
Result DeprecatedService::ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf) {
|
||||||
return impl::ComputeCmac(out_cmac.GetPointer(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize());
|
return impl::ComputeCmac(out_cmac.GetPointer(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
Result DeprecatedService::LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||||
return impl::ImportEsKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
return impl::LoadEsDeviceKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::UnwrapTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
Result DeprecatedService::PrepareEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||||
return impl::UnwrapTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), 0);
|
return impl::PrepareEsTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
Result DeprecatedService::PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||||
return impl::UnwrapTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
return impl::PrepareEsTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::LoadTitleKey(s32 keyslot, AccessKey access_key) {
|
Result DeprecatedService::LoadPreparedAesKey(s32 keyslot, AccessKey access_key) {
|
||||||
return impl::LoadTitleKey(keyslot, this, access_key);
|
return impl::LoadPreparedAesKey(keyslot, this, access_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::UnwrapCommonTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source) {
|
Result DeprecatedService::PrepareCommonEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source) {
|
||||||
return impl::UnwrapCommonTitleKey(out_access_key.GetPointer(), key_source, 0);
|
return impl::PrepareCommonEsTitleKey(out_access_key.GetPointer(), key_source, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
Result DeprecatedService::PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
||||||
return impl::UnwrapCommonTitleKey(out_access_key.GetPointer(), key_source, generation);
|
return impl::PrepareCommonEsTitleKey(out_access_key.GetPointer(), key_source, generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::AllocateAesKeyslot(sf::Out<s32> out_keyslot) {
|
Result DeprecatedService::AllocateAesKeySlot(sf::Out<s32> out_keyslot) {
|
||||||
return impl::AllocateAesKeyslot(out_keyslot.GetPointer(), this);
|
return impl::AllocateAesKeySlot(out_keyslot.GetPointer(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::FreeAesKeyslot(s32 keyslot) {
|
Result DeprecatedService::DeallocateAesKeySlot(s32 keyslot) {
|
||||||
return impl::FreeAesKeyslot(keyslot, this);
|
return impl::DeallocateAesKeySlot(keyslot, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeprecatedService::GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
Result DeprecatedService::GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
||||||
out_hnd.SetValue(impl::GetAesKeyslotAvailableEventHandle());
|
out_hnd.SetValue(impl::GetAesKeySlotAvailableEventHandle());
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeprecatedService::SetBootReason(BootReasonValue boot_reason) {
|
Result DeprecatedService::SetBootReason(BootReasonValue boot_reason) {
|
||||||
|
@ -18,112 +18,39 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class DeprecatedService : public sf::IServiceObject {
|
class DeprecatedService final {
|
||||||
protected:
|
public:
|
||||||
enum class CommandId {
|
virtual ~DeprecatedService();
|
||||||
/* 1.0.0+ */
|
|
||||||
GetConfig = 0,
|
|
||||||
ExpMod = 1,
|
|
||||||
GenerateAesKek = 2,
|
|
||||||
LoadAesKey = 3,
|
|
||||||
GenerateAesKey = 4,
|
|
||||||
SetConfig = 5,
|
|
||||||
GenerateRandomBytes = 7,
|
|
||||||
ImportLotusKey = 9,
|
|
||||||
DecryptLotusMessage = 10,
|
|
||||||
IsDevelopment = 11,
|
|
||||||
GenerateSpecificAesKey = 12,
|
|
||||||
DecryptRsaPrivateKeyDeprecated = 13,
|
|
||||||
DecryptRsaPrivateKey = 13,
|
|
||||||
DecryptAesKey = 14,
|
|
||||||
CryptAesCtrDeprecated = 15,
|
|
||||||
CryptAesCtr = 15,
|
|
||||||
ComputeCmac = 16,
|
|
||||||
ImportEsKey = 17,
|
|
||||||
UnwrapTitleKeyDeprecated = 18,
|
|
||||||
UnwrapTitleKey = 18,
|
|
||||||
LoadTitleKey = 19,
|
|
||||||
|
|
||||||
/* 2.0.0+ */
|
|
||||||
UnwrapCommonTitleKeyDeprecated = 20,
|
|
||||||
UnwrapCommonTitleKey = 20,
|
|
||||||
AllocateAesKeyslot = 21,
|
|
||||||
FreeAesKeyslot = 22,
|
|
||||||
GetAesKeyslotAvailableEvent = 23,
|
|
||||||
|
|
||||||
/* 3.0.0+ */
|
|
||||||
SetBootReason = 24,
|
|
||||||
GetBootReason = 25,
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
DeprecatedService() { /* ... */ }
|
|
||||||
virtual ~DeprecatedService() { /* ... */ }
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result GetConfig(sf::Out<u64> out, u32 which);
|
Result GetConfig(sf::Out<u64> out, u32 which);
|
||||||
virtual Result ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
Result ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
||||||
virtual Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
||||||
virtual Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
||||||
virtual Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
||||||
virtual Result SetConfig(u32 which, u64 value);
|
Result SetConfig(u32 which, u64 value);
|
||||||
virtual Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
||||||
virtual Result ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
Result DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||||
virtual Result DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
Result DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||||
virtual Result IsDevelopment(sf::Out<bool> is_dev);
|
Result IsDevelopment(sf::Out<bool> is_dev);
|
||||||
virtual Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
||||||
virtual Result DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
Result DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||||
virtual Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
||||||
virtual Result CryptAesCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr);
|
Result ComputeCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr);
|
||||||
virtual Result CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
Result ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
||||||
virtual Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
||||||
virtual Result ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
Result LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||||
virtual Result UnwrapTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
Result PrepareEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||||
virtual Result UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
Result PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||||
virtual Result LoadTitleKey(s32 keyslot, AccessKey access_key);
|
Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key);
|
||||||
virtual Result UnwrapCommonTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source);
|
Result PrepareCommonEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source);
|
||||||
virtual Result UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
Result PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
||||||
virtual Result AllocateAesKeyslot(sf::Out<s32> out_keyslot);
|
Result AllocateAesKeySlot(sf::Out<s32> out_keyslot);
|
||||||
virtual Result FreeAesKeyslot(s32 keyslot);
|
Result DeallocateAesKeySlot(s32 keyslot);
|
||||||
virtual void GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd);
|
Result GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd);
|
||||||
virtual Result SetBootReason(BootReasonValue boot_reason);
|
Result SetBootReason(BootReasonValue boot_reason);
|
||||||
virtual Result GetBootReason(sf::Out<BootReasonValue> out);
|
Result GetBootReason(sf::Out<BootReasonValue> out);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportLotusKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptLotusMessage),
|
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateSpecificAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtrDeprecated, hos::Version_1_0_0, hos::Version_1_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr, hos::Version_2_0_0),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportEsKey),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapTitleKeyDeprecated, hos::Version_1_0_0, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapTitleKey, hos::Version_3_0_0),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadTitleKey),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapCommonTitleKeyDeprecated, hos::Version_2_0_0, hos::Version_2_3_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapCommonTitleKey, hos::Version_3_0_0),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
|
||||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIDeprecatedGeneralInterface<DeprecatedService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
30
stratosphere/spl/source/spl_device_unique_data_service.cpp
Normal file
30
stratosphere/spl/source/spl_device_unique_data_service.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 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_api_impl.hpp"
|
||||||
|
#include "spl_device_unique_data_service.hpp"
|
||||||
|
|
||||||
|
namespace ams::spl {
|
||||||
|
|
||||||
|
Result DeviceUniqueDataService::DecryptDeviceUniqueDataDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||||
|
return impl::DecryptDeviceUniqueData(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DeviceUniqueDataService::DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||||
|
return impl::DecryptDeviceUniqueData(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptDeviceUniqueData));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,14 +18,12 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class RsaService : public CryptoService {
|
class DeviceUniqueDataService : public CryptoService {
|
||||||
public:
|
public:
|
||||||
RsaService() : CryptoService() { /* ... */ }
|
|
||||||
virtual ~RsaService() { /* ... */ }
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result DecryptRsaPrivateKeyDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
Result DecryptDeviceUniqueDataDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||||
virtual Result DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
Result DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIDeviceUniqueDataInterface<DeviceUniqueDataService>);
|
||||||
|
|
||||||
}
|
}
|
@ -19,36 +19,36 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
Result EsService::ImportEsKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
Result EsService::LoadEsDeviceKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||||
return impl::ImportEsKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
return impl::LoadEsDeviceKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
Result EsService::LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||||
return impl::ImportEsKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportEsKey));
|
return impl::LoadEsDeviceKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreEsDeviceKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
Result EsService::PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||||
return impl::UnwrapTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
return impl::PrepareEsTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
Result EsService::PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
||||||
return impl::UnwrapCommonTitleKey(out_access_key.GetPointer(), key_source, generation);
|
return impl::PrepareCommonEsTitleKey(out_access_key.GetPointer(), key_source, generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::ImportDrmKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
Result EsService::DecryptAndStoreDrmDeviceCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||||
return impl::ImportDrmKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
return impl::DecryptAndStoreDrmDeviceCertKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::DrmExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
Result EsService::ModularExponentiateWithDrmDeviceCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
||||||
return impl::DrmExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
return impl::ModularExponentiateWithDrmDeviceCertKey(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::UnwrapElicenseKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
Result EsService::PrepareEsArchiveKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||||
return impl::UnwrapElicenseKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
return impl::PrepareEsArchiveKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EsService::LoadElicenseKey(s32 keyslot, AccessKey access_key) {
|
Result EsService::LoadPreparedAesKey(s32 keyslot, AccessKey access_key) {
|
||||||
return impl::LoadElicenseKey(keyslot, this, access_key);
|
return impl::LoadPreparedAesKey(keyslot, this, access_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,53 +14,22 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "spl_rsa_service.hpp"
|
#include "spl_device_unique_data_service.hpp"
|
||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class EsService : public RsaService {
|
class EsService : public DeviceUniqueDataService {
|
||||||
public:
|
public:
|
||||||
EsService() : RsaService() { /* ... */ }
|
|
||||||
virtual ~EsService() { /* ... */}
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result ImportEsKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
Result LoadEsDeviceKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||||
virtual Result ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
Result LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||||
virtual Result UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
Result PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||||
virtual Result UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
Result PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
||||||
virtual Result ImportDrmKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
Result DecryptAndStoreDrmDeviceCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||||
virtual Result DrmExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
Result ModularExponentiateWithDrmDeviceCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
||||||
virtual Result UnwrapElicenseKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
Result PrepareEsArchiveKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||||
virtual Result LoadElicenseKey(s32 keyslot, AccessKey access_key);
|
Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
|
||||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportEsKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportEsKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapTitleKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapCommonTitleKey, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportDrmKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DrmExpMod, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(UnwrapElicenseKey, hos::Version_6_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadElicenseKey, hos::Version_6_0_0),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIEsInterface<EsService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,24 +19,24 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
Result FsService::ImportLotusKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
Result FsService::DecryptAndStoreGcKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||||
return impl::ImportLotusKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
return impl::DecryptAndStoreGcKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FsService::ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
Result FsService::DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||||
return impl::ImportLotusKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportLotusKey));
|
return impl::DecryptAndStoreGcKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreGcKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FsService::DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
Result FsService::DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||||
return impl::DecryptLotusMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
return impl::DecryptGcMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FsService::GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which) {
|
Result FsService::GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which) {
|
||||||
return impl::GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which);
|
return impl::GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FsService::LoadTitleKey(s32 keyslot, AccessKey access_key) {
|
Result FsService::LoadPreparedAesKey(s32 keyslot, AccessKey access_key) {
|
||||||
return impl::LoadTitleKey(keyslot, this, access_key);
|
return impl::LoadPreparedAesKey(keyslot, this, access_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FsService::GetPackage2Hash(const sf::OutPointerBuffer &dst) {
|
Result FsService::GetPackage2Hash(const sf::OutPointerBuffer &dst) {
|
||||||
|
@ -20,41 +20,14 @@ namespace ams::spl {
|
|||||||
|
|
||||||
class FsService : public CryptoService {
|
class FsService : public CryptoService {
|
||||||
public:
|
public:
|
||||||
FsService() : CryptoService() { /* ... */ }
|
|
||||||
virtual ~FsService() { /* ... */ }
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result ImportLotusKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
Result DecryptAndStoreGcKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||||
virtual Result ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
Result DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||||
virtual Result DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
Result DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||||
virtual Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
||||||
virtual Result LoadTitleKey(s32 keyslot, AccessKey access_key);
|
Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key);
|
||||||
virtual Result GetPackage2Hash(const sf::OutPointerBuffer &dst);
|
Result GetPackage2Hash(const sf::OutPointerBuffer &dst);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
|
||||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportLotusKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportLotusKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptLotusMessage),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateSpecificAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadTitleKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetPackage2Hash, hos::Version_5_0_0),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIFsInterface<FsService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,15 @@
|
|||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
Result GeneralService::GetConfig(sf::Out<u64> out, u32 which) {
|
Result GeneralService::GetConfig(sf::Out<u64> out, u32 which) {
|
||||||
return impl::GetConfig(out.GetPointer(), static_cast<SplConfigItem>(which));
|
return impl::GetConfig(out.GetPointer(), static_cast<spl::ConfigItem>(which));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GeneralService::ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
Result GeneralService::ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
||||||
return impl::ExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
return impl::ModularExponentiate(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GeneralService::SetConfig(u32 which, u64 value) {
|
Result GeneralService::SetConfig(u32 which, u64 value) {
|
||||||
return impl::SetConfig(static_cast<SplConfigItem>(which), value);
|
return impl::SetConfig(static_cast<spl::ConfigItem>(which), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GeneralService::GenerateRandomBytes(const sf::OutPointerBuffer &out) {
|
Result GeneralService::GenerateRandomBytes(const sf::OutPointerBuffer &out) {
|
||||||
|
@ -18,76 +18,17 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class GeneralService : public sf::IServiceObject {
|
class GeneralService {
|
||||||
protected:
|
|
||||||
enum class CommandId {
|
|
||||||
/* 1.0.0+ */
|
|
||||||
GetConfig = 0,
|
|
||||||
ExpMod = 1,
|
|
||||||
GenerateAesKek = 2,
|
|
||||||
LoadAesKey = 3,
|
|
||||||
GenerateAesKey = 4,
|
|
||||||
SetConfig = 5,
|
|
||||||
GenerateRandomBytes = 7,
|
|
||||||
ImportLotusKeyDeprecated = 9,
|
|
||||||
ImportLotusKey = 9,
|
|
||||||
DecryptLotusMessage = 10,
|
|
||||||
IsDevelopment = 11,
|
|
||||||
GenerateSpecificAesKey = 12,
|
|
||||||
DecryptRsaPrivateKeyDeprecated = 13,
|
|
||||||
DecryptRsaPrivateKey = 13,
|
|
||||||
DecryptAesKey = 14,
|
|
||||||
CryptAesCtr = 15,
|
|
||||||
ComputeCmac = 16,
|
|
||||||
ImportEsKeyDeprecated = 17,
|
|
||||||
ImportEsKey = 17,
|
|
||||||
UnwrapTitleKey = 18,
|
|
||||||
LoadTitleKey = 19,
|
|
||||||
|
|
||||||
/* 2.0.0+ */
|
|
||||||
UnwrapCommonTitleKey = 20,
|
|
||||||
AllocateAesKeyslot = 21,
|
|
||||||
FreeAesKeyslot = 22,
|
|
||||||
GetAesKeyslotAvailableEvent = 23,
|
|
||||||
|
|
||||||
/* 3.0.0+ */
|
|
||||||
SetBootReason = 24,
|
|
||||||
GetBootReason = 25,
|
|
||||||
|
|
||||||
/* 5.0.0+ */
|
|
||||||
ImportSslKey = 26,
|
|
||||||
SslExpMod = 27,
|
|
||||||
ImportDrmKey = 28,
|
|
||||||
DrmExpMod = 29,
|
|
||||||
ReEncryptRsaPrivateKey = 30,
|
|
||||||
GetPackage2Hash = 31,
|
|
||||||
|
|
||||||
/* 6.0.0+ */
|
|
||||||
UnwrapElicenseKey = 31, /* re-used command id :( */
|
|
||||||
LoadElicenseKey = 32,
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
GeneralService() { /* ... */ }
|
|
||||||
virtual ~GeneralService() { /* ... */ }
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result GetConfig(sf::Out<u64> out, u32 which);
|
Result GetConfig(sf::Out<u64> out, u32 which);
|
||||||
virtual Result ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
Result ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
||||||
virtual Result SetConfig(u32 which, u64 value);
|
Result SetConfig(u32 which, u64 value);
|
||||||
virtual Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
||||||
virtual Result IsDevelopment(sf::Out<bool> is_dev);
|
Result IsDevelopment(sf::Out<bool> is_dev);
|
||||||
virtual Result SetBootReason(BootReasonValue boot_reason);
|
Result SetBootReason(BootReasonValue boot_reason);
|
||||||
virtual Result GetBootReason(sf::Out<BootReasonValue> out);
|
Result GetBootReason(sf::Out<BootReasonValue> out);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIGeneralInterface<GeneralService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -138,18 +138,18 @@ int main(int argc, char **argv)
|
|||||||
spl::impl::Initialize();
|
spl::impl::Initialize();
|
||||||
|
|
||||||
/* Create services. */
|
/* Create services. */
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::RandomService>(RandomServiceName, RandomMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IRandomInterface, spl::RandomService>(RandomServiceName, RandomMaxSessions)));
|
||||||
if (hos::GetVersion() >= hos::Version_4_0_0) {
|
if (hos::GetVersion() >= hos::Version_4_0_0) {
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::GeneralService>(GeneralServiceName, GeneralMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IGeneralInterface, spl::GeneralService>(GeneralServiceName, GeneralMaxSessions)));
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::CryptoService>(CryptoServiceName, CryptoMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::ICryptoInterface, spl::CryptoService>(CryptoServiceName, CryptoMaxSessions)));
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::SslService>(SslServiceName, SslMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::ISslInterface, spl::SslService>(SslServiceName, SslMaxSessions)));
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::EsService>(EsServiceName, EsMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IEsInterface, spl::EsService>(EsServiceName, EsMaxSessions)));
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::FsService>(FsServiceName, FsMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IFsInterface, spl::FsService>(FsServiceName, FsMaxSessions)));
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::ManuService>(ManuServiceName, ManuMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IManuInterface, spl::ManuService>(ManuServiceName, ManuMaxSessions)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::DeprecatedService>(DeprecatedServiceName, DeprecatedMaxSessions));
|
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IDeprecatedGeneralInterface, spl::DeprecatedService>(DeprecatedServiceName, DeprecatedMaxSessions)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
Result ManuService::ReEncryptRsaPrivateKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option) {
|
Result ManuService::ReencryptDeviceUniqueData(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option) {
|
||||||
return impl::ReEncryptRsaPrivateKey(out.GetPointer(), out.GetSize(), src.GetPointer(), src.GetSize(), access_key_dec, source_dec, access_key_enc, source_enc, option);
|
return impl::ReencryptDeviceUniqueData(out.GetPointer(), out.GetSize(), src.GetPointer(), src.GetSize(), access_key_dec, source_dec, access_key_enc, source_enc, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,40 +14,15 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "spl_rsa_service.hpp"
|
#include "spl_device_unique_data_service.hpp"
|
||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class ManuService : public RsaService {
|
class ManuService : public DeviceUniqueDataService {
|
||||||
public:
|
public:
|
||||||
ManuService() : RsaService() { /* ... */ }
|
|
||||||
|
|
||||||
virtual ~ManuService() { /* ... */ }
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result ReEncryptRsaPrivateKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option);
|
Result ReencryptDeviceUniqueData(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
|
||||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReEncryptRsaPrivateKey, hos::Version_5_0_0),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIManuInterface<ManuService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,21 +18,11 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class RandomService final : public sf::IServiceObject {
|
class RandomService final {
|
||||||
protected:
|
|
||||||
enum class CommandId {
|
|
||||||
GenerateRandomBytes = 0,
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
RandomService() { /* ... */ }
|
|
||||||
virtual ~RandomService() { /* ... */ }
|
|
||||||
private:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result GenerateRandomBytes(const sf::OutBuffer &out);
|
Result GenerateRandomBytes(const sf::OutBuffer &out);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsIRandomInterface<RandomService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018-2020 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_api_impl.hpp"
|
|
||||||
#include "spl_rsa_service.hpp"
|
|
||||||
|
|
||||||
namespace ams::spl {
|
|
||||||
|
|
||||||
Result RsaService::DecryptRsaPrivateKeyDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
|
||||||
return impl::DecryptRsaPrivateKey(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result RsaService::DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
|
||||||
return impl::DecryptRsaPrivateKey(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::DecryptRsaPrivateKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -19,12 +19,12 @@
|
|||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
Result SslService::ImportSslKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
Result SslService::DecryptAndStoreSslClientCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||||
return impl::ImportSslKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
return impl::DecryptAndStoreSslClientCertKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SslService::SslExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
Result SslService::ModularExponentiateWithSslClientCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
||||||
return impl::SslExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
return impl::ModularExponentiateWithSslClientCertKey(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,42 +14,16 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "spl_rsa_service.hpp"
|
#include "spl_device_unique_data_service.hpp"
|
||||||
|
|
||||||
namespace ams::spl {
|
namespace ams::spl {
|
||||||
|
|
||||||
class SslService : public RsaService {
|
class SslService : public DeviceUniqueDataService {
|
||||||
public:
|
public:
|
||||||
SslService() : RsaService() { /* ... */ }
|
|
||||||
virtual ~SslService() { /* ... */ }
|
|
||||||
protected:
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result ImportSslKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
Result DecryptAndStoreSslClientCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||||
virtual Result SslExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
Result ModularExponentiateWithSslClientCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
|
||||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
|
||||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ImportSslKey, hos::Version_5_0_0),
|
|
||||||
MAKE_SERVICE_COMMAND_META(SslExpMod, hos::Version_5_0_0),
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
static_assert(spl::impl::IsISslInterface<SslService>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user