问题
I've defined an AES-128 key as a build symbol inside my IDE, so that it calls GCC like this:
arm-none-eabi-gcc -D"AES_KEY=3B7116E69E222295163FF1CAA1681FAC" ...
(which is equivalent to #define AES_KEY 3B7116E69E222295163FF1CAA1681FAC
)
The advantage is that the same symbol can also be passed automatically as a parameter to a post-build CLI script that encrypts the compiled code with this key (e.g. for a secure firmware update)...
But how to store this key as a byte array in my code? I would like to define a pre-processor macro which does the conversion:
uint8_t aes_key[] = { SPLIT_MACRO(AES_KEY) };
to
uint8_t aes_key[] = {0x3B, 0x71, 0x16, 0xE6, 0x9E, 0x22, 0x22, 0x95, ...};
In other words, could the GCC pre-processor split the key string in 2-char blocks and add ", 0x
" between them?
回答1:
A bit clumsy, but if you know the length of your key in advance you could approach it as follows:
- define a macro
HEXTONIBBLE
that translates a hex digit into a number - define a macro
HEXTOBYTE
that usesHEXTONIBBLE
to get a byte from a hex - initialize your array with
HEXTOBYTE
parameterized correctrly
If your KEY
is not in form of a string, i.e. enclosed in double quotes, then use the stringify-operator #
(with a trick using a variadic macro in order to expand a macro when used as parameter or another one):
// 01234567890123456789012345678901
#define K 3B7116E69E222295163FF1CAA1681FAC
#define STRINGIFY_HELPER(A) #A
#define STRINGIFY(...) STRINGIFY_HELPER(__VA_ARGS__)
#define KEY STRINGIFY(K)
#define HEXTONIBBLE(c) (*(c) >= 'A' ? (*(c) - 'A')+10 : (*(c)-'0'))
#define HEXTOBYTE(c) (HEXTONIBBLE(c)*16 + HEXTONIBBLE(c+1))
uint8_t aes_key[] = {
HEXTOBYTE(KEY+0),
HEXTOBYTE(KEY+2),
HEXTOBYTE(KEY+4),
HEXTOBYTE(KEY+6),
HEXTOBYTE(KEY+8),
HEXTOBYTE(KEY+10),
HEXTOBYTE(KEY+12),
HEXTOBYTE(KEY+14),
HEXTOBYTE(KEY+16),
HEXTOBYTE(KEY+18),
HEXTOBYTE(KEY+20),
HEXTOBYTE(KEY+22),
HEXTOBYTE(KEY+24),
HEXTOBYTE(KEY+26),
HEXTOBYTE(KEY+28),
HEXTOBYTE(KEY+30)
};
int main() {
for (int i=0; i<sizeof(aes_key); i++) {
printf("%02X ", aes_key[i]);
}
return 0;
}
Output:
3B 71 16 E6 9E 22 22 95 16 3F F1 CA A1 68 1F AC
回答2:
This does not answer the original question but if the key can be written in this format instead:
#define AES_KEY 3B,71,16,E6,9E,22,22,95,16,3F,F1,CA,A1,68,1F,AC
The following macro will work, even under GCC:
#define BA(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) {0x##a,0x##b,0x##c,0x##d,\
0x##e,0x##f,0x##g,0x##h,0x##i,0x##j,0x##k,0x##l,0x##m,0x##n,0x##o,0x##p}
#define TO_BYTEARRAY(...) BA(__VA_ARGS__)
uint8_t aes_key[] = TO_BYTEARRAY(AES_KEY);
See Concatenation, Argument Prescan and Variadic Macros
来源:https://stackoverflow.com/questions/45848866/pre-processor-macro-to-convert-an-hex-string-to-a-byte-array