· 

KeeLoqを題材にLinux共有ライブラリ

KeeLoqを題材にして、WSL内でLinuxの共有ライブラリ(WindowsでいうところのDLL)を作って、Pythonから呼び出してみます。まったく需要がなさそうなこの題材。まぁメモですから!

 

keeloq.cはCで実装したものそのまんまです。mainも消さずにほったらかし。

libkeeloq.mapはエクスポートする関数の指定です。DLLでいうところのdefファイル的なやつ。

Makefileは相変わらず稚拙な感じ。リンカオプションの"--version-script,libkeeloq.map"がキモです。

keeloq.c

#include <stdio.h>
#include <stdint.h>

uint32_t keeloq_enc(uint32_t pr,uint64_t kr){
    uint32_t nlf_table=0x3a5c742e;
    uint32_t nlf_arg;
    uint32_t nlf;
    uint32_t newz;
    uint32_t i;
    for(i=0;i<528;i++){
        nlf_arg=((pr&0x80000000)>>(31-4))
               |((pr&0x04000000)>>(26-3))
               |((pr&0x00100000)>>(20-2))
               |((pr&0x00000200)>>(9-1))
               |((pr&0x00000002)>>(1-0));
        nlf=((nlf_table>>nlf_arg)&0x00000001);
        newz=nlf^((pr&0x00010000)>>16)^(pr&0x00000001)^(uint32_t)(kr&0x0000000000000001);
        pr=(newz<<31)|(pr>>1);
        kr=((kr&0x0000000000000001)<<63)|(kr>>1);
    }
    return pr;
}
uint32_t keeloq_dec(uint32_t cr,uint64_t kr){
    uint32_t nlf_table=0x3a5c742e;
    uint32_t nlf_arg;
    uint32_t nlf;
    uint32_t newz;
    uint32_t i;
    for(i=0;i<528;i++){
        nlf_arg=((cr&0x40000000)>>(30-4))
               |((cr&0x02000000)>>(25-3))
               |((cr&0x00080000)>>(19-2))
               |((cr&0x00000100)>>(8-1))
               |((cr&0x00000001)>>(0-0));
        nlf=((nlf_table>>nlf_arg)&0x00000001);
        newz=nlf^((cr&0x00008000)>>15)^((cr&0x80000000)>>31)^(uint32_t)((kr&0x0000000000008000)>>15);
        cr=(cr<<1)|(newz);
        kr=((kr&0x8000000000000000)>>63)|(kr<<1);
    }
    return cr;
}
int main(int argc,char** argv){
    uint32_t pr=0xf741e2db;
    uint64_t kr=0x5cec6701b79fd949;
    uint32_t cr;
    int i;
    cr=keeloq_enc(pr,kr);
    printf("%08X\n",cr);
    pr=keeloq_dec(cr,kr);
    printf("%08X\n",pr);
    return 0;
}

libkeeloq.map

{
  global:
    keeloq_enc;
    keeloq_dec;
  local: *;
};

Makefile

CC            = gcc
CFLAGS        = -fPIC -O4 -Wall -I/usr/local/include
LDFLAGS+=-Wl,--version-script,libkeeloq.map

libkeeloq.so: keeloq.o
        $(CC) keeloq.o $(LDFLAGS) -o libkeeloq.so

keeloq.o: keeloq.c
        $(CC) $(CFLAGS) keeloq.c -c -o keeloq.o

clean:
        rm keeloq.o libkeeloq.so

make

ってすると、

libkeeloq.so

ができます。

で、これをPythonから使ってみる。

keeloq.py

import ctypes

dll = ctypes.cdll.LoadLibrary("./libkeeloq.so")

pr=ctypes.c_uint32(0xf741e2db)
kr=ctypes.c_uint64(0x5cec6701b79fd949)
ret=ctypes.c_uint32(0x00000000)
ret.value=dll.keeloq_enc(pr,kr)
print(hex(ret.value))

うまくいきましたー。