mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-19 14:21:06 +00:00
service/cecd: Add hmac handling
This commit is contained in:
parent
192a0f3b92
commit
105bcc95c0
@ -4,6 +4,7 @@
|
||||
|
||||
#include <cryptopp/base64.h>
|
||||
#include <cryptopp/hmac.h>
|
||||
#include <cryptopp/sha.h>
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
@ -189,8 +190,8 @@ void Module::Interface::ReadMessage(Kernel::HLERequestContext& ctx) {
|
||||
message->backend->Close();
|
||||
|
||||
CecMessageHeader msg_header;
|
||||
|
||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||
|
||||
LOG_DEBUG(Service_CECD,
|
||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#010x}, "
|
||||
@ -234,8 +235,6 @@ void Module::Interface::ReadMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
||||
auto& hmac_key_buffer = rp.PopMappedBuffer();
|
||||
auto& write_buffer = rp.PopMappedBuffer();
|
||||
|
||||
// TODO verify message HMAC with the given key
|
||||
|
||||
FileSys::Mode mode;
|
||||
mode.read_flag.Assign(1);
|
||||
|
||||
@ -261,8 +260,8 @@ void Module::Interface::ReadMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
||||
message->backend->Close();
|
||||
|
||||
CecMessageHeader msg_header;
|
||||
|
||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||
|
||||
LOG_DEBUG(Service_CECD,
|
||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#010x}, "
|
||||
@ -280,6 +279,28 @@ void Module::Interface::ReadMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
||||
msg_header.sender_id, msg_header.sender_id2, msg_header.send_count,
|
||||
msg_header.forward_count, msg_header.user_data);
|
||||
|
||||
std::vector<u8> hmac_digest(0x20);
|
||||
std::memcpy(hmac_digest.data(),
|
||||
buffer.data() + msg_header.header_size + msg_header.body_size, 0x20);
|
||||
|
||||
std::vector<u8> message_body(msg_header.body_size);
|
||||
std::memcpy(message_body.data(), buffer.data() + msg_header.header_size,
|
||||
msg_header.body_size);
|
||||
|
||||
using namespace CryptoPP;
|
||||
SecByteBlock key(0x20);
|
||||
hmac_key_buffer.Read(key.data(), 0, key.size());
|
||||
|
||||
HMAC<SHA256> hmac(key, key.size());
|
||||
|
||||
const bool verify_hmac =
|
||||
hmac.VerifyDigest(hmac_digest.data(), message_body.data(), message_body.size());
|
||||
|
||||
if (verify_hmac)
|
||||
LOG_DEBUG(Service_CECD, "Verification succeeded");
|
||||
else
|
||||
LOG_DEBUG(Service_CECD, "Verification failed");
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(bytes_read);
|
||||
} else {
|
||||
@ -374,11 +395,13 @@ void Module::Interface::WriteMessage(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 4);
|
||||
if (message_result.Succeeded()) {
|
||||
auto message = message_result.Unwrap();
|
||||
std::vector<u8> buffer(buffer_size);
|
||||
CecMessageHeader msg_header;
|
||||
|
||||
std::vector<u8> buffer(buffer_size);
|
||||
read_buffer.Read(buffer.data(), 0, buffer_size);
|
||||
|
||||
CecMessageHeader msg_header;
|
||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||
|
||||
LOG_DEBUG(Service_CECD,
|
||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#010x}, "
|
||||
@ -425,8 +448,6 @@ void Module::Interface::WriteMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
||||
auto& hmac_key_buffer = rp.PopMappedBuffer();
|
||||
auto& message_id_buffer = rp.PopMappedBuffer();
|
||||
|
||||
// TODO verify message HMAC with the given key
|
||||
|
||||
FileSys::Mode mode;
|
||||
mode.write_flag.Assign(1);
|
||||
mode.create_flag.Assign(1);
|
||||
@ -446,11 +467,13 @@ void Module::Interface::WriteMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 6);
|
||||
if (message_result.Succeeded()) {
|
||||
auto message = message_result.Unwrap();
|
||||
std::vector<u8> buffer(buffer_size);
|
||||
CecMessageHeader msg_header;
|
||||
|
||||
std::vector<u8> buffer(buffer_size);
|
||||
read_buffer.Read(buffer.data(), 0, buffer_size);
|
||||
|
||||
CecMessageHeader msg_header;
|
||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||
|
||||
LOG_DEBUG(Service_CECD,
|
||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#010x}, "
|
||||
@ -468,6 +491,22 @@ void Module::Interface::WriteMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
||||
msg_header.sender_id, msg_header.sender_id2, msg_header.send_count,
|
||||
msg_header.forward_count, msg_header.user_data);
|
||||
|
||||
const u32 hmac_offset = msg_header.header_size + msg_header.body_size;
|
||||
const u32 hmac_size = 0x20;
|
||||
|
||||
std::vector<u8> hmac_digest(hmac_size);
|
||||
std::vector<u8> message_body(msg_header.body_size);
|
||||
std::memcpy(message_body.data(), buffer.data() + msg_header.header_size,
|
||||
msg_header.body_size);
|
||||
|
||||
using namespace CryptoPP;
|
||||
SecByteBlock key(hmac_size);
|
||||
hmac_key_buffer.Read(key.data(), 0, hmac_size);
|
||||
|
||||
HMAC<SHA256> hmac(key, hmac_size);
|
||||
hmac.CalculateDigest(hmac_digest.data(), message_body.data(), msg_header.body_size);
|
||||
std::memcpy(buffer.data() + hmac_offset, hmac_digest.data(), hmac_size);
|
||||
|
||||
const u32 bytes_written =
|
||||
message->backend->Write(0, buffer_size, true, buffer.data()).Unwrap();
|
||||
message->backend->Close();
|
||||
|
Loading…
Reference in New Issue
Block a user