mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Implement PS:GetRandomBytes and use openssl for random bytes (#7164)
This commit is contained in:
		
							parent
							
								
									e9936e01c2
								
							
						
					
					
						commit
						de40153fa4
					
				
					 3 changed files with 28 additions and 32 deletions
				
			
		|  | @ -9,6 +9,7 @@ | |||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/service/ps/ps_ps.h" | ||||
| #include "core/hle/service/ssl/ssl_c.h" | ||||
| #include "core/hw/aes/arithmetic128.h" | ||||
| #include "core/hw/aes/key.h" | ||||
| 
 | ||||
|  | @ -146,6 +147,20 @@ void PS_PS::EncryptDecryptAes(Kernel::HLERequestContext& ctx) { | |||
|     rb.PushMappedBuffer(destination); | ||||
| } | ||||
| 
 | ||||
| void PS_PS::GenerateRandomBytes(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     const u32 size = rp.Pop<u32>(); | ||||
|     auto buffer = rp.PopMappedBuffer(); | ||||
| 
 | ||||
|     std::vector<u8> out_data(size); | ||||
|     SSL::GenerateRandomData(out_data); | ||||
|     buffer.Write(out_data.data(), 0, size); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     rb.PushMappedBuffer(buffer); | ||||
| } | ||||
| 
 | ||||
| PS_PS::PS_PS() : ServiceFramework("ps:ps", DefaultMaxSessions) { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         // clang-format off
 | ||||
|  | @ -160,7 +175,7 @@ PS_PS::PS_PS() : ServiceFramework("ps:ps", DefaultMaxSessions) { | |||
|         {0x000A, nullptr, "GetLocalFriendCodeSeed"}, | ||||
|         {0x000B, nullptr, "GetDeviceId"}, | ||||
|         {0x000C, nullptr, "SeedRNG"}, | ||||
|         {0x000D, nullptr, "GenerateRandomBytes"}, | ||||
|         {0x000D, &PS_PS::GenerateRandomBytes, "GenerateRandomBytes"}, | ||||
|         {0x000E, nullptr, "InterfaceForPXI_0x04010084"}, | ||||
|         {0x000F, nullptr, "InterfaceForPXI_0x04020082"}, | ||||
|         {0x0010, nullptr, "InterfaceForPXI_0x04030044"}, | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <openssl/rand.h> | ||||
| #include "common/archives.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/core.h" | ||||
|  | @ -16,10 +17,6 @@ void SSL_C::Initialize(Kernel::HLERequestContext& ctx) { | |||
|     IPC::RequestParser rp(ctx); | ||||
|     rp.PopPID(); | ||||
| 
 | ||||
|     // Seed random number generator when the SSL service is initialized
 | ||||
|     std::random_device rand_device; | ||||
|     rand_gen.seed(rand_device()); | ||||
| 
 | ||||
|     // Stub, return success
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|  | @ -27,33 +24,13 @@ void SSL_C::Initialize(Kernel::HLERequestContext& ctx) { | |||
| 
 | ||||
| void SSL_C::GenerateRandomData(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     u32 size = rp.Pop<u32>(); | ||||
|     const u32 size = rp.Pop<u32>(); | ||||
|     auto buffer = rp.PopMappedBuffer(); | ||||
| 
 | ||||
|     // Fill the output buffer with random data.
 | ||||
|     u32 data = 0; | ||||
|     u32 i = 0; | ||||
|     while (i < size) { | ||||
|         if ((i % 4) == 0) { | ||||
|             // The random number generator returns 4 bytes worth of data, so generate new random
 | ||||
|             // data when i == 0 and when i is divisible by 4
 | ||||
|             data = rand_gen(); | ||||
|         } | ||||
|     std::vector<u8> out_data(size); | ||||
|     SSL::GenerateRandomData(out_data); | ||||
|     buffer.Write(out_data.data(), 0, size); | ||||
| 
 | ||||
|         if (size > 4) { | ||||
|             // Use up the entire 4 bytes of the random data for as long as possible
 | ||||
|             buffer.Write(&data, i, 4); | ||||
|             i += 4; | ||||
|         } else if (size == 2) { | ||||
|             buffer.Write(&data, i, 2); | ||||
|             i += 2; | ||||
|         } else { | ||||
|             buffer.Write(&data, i, 1); | ||||
|             i++; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Stub, return success
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     rb.PushMappedBuffer(buffer); | ||||
|  | @ -96,4 +73,9 @@ void InstallInterfaces(Core::System& system) { | |||
|     std::make_shared<SSL_C>()->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| void GenerateRandomData(std::vector<u8>& out) { | ||||
|     // Fill the output buffer with random data.
 | ||||
|     RAND_bytes(out.data(), static_cast<int>(out.size())); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::SSL
 | ||||
|  |  | |||
|  | @ -21,14 +21,13 @@ private: | |||
|     void Initialize(Kernel::HLERequestContext& ctx); | ||||
|     void GenerateRandomData(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     // TODO: Implement a proper CSPRNG in the future when actual security is needed
 | ||||
|     std::mt19937 rand_gen; | ||||
| 
 | ||||
|     SERVICE_SERIALIZATION_SIMPLE | ||||
| }; | ||||
| 
 | ||||
| void InstallInterfaces(Core::System& system); | ||||
| 
 | ||||
| void GenerateRandomData(std::vector<u8>& out); | ||||
| 
 | ||||
| } // namespace Service::SSL
 | ||||
| 
 | ||||
| BOOST_CLASS_EXPORT_KEY(Service::SSL::SSL_C) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue