rpcsx/rpcs3/Crypto/utils.cpp
Ani a49446c9e9
Replace gsl::span for std::span (c++20) (#7531)
* Replace gsl::span for std::span (c++20)
* Replace gsl::byte with std::byte

Co-authored-by: Bevan Weiss <bevan.weiss@gmail.com>
2021-05-30 17:10:46 +03:00

145 lines
3.6 KiB
C++

// Copyright (C) 2014 Hykem <hykem@hotmail.com>
// Licensed under the terms of the GNU GPL, version 2.0 or later versions.
// http://www.gnu.org/licenses/gpl-2.0.txt
#include "utils.h"
#include "aes.h"
#include "sha1.h"
#include <cstring>
#include <stdio.h>
#include <time.h>
#include "Utilities/StrUtil.h"
#include "Utilities/File.h"
#include <memory>
#include <string>
#include <string_view>
#include <span>
// Auxiliary functions (endian swap, xor).
// Hex string conversion auxiliary functions.
u64 hex_to_u64(const char* hex_str)
{
auto length = std::strlen(hex_str);
u64 tmp = 0;
u64 result = 0;
char c;
while (length--)
{
c = *hex_str++;
if((c >= '0') && (c <= '9'))
tmp = c - '0';
else if((c >= 'a') && (c <= 'f'))
tmp = c - 'a' + 10;
else if((c >= 'A') && (c <= 'F'))
tmp = c - 'A' + 10;
else
tmp = 0;
result |= (tmp << (length * 4));
}
return result;
}
void hex_to_bytes(unsigned char* data, const char* hex_str, unsigned int str_length)
{
const auto strn_length = (str_length > 0) ? str_length : std::strlen(hex_str);
auto data_length = strn_length / 2;
char tmp_buf[3] = {0, 0, 0};
// Don't convert if the string length is odd.
if ((strn_length % 2) == 0)
{
while (data_length--)
{
tmp_buf[0] = *hex_str++;
tmp_buf[1] = *hex_str++;
*data++ = static_cast<u8>(hex_to_u64(tmp_buf) & 0xFF);
}
}
}
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len)
{
aes_context ctx;
aes_setkey_dec(&ctx, key, 128);
aes_crypt_cbc(&ctx, AES_DECRYPT, len, iv, in, out);
// Reset the IV.
memset(iv, 0, 0x10);
}
void aescbc128_encrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len)
{
aes_context ctx;
aes_setkey_enc(&ctx, key, 128);
aes_crypt_cbc(&ctx, AES_ENCRYPT, len, iv, in, out);
// Reset the IV.
memset(iv, 0, 0x10);
}
void aesecb128_encrypt(unsigned char *key, unsigned char *in, unsigned char *out)
{
aes_context ctx;
aes_setkey_enc(&ctx, key, 128);
aes_crypt_ecb(&ctx, AES_ENCRYPT, in, out);
}
bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
{
const std::unique_ptr<u8[]> out(new u8[key_len]);
sha1_hmac(key, key_len, in, in_len, out.get());
return std::memcmp(out.get(), hash, hash_len) == 0;
}
void hmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash)
{
sha1_hmac(key, key_len, in, in_len, hash);
}
bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
{
const std::unique_ptr<u8[]> out(new u8[key_len]);
aes_context ctx;
aes_setkey_enc(&ctx, key, 128);
aes_cmac(&ctx, in_len, in, out.get());
return std::memcmp(out.get(), hash, hash_len) == 0;
}
void cmac_hash_forge(unsigned char *key, int /*key_len*/, unsigned char *in, int in_len, unsigned char *hash)
{
aes_context ctx;
aes_setkey_enc(&ctx, key, 128);
aes_cmac(&ctx, in_len, in, hash);
}
char* extract_file_name(const char* file_path, char real_file_name[CRYPTO_MAX_PATH])
{
std::string_view v(file_path);
if (const auto pos = v.find_last_of(fs::delim); pos != umax)
{
v.remove_prefix(pos + 1);
}
std::span r(real_file_name, CRYPTO_MAX_PATH);
strcpy_trunc(r, v);
return real_file_name;
}
void mbedtls_zeroize(void *v, size_t n)
{
static void *(*const volatile unop_memset)(void *, int, size_t) = &memset;
(void)unop_memset(v, 0, n);
}