From 85e8506fa8a1d411d09fb90d62dc0079925deaf3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 25 Apr 2019 00:33:10 -0700 Subject: [PATCH] spl: Implement non-Lotus FsService commands. --- stratosphere/spl/source/spl_fs_service.cpp | 44 +++++++++++++ stratosphere/spl/source/spl_fs_service.hpp | 65 +++++++++++++++++++ stratosphere/spl/source/spl_main.cpp | 6 +- .../spl/source/spl_secmon_wrapper.cpp | 20 ++++++ .../spl/source/spl_secmon_wrapper.hpp | 2 + stratosphere/spl/source/spl_smc_wrapper.cpp | 4 +- stratosphere/spl/source/spl_smc_wrapper.hpp | 2 +- 7 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 stratosphere/spl/source/spl_fs_service.cpp create mode 100644 stratosphere/spl/source/spl_fs_service.hpp diff --git a/stratosphere/spl/source/spl_fs_service.cpp b/stratosphere/spl/source/spl_fs_service.cpp new file mode 100644 index 000000000..81dd84f00 --- /dev/null +++ b/stratosphere/spl/source/spl_fs_service.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "spl_fs_service.hpp" + +Result FsService::ImportLotusKey(InPointer src, AccessKey access_key, KeySource key_source, u32 option) { + return ResultSuccess; + /* TODO */ + return ResultKernelConnectionClosed; +} + +Result FsService::DecryptLotusMessage(Out out_size, OutPointerWithClientSize out, InPointer base, InPointer mod, InPointer label_digest) { + return ResultSuccess; + /* TODO */ + return ResultKernelConnectionClosed; +} + +Result FsService::GenerateSpecificAesKey(Out out_key, KeySource key_source, u32 generation, u32 which) { + return this->GetSecureMonitorWrapper()->GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which); +} + +Result FsService::LoadTitleKey(u32 keyslot, AccessKey access_key) { + return this->GetSecureMonitorWrapper()->LoadTitleKey(keyslot, this, access_key); +} + +Result FsService::GetPackage2Hash(OutPointerWithClientSize dst) { + return this->GetSecureMonitorWrapper()->GetPackage2Hash(dst.pointer, dst.num_elements); +} diff --git a/stratosphere/spl/source/spl_fs_service.hpp b/stratosphere/spl/source/spl_fs_service.hpp new file mode 100644 index 000000000..4a7bd4872 --- /dev/null +++ b/stratosphere/spl/source/spl_fs_service.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-2019 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 . + */ + +#pragma once +#include +#include + +#include "spl_types.hpp" +#include "spl_crypto_service.hpp" + +class FsService : public CryptoService { + public: + FsService(SecureMonitorWrapper *sw) : CryptoService(sw) { + /* ... */ + } + + virtual ~FsService() { + /* ... */ + } + protected: + /* Actual commands. */ + virtual Result ImportLotusKey(InPointer src, AccessKey access_key, KeySource key_source, u32 option); + virtual Result DecryptLotusMessage(Out out_size, OutPointerWithClientSize out, InPointer base, InPointer mod, InPointer label_digest); + virtual Result GenerateSpecificAesKey(Out out_key, KeySource key_source, u32 generation, u32 which); + virtual Result LoadTitleKey(u32 keyslot, AccessKey access_key); + virtual Result GetPackage2Hash(OutPointerWithClientSize dst); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + + }; +}; diff --git a/stratosphere/spl/source/spl_main.cpp b/stratosphere/spl/source/spl_main.cpp index 1fa653a73..47eec447e 100644 --- a/stratosphere/spl/source/spl_main.cpp +++ b/stratosphere/spl/source/spl_main.cpp @@ -27,6 +27,7 @@ #include "spl_crypto_service.hpp" #include "spl_ssl_service.hpp" #include "spl_es_service.hpp" +#include "spl_fs_service.hpp" #include "spl_manu_service.hpp" extern "C" { @@ -92,6 +93,7 @@ static const auto MakeGeneralService = []() { return std::make_shared(&s_secmon_wrapper); }; static const auto MakeSslService = []() { return std::make_shared(&s_secmon_wrapper); }; static const auto MakeEsService = []() { return std::make_shared(&s_secmon_wrapper); }; +static const auto MakeFsService = []() { return std::make_shared(&s_secmon_wrapper); }; static const auto MakeManuService = []() { return std::make_shared(&s_secmon_wrapper); }; int main(int argc, char **argv) @@ -111,13 +113,15 @@ int main(int argc, char **argv) s_server_manager.AddWaitable(new ServiceServer("spl:mig", 6)); s_server_manager.AddWaitable(new ServiceServer("spl:ssl", 2)); s_server_manager.AddWaitable(new ServiceServer("spl:es", 2)); - /* TODO: spl:fs. */ + s_server_manager.AddWaitable(new ServiceServer("spl:fs", 2)); if (GetRuntimeFirmwareVersion() >= FirmwareVersion_500) { s_server_manager.AddWaitable(new ServiceServer("spl:manu", 1)); } } else { /* TODO, DeprecatedGeneralService */ } + + RebootToRcm(); /* Loop forever, servicing our services. */ s_server_manager.Process(); diff --git a/stratosphere/spl/source/spl_secmon_wrapper.cpp b/stratosphere/spl/source/spl_secmon_wrapper.cpp index 83c220c00..1105ab896 100644 --- a/stratosphere/spl/source/spl_secmon_wrapper.cpp +++ b/stratosphere/spl/source/spl_secmon_wrapper.cpp @@ -726,6 +726,10 @@ Result SecureMonitorWrapper::LoadElicenseKey(u32 keyslot, const void *owner, con return LoadTitleKey(keyslot, owner, access_key); } +Result SecureMonitorWrapper::GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which) { + return ConvertToSplResult(SmcWrapper::GenerateSpecificAesKey(out_key, key_source, generation, which)); +} + Result SecureMonitorWrapper::LoadTitleKey(u32 keyslot, const void *owner, const AccessKey &access_key) { Result rc = ValidateAesKeyslot(keyslot, owner); if (R_FAILED(rc)) { @@ -734,6 +738,22 @@ Result SecureMonitorWrapper::LoadTitleKey(u32 keyslot, const void *owner, const return ConvertToSplResult(SmcWrapper::LoadTitleKey(keyslot, access_key)); } +Result SecureMonitorWrapper::GetPackage2Hash(void *dst, const size_t size) { + u64 hash[4]; + + if (size < sizeof(hash)) { + return ResultSplInvalidSize; + } + + SmcResult smc_res; + if ((smc_res = SmcWrapper::GetConfig(hash, 4, SplConfigItem_Package2Hash)) != SmcResult_Success) { + return ConvertToSplResult(smc_res); + } + + std::memcpy(dst, hash, sizeof(hash)); + return ResultSuccess; +} + Result SecureMonitorWrapper::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) { struct ReEncryptRsaPrivateKeyLayout { u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10]; diff --git a/stratosphere/spl/source/spl_secmon_wrapper.hpp b/stratosphere/spl/source/spl_secmon_wrapper.hpp index d4e93ecb1..4ec4e4222 100644 --- a/stratosphere/spl/source/spl_secmon_wrapper.hpp +++ b/stratosphere/spl/source/spl_secmon_wrapper.hpp @@ -93,7 +93,9 @@ class SecureMonitorWrapper { Result LoadElicenseKey(u32 keyslot, const void *owner, const AccessKey &access_key); /* FS */ + Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which); Result LoadTitleKey(u32 keyslot, const void *owner, const AccessKey &access_key); + Result GetPackage2Hash(void *dst, const size_t size); /* 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); diff --git a/stratosphere/spl/source/spl_smc_wrapper.cpp b/stratosphere/spl/source/spl_smc_wrapper.cpp index 8f39e87ec..5845f37ce 100644 --- a/stratosphere/spl/source/spl_smc_wrapper.cpp +++ b/stratosphere/spl/source/spl_smc_wrapper.cpp @@ -168,7 +168,7 @@ SmcResult SmcWrapper::CryptAes(AsyncOperationKey *out_op, u32 mode, const IvCtr return static_cast(args.X[0]); } -SmcResult SmcWrapper::GenerateSpecificAesKey(u64 *out, const KeySource &source, u32 generation, u32 which) { +SmcResult SmcWrapper::GenerateSpecificAesKey(AesKey *out_key, const KeySource &source, u32 generation, u32 which) { SecmonArgs args; args.X[0] = SmcFunctionId_GenerateSpecificAesKey; @@ -178,6 +178,8 @@ SmcResult SmcWrapper::GenerateSpecificAesKey(u64 *out, const KeySource &source, args.X[4] = which; svcCallSecureMonitor(&args); + out_key->data64[0] = args.X[1]; + out_key->data64[1] = args.X[2]; return static_cast(args.X[0]); } diff --git a/stratosphere/spl/source/spl_smc_wrapper.hpp b/stratosphere/spl/source/spl_smc_wrapper.hpp index be7b682d7..ea8798ee5 100644 --- a/stratosphere/spl/source/spl_smc_wrapper.hpp +++ b/stratosphere/spl/source/spl_smc_wrapper.hpp @@ -38,7 +38,7 @@ class SmcWrapper { static SmcResult GenerateAesKek(AccessKey *out, const KeySource &source, u32 generation, u32 option); static SmcResult LoadAesKey(u32 keyslot, const AccessKey &access_key, const KeySource &source); static SmcResult CryptAes(AsyncOperationKey *out_op, u32 mode, const IvCtr &iv_ctr, u32 dst_addr, u32 src_addr, size_t size); - static SmcResult GenerateSpecificAesKey(u64 *out, const KeySource &source, u32 generation, u32 which); + static SmcResult GenerateSpecificAesKey(AesKey *out_key, const KeySource &source, u32 generation, u32 which); static SmcResult ComputeCmac(Cmac *out_mac, u32 keyslot, const void *data, size_t size); static SmcResult 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); static SmcResult DecryptOrImportRsaPrivateKey(void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option);