#include "helpers/crypto.hpp" #include #include #include #include #include #include #include #include namespace hex::crypt { u16 crc16(prv::Provider* &data, u64 offset, size_t size, u16 polynomial, u16 init) { const auto table = [polynomial] { std::array table; for (u16 i = 0; i < 256; i++) { u16 crc = 0; u16 c = i; for (u16 j = 0; j < 8; j++) { if (((crc ^ c) & 0x0001U) != 0) crc = (crc >> 1U) ^ polynomial; else crc >>= 1U; c >>= 1U; } table[i] = crc; } return table; }(); u16 crc = init; std::array buffer = { 0 }; for (u64 bufferOffset = 0; offset < size; offset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); for (size_t i = 0; i < readSize; i++) { crc = (crc >> 8) ^ table[(crc ^ u16(buffer[i])) & 0x00FF]; } } return crc; } u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init) { auto table = [polynomial] { std::array table = {0}; for (uint32_t i = 0; i < 256; i++) { uint32_t c = i; for (size_t j = 0; j < 8; j++) { if (c & 1) c = polynomial ^ (c >> 1); else c >>= 1; } table[i] = c; } return table; }(); uint32_t c = init; std::array buffer = { 0 }; for (u64 bufferOffset = 0; offset < size; offset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); for (size_t i = 0; i < readSize; i++) { c = table[(c ^ buffer[i]) & 0xFF] ^ (c >> 8); } } return ~c; } std::array md5(prv::Provider* &data, u64 offset, size_t size) { std::array result = { 0 }; mbedtls_md5_context ctx; mbedtls_md5_init(&ctx); mbedtls_md5_starts_ret(&ctx); std::array buffer = { 0 }; for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); mbedtls_md5_update_ret(&ctx, buffer.data(), readSize); } mbedtls_md5_finish_ret(&ctx, result.data()); mbedtls_md5_free(&ctx); return result; } std::array sha1(prv::Provider* &data, u64 offset, size_t size) { std::array result = { 0 }; mbedtls_sha1_context ctx; mbedtls_sha1_init(&ctx); mbedtls_sha1_starts_ret(&ctx); std::array buffer = { 0 }; for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); mbedtls_sha1_update_ret(&ctx, buffer.data(), readSize); } mbedtls_sha1_finish_ret(&ctx, result.data()); mbedtls_sha1_free(&ctx); return result; } std::array sha224(prv::Provider* &data, u64 offset, size_t size) { std::array result = { 0 }; mbedtls_sha256_context ctx; mbedtls_sha256_init(&ctx); mbedtls_sha256_starts_ret(&ctx, true); std::array buffer = { 0 }; for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); mbedtls_sha256_update_ret(&ctx, buffer.data(), readSize); } mbedtls_sha256_finish_ret(&ctx, result.data()); mbedtls_sha256_free(&ctx); return result; } std::array sha256(prv::Provider* &data, u64 offset, size_t size) { std::array result = { 0 }; mbedtls_sha256_context ctx; mbedtls_sha256_init(&ctx); mbedtls_sha256_starts_ret(&ctx, false); std::array buffer = { 0 }; for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); mbedtls_sha256_update_ret(&ctx, buffer.data(), readSize); } mbedtls_sha256_finish_ret(&ctx, result.data()); mbedtls_sha256_free(&ctx); return result; } std::array sha384(prv::Provider* &data, u64 offset, size_t size) { std::array result = { 0 }; mbedtls_sha512_context ctx; mbedtls_sha512_init(&ctx); mbedtls_sha512_starts_ret(&ctx, true); std::array buffer = { 0 }; for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); mbedtls_sha512_update_ret(&ctx, buffer.data(), readSize); } mbedtls_sha512_finish_ret(&ctx, result.data()); mbedtls_sha512_free(&ctx); return result; } std::array sha512(prv::Provider* &data, u64 offset, size_t size) { std::array result = { 0 }; mbedtls_sha512_context ctx; mbedtls_sha512_init(&ctx); mbedtls_sha512_starts_ret(&ctx, false); std::array buffer = { 0 }; for (u64 bufferOffset = 0; bufferOffset < size; bufferOffset += buffer.size()) { const u64 readSize = std::min(u64(buffer.size()), size - bufferOffset); data->read(offset + bufferOffset, buffer.data(), readSize); mbedtls_sha512_update_ret(&ctx, buffer.data(), readSize); } mbedtls_sha512_finish_ret(&ctx, result.data()); mbedtls_sha512_free(&ctx); return result; } std::vector decode64(const std::vector &input) { size_t outputSize = (3 * input.size()) / 4; std::vector output(outputSize + 1, 0x00); size_t written = 0; if (mbedtls_base64_decode(output.data(), output.size(), &written, reinterpret_cast(input.data()), input.size())) return { }; return output; } std::vector encode64(const std::vector &input) { size_t outputSize = 4 * ((input.size() + 2) / 3); std::vector output(outputSize + 1, 0x00); size_t written = 0; if (mbedtls_base64_encode(output.data(), output.size(), &written, reinterpret_cast(input.data()), input.size())) return { }; return output; } }