Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7262240
Very first version of the port to C. Still i2c call missing and Makefile
antonhristozov Oct 12, 2020
bd3cae4
Forgot to return in this function
antonhristozov Oct 13, 2020
502d8da
Added a Makefile for creating a shared library from the .c file
antonhristozov Oct 13, 2020
32335e4
Added a simple C test application
antonhristozov Oct 13, 2020
82e6d78
Added a Python Test Application to Demonstrate How the C Library is C…
antonhristozov Oct 13, 2020
6c86535
Fixed Markdown for README.md
antonhristozov Oct 13, 2020
3344020
Added an i2c call
antonhristozov Oct 13, 2020
3a1b0a0
Added Line breaks in the README.md
sei-ahristozov Oct 14, 2020
7c44bd9
Added printfs for the .c line follower module
sei-ahristozov Oct 29, 2020
bff8188
variable declaration not supported by basic compiler
Oct 29, 2020
8e1e67a
Reverse changes in order to make a pull request from another branch
sei-ahristozov Nov 2, 2020
5b5741a
Adding difference files in cline branch
sei-ahristozov Nov 3, 2020
fad8e98
Merge pull request #2 from uberspark/cline
amitvasudevan Nov 3, 2020
120aa4a
Fixed code because of a compiler error on the Pi
antonhristozov Dec 1, 2020
3378e9e
Had to change the path type for this version of Python on this Raspbi…
antonhristozov Dec 1, 2020
9db2012
Had to return the number of bytes read
antonhristozov Dec 1, 2020
e63f764
Adding hmac256 files in a subfolder
sei-ahristozov Nov 3, 2020
deea6e3
Needed this header file in order to compile the hmac256 files
sei-ahristozov Nov 3, 2020
1d3793c
Predefined types needed for compilation
sei-ahristozov Nov 3, 2020
ac9ecd5
Added hmac files to the C library
antonhristozov Nov 3, 2020
df055ab
Merged with changes from uobjcoll
antonhristozov Dec 1, 2020
01a8fb1
Merge pull request #3 from uberspark/hmac256
amitvasudevan Dec 1, 2020
ce1fb06
Working line following functionality with C library calls
antonhristozov Dec 2, 2020
ec2bb4e
HMAC debugging messages added
antonhristozov Dec 2, 2020
0158e1d
Merge pull request #4 from uberspark/cartest
amitvasudevan Dec 7, 2020
9312246
Extended unit test
antonhristozov Jan 4, 2021
103b4a9
Line follower Unit Test
antonhristozov Jan 4, 2021
966bfc2
Added printing of address
antonhristozov Jan 4, 2021
01c8213
Aadded dynamic array on the heap
antonhristozov Jan 4, 2021
70c1449
Added minor changes to be able to intervene with memory attack
antonhristozov Jan 4, 2021
7f7497c
Need the print statement in ordert to print the address
antonhristozov Jan 4, 2021
911d922
Removed heap related variables. Back to static buffers.
antonhristozov Jan 5, 2021
7c93f3d
Merge pull request #5 from uberspark/cartest
amitvasudevan Jan 11, 2021
e8ef4d5
Remove a print statement
antonhristozov Jan 19, 2021
3aa12f7
Added cross compilation of this library
antonhristozov Jan 19, 2021
d2751d0
Added a flag in Makefile
antonhristozov Jan 20, 2021
c4fb06e
Adding uhcall dependencies
antonhristozov Jan 20, 2021
5d576df
Added all code for HMAC calculation
antonhristozov Jan 20, 2021
72b6d43
Linked static library to the shared library
antonhristozov Jan 20, 2021
cd70438
Brought uhcall.c to link in the .so library
antonhristozov Jan 21, 2021
933a22c
Removed local uhcall.c file
antonhristozov Jan 22, 2021
ee62278
Merge pull request #7 from uberspark/cartest
amitvasudevan Jan 24, 2021
51b02c5
Now attack is goinf to be on raw_buffer
antonhristozov Jan 25, 2021
5460959
Changes to implement two buffers
antonhristozov Jan 26, 2021
c7abdbe
Line following worked with hyoer calls
antonhristozov Jan 28, 2021
89d09f6
Changes needed for the attack
antonhristozov Jan 29, 2021
11bd997
Moved the sleep in order to be effective for decrypted buffer attack
antonhristozov Feb 2, 2021
f1e96ad
Merge pull request #8 from uberspark/cartest
amitvasudevan Feb 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
334 changes: 334 additions & 0 deletions Line_Follower.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
/* C module with equivalen functionality like the original Line_Follwer.py */

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> //Needed for I2C port
#include <fcntl.h> //Needed for I2C port
#include <sys/ioctl.h> //Needed for I2C port
#include <linux/i2c-dev.h> //Needed for I2C port
#include "Line_Follower.h"
#include "xmhfcrypto.h"
#include "picar-s.h"

