-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged branch developing. First working libmbc version.
- Loading branch information
Showing
4 changed files
with
312 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
#include "libmbc.h" | ||
#include <inttypes.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
|
||
/*********************** | ||
** PRIVATE ** | ||
***********************/ | ||
|
||
typedef uint8_t mbc_oct_key_el_t[2]; | ||
typedef mbc_oct_key_el_t* mbc_oct_key_t; | ||
|
||
static uint8_t* user_key; | ||
static size_t user_key_size; | ||
static mbc_oct_key_t oct_key; | ||
static size_t oct_key_size; | ||
|
||
/** | ||
* Generates the octal key (to be used in misc phase) from a user key passed as parameter. | ||
* @ret Generated octal key, `NULL` if the key cannot be `malloc`ated. | ||
* @post `*okey_size_ptr` now contains the size of the `oct_key` generated. | ||
*/ | ||
static mbc_oct_key_t make_oct_key(const uint8_t* key, size_t key_size, size_t* okey_size_ptr) { | ||
uint8_t l_bit, r_bit, swap_temp, current, next; | ||
uint8_t swap_mask[8] = {0,1,2,3,4,5,6,7}; | ||
bool to_check[8] = {1,1,1,1,1,1,1,1}; | ||
register size_t i, j; | ||
size_t okey_size; | ||
mbc_oct_key_el_t to_find; | ||
mbc_oct_key_t okey; | ||
|
||
for (i = 0; i < key_size; i++) { | ||
l_bit = (key[i] >> 4) & 0x07; | ||
r_bit = (key[i] >> 1) & 0x07; | ||
|
||
if (l_bit != r_bit) { | ||
if ((key[i] & 0x01) && l_bit != (r_bit ^ 0x07)) { | ||
l_bit ^= 0x07; | ||
r_bit ^= 0x07; | ||
} | ||
|
||
swap_temp = swap_mask[l_bit]; | ||
swap_mask[l_bit] = swap_mask[r_bit]; | ||
swap_mask[r_bit] = swap_temp; | ||
} | ||
} | ||
|
||
okey = malloc(sizeof(mbc_oct_key_el_t) * 8); | ||
okey_size = 0; | ||
for (i = 0; i < 8; i++) { | ||
if (i == swap_mask[i]) { | ||
to_check[i] = false; | ||
} else if (to_check[i]) { | ||
current = i; | ||
for (next = swap_mask[i]; next != current; next = swap_mask[next]) { | ||
to_check[next] = false; | ||
okey[okey_size][0] = current; | ||
okey[okey_size][1] = next; | ||
okey_size++; | ||
} | ||
} | ||
} | ||
|
||
*okey_size_ptr = okey_size; | ||
return okey; | ||
} | ||
|
||
|
||
/********************** | ||
** PUBLIC ** | ||
**********************/ | ||
|
||
bool mbc_set_user_key(const uint8_t* key, size_t key_size) { | ||
user_key = malloc(key_size); | ||
if (user_key == NULL) | ||
return false; | ||
|
||
memcpy(user_key, key, key_size); | ||
user_key_size = key_size; | ||
oct_key = make_oct_key(user_key, user_key_size, &oct_key_size); | ||
if (oct_key == NULL) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
void mbc_free() { | ||
free(user_key); | ||
user_key = NULL; | ||
user_key_size = 0; | ||
free(oct_key); | ||
oct_key = NULL; | ||
oct_key_size = 0; | ||
} | ||
|
||
uint8_t* mbc_encode(const uint8_t* data, size_t data_size) { | ||
uint8_t* edata; | ||
register size_t i, j; | ||
|
||
edata = malloc(data_size); | ||
if (edata == NULL) | ||
return NULL; | ||
|
||
memcpy(edata, data, data_size); | ||
|
||
// XOR | ||
for (i = 0; i < data_size; i++) | ||
edata[i] ^= user_key[i % user_key_size]; | ||
for (; i < user_key_size; i++) | ||
edata[i % data_size] ^= user_key[i]; | ||
|
||
// SWAP | ||
for (i = 0; i < data_size; i++) | ||
for (j = 0; j < oct_key_size; j++) | ||
if (edata[i] >> oct_key[j][0] != edata[i] >> oct_key[j][1]) | ||
edata[i] ^= (0x01 << oct_key[j][0]) ^ (0x01 << oct_key[j][1]); | ||
|
||
return edata; | ||
} | ||
|
||
uint8_t* mbc_decode(const uint8_t* data, size_t data_size) { | ||
uint8_t* ddata; | ||
register size_t i; | ||
register int8_t j; | ||
|
||
ddata = malloc(data_size); | ||
if (ddata == NULL) | ||
return NULL; | ||
|
||
memcpy(ddata, data, data_size); | ||
|
||
// SWAP | ||
for (i = 0; i < data_size; i++) | ||
for (j = oct_key_size-1; j >= 0; j--) | ||
if (ddata[i] >> oct_key[j][0] != ddata[i] >> oct_key[j][1]) | ||
ddata[i] ^= (0x01 << oct_key[j][0]) ^ (0x01 << oct_key[j][1]); | ||
|
||
// XOR | ||
for (i = 0; i < data_size; i++) | ||
ddata[i] ^= user_key[i % user_key_size]; | ||
for (; i < user_key_size; i++) | ||
ddata[i % data_size] ^= user_key[i]; | ||
|
||
return ddata; | ||
} | ||
|
||
char* mbc_raw_to_hex(const uint8_t* raw, size_t raw_size, bool uppercase) { | ||
char* hex; | ||
size_t hex_size; | ||
register size_t i; | ||
|
||
hex_size = raw_size * 2 + 1; | ||
hex = malloc(hex_size); | ||
if (hex == NULL) | ||
return NULL; | ||
|
||
if (uppercase) | ||
for (i = 0; i < raw_size; i++) | ||
sprintf(hex + i*2, "%02X", raw[i]); | ||
else | ||
for (i = 0; i < raw_size; i++) | ||
sprintf(hex + i*2, "%02x", raw[i]); | ||
|
||
hex[hex_size-1] = '\0'; | ||
|
||
return hex; | ||
} | ||
|
||
uint8_t* mbc_hex_to_raw(const char* hex, size_t* raw_size_ptr) { | ||
uint8_t* raw; | ||
unsigned int temp; | ||
size_t hex_size, raw_size; | ||
register size_t i; | ||
|
||
hex_size = strlen(hex); | ||
raw_size = hex_size/2; | ||
raw = malloc(raw_size); | ||
if (raw == NULL) | ||
return NULL; | ||
|
||
for (i = 0; i < raw_size; i++) { | ||
sscanf(hex + i*2, "%2x", &temp); | ||
raw[i] = (uint8_t) temp; | ||
} | ||
|
||
*raw_size_ptr = raw_size; | ||
|
||
return raw; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#ifndef MBC_H_INCLUDED | ||
#define MBC_H_INCLUDED | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
/** | ||
* Sets the value of global `user_key` and calculates global `oct_key`. | ||
* @ret `true` if success, `false` otherwise. | ||
* @pre `key` is an array of bytes; `key_size` > 0 | ||
*/ | ||
bool mbc_set_user_key(const uint8_t* key, size_t key_size); | ||
|
||
/** | ||
* Frees any dynamically allocated variables (basically the global keys). | ||
*/ | ||
void mbc_free(); | ||
|
||
/** | ||
* Encodes data. | ||
* @ret Encoded data as array, `NULL` if the array cannot be `malloc`ated. | ||
* @pre A key has been corectly set; `data` is an array of bytes; `data_size > 0`. | ||
*/ | ||
uint8_t* mbc_encode(const uint8_t* data, size_t data_size); | ||
|
||
/** | ||
* Decodes data. | ||
* @ret Decoded data as array, `NULL` if the array cannot be `malloc`ated. | ||
* @pre A key has been corectly set; `data` is an array of bytes; `data_size > 0`. | ||
*/ | ||
uint8_t* mbc_decode(const uint8_t* data, size_t data_size); | ||
|
||
/** | ||
* Converts raw data into an hexadecimal string. | ||
* @ret NULL-terminated hexadecimal string, `NULL` if the string cannot be `malloc`ated. | ||
* @pre `raw` is an array of bytes; `raw_size > 0`. | ||
* @post The length of the returned string is even, containing only lower/uppercase (accordingly to `uppercase`) hexadecimal ASCII characters. | ||
*/ | ||
char* mbc_raw_to_hex(const uint8_t* raw, size_t raw_size, bool uppercase); | ||
|
||
/** | ||
* Converts hexadecimal string into raw data. | ||
* @ret Raw data array, `NULL` if the array cannot be `malloc`ated. | ||
* @pre `hex` is a NULL-terminated string containing only lower/uppercase hexadecimal ASCII characters, and its length should be > 0. | ||
* @post `*raw_size_ptr` contains the size of the raw data returned. | ||
*/ | ||
uint8_t* mbc_hex_to_raw(const char* hex, size_t* raw_size_ptr); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <inttypes.h> | ||
#include <stdlib.h> | ||
#include "libmbc.c" | ||
// ^^^^^^^^^^^^^ Never include the .c! This include is for quick testing purposes only. | ||
|
||
int main(int argc, char* argv[]) { | ||
uint8_t *encoded, *decoded, *user_data; | ||
size_t user_data_len, user_key_len; | ||
register size_t i; | ||
|
||
user_data = argv[1]; | ||
user_data_len = strlen(user_data); | ||
user_key = argv[2]; | ||
user_key_len = strlen(user_key); | ||
|
||
mbc_set_user_key(user_key, user_key_len); | ||
encoded = mbc_encode(user_data, user_data_len); | ||
decoded = mbc_decode(encoded, user_data_len); | ||
|
||
printf("Testing encoding/decoding:\n"); | ||
for (i = 0; i < user_data_len; i++) | ||
printf("%2x ", user_data[i]); | ||
printf("\n"); | ||
|
||
for (i = 0; i < user_data_len; i++) | ||
printf("%2x ", encoded[i]); | ||
printf("\n"); | ||
|
||
for (i = 0; i < user_data_len; i++) | ||
printf("%2x ", decoded[i]); | ||
printf("\n"); | ||
|
||
uint8_t test_raw[] = {0x10, 0xff, 0xaa, 0x01, 0x11}; | ||
char test_hex[] = "10fFAA0111"; | ||
size_t test_raw_size, test_hex_size, raw_result_size; | ||
uint8_t* raw_result; | ||
char* hex_result; | ||
|
||
test_raw_size = sizeof(test_raw); | ||
test_hex_size = strlen(test_hex); | ||
|
||
hex_result = mbc_raw_to_hex(test_raw, test_raw_size, false); | ||
raw_result = mbc_hex_to_raw(test_hex, &raw_result_size); | ||
|
||
printf("\nTesting conversion:\n Raw: "); | ||
for (i = 0; i < test_raw_size; i++) | ||
printf("%2x", test_raw[i]); | ||
printf("\n"); | ||
|
||
printf("To hex: "); | ||
printf("%s\n", hex_result); | ||
|
||
printf(" Hex: "); | ||
printf("%s\n", test_hex); | ||
|
||
printf("To raw: "); | ||
for (i = 0; i < raw_result_size; i++) | ||
printf("%2x", raw_result[i]); | ||
printf("\n"); | ||
|
||
mbc_free(); | ||
free(raw_result); | ||
free(hex_result); | ||
|
||
return 0; | ||
} |