예전에는 제품을 만들어 출시하면 끝이었지만 요즘에는 출시후에도 버그수정, 기능추가등의 이유로 펌웨어를 사용자에게 배포하는 경우가 굉장히 많습니다. 특히 MP3나 휴대폰은 그 정도가 더 심한데요..
펌웨어를 공개할 때 그냥 바이너리로 배포하게 되면 해커들에 의해 여러가지 정보가 누출될 우려가 있습니다. 특히 중요한 비밀 키 코드가 누출된다거나 하면 자칫 큰 문제가 생길 수 있습니다.
때문에 펌웨어를 암호화 해서 해킹이 불가능하도록 하는 것이 여러모로 안심이 되겠지요.
이럴 때 쓸 수 있는 간단하면서도 강력한 암호화 기법이 있는데 다름아닌 XOR 입니다.
아래 진리표는 전자/전산과 출신이라면 누구나 아실겁니다.
A B A XOR B
T T F
T F T
F T T
F F F
XOR을 암호화에 이용할 수 있는 이유는 XOR의 결과로부터 원래의 A,B를 유추해내는 것이불가능하다는 점에 착안하고 있습니다.
즉 A XOR B 가 True일때 이것만 가지고는 A가 True이고 B가 False 였는지 아니면 그 반대인지를 알 수 가 없습니다.
하지만 만일 A 또는 B중 하나를 알고 있다면 원래의 A 또는 B를 되돌릴 수 있습니다.
눈치 채셨겠지만 A 는 원본 Firmware, B는 key로 하면 XOR Encryption 기법을 사용하는 것입니다.
아래는 이러한 XOR 암호화 기법을 이용한 암호/복호화 루틴입니다.
예에서는 키의 크기를 128byte 로 하였는데 암호화 하고자 하는 데이터를 128byte 마다 반복하여 XOR 을 취하여 암호화 합니다. 복호화는 동일한 키를 이용하여 다시한번 XOR을 수행하면 됩니다.
#define KEY_SIZE 128
char key[KEY_SIZE]; // <--- 임의의 패턴을 가지는 키배열을 만드시고 유출되지 않도록 잘 관리해야합니다.
void code(char *buf, int len)
{
int i, j;
for ( i = 0, j = 0; i < len; i++ ) {
buf[i] = buf[i] ^ key[j];
j = ( ++j < KEY_SIZE ? j : 0);
}
}
main()
{
/*
src_fd = 펌웨어 바이너리
dst_fd = XOR 암호화된 펌웨어 바이너리
*/
...
/* process data blocks */
while ( len = read ( src_fd, buf, BLK_SIZE) ) {
/* en/decrypt block */
code(buf,len);
/* write XOR en/decrypted data */
write(dst_fd, buf, len);
}
...
}
이 방법을 이용하면 128byte (bit가 아닌 byte) 의 키로 강력하게 펌웨어를 암호화 할 수 있습니다.