Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AKMC-113: Add SADB MariaDB code for working with MySQL BINARY fields #17

Merged
merged 1 commit into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions fsw/crypto_sadb/sadb_mariadb_admin_scripts/create_sadb.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ CREATE TABLE security_associations
,shplf_len SMALLINT
,stmacf_len SMALLINT
,ecs_len SMALLINT
,ecs SMALLINT NOT NULL DEFAULT 0
,ecs BINARY(4) NOT NULL DEFAULT X'00000000' -- ECS_SIZE=4
,iv_len SMALLINT NOT NULL DEFAULT 12
,iv BINARY(12) NOT NULL DEFAULT 0 -- IV_SIZE=12
,iv BINARY(12) NOT NULL DEFAULT X'000000000000000000000000' -- IV_SIZE=12
,acs_len SMALLINT NOT NULL DEFAULT 0
,acs SMALLINT NOT NULL DEFAULT 0
,abm_len MEDIUMINT
,abm SMALLINT
,abm BINARY(20) NOT NULL DEFAULT X'1111111111111111111111111111111111111111' -- ABM_SIZE=20
,arc_len SMALLINT NOT NULL DEFAULT 0
,arc BINARY(20) NOT NULL DEFAULT 0 -- ARC_LEN=20 , TBD why so large...
,arc BINARY(20) NOT NULL DEFAULT X'0000000000000000000000000000000000000000' -- ARC_SIZE=20 , TBD why so large...
,arcw_len SMALLINT
,arcw SMALLINT
,arcw BINARY(1) NOT NULL DEFAULT X'00' -- ARCW_SIZE=1
);
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@ USE sadb;

-- SA 1 - CLEAR MODE
INSERT INTO security_associations (spi,sa_state,est,ast,arc_len,arc,arcw_len,arcw,tfvn,scid,vcid,mapid)
VALUES (1,3,0,0,1,0,1,5,0,3,0,0);
VALUES (1,3,0,0,1,X'0000000000000000000000000000000000000000',1,X'0101',0,3,0,0);

-- SA 2 - KEYED; ARCW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: 128
INSERT INTO security_associations (spi,ekid,sa_state,est,ast,shivf_len,iv_len,iv,abm_len,abm,arcw_len,arcw,arc_len)
VALUES (2,128,2,1,1,12,12,0,20,0,1,5,11);
VALUES (2,128,2,1,1,12,12,X'000000000000000000000000',20,X'0000000000000000000000000000000000000000',1,5,11);

-- SA 3 - KEYED; ARCW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: 129
INSERT INTO security_associations (spi,ekid,sa_state,est,ast,shivf_len,stmacf_len,iv_len,iv,abm_len,abm,arcw_len,arcw,arc_len)
VALUES (3,129,2,1,1,12,16,12,0,20,0,1,5,11);
VALUES (3,129,2,1,1,12,16,12,X'000000000000000000000000',20,X'0000000000000000000000000000000000000000',1,5,11);

-- SA 4 - KEYED; ARCW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: 130
INSERT INTO security_associations (spi,ekid,sa_state,est,ast,shivf_len,iv_len,iv,abm_len,abm,arcw_len,arcw,arc_len,tfvn,scid,vcid,mapid)
VALUES (4,130,2,1,1,12,12,0,20,0,1,5,11,0,3,0,0);
VALUES (4,130,2,1,1,12,12,X'000000000000000000000001',20,X'0000000000000000000000000000000000000000',1,5,11,0,3,0,0);

-- SA 5 - KEYED; ARCW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: 131
INSERT INTO security_associations (spi,ekid,sa_state,est,ast,shivf_len,iv_len,iv,abm_len,abm,arcw_len,arcw,arc_len)
VALUES (5,131,2,1,1,12,12,0,20,0,1,5,11);
VALUES (5,131,2,1,1,12,12,X'000000000000000000000000',20,X'0000000000000000000000000000000000000000',1,5,11);

-- SA 6 - UNKEYED; ARCW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: -
INSERT INTO security_associations (spi,sa_state,est,ast,shivf_len,iv_len,iv,abm_len,abm,arcw_len,arcw,arc_len)
VALUES (6,1,1,1,12,12,0,20,0,1,5,11);
VALUES (6,1,1,1,12,12,X'000000000000000000000000',20,X'0000000000000000000000000000000000000000',1,5,11);

-- SA 7 - KEYED; ARCW:5; AES-GCM; IV:00...00; IV-len:12; MAC-len:16; Key-ID: 130
INSERT INTO security_associations (spi,ekid,sa_state,est,ast,shivf_len,iv_len,iv,abm_len,abm,arcw_len,arcw,arc_len,tfvn,scid,vcid,mapid)
VALUES (7,130,2,1,1,12,12,0,20,0,1,5,11,0,3,1,0);
VALUES (7,130,2,1,1,12,12,X'000000000000000000000000',20,X'0000000000000000000000000000000000000000',1,5,11,0,3,1,0);

