Implemented: MD5 guest functions

This commit is contained in:
Adrian 2024-08-20 21:28:18 +01:00 committed by Radosław Gliński
parent 0ad1e3d585
commit b802894037
1 changed files with 99 additions and 0 deletions

View File

@ -29,6 +29,7 @@
#include "third_party/crypto/sha256.h" #include "third_party/crypto/sha256.h"
extern "C" { extern "C" {
#include "third_party/FFmpeg/libavutil/md5.h"
#include "third_party/FFmpeg/libavutil/sha512.h" #include "third_party/FFmpeg/libavutil/sha512.h"
#include "third_party/aes_128/aes.h" #include "third_party/aes_128/aes.h"
} }
@ -168,6 +169,33 @@ void XeCryptSha_entry(lpvoid_t input_1, dword_t input_1_size, lpvoid_t input_2,
} }
DECLARE_XBOXKRNL_EXPORT1(XeCryptSha, kNone, kImplemented); DECLARE_XBOXKRNL_EXPORT1(XeCryptSha, kNone, kImplemented);
void XeCryptMd5_entry(lpvoid_t input_1, dword_t input_1_size, lpvoid_t input_2,
dword_t input_2_size, lpvoid_t input_3,
dword_t input_3_size, lpvoid_t output,
dword_t output_size) {
AVMD5* md5 = av_md5_alloc();
av_md5_init(md5);
if (input_1 && input_1_size) {
av_md5_update(md5, input_1, input_1_size);
}
if (input_2 && input_2_size) {
av_md5_update(md5, input_2, input_2_size);
}
if (input_3 && input_3_size) {
av_md5_update(md5, input_3, input_3_size);
}
uint8_t digest[16];
av_md5_final(md5, digest);
std::copy_n(digest, std::min<size_t>(xe::countof(digest), output_size),
output.as<uint8_t*>());
}
DECLARE_XBOXKRNL_EXPORT1(XeCryptMd5, kNone, kImplemented);
// TODO: Size of this struct hasn't been confirmed yet. // TODO: Size of this struct hasn't been confirmed yet.
typedef struct { typedef struct {
xe::be<uint32_t> count; // 0x0 xe::be<uint32_t> count; // 0x0
@ -299,6 +327,77 @@ void XeCryptSha512Final_entry(pointer_t<XECRYPT_SHA256_STATE> sha_state,
} }
DECLARE_XBOXKRNL_EXPORT1(XeCryptSha512Final, kNone, kImplemented); DECLARE_XBOXKRNL_EXPORT1(XeCryptSha512Final, kNone, kImplemented);
// TODO: Size of this struct hasn't been confirmed yet.
typedef struct {
xe::be<uint64_t> count;
xe::be<uint32_t> state[4];
uint8_t buffer[64];
} XECRYPT_MD5_STATE;
void XeCryptMd5Init_entry(pointer_t<XECRYPT_MD5_STATE> md5_state) {
md5_state.Zero();
// must match av_md5_init
md5_state->state[0] = 0x10325476;
md5_state->state[1] = 0x98badcfe;
md5_state->state[2] = 0xefcdab89;
md5_state->state[3] = 0x67452301;
}
DECLARE_XBOXKRNL_EXPORT1(XeCryptMd5Init, kNone, kImplemented);
struct MD5_STATE {
uint64_t len;
uint8_t block[64];
uint32_t ABCD[4];
};
void XeCryptMd5Update_entry(pointer_t<XECRYPT_MD5_STATE> md5_state,
lpvoid_t input, dword_t input_size) {
AVMD5* md5 = av_md5_alloc();
av_md5_init(md5);
// Trick to make similar implementation as SHA256
MD5_STATE* md5InternalState = reinterpret_cast<MD5_STATE*>(md5);
std::copy(std::begin(md5_state->state), std::end(md5_state->state),
md5InternalState->ABCD);
std::copy(std::begin(md5_state->buffer), std::end(md5_state->buffer),
md5InternalState->block);
md5InternalState->len = md5_state->count;
// Add new entry from input
av_md5_update(md5, input, input_size);
// Copy back data to guest md5_state
std::copy_n(md5InternalState->ABCD, xe::countof(md5_state->state),
md5_state->state);
std::copy_n(md5InternalState->block, xe::countof(md5_state->buffer),
md5_state->buffer);
md5_state->count = md5InternalState->len;
}
DECLARE_XBOXKRNL_EXPORT1(XeCryptMd5Update, kNone, kImplemented);
void XeCryptMd5Final_entry(pointer_t<XECRYPT_MD5_STATE> md5_state,
pointer_t<uint8_t> out, dword_t out_size) {
AVMD5* md5 = av_md5_alloc();
av_md5_init(md5);
// Trick to make similar implementation as SHA256
MD5_STATE* md5InternalState = reinterpret_cast<MD5_STATE*>(md5);
std::copy(std::begin(md5_state->state), std::end(md5_state->state),
md5InternalState->ABCD);
std::copy(std::begin(md5_state->buffer), std::end(md5_state->buffer),
md5InternalState->block);
md5InternalState->len = md5_state->count;
uint8_t hash[16];
av_md5_final(md5, hash);
std::copy_n(hash, std::min<size_t>(xe::countof(hash), out_size),
static_cast<uint8_t*>(out));
std::copy(std::begin(hash), std::end(hash), md5_state->buffer);
}
DECLARE_XBOXKRNL_EXPORT1(XeCryptMd5Final, kNone, kImplemented);
// Byteswaps each 8 bytes // Byteswaps each 8 bytes
void XeCryptBnQw_SwapDwQwLeBe_entry(pointer_t<uint64_t> qw_inp, void XeCryptBnQw_SwapDwQwLeBe_entry(pointer_t<uint64_t> qw_inp,
pointer_t<uint64_t> qw_out, dword_t size) { pointer_t<uint64_t> qw_out, dword_t size) {