How to set and delete AES key within AES HAL - c

I have the following auto-generated (from HAL) pKeyAES array (there is also an initVectorAES that looks the same):
__ALIGN_BEGIN static const uint8_t pKeyAES[16] __ALIGN_END = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00};
Along with the init function such as:
void Hal_MX_init (void){
hcryp.Instance = AES;
hcryp.Init.DataType = CRYP_DATATYPE_8B;
hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
hcryp.Init.ChainingMode = CRYP_CHAINMODE_AES_CBC;
hcryp.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE;
hcryp.Init.pKey = (uint8_t *)pKeyAES;
hcryp.Init.pInitVect = (uint8_t *)pInitVectAES;
if (HAL_CRYP_Init(&hcryp) != HAL_OK)
{
Error_Handler();
}
}
Now I want to create a new function in this file generated by the HAL so that the "key" is always kept within the HAL. To do this I am thinking of using the pKeyAES to always keep the "key". However, I am not really sure on how to do this; for instace, if I want to create a new "set key" or "delete key" method, how would this look like when doing it within the HAL?
For instance, for "set key" I think it would be best to store it within the pKeyAES (having an in-param for getting the new key). And for "delete key" function, I would suspect you could "delete"/reset anything that is currently stored in pKeyAES array? However, I'm not entirely sure how to accomplish this code-wise.
Also, when doing "set-key" would I need to do something with the "initVector" that is provided as well, or just keep it as it is (currently holding the same value as the pKeyAES).
Any help, tips etc. Would be most helpful.
I can guess that I have to create a new init function for set key, such as "void setKey_init (){}" and add the same stuff from hcryp such as in the example code provided above; but where I have the new Key as a param input variable. hcryp.Init.pKey is a uint8_t pointer key; where I want my new key to be set. But my problem is how it would look code-wise to make it the most efficient when setting a new key here. I don't want to point to a key outside of my aes.c file (risky), but rather have a key sent in that I can add to the struct and init with the function.

If I understand correctly, it should be quite simple. Having a pointer to a new key (const uint8_t *pNewKeyAES), copy it to the pKeyAES storage and perform the initialization. In the following, if pNewKeyAESis NULL, the key is set to the all-zeroes key (corresponding to deleting the key):
#include <string.h>
#include <stdint.h>
// Discard `const` from pKeyAES to be able to modify it
__ALIGN_BEGIN static uint8_t pKeyAES[16] __ALIGN_END = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00};
void setKey_init (const uint8_t *pNewKeyAES)
{
if(pNewKeyAES != NULL)
{ // Use new key
memcpy(pKeyAES, pNewKeyAES, CRYP_KEYSIZE_128B);
}
else
{ // Delete key
memset(pKeyAES, 0, CRYP_KEYSIZE_128B);
}
Hal_MX_init(); // As defined in the question, may also copy contents here
}

Related

C embedded change values of struct from another file

Hello I am working on a small roboter project at uni and I have run into following issue.
I have a typedef called RoboterData inside of a header file because I want to make use of it across multiple files. Inside of the main file I have a RoboterData data variable which holds important data.
My goal is to have access from other files to this data having the ability to get and set it from another file. I want to avoid the use of a global variable.
Here are the relevant code fragments of my approach:
main.h
typedef struct {
DriveMode mode;
short sensor_left;
short sensor_mid;
short sensor_right;
int left_eng_speed;
int right_eng_speed;
} RoboterData;
main.c
# include "motors.h"
// The Data I want to get and set from other files.
RoboterData data;
// Call to a funcion defined in motors.c
drive_straight(RoboterData *data);
motors.h
void drive_straight(RoboterData *data);
motors.c
# include "main.h"
enum {
ENG_STILL = 0,
ENG_SLOW = 50,
ENG_MID = 155,
ENG_FAST = 200
}
void drive_straight(RoboterData *data) {
data ->left_eng_speed = ENG_FAST;
data ->right_eng_speed = ENG_FAST;
set_duty_cycle(LEFT_ENG, ENG_FAST);
set_duty_cycle(RIGHT_ENG, ENG_FAST);
}
When I later try to print out the values left_eng_speed and right_eng_speed via serial port it stays at 0. I know C is call by value but since I am passing a ptr to my struct the value I am passing is the adress of the struct and when I dereference it via '->' I should be able to access its original data from my understanding and not a copy because the only thing I copied was the address.
If someone could explain to me why this is not working and provide a viable alternative, I would be very greatfull.
// Call to a funcion defined in motors.c
drive_straight(RoboterData *data);
This is a function declaration. It doesn't do anything. You want
drive_straight(&data);
to actually call the function.