/* Globals */
#define RAW_LEN (2*NUM_REF)
int references[NUM_REF] = {200,200,200,200,200};
const int SLAVE_ADDRESS = 0x11;
int bus = 1;

__attribute__((section("i2c_section"))) unsigned char uhsign_key[]="super_secret_key_for_hmac";
#define UHSIGN_KEY_SIZE (sizeof(uhsign_key))
#define HMAC_DIGEST_SIZE 32

__attribute__((section(".palign_data"))) __attribute__((aligned(4096))) picar_s_param_t upicar;
__attribute__((aligned(4096))) __attribute__((section("i2c_section_2"))) static char encrypted_buffer[4096];
__attribute__((aligned(4096))) __attribute__((section("i2c_section_3"))) static char decrypted_buffer[4096];

int read_i2c(char *buffer,int length){
int file_i2c;
int ret_length=0;
int i;
unsigned long digest_size = HMAC_DIGEST_SIZE;
unsigned char digest_result[HMAC_DIGEST_SIZE];

//printf("read_i2c() :: encrypted_buffer address : %p \n",encrypted_buffer);
printf("read_i2c() :: decrypted_buffer address : %p \n",decrypted_buffer);
//----- OPEN THE I2C BUS -----
char *filename = (char*)"/dev/i2c-1";
if ((file_i2c = open(filename, O_RDWR)) < 0)
{
//ERROR HANDLING: you can check errno to see what went wrong
printf("Failed to open the i2c bus");
return 0;
}

int addr = SLAVE_ADDRESS; //<<<<<The I2C address of the slave
if (ioctl(file_i2c, I2C_SLAVE, addr) < 0)
{
printf("Failed to acquire bus access and/or talk to slave.\n");
//ERROR HANDLING; you can check errno to see what went wrong
return 0;
}
ret_length = read(file_i2c, buffer, length);
if(ret_length == 0){
printf("i2c read() returned 0 bytes\n");
close(file_i2c);
return ret_length;
}


//----- READ BYTES -----
//read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
if (ret_length != length){
if(ret_length == length + HMAC_DIGEST_SIZE){
#ifdef UOBJCOLL
picar_s_param_t *ptr_upicar = &upicar;
int i;
ptr_upicar->encrypted_buffer_va = (uint32_t) encrypted_buffer;
ptr_upicar->decrypted_buffer_va = (uint32_t) decrypted_buffer;
ptr_upicar->len = length;
// Perform an uobject call
if(!uhcall(UAPP_PICAR_S_FUNCTION_TEST, ptr_upicar, sizeof(picar_s_param_t)))
printf("hypercall FAILED\n");
else{
//printf("hypercall SUCCESS\n");
memcpy(digest_result,decrypted_buffer,digest_size);
digest_size = HMAC_DIGEST_SIZE;
}

// Sleep for 10ms so that an attack can succeed in overwriting bytes in buffer
// Car still runs fine with this delay
usleep(10000);
if(memcmp(buffer+length,decrypted_buffer,digest_size) != 0){
printf("HMAC digest did not match with driver's digest \n");
printf("Bytes returned: ");
for(i=0;i<length+HMAC_DIGEST_SIZE;i++){
printf("%X ",buffer[i]);
}
printf("\nDigest calculated: ");
for(i=0;i<HMAC_DIGEST_SIZE;i++){
printf("%X ",digest_result[i]);
}
for(i=0;i<length;i++){
buffer[i] = 0;
}
printf("\n");
}
#else
// Calculate the HMAC
if(hmac_sha256_memory(uhsign_key, (unsigned long) UHSIGN_KEY_SIZE, (unsigned char *) buffer, (unsigned long) length, digest_result, &digest_size)==CRYPT_OK) {
if(memcmp(buffer+length,digest_result,digest_size) != 0){
printf("HMAC digest did not match with driver's digest \n");
printf("Bytes returned: ");
for(i=0;i<length;i++){
printf("%d ",buffer[i]);
}
printf("\nDigest calculated: ");
for(i=0;i<HMAC_DIGEST_SIZE;i++){
printf("%d ",digest_result[i]);
}
for(i=0;i<length;i++){
buffer[i] = 0;
}
printf("\n");
}
// else{
// printf("HMAC digest match\n");
// }
}
#endif
}
else{
//ERROR HANDLING: i2c transaction failed
printf("Read unexpected number of bytes from the i2c bus.\n");
}
}
close(file_i2c);
return ret_length;
}


