diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-07-18 18:04:54 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-07-18 18:04:54 -0300 |
| commit | baaeac349dc5da2cb4892662c69566a98a66a124 (patch) | |
| tree | 634b3d4be3f659290f0271402f3c68d061c686d1 /src/crypto.cc | |
| download | login-baaeac349dc5da2cb4892662c69566a98a66a124.tar.gz login-baaeac349dc5da2cb4892662c69566a98a66a124.zip | |
initial version
Diffstat (limited to 'src/crypto.cc')
| -rw-r--r-- | src/crypto.cc | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/crypto.cc b/src/crypto.cc new file mode 100644 index 0000000..8be90fd --- /dev/null +++ b/src/crypto.cc @@ -0,0 +1,102 @@ +#include "login.hh" + +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/pem.h> + +static void DumpOpenSSLErrors(const char *Where, const char *What){ + LOG_ERR("OpenSSL error(s) while executing %s at %s:", What, Where); + ERR_print_errors_cb( + [](const char *str, usize len, void *u) -> int { + // NOTE(fusion): These error strings already have trailing newlines, + // for whatever reason. + if(len > 0 && str[len - 1] == '\n'){ + len -= 1; + } + + if(len > 0){ + LOG_ERR("> %*s", (int)len, str); + } + + return 1; + }, NULL); +} + +RSAKey *RSALoadPEM(const char *FileName){ + FILE *File = fopen(FileName, "rb"); + if(File == NULL){ + LOG_ERR("Failed to open \"%s\"", FileName); + return NULL; + } + + RSA *Key = PEM_read_RSAPrivateKey(File, NULL, NULL, NULL); + fclose(File); + if(Key == NULL){ + LOG_ERR("Failed to read key from \"%s\"", FileName); + DumpOpenSSLErrors("RSALoadPem", "PEM_read_PrivateKey"); + } + + return (RSAKey*)Key; +} + +void RSAFree(RSAKey *Key){ + RSA_free((RSA*)Key); +} + +bool RSADecrypt(RSAKey *Key, uint8 *Data, int Size){ + ASSERT(Data != NULL && Size > 0); + if(Key == NULL){ + LOG_ERR("Key not initialized"); + return false; + } + + if(Size != RSA_size((RSA*)Key)){ + LOG_ERR("Invalid data size %d (expected %d)", Size, RSA_size((RSA*)Key)); + return false; + } + + if(RSA_private_decrypt(Size, Data, Data, (RSA*)Key, RSA_NO_PADDING) == -1){ + DumpOpenSSLErrors("RSADecrypt", "RSA_private_decrypt"); + return false; + } + + return true; +} + +void XTEAEncrypt(const uint32 *Key, uint8 *Data, int Size){ + ASSERT(Key != NULL); + while(Size >= 8){ + uint32 Sum = 0x00000000UL; + uint32 Delta = 0x9E3779B9UL; + uint32 V0 = BufferRead32LE(&Data[0]); + uint32 V1 = BufferRead32LE(&Data[4]); + for(int i = 0; i < 32; i += 1){ + V0 += (((V1 << 4) ^ (V1 >> 5)) + V1) ^ (Sum + Key[Sum & 3]); + Sum += Delta; + V1 += (((V0 << 4) ^ (V0 >> 5)) + V0) ^ (Sum + Key[(Sum >> 11) & 3]); + } + BufferWrite32LE(&Data[0], V0); + BufferWrite32LE(&Data[4], V1); + Data += 8; + Size -= 8; + } +} + +void XTEADecrypt(const uint32 *Key, uint8 *Data, int Size){ + ASSERT(Key != NULL); + while(Size >= 8){ + uint32 Sum = 0xC6EF3720UL; + uint32 Delta = 0x9E3779B9UL; + uint32 V0 = BufferRead32LE(&Data[0]); + uint32 V1 = BufferRead32LE(&Data[4]); + for(int i = 0; i < 32; i += 1){ + V1 -= (((V0 << 4) ^ (V0 >> 5)) + V0) ^ (Sum + Key[(Sum >> 11) & 3]); + Sum -= Delta; + V0 -= (((V1 << 4) ^ (V1 >> 5)) + V1) ^ (Sum + Key[Sum & 3]); + } + BufferWrite32LE(&Data[0], V0); + BufferWrite32LE(&Data[4], V1); + Data += 8; + Size -= 8; + } +} |
