mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-15 09:00:05 +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/base64.h>
|
||||||
#include <cryptopp/hmac.h>
|
#include <cryptopp/hmac.h>
|
||||||
|
#include <cryptopp/sha.h>
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
@ -189,8 +190,8 @@ void Module::Interface::ReadMessage(Kernel::HLERequestContext& ctx) {
|
|||||||
message->backend->Close();
|
message->backend->Close();
|
||||||
|
|
||||||
CecMessageHeader msg_header;
|
CecMessageHeader msg_header;
|
||||||
|
|
||||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||||
|
|
||||||
LOG_DEBUG(Service_CECD,
|
LOG_DEBUG(Service_CECD,
|
||||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#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& hmac_key_buffer = rp.PopMappedBuffer();
|
||||||
auto& write_buffer = rp.PopMappedBuffer();
|
auto& write_buffer = rp.PopMappedBuffer();
|
||||||
|
|
||||||
// TODO verify message HMAC with the given key
|
|
||||||
|
|
||||||
FileSys::Mode mode;
|
FileSys::Mode mode;
|
||||||
mode.read_flag.Assign(1);
|
mode.read_flag.Assign(1);
|
||||||
|
|
||||||
@ -261,8 +260,8 @@ void Module::Interface::ReadMessageWithHMAC(Kernel::HLERequestContext& ctx) {
|
|||||||
message->backend->Close();
|
message->backend->Close();
|
||||||
|
|
||||||
CecMessageHeader msg_header;
|
CecMessageHeader msg_header;
|
||||||
|
|
||||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||||
|
|
||||||
LOG_DEBUG(Service_CECD,
|
LOG_DEBUG(Service_CECD,
|
||||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#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.sender_id, msg_header.sender_id2, msg_header.send_count,
|
||||||
msg_header.forward_count, msg_header.user_data);
|
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(RESULT_SUCCESS);
|
||||||
rb.Push<u32>(bytes_read);
|
rb.Push<u32>(bytes_read);
|
||||||
} else {
|
} else {
|
||||||
@ -374,11 +395,13 @@ void Module::Interface::WriteMessage(Kernel::HLERequestContext& ctx) {
|
|||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 4);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 4);
|
||||||
if (message_result.Succeeded()) {
|
if (message_result.Succeeded()) {
|
||||||
auto message = message_result.Unwrap();
|
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);
|
read_buffer.Read(buffer.data(), 0, buffer_size);
|
||||||
|
|
||||||
|
CecMessageHeader msg_header;
|
||||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||||
|
|
||||||
LOG_DEBUG(Service_CECD,
|
LOG_DEBUG(Service_CECD,
|
||||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#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& hmac_key_buffer = rp.PopMappedBuffer();
|
||||||
auto& message_id_buffer = rp.PopMappedBuffer();
|
auto& message_id_buffer = rp.PopMappedBuffer();
|
||||||
|
|
||||||
// TODO verify message HMAC with the given key
|
|
||||||
|
|
||||||
FileSys::Mode mode;
|
FileSys::Mode mode;
|
||||||
mode.write_flag.Assign(1);
|
mode.write_flag.Assign(1);
|
||||||
mode.create_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);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 6);
|
||||||
if (message_result.Succeeded()) {
|
if (message_result.Succeeded()) {
|
||||||
auto message = message_result.Unwrap();
|
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);
|
read_buffer.Read(buffer.data(), 0, buffer_size);
|
||||||
|
|
||||||
|
CecMessageHeader msg_header;
|
||||||
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
std::memcpy(&msg_header, buffer.data(), sizeof(CecMessageHeader));
|
||||||
|
|
||||||
LOG_DEBUG(Service_CECD,
|
LOG_DEBUG(Service_CECD,
|
||||||
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
"magic={:#06x}, message_size={:#010x}, header_size={:#010x}, "
|
||||||
"body_size={:#010x}, title_id={:#010x}, title_id_2={:#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.sender_id, msg_header.sender_id2, msg_header.send_count,
|
||||||
msg_header.forward_count, msg_header.user_data);
|
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 =
|
const u32 bytes_written =
|
||||||
message->backend->Write(0, buffer_size, true, buffer.data()).Unwrap();
|
message->backend->Write(0, buffer_size, true, buffer.data()).Unwrap();
|
||||||
message->backend->Close();
|
message->backend->Close();
|
||||||
|
Loading…
Reference in New Issue
Block a user