-- SA 8 - CLEAR MODE
INSERT INTO security_associations (spi,sa_state,est,ast,arc_len,arc,arcw_len,arcw,tfvn,scid,vcid,mapid)
VALUES (8,3,0,0,1,0,1,5,0,3,1,0);
VALUES (8,3,0,0,1,X'0000000000000000000000000000000000000000',1,5,0,3,1,0);
83 changes: 65 additions & 18 deletions fsw/src_mysql/sadb_routine_mariadb.template.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,18 @@ static int32 sadb_sa_delete(void);
//MySQL local functions
static int32 finish_with_error(MYSQL *con,int err);
//MySQL Queries
const static char* SQL_SADB_GET_SA_BY_SPI = "SELECT * FROM security_associations WHERE spi='%d';";
const static char* SQL_SADB_GET_SA_BY_GVCID = "SELECT * FROM security_associations WHERE tfvn='%d' AND scid='%d' AND vcid='%d' AND mapid='%d';";
const static char* SQL_SADB_UPDATE_IV_ARC_BY_SPI = "UPDATE security_associations "\
"SET iv='%d', arc='%d' " \
"WHERE spi='%d'AND tfvn='%d' AND scid='%d' AND vcid='%d' AND mapid='%d';";
const static char* SQL_SADB_GET_SA_BY_SPI = "SELECT spi,ekid,akid,sa_state,tfvn,scid,vcid,mapid,lpid,est,ast,shivf_len,shsnf_len,shplf_len,stmacf_len,ecs_len,HEX(ecs),iv_len,HEX(iv),acs_len,acs,abm_len,HEX(abm),arc_len,HEX(arc),arcw_len,HEX(arcw)"
" FROM security_associations WHERE spi='%d'";
const static char* SQL_SADB_GET_SA_BY_GVCID = "SELECT spi,ekid,akid,sa_state,tfvn,scid,vcid,mapid,lpid,est,ast,shivf_len,shsnf_len,shplf_len,stmacf_len,ecs_len,HEX(ecs),iv_len,HEX(iv),acs_len,acs,abm_len,HEX(abm),arc_len,HEX(arc),arcw_len,HEX(arcw)"
" FROM security_associations WHERE tfvn='%d' AND scid='%d' AND vcid='%d' AND mapid='%d' AND sa_state='%d'";
const static char* SQL_SADB_UPDATE_IV_ARC_BY_SPI = "UPDATE security_associations"
" SET iv=X'%s', arc=X'%s'"
" WHERE spi='%d'AND tfvn='%d' AND scid='%d' AND vcid='%d' AND mapid='%d'";

// sadb_routine mariaDB private helper functions
static int32 parse_sa_from_mysql_query(char* query, SecurityAssociation_t** security_association);

static int32 convert_hexstring_to_byte_array(char* hexstr, uint8* byte_array);
static char* convert_byte_array_to_hexstring(void* src_buffer, size_t buffer_length);