char * read_raw(){
int flag = 0;
int i;
for(i=0;i<NUM_REF;i++){
/* Do an i2c read and if successful break from the loop */
if(read_i2c(encrypted_buffer,RAW_LEN)){
flag = 1;
break;
}
}
if(flag){
return encrypted_buffer;
}
else{
return NULL;
}
}

int * read_analog(int trys){
int i,j;
char *raw_result;
int high_byte, low_byte;
static int analog_result[NUM_REF];
if(trys <= 0){
trys = NUM_REF;
}
for(j=0;j<trys;j++){
raw_result = read_raw();
if(raw_result != NULL){
for(i=0;i<NUM_REF;i++){
high_byte = raw_result[i*2] << 8;
low_byte = raw_result[i*2+1];
analog_result[i] = high_byte + low_byte;
if(analog_result[i] > 1024){
continue;
}
}
return analog_result;
}
else{
break;
}
}
printf("Line follower read error. Please check the wiring.\n");
return NULL;
}

__attribute__ ((section("i2c_section"))) static int digital_list[NUM_REF] = {0};

int * read_digital(){
int * lt;
int i;
lt = read_analog(NUM_REF);
if(lt != NULL){
for(i=0;i<NUM_REF;i++){
if(lt[i] > references[i]){
digital_list[i] = 0;
}
else if(lt[i] < references[i]){
digital_list[i] = 1;
}
else{
digital_list[i] = -1;
}
}
printf("\n");
}
//printf("read_digital() :: digital_list address : %p \n",digital_list);
return digital_list;
}

float * get_average(int mount){
static float average[NUM_REF] = {0.0,0.0,0.0,0.0,0.0};
float *lt_list [NUM_REF];
int i,lt_id;
int * lt;
float sum;
for(i=0;i<NUM_REF;i++){
lt_list[i] = malloc(sizeof(float)*mount);
}
for(i=0;i<mount;i++){
lt = read_analog(NUM_REF);
for(lt_id=0;lt_id<NUM_REF;lt_id++){
lt_list[lt_id][i] = lt[lt_id];
}
}
for(lt_id=0;lt_id < NUM_REF;lt_id++){
sum = 0;
for(i=0;i<mount;i++){
sum += lt_list[lt_id][i];
}
average[lt_id] = sum/mount;
}
for(i=0;i<NUM_REF;i++){
free(lt_list[i]);
}
return average;
}

int * found_line_in(float timeout){
int * lt_status;
float time_during;
clock_t time_start;
clock_t time_now;
int i;
time_start = clock();
time_during = 0;
while(time_during < timeout){
lt_status = read_digital();
for(i=0;i<NUM_REF;i++){
if(lt_status[i] == 1){
return lt_status;
}
}
time_now = clock();
time_during = (time_now - time_start)/1000000; /* Convert from micro to seconds */
}
return NULL;

}

