#include <stdio.h>
#include "dukpt.h"
//#include "dukptAPI.h"
#include "des.h"
enum{
FKEY_LEFT = 0,
FKEY_RIGHT
};
struct dukpt_fkey{
unsigned char key[2][8];
unsigned char lrc;
};
struct dukpt_info{
unsigned char reserve[32];
unsigned char initial_sn[8];
unsigned char counter[4];
unsigned char initkey[2][8];
unsigned int shift;
char flag;
unsigned char crypto1[8];
unsigned char crypto2[8];
unsigned char key[2][8];
unsigned char *curkey;
struct dukpt_fkey fk[21];
unsigned char keysn[10];
#ifdef DUKPT_MSG_AUTHENTICATION
unsigned char mac[2][8];
#endif
};
static struct dukpt_info d_info;
#define DEBUG_DUKPT 1
#define DEBUG_DUKPT_TEST_DATA 1
#define GET_UINT24(n,b,i) \
{ \
(n) = ( (unsigned int) (b)[(i) ] << 16 ) \
| ( (unsigned int) (b)[(i) + 1] << 8 ) \
| ( (unsigned int) (b)[(i) + 2] ); \
}
#define PUT_UINT24(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) ); \
}
int Triple_DEA_Encrypt(void)
{
/*DES_key pKey;
DESInit(&pKey, d_info.key[FKEY_LEFT]);
DESEncryptUpdate(&pKey, d_info.crypto1, d_info.crypto1);
DESInit(&pKey, d_info.key[FKEY_RIGHT]);
DESDecryptUpdate(&pKey, d_info.crypto1, d_info.crypto1);
DESInit(&pKey, d_info.key[FKEY_LEFT]);
DESEncryptUpdate(&pKey, d_info.crypto1, d_info.crypto1);*/
EncryptTDES(d_info.key, d_info.crypto1, d_info.crypto1);
return 0;
}
int SetBit(void)
{
int i;
unsigned int cnt;
#ifdef DEBUG_DUKPT
printf("In SetBit -----------------------------\n");
#endif
GET_UINT24(cnt, d_info.counter, 0);
for(i=0; i<21; i++)
{
if ( ((cnt >> i) & 0x01) == 1)
break;
}
if (i==21)
return -1;
d_info.shift = 0;
d_info.shift = 1<<i;
#ifdef DEBUG_DUKPT
printf(" set bit shift = %d, %x\n", d_info.shift, d_info.shift);
#endif
return 0;
}
int Non_reversible(void)
{
int i,j;
unsigned char out[8];
//DES_key pKey;
/*step 1*/
for(i=0; i<8; i++)
d_info.crypto2[i] = d_info.crypto1[i] ^ d_info.key[FKEY_RIGHT][i];
/*step 2*/
//DESInit(&pKey, d_info.key[FKEY_LEFT]);
//DESEncryptUpdate(&pKey, d_info.crypto2, d_info.crypto2);
DES(d_info.key[FKEY_LEFT], d_info.crypto2, d_info.crypto2);
/*step 3*/
for(i=0; i<8; i++)
d_info.crypto2[i] ^= d_info.key[FKEY_RIGHT][i];
/*step 4*/
for(i=0; i<4; i++){
d_info.key[FKEY_LEFT][i] ^= 0xc0;
d_info.key[FKEY_LEFT][i+4] ^= 0x0;
d_info.key[FKEY_RIGHT][i] ^= 0xc0;
d_info.key[FKEY_RIGHT][i+4] ^= 0x0;
}
/*step 5*/
for(i=0; i<8; i++)
d_info.crypto1[i] ^= d_info.key[FKEY_RIGHT][i];
/*step 6*/
//DESInit(&pKey, d_info.key[FKEY_LEFT]);
//DESEncryptUpdate(&pKey, d_info.crypto1, d_info.crypto1);
DES(d_info.key[FKEY_LEFT], d_info.crypto1, d_info.crypto1);
/*step 7*/
for(i=0; i<8; i++)
d_info.crypto1[i] ^= d_info.key[FKEY_RIGHT][i];
return 0;
}
int ShiftSingleOneLoc(void)
{
int i;
for(i=0; i<21; i++)
{
if ( (((d_info.shift>>i) & 0x01) == 1) )
return i;
}
return -1;
}
void LoadPara(void)
{
#ifndef DEBUG_DUKPT_TEST_DATA
struct dukpt_info *info;
info = (struct dukpt_info *)DUKPT_KEY_ADDR;
memcpy((char *)&d_info, (char *)info, sizeof(d_info));
#else
/*
d_info.initkey[FKEY_LEFT][0] = 0x01 ;d_info.initkey[FKEY_LEFT][1] = 0x23 ;
d_info.initkey[FKEY_LEFT][2] = 0x45 ;d_info.initkey[FKEY_LEFT][3] = 0x67 ;
d_info.initkey[FKEY_LEFT][4] = 0x89 ;d_info.initkey[FKEY_LEFT][5] = 0xab ;
d_info.initkey[FKEY_LEFT][6] = 0xcd ;d_info.initkey[FKEY_LEFT][7] = 0xef ;
d_info.initkey[FKEY_RIGHT][0] = 0xfe ;d_info.initkey[FKEY_RIGHT][1] = 0xdc ;
d_info.initkey[FKEY_RIGHT][2] = 0xba ;d_info.initkey[FKEY_RIGHT][3] = 0x98 ;
d_info.initkey[FKEY_RIGHT][4] = 0x76 ;d_info.initkey[FKEY_RIGHT][5] = 0x54 ;
d_info.initkey[FKEY_RIGHT][6] = 0x32 ;d_info.initkey[FKEY_RIGHT][7] = 0x10 ;
*/
d_info.initkey[FKEY_LEFT][0] = 0x6a ;d_info.initkey[FKEY_LEFT][1] = 0xc2 ;
d_info.initkey[FKEY_LEFT][2] = 0x92 ;d_info.initkey[FKEY_LEFT][3] = 0xfa ;
d_info.initkey[FKEY_LEFT][4] = 0xa1 ;d_info.initkey[FKEY_LEFT][5] = 0x31 ;
d_info.initkey[FKEY_LEFT][6] = 0x5b ;d_info.initkey[FKEY_LEFT][7] = 0x4d ;
d_info.initkey[FKEY_RIGHT][0] = 0x85 ;d_info.initkey[FKEY_RIGHT][1] = 0x8a ;
d_info.initkey[FKEY_RIGHT][2] = 0xb3 ;d_info.initkey[FKEY_RIGHT][3] = 0xa3 ;
d_info.initkey[FKEY_RIGHT][4] = 0xd7 ;d_info.initkey[FKEY_RIGHT][5] = 0xd5 ;
d_info.initkey[FKEY_RIGHT][6] = 0x93 ;d_info.initkey[FKEY_RIGHT][7] = 0x3a ;
d_info.initial_sn[0] = 0xff ;d_info.initial_sn[1] = 0xff ;d_info.initial_sn[2] = 0x98 ;d_info.initial_sn[3] = 0x76 ;
d_info.initial_sn[4] = 0x54 ;d_info.initial_sn[5] = 0x32 ;d_info.initial_sn[6] = 0x10 ;d_info.initial_sn[7] = 0xe0 ;//59-bit
d_info.shift = 0x100010;
d_info.counter[0] = 0;
d_info.counter[1] = 0;
d_info.counter[2] = 0;
d_info.counter[3] = 0;
d_info.flag = 0;
#endif
return;
}
int LoadInitialKeyCmd(void)
{
LoadPara();
GetCurrentKey();
GetKeySN();
return 0;
}
/**
*
*/
int NewKey(void)
{
int i,j;
int rc;
unsigned int cnt;
#ifdef DEBUG_DUKPT
printf("In newkey -----------------------------\n");
#endif
GET_UINT24(cnt, d_info.counter, 0);
j = 0;
for(i=0; i<21; i++)
{
if ( ((cnt>>i & 0x01) == 1) )
j++;
}
#ifdef DEBUG_DUKPT
printf("newkey: step 1, number of 1 = %d\n", j);
#endif
if (j<10)
{
rc = NewKey1();
if (rc == 0)
NewKey3();
NewKey4();
rc = NewKey2();
if (rc<0)
return -1;
}
else
{
#ifdef DEBUG_DUKPT
printf("newkey : step 2 \n");
#endif
//erase at the curkey
for(i=0; i<sizeof(d_info.fk); i++)
{
if ((unsigned char *)&d_info.fk[i] == d_info.curkey)
{
d_info.fk[i].lrc++;
break;
}
}
GET_UINT24(cnt, d_info.counter, 0);
cnt += d_info.shift;
PUT_UINT24(cnt, d_info.counter, 0);
#ifdef DEBUG_DUKPT
printf("newkey : step 3 , count = %d, %x\n", cnt, cnt);
#endif
GetKeySN();
rc = NewKey2();
if (rc<0)
return -1;
}
return 0;
}
/**
*
*/
int NewKey1(void)
{
#ifdef DEBUG_DUKPT
printf("In newkey-1 -----------------------------\n");
#endif
d_info.shift >>= 1;
#ifdef DEBUG_DUKPT
printf("newkey-1 : step 1, shift = %d, 0x%x\n", d_info.shift, d_info.shift);
#endif
if (d_info.shift == 0)
return -4;
return 0;
}
/**
*
*/
int NewKey2(void)
{
unsigned int cnt;
#ifdef DEBUG_DUKPT
printf("In newkey-2 -----------------------------\n");
#endif
GET_UINT24(cnt, d_info.counter, 0);
#ifdef DEBUG_DUKPT
printf("newkey-2 , count = %d, 0x%x\n",cnt, cnt);
#endif
if (cnt > 1000000)
return -1;
return 0;
}
/**
*
*/
int NewKey3(void)
{
int i;
int j;
int place;
int rc;
unsigned char sh[3];
struct dukpt_fkey *d_fk;
#ifdef DEBUG_DUKPT
printf("In newkey-3 -----------------------------\n");
#endif
while(1)
{
PUT_UINT24(d_info.shift, sh, 0);
#ifdef DEBUG_DUKPT
printf(" shift = %02x %02x %02x \n", sh[0], sh[1], sh[2]);
#endif
//for(i=7; i<10; i++)
//d_info.crypto[i-2] = d_info.keysn[i] |sh[i-7];
for(i=7; i<10; i++)
sh[i-7] |= d_info.keysn[i];
for(i=7; i<10; i++)
d_info.crypto1[i-2] = sh[i-7];
for(i=6; i>=2; i--)
d_info.crypto1[i-2] = d_info.keysn[i];
#ifdef DEBUG_DUKPT
printf("newkey-3 : step 1, crypto1 = ");
for(i=0; i<8; i++)
printf("%02x ", d_info.crypto1[i]);
printf("\n");
#endif
d_fk = (struct dukpt_fkey *)d_info.curkey;
for(j=0; j<2; j