Skip to content

Commit

Permalink
Merged branch developing. First working libmbc version.
Browse files Browse the repository at this point in the history
  • Loading branch information
mebeim committed Apr 9, 2017
2 parents b5211e4 + b38e1a4 commit 2d75c02
Show file tree
Hide file tree
Showing 4 changed files with 312 additions and 3 deletions.
190 changes: 190 additions & 0 deletions libmbc.c
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;
}
50 changes: 50 additions & 0 deletions libmbc.h
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
7 changes: 4 additions & 3 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Something like:

### `make_oct_key` rationale:

The `okey` starts as `{0,1,2,3,4,5,6,7}`, then for every `i = 0` to `key_len-1`:
The `swap_mask` starts as `{0,1,2,3,4,5,6,7}`, then for every `i` from `0` to `key_len-1`:

1. Extract positions of bits to swap:

Expand All @@ -41,6 +41,7 @@ The `okey` starts as `{0,1,2,3,4,5,6,7}`, then for every `i = 0` to `key_len-1`:
r_bit ^= 0x07;
}

3. Swap `okey[l_bit]` with `okey[r_bit]`.
3. Swap `swap_mask[l_bit]` with `swap_mask[r_bit]`.

4. At the end of the cycle, `okey` contains a swap map to be applied to the bits of every byte of data.
4. At the end of the cycle, `swap_mask` contains the swap mask to be applied to the bits of every byte of data.
5. The following cycle scans `swap_mask` to extact the shortest array of moves (which will be the real `oct_key`) to perform to obtain the same result.
68 changes: 68 additions & 0 deletions test.c
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;
}

0 comments on commit 2d75c02

Please sign in to comment.