/*
** Global Variables
Expand Down Expand Up @@ -122,7 +125,7 @@ static int32 sadb_get_operational_sa_from_gvcid(uint8 tfvn,uint16 scid,uint16 vc
int32 status = OS_SUCCESS;

char gvcid_query[2048];
snprintf(gvcid_query, sizeof(gvcid_query),SQL_SADB_GET_SA_BY_GVCID,tfvn,scid,vcid,mapid);
snprintf(gvcid_query, sizeof(gvcid_query),SQL_SADB_GET_SA_BY_GVCID,tfvn,scid,vcid,mapid,SA_OPERATIONAL);

status = parse_sa_from_mysql_query(&gvcid_query[0],security_association);

Expand All @@ -132,11 +135,15 @@ static int32 sadb_save_sa(SecurityAssociation_t* sa)
{
int32 status = OS_SUCCESS;

char gvcid_query[2048];
snprintf(gvcid_query, sizeof(gvcid_query),SQL_SADB_UPDATE_IV_ARC_BY_SPI,sa->iv,sa->arc,sa->spi,sa->gvcid_tc_blk.tfvn,sa->gvcid_tc_blk.scid,sa->gvcid_tc_blk.vcid,sa->gvcid_tc_blk.mapid);
char update_sa_query[2048];
snprintf(update_sa_query, sizeof(update_sa_query),SQL_SADB_UPDATE_IV_ARC_BY_SPI,convert_byte_array_to_hexstring(sa->iv,sa->shivf_len),convert_byte_array_to_hexstring(sa->arc,sa->shsnf_len),sa->spi,sa->gvcid_tc_blk.tfvn,sa->gvcid_tc_blk.scid,sa->gvcid_tc_blk.vcid,sa->gvcid_tc_blk.mapid);

Crypto_saPrint(sa);
if(mysql_query(con,gvcid_query)) {
#ifdef SA_DEBUG
fprintf(stderr,"MySQL Insert SA Query: %s \n", update_sa_query);
#endif

//Crypto_saPrint(sa);
if(mysql_query(con,update_sa_query)) {
status = finish_with_error(con,SADB_QUERY_FAILED); return status;
}
// todo - if query fails, need to push failure message to error stack instead of just return code.
Expand All @@ -161,7 +168,11 @@ static int32 parse_sa_from_mysql_query(char* query, SecurityAssociation_t** secu
int32 status = OS_SUCCESS;
SecurityAssociation_t* sa = malloc(sizeof(SecurityAssociation_t));

if(mysql_query(con,query)) {
#ifdef SA_DEBUG
fprintf(stderr,"MySQL Query: %s \n", query);
#endif

if(mysql_real_query(con,query,strlen(query))) { //query should be NUL terminated!
status = finish_with_error(con,SADB_QUERY_FAILED); return status;
}
// todo - if query fails, need to push failure message to error stack instead of just return code.
Expand Down Expand Up @@ -210,17 +221,18 @@ static int32 parse_sa_from_mysql_query(char* query, SecurityAssociation_t** secu
if(strcmp(field_names[i],"shplf_len")==0){sa->shplf_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"stmacf_len")==0){sa->stmacf_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"ecs_len")==0){sa->ecs_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"ecs")==0){tmp_uint8 = (uint8)atoi(row[i]); memcpy(&(sa->ecs),&tmp_uint8,sizeof(tmp_uint8));continue;}
if(strcmp(field_names[i],"HEX(ecs)")==0){convert_hexstring_to_byte_array(row[i],sa->ecs);continue;}
if(strcmp(field_names[i],"iv_len")==0){sa->iv_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"iv")==0){memcpy(&(sa->iv),&row[i],sizeof(row[i]));continue;}
//if(strcmp(field_names[i],"HEX(iv)")==0){memcpy(&(sa->iv),&row[i],IV_SIZE);continue;}
if(strcmp(field_names[i],"HEX(iv)")==0){convert_hexstring_to_byte_array(row[i],sa->iv);continue;}
if(strcmp(field_names[i],"acs_len")==0){sa->acs_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"acs")==0){sa->acs=atoi(row[i]);continue;}
if(strcmp(field_names[i],"abm_len")==0){sa->abm_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"abm")==0){tmp_uint8 = (uint8)atoi(row[i]);memcpy(&(sa->abm),&tmp_uint8,sizeof(tmp_uint8));continue;}
if(strcmp(field_names[i],"HEX(abm)")==0){convert_hexstring_to_byte_array(row[i],sa->abm);continue;}
if(strcmp(field_names[i],"arc_len")==0){sa->arc_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"arc")==0){memcpy(&(sa->arc),&row[i],sizeof(row[i]));continue;}
if(strcmp(field_names[i],"HEX(arc)")==0){convert_hexstring_to_byte_array(row[i],sa->arc);continue;}
if(strcmp(field_names[i],"arcw_len")==0){sa->arcw_len=atoi(row[i]);continue;}
if(strcmp(field_names[i],"arcw")==0){tmp_uint8 = (uint8)atoi(row[i]);memcpy(&(sa->arcw),&tmp_uint8,sizeof(tmp_uint8));continue;}
if(strcmp(field_names[i],"HEX(arcw)")==0){convert_hexstring_to_byte_array(row[i],sa->arcw);continue;}
//printf("%s:%s ",field_names[i], row[i] ? row[i] : "NULL");
}
//printf("\n");
Expand All @@ -231,10 +243,45 @@ static int32 parse_sa_from_mysql_query(char* query, SecurityAssociation_t** secu

return status;
}
static int32 convert_hexstring_to_byte_array(char* source_str, uint8* dest_buffer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this function - should we consider moving some of these helpers like this to a utils file / directory for access in other files e.g. crypto_util/src?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the MariaDB/mysql source code should depend on the crypto_util source tree at this time... So far, everything under crypto_util are test & related helper applications/libraries, not things we expect end-users to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an intermediary PR, there is still mysql integration work to do... since this is the only comment and the function can be refactored when needed, I'm going to proceed with the merge.

{ // https://stackoverflow.com/questions/3408706/hexadecimal-string-to-byte-array-in-c/56247335#56247335
char *line = source_str;
char *data = line;
int offset;
uint8 read_byte;
uint8 data_len = 0;

while (sscanf(data, " %02x%n", &read_byte, &offset) == 1) {
dest_buffer[data_len++] = read_byte;
data += offset;
}
return data_len;
}

static char* convert_byte_array_to_hexstring(void* src_buffer, size_t buffer_length)
{
if(buffer_length==0){ //Return empty string (with null char!) if buffer is empty
return "";
}

unsigned char* bytes = src_buffer;
unsigned char* hexstr = malloc(buffer_length*2+1);

if(src_buffer == NULL) return NULL;

for(size_t i = 0; i < buffer_length; i++){
uint8 nib1 = (bytes[i] >> 4) & 0x0F;
uint8 nib2 = (bytes[i]) & 0x0F;
hexstr[i*2+0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA;
hexstr[i*2+1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA;
}
return hexstr;
}


static int32 finish_with_error(MYSQL *con, int err)
{
fprintf(stderr, "%s\n", mysql_error(con));
fprintf(stderr, "%s%s%s\n", KRED,mysql_error(con),RESET); // todo - if query fails, need to push failure message to error stack
mysql_close(con);
return err;
}