SNMP Agent: Could mib2c generate code for InetAddress or String type (ie something not an integer type)

I was able to transform 95% of a dedicated MIB to C code and make it run in a sub-agent like described in the last part of this Net-SNMP tutorial
For this I naturally use the mib2c.mfd.conf (I just read that mfd stands for Mib For Dummies ... all is said ...)
mib2c -I -c mib2c.mfd.conf my_mib_node
It generated a long .c file with almost all the oids like the one below.
Almost no lines were generated for the VideoInetAddr OID
//ABSTRACT OF SOURCE FILE GENERATED BY MIB2C
//...
long VideoFormat = 0; /* XXX: set default value */
// <<<=== NOTHING GENERATED HERE FOR VideoInetAddr OF TYPE INETADDRESS
// WHEREAS OTHER INTEGERS ARE NORMALLY PRESENT
long VideoInetPort = 0; /* XXX: set default value */
//...
void init_my_mib_node(void)
{
//...
const oid VideoFormat_oid[] = { 1,3,6,1,4,1,a,b,c,d,e };
static netsnmp_watcher_info VideoFormat_winfo;
// <<<=== NO OID GENERATED for VideoInetAddr OF TYPE INETADDRESS
// WHEREAS OTHER OIDs ARE NORMALLY GENERATED
static netsnmp_watcher_info VideoInetAddr_winfo; //We have the winfo after all
const oid VideoInetPort_oid[] = { 1,3,6,1,4,1,a,b,c,d,g };
static netsnmp_watcher_info VideoInetPort_winfo;
DEBUGMSGTL(("my_mib_node",
"Initializing VideoFormat scalar integer. Default value = %d\n",
VideoFormat));
reg = netsnmp_create_handler_registration(
"VideoFormat", NULL,
VideoFormat_oid, OID_LENGTH(VideoFormat_oid),
HANDLER_CAN_RWRITE);
netsnmp_init_watcher_info(&VideoFormat_winfo, &VideoFormat,
sizeof(long),ASN_INTEGER, WATCHER_FIXED_SIZE);
if (netsnmp_register_watched_scalar( reg, &VideoFormat_winfo ) < 0 ) {
snmp_log( LOG_ERR, "Failed to register watched VideoFormat" );
//...
}
This worked fine and needed 5 minutes (no code to write, just call the init() function), I was able to GET and SET all ... integers ...
Some oids are of Type InetAddress were not generated, neither were strings
Question
Is there a mib conf file able to generate code for every type
I tried the mib2c.old-api.conf which generates code also for the non-integer oids but I find it not as convenient. There is more boilerplate code to write.
Yes, mib2c could generate code for IP addresses. I cannot say that mfd does this, but, definitely, some mib2c.iterate.conf (for tables) does this.
The type of IP in SNMP is ASN_IPADDRESS represented by unint32_t in C.
Also,You need to make sure that in MIB-file for object, which represents IP, you have "SYNTAX IpAddress".
Have a look:
at the MIB file with IP object and implementation in C
Piece of answer but I am very far from comprehension and so side problems persist
Very pragmatically I managed to add by hand
//I put here ONLY what I added, see question above to complete code
#define STR_LENGTH_IPV4 sizeof("xxx.yyy.zzz.www")
char VideoInetAddr[STR_LENGTH_IPV4] = "192.168.2.3";
//...
const oid VideoInetAddr_oid[] = { 1,3,6,1,4,1,a,b,c,d,f };
reg = netsnmp_create_handler_registration(
"VideoInetAddr", NULL,
VideoInetAddr_oid, OID_LENGTH(VideoInetAddr_oid),
HANDLER_CAN_RWRITE);
netsnmp_init_watcher_info(&VideoInetAddr_winfo, &VideoInetAddr, sizeof(VideoInetAddr),
ASN_OCTET_STR, WATCHER_MAX_SIZE );
if (netsnmp_register_watched_scalar( reg, &VideoInetAddr_winfo ) < 0 ) {
snmp_log( LOG_ERR, "Failed to register watched VideoInetAddr" );
}
It still need to understand exactly the option like WATCHER_MAX_SIZE (is-it the good one ?)

Is there a way to get the evdev keycode from a string?

I'd like to read button mappings from a text file that contains data like this:
DPAD_LEFT = 105
DPAD_RIGHT = 106
DPAD_UP = 103
DPAD_DOWN = 108
The right part is actually the evdev keycode (as defined in <linux/input.h>).
This is quite hard to read, so I'd like to be able have files like this:
DPAD_LEFT = KEY_LEFT
DPAD_RIGHT = KEY_RIGHT
DPAD_UP = KEY_UP
DPAD_DOWN = KEY_DOWN
But I'm currently not able to convert them back:
char[256] keyname;
some_method_to_read(&keyname, "DPAD_LEFT");
//keyname now contains "KEY_LEFT"
How do I get the corresponding keycode (e.g. 105)? Is there a standard way to do this?
EDIT: The only way I can think of right now is by duplicating all the keycodes in my source and putting them in an array or map, like the evtest utility does. But there are a lot of keycodes and this seems quite a bit of overkill to me. Also, this might get out-of-sync with the keycodes defined in <input/linux.h> at some point.
std::map<string, int> keynames;
#define MAP_KEYCODE(keycode) keynames[#keycode] = keycode
MAP_KEYCODE(KEY_LEFT);
MAP_KEYCODE(KEY_RIGHT);
MAP_KEYCODE(KEY_UP);
MAP_KEYCODE(KEY_DOWN);
// [...]
Have your program read the name-to-code mapping from a configuration file(s), say /usr/share/yourprogram/keycodes and/or $HOME/.yourprogram/keycodes.
Document that anyone can regenerate that file from their /usr/include/linux/input.h -- and regenerate the initial file yourself -- using for example
awk '$2 ~ /^KEY_/ { code[$2] = $3 }
END {
for (name in code)
if (code[name] ~ /^KEY_/)
code[name] = code[code[name]];
for (name in code)
if (code[name] !~ /KEY_/)
printf "%-24s %s\n", name, code[name]
}' /usr/include/linux/input.h | sort
You might have to add KEY_CNT youself (it's value is one more than KEY_MAX), as the above script does not do math, only direct aliases.
To describing the name-to-code mappings, I'd use
struct keycode {
struct keycode *next;
unsigned int code;
unsigned int hash;
unsigned char namelen;
char name[];
};
where the hash is a simple hash, say djb2,
unsigned int djb2(const char *const str, const size_t len)
{
unsigned int result = 5831U;
size_t i;
for (i = 0; i < len; i++)
result = result * 33U ^ (unsigned int)str[i];
return result;
}
Of currently defined key codes, only KEY_CUT and KEY_F15 map to the same djb2 hash, 1857856141. (If you used 31U instead of 33U, the current set would have no collisions, but that's no proof against future collisions. Better have one collision already, so you can test it is handled correctly.)
The function that reads the configuration file could just return the codes by prepending new ones to a singly-linked list, perhaps
int read_keycodes(const char *const filename,
struct keycode **list);
If you prepend to the list, you should later on ignore redefinitions of the same name. This way, if you read the system-wide configuration first, then the user-specific one, the user-specific one can override the system-wide ones.
After all keycode mappings are read, you construct a hash table, something like
struct keytab {
unsigned int size; /* index = hash % size */
struct keycode **slot;
};
(When building the hash table, discard keycodes whose exact names are already in the keytab. This way later definitions override earlier ones.)
This way you only need to calculate the hash of the name you want to look up, then probe the linked list in your keytab structure. Compare hashes first, then lengths; if both match, finally do a strcmp(). This way the lookup will be very fast, and relatively simple to implement, too. With current key codes, you'll only do the slow strcmp() twice for KEY_F15 and KEY_CUT; for all others, a single strcmp() will suffice.
Questions?
I found a way to do this properly: By using libevdev's libevdev_event_code_from_name function.
unsigned int event_type = EV_KEY;
const char* name = "BTN_A";
int code = libevdev_event_code_from_name(event_type, name);
if(code < 0)
{
puts("There was an error!");
}

Static mapping of array index and array content in C

I am having a list of parameters. Each parameter is defined by an unique identifier (ParamID) and some other data (&ParamX, SomeOtherDataX) associated with this parameter. All the available parameters are organized in a table, which is implemented as a struct array (ParameterList[]) in C. Thus, on each row I can see all associated data for one parameter. The following code snippet should (hopefully) make this clearer:
// predefined IDs; not changeable!
#define PARAM_ID_A 10
#define PARAM_ID_B 12
#define PARAM_ID_C 14
// the basic structure of my parameter list
typedef struct ParameterList_t {
int ParamID,
*int ParamAddr,
*float SomeConnectedData
}
// definition of my list in ROM
const ParameterList_t ParameterList[] = {
{ PARAM_ID_A, &Param1, SomeOtherData1},
{ PARAM_ID_B, &Param2, SomeOtherData2},
{ PARAM_ID_C, &Param3, SomeOtherData3}
};
Now I want to create another list, which contains references on a subset of the parameters defined in the ParameterList[] table. This list should also be resided in ROM. I basically want to access all associated data for a subset of the parameters.
const *ParameterList_t ParameterSubListA[] = {
&ParameterList[2], // parameter: PARAM_ID_B
&ParameterList[3], // parameter: PARAM_ID_C
};
The problem here is that the code will be maintained by many people and the parameter list (ParameterList[]) might change frequently and parameters will be sorted into the table at the beginning or in the middle. This means the sub list (ParameterSubListA[]) must be updated to point to the desired parameters if their index (index = row in ParameterList[]) changes.
Question:
Basically my code needs a mapping from ParamID to the index of the ParameterList[] table, preferably by use of the preprocessor and only in ROM. I found different ways to implement this, which are all not satisfying:
Option 1:
Automatically generate a list in the RAM at startup, which maps the ParamID to the index in ParameterList[]. What I get is an array, that could be called CrossRefTable[]:
IndexOfParameterA_InParameterList = CrossRefTable[PARAM_ID_A];
My sublist would then look like this (cannot be constant anymore :/ ):
*ParameterList_t ParameterSubListA[] = {
&ParameterList[CrossRefTable[PARAM_ID_B]], // parameter: PARAM_ID_B
&ParameterList[CrossRefTable[PARAM_ID_C]], // parameter: PARAM_ID_C
};
I am short of RAM, so I would prefer a solution that only uses ROM.
Option 2:
Use a predefined macro __COUNTER__, which increments with each call and generate a macro in each row:
const ParameterList_t ParameterList[] = {
{ PARAM_ID_A, &Param1, SomeOtherData1},
#define PARAM_IDX_A __COUNTER__
{ PARAM_ID_B, &Param2, SomeOtherData2},
#define PARAM_IDX_B __COUNTER__
{ PARAM_ID_C, &Param3, SomeOtherData3}
#define PARAM_IDX_C __COUNTER__
};
My sublist would then look like this:
const *ParameterList_t ParameterSubListA[] = {
&ParameterList[PARAM_IDX_B], // parameter: PARAM_ID_B
&ParameterList[PARAM_IDX_C], // parameter: PARAM_ID_C
};
I would favorise this option, apparently it is not possible to use GCC.
Other Options:
I also figured there might be a possiblity in using X-MACROS, but I am not sure about that.
Boost is also not an option.
Hopefully my explanation is somehow clear...
Since the data is static, I'd say go on and initialize it statically.
Using external tools if the compiler is not capable enough.
parameter_list.c:
const struct ParameterList_t ParameterList[] = {
{ PARAM_ID_A, &Param1, SomeOtherData1},
{ PARAM_ID_C, &Param2, SomeOtherData2},
{ PARAM_ID_B, &Param3, SomeOtherData3}
};
#include "parameter_list_index.h"
const *ParameterList_t ParameterSubListA[] = {
&ParameterList[PARAM_ID_C_INDEX],
&ParameterList[PARAM_ID_B_INDEX],
};
parameter_list.px:
#!/usr/bin/perl -n
print "#define $1_INDEX ".($n++)."\n" if
/^const.*ParameterList\[\]/../^}/ and /^\s*{\s*([^,]+)/;
Makefile:
parameter_list.o: parameter_list.c parameter_list.h
parameter_list_index.h: parameter_list.c
./parameter_list.px $< > $#
This is just a general idea, your implementation may differ of course.
You may choose to generate ParameterList[] the same way or use [PARAM_ID_A_INDEX] = { ... } to make extra sure the indexes match.
Note the code above relies heavily on formatting, which may or may not be ok.
And in any case, some people may find tricks like this inappropriate.
Were I doing this, and I needed flexibility
Then I would have defined an enum that matches the table of data.
(no actual instance of the enum needed, just the definition
Then declared an array that contains some values from the enum.
The values in that array are the offsets into the data array

Dynamically create an object in C(using radiohead library)

I am trying to implement dynamic address assignment on my arduino using an NRF24l01+, but I can't get a RHReliableDatagram initialized globally after my unit receives it's assigned address
This is what I have(which for some reason doesnt work:
manager = new RHReliableDatagram(driver, ID);
Error:
sketch_oct02b.ino: In function 'void setup()':
sketch_oct02b:47: error: no match for 'operator=' in 'manager = (((RHReliableDatagram*)operator new(267u)), (<anonymous>->RHReliableDatagram::RHReliableDatagram(((RHGenericDriver&)(& driver.RH_NRF24::<anonymous>.RHNRFSPIDriver::<anonymous>)), ((uint8_t)ID)), <anonymous>))'
C:\Users\****\Documents\HAS\HAS-mc\libraries\RadioHead/RHReliableDatagram.h:66: note: candidates are: RHReliableDatagram& RHReliableDatagram::operator=(const RHReliableDatagram&)
This is code that works, but I cant change the address during runtime.
RHReliableDatagram manager(driver, DHT1_ADDRESS);
A minimal reproduction of my problem here:
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>
#include <DHT.h>
RH_NRF24 driver(8,10);
int ID = 255; //init ID, will be reassigned by server
RHReliableDatagram manager(driver,ID);//255 is the ID before init
void setup()
{
ID = 15;
manager = new RHReliableDatagram(driver, ID);//NOTE added this
//spi.setPins(13, 4, 3); //miso mosi sck
if (!manager.init()){
Serial.println("NRF failed to initialise");
digitalWrite(PIN_NRF_ERROR,HIGH);
} else {
Serial.println("NRF succesfully initialized");
}
}
void loop()
{
}
The documentation for the radio head library is here:
http://www.airspayce.com/mikem/arduino/RadioHead/classRHReliableDatagram.html
You need to assign the dynamic allocated object to the pointer of that object type, such as
type *p_var = new type(initializer)
In your code it should be remove
RHReliableDatagram manager(driver,ID);//255 is the ID before init
and change
manager = new RHReliableDatagram(driver, ID);//NOTE added this
to
RHReliableDatagram *manager = new RHReliableDatagram(driver, ID);//NOTE added this
Also you need to remember to use delete() to free the memory that the manager when it is no longer needed.
I am late but - there is a function to do that.
Use:
manager.setThisAddress(ID);
void RHDatagram::setThisAddress(uint8_t thisAddress)
{
_driver.setThisAddress(thisAddress);
// Use this address in the transmitted FROM header
setHeaderFrom(thisAddress);
_thisAddress = thisAddress;
}

Resources