mirror of
https://github.com/pumpitupdev/pumptools.git
synced 2026-09-26 16:38:29 +03:00
sec/prinet: Module for encryption/decryption of prime network traffic
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
add_subdirectory(hasp)
|
||||
add_subdirectory(lockchip)
|
||||
add_subdirectory(microdog34)
|
||||
add_subdirectory(microdog40)
|
||||
add_subdirectory(microdog40)
|
||||
add_subdirectory(prinet)
|
||||
@@ -0,0 +1,13 @@
|
||||
project(sec-prinet)
|
||||
message(STATUS "Project " ${PROJECT_NAME})
|
||||
|
||||
set(SRC ${PT_ROOT_MAIN}/sec/prinet)
|
||||
|
||||
set(SOURCE_FILES
|
||||
${SRC}/prinet.c)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} util -lsodium)
|
||||
@@ -5,5 +5,6 @@ include_directories(${PT_ROOT_TEST})
|
||||
|
||||
add_subdirectory(capnhook)
|
||||
add_subdirectory(hook)
|
||||
add_subdirectory(sec)
|
||||
add_subdirectory(test-util)
|
||||
add_subdirectory(util)
|
||||
@@ -0,0 +1 @@
|
||||
add_subdirectory(prinet)
|
||||
@@ -0,0 +1 @@
|
||||
add_subdirectory(prinet)
|
||||
@@ -0,0 +1,14 @@
|
||||
project(test-sec-prinet-prinet)
|
||||
message(STATUS "Project " ${PROJECT_NAME})
|
||||
|
||||
set(SRC ${PT_ROOT_TEST}/sec/prinet/prinet)
|
||||
|
||||
add_resources(PRI_PRIVATE_KEY ${SRC} prime.private.key)
|
||||
add_resources(PRI_PUBLIC_KEY ${SRC} prime.public.key)
|
||||
|
||||
set(SOURCE_FILES
|
||||
${SRC}/main.c)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${PRI_PRIVATE_KEY} ${PRI_PUBLIC_KEY})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} cmocka sec-prinet test-util util)
|
||||
@@ -0,0 +1,118 @@
|
||||
#define LOG_MODULE "sec-prinet"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sodium.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sec/prinet/prinet.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
|
||||
_Static_assert (crypto_box_NONCEBYTES == SEC_PRINET_NOUNCE_LEN, "Nounce length not as expected for prinet");
|
||||
_Static_assert (crypto_box_MACBYTES == SEC_PRINET_MACBYTES_LEN, "Nounce length not as expected for prinet");
|
||||
|
||||
static void* _key_pub;
|
||||
static size_t _key_pub_len;
|
||||
static void* _key_priv;
|
||||
static size_t _key_priv_len;
|
||||
|
||||
static void* _sec_prinet_safe_malloc(size_t size)
|
||||
{
|
||||
size_t pagesize = getpagesize();
|
||||
size_t num_pages = size / pagesize;
|
||||
size_t num_pages_round_up = num_pages;
|
||||
|
||||
if (size % pagesize != 0) {
|
||||
num_pages_round_up++;
|
||||
}
|
||||
|
||||
size_t size_aligned = num_pages_round_up * pagesize;
|
||||
|
||||
void* ptr = sodium_malloc(size_aligned);
|
||||
|
||||
if (ptr == NULL) {
|
||||
log_error("Sodium malloc failed, %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void sec_prinet_init(
|
||||
const uint8_t* key_pub, size_t key_pub_len,
|
||||
const uint8_t* key_priv, size_t key_priv_len)
|
||||
{
|
||||
_key_pub = util_xmalloc(key_pub_len);
|
||||
memcpy(_key_pub, key_pub, key_pub_len);
|
||||
_key_pub_len = key_pub_len;
|
||||
|
||||
_key_priv = util_xmalloc(key_priv_len);
|
||||
memcpy(_key_priv, key_priv, key_priv_len);
|
||||
_key_priv_len = key_priv_len;
|
||||
|
||||
// 0 on success, 1 if already initialized
|
||||
if (sodium_init() == -1) {
|
||||
log_error("Initializing sodium failed");
|
||||
}
|
||||
}
|
||||
|
||||
void sec_prinet_finit()
|
||||
{
|
||||
util_xfree(&_key_pub);
|
||||
util_xfree(&_key_priv);
|
||||
}
|
||||
|
||||
size_t sec_prinet_get_enc_data_buffer_size(size_t enc_data_len)
|
||||
{
|
||||
return enc_data_len + crypto_box_MACBYTES;
|
||||
}
|
||||
|
||||
size_t sec_prinet_decrypt(
|
||||
const uint8_t* nounce, size_t nounce_len, const uint8_t* enc_data,
|
||||
size_t enc_data_len, uint8_t* dec_data)
|
||||
{
|
||||
if (nounce_len != SEC_PRINET_NOUNCE_LEN) {
|
||||
log_error("Nounce len %d does not match expected len %d", nounce_len, SEC_PRINET_NOUNCE_LEN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (crypto_box_open_easy(dec_data, enc_data, enc_data_len, nounce, _key_pub, _key_priv) != 0) {
|
||||
log_error("Decrypting message, len %d, failed", enc_data_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return enc_data_len;
|
||||
}
|
||||
|
||||
size_t sec_prinet_encrypt(
|
||||
const uint8_t* nounce, size_t nounce_len, const uint8_t* dec_data,
|
||||
size_t dec_data_len, uint8_t* enc_data)
|
||||
{
|
||||
if (nounce_len != SEC_PRINET_NOUNCE_LEN) {
|
||||
log_error("Nounce len %d does not match expected len %d", nounce_len, SEC_PRINET_NOUNCE_LEN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* tmp_enc = _sec_prinet_safe_malloc(dec_data_len);
|
||||
|
||||
if (tmp_enc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (crypto_box_easy(tmp_enc, dec_data, dec_data_len, nounce, _key_pub, _key_priv) != 0) {
|
||||
log_error("Encrypting message, len %d, failed", dec_data_len);
|
||||
sodium_free(tmp_enc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Encrypted data/response expects additional data after game specific payload
|
||||
size_t enc_data_len = sec_prinet_get_enc_data_buffer_size(dec_data_len);
|
||||
|
||||
memcpy(enc_data, tmp_enc, enc_data_len);
|
||||
|
||||
sodium_free(tmp_enc);
|
||||
|
||||
return enc_data_len;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SEC_PRINET_NOUNCE_LEN 24
|
||||
#define SEC_PRINET_MACBYTES_LEN 16
|
||||
|
||||
void sec_prinet_init(
|
||||
const uint8_t* key_pub, size_t key_pub_len,
|
||||
const uint8_t* key_priv, size_t key_priv_len);
|
||||
|
||||
void sec_prinet_finit();
|
||||
|
||||
size_t sec_prinet_get_enc_data_buffer_size(size_t enc_data_len);
|
||||
|
||||
size_t sec_prinet_decrypt(
|
||||
const uint8_t* nounce, size_t nounce_len, const uint8_t* enc_data,
|
||||
size_t enc_data_len, uint8_t* dec_data);
|
||||
|
||||
size_t sec_prinet_encrypt(
|
||||
const uint8_t* nounce, size_t nounce_len, const uint8_t* dec_data,
|
||||
size_t dec_data_len, uint8_t* enc_data);
|
||||
@@ -0,0 +1,115 @@
|
||||
#include <cmocka/cmocka.h>
|
||||
|
||||
#include "sec/prinet/prinet.h"
|
||||
|
||||
#include "test-util/mem.h"
|
||||
|
||||
#include "util/mem.h"
|
||||
#include "util/rand.h"
|
||||
|
||||
/* Compiled binary data from data folder. Symbols are defined by compiler */
|
||||
extern const uint8_t _binary_prime_private_key_start[];
|
||||
extern const uint8_t _binary_prime_private_key_end[];
|
||||
extern const uint8_t _binary_prime_public_key_start[];
|
||||
extern const uint8_t _binary_prime_public_key_end[];
|
||||
|
||||
static void _test_encrypt_decrypt(uint32_t seed)
|
||||
{
|
||||
util_rand_init(seed);
|
||||
|
||||
uint8_t* data;
|
||||
size_t data_len;
|
||||
uint8_t* nounce;
|
||||
uint8_t* enc_data;
|
||||
size_t enc_data_len;
|
||||
uint8_t* dec_data;
|
||||
size_t dec_data_len;
|
||||
size_t enc_data_len_res;
|
||||
size_t dec_data_len_res;
|
||||
|
||||
for (uint32_t i = 0; i < 20; i++) {
|
||||
data_len = util_rand_gen_range_32(1024 * 1024);
|
||||
data = util_xmalloc(data_len);
|
||||
util_rand_gen_bytes(data, data_len);
|
||||
|
||||
nounce = util_xmalloc(SEC_PRINET_NOUNCE_LEN);
|
||||
util_rand_gen_bytes(nounce, SEC_PRINET_NOUNCE_LEN);
|
||||
|
||||
enc_data_len = sec_prinet_get_enc_data_buffer_size(data_len);
|
||||
enc_data = util_xmalloc(enc_data_len);
|
||||
|
||||
enc_data_len_res =
|
||||
sec_prinet_encrypt(nounce, SEC_PRINET_NOUNCE_LEN, data, data_len, enc_data);
|
||||
|
||||
assert_int_equal(enc_data_len_res, enc_data_len);
|
||||
|
||||
dec_data_len = enc_data_len_res;
|
||||
dec_data = util_xmalloc(dec_data_len);
|
||||
|
||||
dec_data_len_res =
|
||||
sec_prinet_decrypt(nounce, SEC_PRINET_NOUNCE_LEN, enc_data, dec_data_len, dec_data);
|
||||
|
||||
assert_int_equal(dec_data_len_res, sec_prinet_get_enc_data_buffer_size(data_len));
|
||||
|
||||
assert_memory_equal(data, dec_data, data_len);
|
||||
|
||||
util_xfree((void**) &dec_data);
|
||||
util_xfree((void**) &enc_data);
|
||||
util_xfree((void**) &nounce);
|
||||
util_xfree((void**) &data);
|
||||
}
|
||||
}
|
||||
|
||||
static int setup(void** state)
|
||||
{
|
||||
test_util_mem_install_mem_interface();
|
||||
|
||||
sec_prinet_init(
|
||||
(const uint8_t*) _binary_prime_public_key_start,
|
||||
((uintptr_t) &_binary_prime_public_key_end -
|
||||
(uintptr_t) &_binary_prime_public_key_start),
|
||||
(const uint8_t*) _binary_prime_private_key_start,
|
||||
((uintptr_t) &_binary_prime_private_key_end -
|
||||
(uintptr_t) &_binary_prime_private_key_start));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void** state)
|
||||
{
|
||||
sec_prinet_finit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_encrypt_decrypt_1(void** state)
|
||||
{
|
||||
_test_encrypt_decrypt(1);
|
||||
}
|
||||
|
||||
static void test_encrypt_decrypt_2(void** state)
|
||||
{
|
||||
_test_encrypt_decrypt(2);
|
||||
}
|
||||
|
||||
static void test_encrypt_decrypt_3(void** state)
|
||||
{
|
||||
_test_encrypt_decrypt(3);
|
||||
}
|
||||
|
||||
static void test_encrypt_decrypt_4(void** state)
|
||||
{
|
||||
_test_encrypt_decrypt(4);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const struct CMUnitTest tests[] ={
|
||||
cmocka_unit_test_setup_teardown(test_encrypt_decrypt_1, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_encrypt_decrypt_2, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_encrypt_decrypt_3, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(test_encrypt_decrypt_4, setup, teardown)
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
“²ø à•I߯þ6V朚S›öcÓ|ð¤æ)<¿údV
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
°כ�GQ
|
||||
. 2ם/ְשװכˆ°ֺ-½חײNג׀ƒL;¶�1U
|
||||
Reference in New Issue
Block a user