📄 cave_test_new.c
字号:
void SSD_Update(void)
{
int i;
for (i = 0; i < 8; i++)
{
SSD_A[i] = SSD_A_NEW[i];
SSD_B[i] = SSD_B_NEW[i];
}
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* Auth_Signature has the same header as CAVE (see Exhibit 2-4) */
unsigned long Auth_Signature(const unsigned char RAND_CHALLENGE[4],
const unsigned char AUTH_DATA[3],
const unsigned char *SSD_AUTH,
const int SAVE_REGISTERS)
{
int i,offset_1,offset_2;
unsigned long AUTH_SIGNATURE;
for (i = 0; i < 4; i++)
{
LFSR[i] = RAND_CHALLENGE[i] ^ SSD_AUTH[i] ^ SSD_AUTH[i+4];
}
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
for (i = 0; i < 4; i++)
LFSR[i] = RAND_CHALLENGE[i];
}
/* put SSD_AUTH into r0-r7 */
for (i = 0; i < 8; i++)
Register[i] = SSD_AUTH[i];
Register[8] = AAV;
/* put AUTH_DATA into r9-r11 */
for (i = 9; i < 12; i++)
Register[i] = AUTH_DATA[i-9];
/* put ESN into r12-r15 */
for (i = 12; i < 16; i++)
Register[i] = ESN[i-12];
offset_1 = offset_2 = 128;
CAVE(8, &offset_1, &offset_2);
AUTH_SIGNATURE =
( ((unsigned long)(Register[0] ^ Register[13]) << 16) +
((unsigned long)(Register[1] ^ Register[14]) << 8) +
((unsigned long)(Register[2] ^ Register[15]) )) & 0x3ffff;
if (SAVE_REGISTERS)
{
/* save LFSR and offsets */
SAVED_OFFSET_1 = offset_1;
SAVED_OFFSET_2 = offset_2;
for (i = 0; i < 4; i++)
{
SAVED_LFSR[i] = LFSR[i];
SAVED_RAND[i] = RAND_CHALLENGE[i];
if (i < 3)
{
SAVED_DATA[i] = AUTH_DATA[i];
}
}
}
return(AUTH_SIGNATURE);
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* Key_VPM_Generation has the same header as CAVE (see Exhibit 2-4) */
static void roll_LFSR(void)
{
int i;
LFSR_A = Register[0];
LFSR_B = Register[1];
LFSR_C = Register[14];
LFSR_D = Register[15];
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
for (i = 0; i < 4; i++)
LFSR[i] = SAVED_RAND[i];
}
}
void Key_VPM_Generation(void)
{
int i,j,r_ptr,offset_1,offset_2,vpm_ptr;
/* iteration 1, first pass through CAVE */
for (i = 0; i < 4; i++)
LFSR[i] = SAVED_LFSR[i] ^ SSD_B[i] ^ SSD_B[i+4];
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
for (i = 0; i < 4; i++)
LFSR[i] = SAVED_RAND[i];
}
for (i = 0; i < 8; i++)
Register[i] = SSD_B[i];
Register[8] = AAV;
/* put SAVED_DATA into r9-r11 */
for (i = 9; i < 12; i++)
Register[i] = SAVED_DATA[i-9];
/* put ESN into r12-r15 */
for (i = 12; i < 16; i++)
Register[i] = ESN[i-12];
offset_1 = SAVED_OFFSET_1;
offset_2 = SAVED_OFFSET_2;
CAVE(8, &offset_1, &offset_2);
/* iteration 2, generation of first CMEA key parameters */
roll_LFSR();
CAVE(4, &offset_1, &offset_2);
for (i = 0; i < 4; i++)
cmeakey[i] = Register[i+4] ^ Register[i+8];
/* iteration 3, generation of second CMEA key parameters */
roll_LFSR();
CAVE(4, &offset_1, &offset_2);
for (i = 4; i < 8; i++)
cmeakey[i] = Register[i] ^ Register[i+4];
/* iterations 4-13, generation of VPM */
vpm_ptr = 0;
for (i = 0; i < 10; i++)
{
roll_LFSR();
CAVE(4, &offset_1, &offset_2);
for (r_ptr = 0; r_ptr < 6; r_ptr++)
{
VPM[vpm_ptr] = Register[r_ptr+2] ^ Register[r_ptr+8];
vpm_ptr++;
}
}
/* iteration 14, generation of last VPM bits */
roll_LFSR();
CAVE(4, &offset_1, &offset_2);
for (j = 0; j < 5; j++)
{
VPM[vpm_ptr] = Register[j+2] ^ Register[j+8];
vpm_ptr++;
}
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* ECMEA_Secret_Generation has the same header as ECMEA (see Exhibit 2-
30) */
static void roll_LFSR_2(void)
{
LFSR_A = Register[0];
LFSR_B = Register[1];
LFSR_C = Register[14];
LFSR_D = Register[15];
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
LFSR_A = 0x31;
LFSR_B = 0x41;
LFSR_C = 0x59;
LFSR_D = 0x26;
}
}
void ECMEA_Secret_Generation(void)
{
int i,j,offset_1,offset_2;
/* iteration 1, first pass through CAVE */
for (i = 0; i < 4; i++)
LFSR[i] = cmeakey[i+4];
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
LFSR_A = 0x31;
LFSR_B = 0x41;
LFSR_C = 0x59;
LFSR_D = 0x26;
}
for (i = 0; i < 8; i++)
Register[i] = cmeakey[i];
for (i = 8; i < 16; i++)
Register[i] = ~cmeakey[i-8];
offset_1 = 0x0;
offset_2 = 0x0;
CAVE(8, &offset_1, &offset_2);
/* Iterations 2 and 3, generation of ECMEA_KEY */
i = 0; j = 4;
while (i < 8)
{
/* see if new key material needs to be generated */
if( j == 4 )
{
j = 0;
roll_LFSR_2();
CAVE(4, &offset_1, &offset_2);
}
ecmea_key[i] = Register[j+4] ^ Register[j+8];
j++;
/* advance to next octet of ECMEA_KEY if not zero; otherwise
generate another value */
if (ecmea_key[i] != 0)
i++;
}
/* iteration 4, generation of ECMEA offset keys */
roll_LFSR_2();
CAVE(4, &offset_1, &offset_2);
for (i = 0; i < 4; i++)
offset_key[i] = Register[i+4] ^ Register[i+8];
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* Non_Financial_Seed_Key_Generation has the same header as ECMEA (see
Exhibit 2-30) */
void Non_Financial_Seed_Key_Generation(void)
{
int i,offset_1,offset_2;
/* iteration 1, first pass through CAVE */
for (i = 0; i < 4; i++)
LFSR[i] = cmeakey[i];
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
LFSR_A = 0x31;
LFSR_B = 0x41;
LFSR_C = 0x59;
LFSR_D = 0x26;
}
for (i = 0; i < 8; i++)
Register[i] = ~cmeakey[i];
for (i = 8; i < 16; i++)
Register[i] = cmeakey[i-8];
offset_1 = 0x0;
offset_2 = 0x0;
CAVE(8, &offset_1, &offset_2);
/* iteration 2, generation of seed_nf_key */
roll_LFSR_2(); /* defined in Exhibit 2-19 */
CAVE(4, &offset_1, &offset_2);
for (i = 0; i < 5; i++)
seed_nf_key[i] = Register[i+2] ^ Register[i+8];
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* Non_Financial_Secret_Generation has the same header as ECMEA (see
Exhibit 2-30) */
void Non_Financial_Secret_Generation(void)
{
int i,j,offset_1,offset_2;
/* iteration 1, first pass through CAVE */
for (i = 0; i < 4; i++)
LFSR[i] = seed_nf_key[i+1];
if ((LFSR_A | LFSR_B | LFSR_C | LFSR_D) == 0)
{
LFSR_A = 0x31;
LFSR_B = 0x41;
LFSR_C = 0x59;
LFSR_D = 0x26;
}
for (i = 0; i < 5; i++)
Register[i] = seed_nf_key[i];
for (i = 5; i < 8; i++)
Register[i] = 0;
for (i = 8; i < 13; i++)
Register[i] = ~seed_nf_key[i-8];
for (i = 13; i < 16; i++)
Register[i] = 0;
offset_1 = 0x0;
offset_2 = 0x0;
CAVE(8, &offset_1, &offset_2);
/* Iterations 2 and 3, generation of ECMEA_NF_KEY */
i = 0; j = 4;
while (i < 8)
{
/* see if new key material needs to be generated */
if( j == 4 )
{
j = 0;
roll_LFSR_2();
CAVE(4, &offset_1, &offset_2);
}
ecmea_nf_key[i] = Register[j+4] ^ Register[j+8];
j++;
/* advance to next octet of ECMEA_NF_KEY if not zero; otherwise
generate another value */
if (ecmea_nf_key[i] != 0)
i++;
}
/* iteration 4, generation of ECMEA offset_nf_key */
roll_LFSR_2(); /* defined in Exhibit 2-19 */
CAVE(4, &offset_1, &offset_2);
for (i = 0; i < 4; i++)
offset_nf_key[i] = Register[i+4] ^ Register[i+8];
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* tbox has the same header as CAVE (see Exhibit 2-4) */
static unsigned char tbox(const unsigned char z)
{
int k_index,i;
unsigned char result;
k_index = 0;
result = z;
for (i = 0; i < 4; i++)
{
result ^= cmeakey[k_index];
result += cmeakey[k_index+1];
result = z + CaveTable[result];
k_index += 2;
}
return(result);
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* CMEA has the same header as CAVE (see Exhibit 2-4) */
void CMEA(unsigned char *msg_buf, const int octet_count)
{
int msg_index,half;
unsigned char k,z;
/* first manipulation (inverse of third) */
z = 0;
for (msg_index = 0; msg_index < octet_count; msg_index++)
{
k = tbox((unsigned char)(z ^ (msg_index & 0xff)));
msg_buf[msg_index] += k;
z += msg_buf[msg_index];
}
/* second manipulation (self-inverse) */
half = octet_count/2;
for (msg_index = 0; msg_index < half; msg_index++)
{
msg_buf[msg_index] ^=
msg_buf[octet_count - 1 - msg_index] | 0x01;
}
/* third manipulation (inverse of first) */
z = 0;
for (msg_index = 0; msg_index < octet_count; msg_index++)
{
k = tbox((unsigned char)(z ^ (msg_index & 0xff)));
z += msg_buf[msg_index];
msg_buf[msg_index] -= k;
}
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* enhanced tbox has the same header as ECMEA (see Exhibit 2-30) */
unsigned char etbox(const unsigned char z,
const unsigned char *ecmea_key)
{
unsigned char t;
t = ibox[(z + ecmea_key[0]) & 0xff];
t = ibox[t ^ ecmea_key[1]];
t = ibox[(t + ecmea_key[2]) & 0xff];
t = ibox[t ^ ecmea_key[3]];
t = ibox[(t + ecmea_key[4]) & 0xff];
t = ibox[t ^ ecmea_key[5]];
t = ibox[(t + ecmea_key[6]) & 0xff];
t = ibox[t ^ ecmea_key[7]];
t = ibox[(t - ecmea_key[6]) & 0xff];
t = ibox[t ^ ecmea_key[5]];
t = ibox[(t - ecmea_key[4]) & 0xff];
t = ibox[t ^ ecmea_key[3]];
t = ibox[(t - ecmea_key[2]) & 0xff];
t = ibox[t ^ ecmea_key[1]];
t = (t - ecmea_key[0]) & 0xff;
return t;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* transform and inv_transform have the same header as ECMEA (see
Exhibit 2-30) */
void transform(unsigned char *msg_buf, const int octet_count,
unsigned char offseta, const unsigned char offsetb,
const unsigned char *key)
{
unsigned char k, z;
int msg_index;
for (msg_index = 0; msg_index < octet_count; msg_index++)
{
/* offseta rotation and involutary lookup of present octet */
if (msg_index > 0)
offseta = (offseta >> 1) | (offseta << 7);
msg_buf[msg_index] = offsetb ^
etbox((unsigned char)(msg_buf[msg_index] ^ offseta), key);
/* bit-trade between present octet and the one below */
if (msg_index > 0)
{
k = msg_buf[msg_index - 1] ^ msg_buf[msg_index];
k &= etbox((unsigned char)(k ^ offseta), key);
msg_buf[msg_index - 1] ^= k;
msg_buf[msg_index] ^= k;
}
/* random octet permutation */
/* exchange previous octet with a random one below it */
if (msg_index > 1)
{
k = etbox((unsigned char)(msg_buf[msg_index] ^ offseta),
key);
k = ((msg_index) * k) >> 8;
z = msg_buf[k];
msg_buf[k] = msg_buf[msg_index - 1];
msg_buf[msg_index - 1] = z;
}
}
/* final octet permutation */
/* exchange last octet with a random one below it */
k = etbox((unsigned char)(0x37 ^ offseta), key);
k = ((msg_index) * k) >> 8;
z = msg_buf[k];
msg_buf[k] = msg_buf[msg_index - 1];
msg_buf[msg_index - 1] = z;
/* final involution and XORing */
k = etbox(msg_buf[0], key);
for (msg_index = 1; msg_index < octet_count; msg_index++)
{
msg_buf[msg_index] = etbox(msg_buf[msg_index], key);
k ^= msg_buf[msg_index];
}
msg_buf[0] = k;
for (msg_index = 1; msg_index < octet_count; msg_index++)
msg_buf[msg_index] ^= k ;
}
/* Inverse Transformation */
void inv_transform(unsigned char *msg_buf, const int octet_count,
unsigned char offseta, const unsigned char offsetb,
const unsigned char *key)
{
unsigned char k, z;
int msg_index;
/* initial offseta rotation */
k = (octet_count - 1) & 0x07;
offseta = (offseta >> k) | (offseta << (8 - k));
/* inverse of final involution and XORing */
for (msg_index = 1; msg_index < octet_count; msg_index++)
msg_buf[msg_index] ^= msg_buf[0];
for (msg_index = 1; msg_index < octet_count; msg_index++)
{
msg_buf[0] ^= msg_buf[msg_index];
msg_buf[msg_index] = etbox(msg_buf[msg_index], key);
}
msg_buf[0] = etbox(msg_buf[0], key);
/* initial octet permutation */
/* exchange last octet with a random one below it */
k = etbox((unsigned char)(0x37 ^ offseta), key);
k = ((octet_count) * k) >> 8;
z = msg_buf[k];
msg_buf[k] = msg_buf[octet_count - 1];
msg_buf[octet_count - 1] = z;
for (msg_index = octet_count - 1; msg_index >= 0; msg_index--)
{
/* random octet permutation */
/* exchange previous octet with a random one below it */
if (msg_index > 1)
{
k = etbox((unsigned char)(msg_buf[msg_index] ^ offseta),
key);
k = ((msg_index) * k) >> 8;
z = msg_buf[k];
msg_buf[k] = msg_buf[msg_index - 1];
msg_buf[msg_index - 1] = z;
}
/* bit-trade between present octet and the one below */
if (msg_index > 0)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -