forked from ximinchao/ZUC
/
EIA3.cpp
127 lines (104 loc) · 1.92 KB
/
EIA3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "ZUC.h"
#include "EIA3.h"
#include <string.h>
/*Length range of input message*/
u32 gMsgLen;
/*Key Stream*/
#define KEY_STREAM_COUNT 3
u32 gKeyStream[KEY_STREAM_COUNT] = {0};
/*MAC*/
u32 gMAC = 0;
/*Get i-th bit in bit stream DATA*/
u32 GET_BIT(u8 *DATA, u32 i)
{
return (DATA[i/8] & ((0x80)>>(i%8))) ? 1 : 0;
}
/*Get i-th WORD(4 bytes) in bit stream DATA*/
u32 GET_WORD(u32 *DATA, u32 i)
{
if (i%32 == 0)
{
return DATA[i/32];
}
else
{
return ( (DATA[i/32] << (i%32)) | (DATA[i/32+1] >> (32-i%32)) );
}
}
u32 GET_NEXT_KEYSTREAM()
{
u32 i = 0;
if ((gMsgLen % 32) == 0)
{
for (i=0; i<KEY_STREAM_COUNT-1; i++)
{
gKeyStream[i] = gKeyStream[i+1];
}
GenerateKeyStream(&gKeyStream[i], 1);
}
return GET_WORD(gKeyStream, (gMsgLen%32));
}
u32 GET_FINAL_KEYSTREAM()
{
if ((gMsgLen%32) == 0)
{
return gKeyStream[1];
}
else
{
return gKeyStream[2];
}
}
/*Length of COUNT is 4*/
void EIA3_Init(u8 *IK, u8 *COUNT, u8 BEARER, u8 DIRECTION)
{
u8 IV[16] = {0};
u32 i = 0;
IV[0] = COUNT[0];
IV[1] = COUNT[1];
IV[2] = COUNT[2];
IV[3] = COUNT[3];
IV[4] = BEARER << 3;
IV[5] = IV[6] = IV[7] = 0;
IV[8] = IV[0] ^ ((DIRECTION & 1) << 7);
IV[9] = IV[1];
IV[10] = IV[2];
IV[11] = IV[3];
IV[12] = IV[4];
IV[13] = IV[5];
IV[14] = IV[6] ^ ((DIRECTION & 1) << 7);
IV[15] = IV[7];
Initialization(IK, IV);
/*Skip the first 4 bytes, because GET_NEXT_KEYSTREAM will do this for us at the beginning*/
for (i=1; i<KEY_STREAM_COUNT; i++)
{
GenerateKeyStream(&gKeyStream[i], 1);
}
gMsgLen = 0;
gMAC = 0;
}
/*Length of MAC is 4*/
void EIA3_Update(u8 *M, u32 LENGTH)
{
u32 i = 0;
u32 MACTemp = 0;
for (i=0; i<LENGTH; i++)
{
MACTemp = GET_NEXT_KEYSTREAM();
if (GET_BIT(M, i))
{
gMAC = gMAC ^ MACTemp;
}
gMsgLen++;
}
}
u32 EIA3_Final()
{
u32 i = 0;
u32 MACTemp = 0;
MACTemp = GET_NEXT_KEYSTREAM();
gMAC = gMAC ^ MACTemp;
MACTemp = GET_FINAL_KEYSTREAM();
gMAC = gMAC ^ MACTemp;
return gMAC;
}