void wait_tile_status(int * status){
int * lt_status;
int i;
int flag = 1;
while(1){
flag = 1;
lt_status = read_digital();
for(i=0;i<NUM_REF;i++){
if(lt_status[i] != status[i]){
flag = 0;
}
}
if(flag == 1){
break;
}
}
}

void wait_tile_center(){
int * lt_status;
while(1){
lt_status = read_digital();
if(lt_status[2] == 1){
break;
}
}
}



//return 0 on success, -1 on any error

int lib_init(void){
picar_s_param_t *ptr_upicar = &upicar;
ptr_upicar->buffer_va = (uint32_t)&decrypted_buffer;

if(mlock(&encrypted_buffer, 4096) == -1){
printf("could not lock memory backing for encrypted buffer");
return -1;
}

if(mlock(ptr_upicar->buffer_va, 4096) == -1){
printf("could not lock memory backing for decrypted buffer");
return -1;
}

if(!uhcall(UAPP_PICAR_S_FUNCTION_PROT, ptr_upicar, sizeof(picar_s_param_t))){
printf("PROT hypercall FAILED\n");
return -1; //error
} else{
printf("PROT hypercall SUCCESS\n");
return 0; //success
}
}




//return 0 on success, -1 on any error
int lib_exit(void){
picar_s_param_t *ptr_upicar = &upicar;
ptr_upicar->buffer_va = (uint32_t)&decrypted_buffer;

if(!uhcall(UAPP_PICAR_S_FUNCTION_UNPROT, ptr_upicar, sizeof(picar_s_param_t))){
printf("UNPROT hypercall FAILED\n");
return -1; //error
}

if(munlock(ptr_upicar->buffer_va, 4096) == -1){
printf("could not unlock memory backing for buffer after return from UNPROT hypercall");
return -1;
}

if(munlock(&encrypted_buffer, 4096) == -1){
printf("could not unlock memory backing for encrypted buffer after return from UNPROT hypercall");
return -1;
}

return 0; //success
}

14 changes: 14 additions & 0 deletions Line_Follower.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* Header file to be used by callers of this functionality */

#define NUM_REF 5

/* Function Prototypes for Line_Follower.c */
char * read_raw();
int * read_analog(int trys);
int * read_digital();
float * get_average(int mount);
int * found_line_in(float timeout);
void wait_tile_status(int *status);
void wait_tile_center();
int lib_init(void);
int lib_exit(void);
26 changes: 26 additions & 0 deletions Line_Follower_Test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* C module with equivalen functionality like the original Line_Follwer.py */

#include <stdio.h>
#include "Line_Follower.h"

int main(){
printf("Line Follower C Test Application Running\n");
int *dig_list;
int i;
int cnt = 0;
lib_init();
for(cnt=0;cnt<20;cnt++){
dig_list = read_digital();
printf("i2c buffer address %p \n",dig_list);
for(i=0;i<NUM_REF;i++){
printf("%d ",dig_list[i]);
}
printf("\n");
sleep(1);
for(i=0;i<NUM_REF;i++){
printf("%d ",dig_list[i]);
}
}
lib_exit();
return 0;
}
18 changes: 18 additions & 0 deletions Line_Follower_Test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ctypes_test.py
import ctypes
import pathlib
import os
import time

if __name__ == "__main__":
print("Line Follower Python Test Application Running")
# Load the shared library into ctypes
libname = os.path.abspath(".") + "/" + "libLine_Follower.so";
print(libname)
c_lib = ctypes.CDLL(libname)
while True:
dt_list = c_lib.read_digital()
ptr = ctypes.cast(dt_list,ctypes.POINTER(ctypes.c_int))
print(hex(id(ptr)))
print(ptr[0], ptr[1], ptr[2], ptr[3], ptr[4])
time.sleep(1)
Loading