-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloading.c
242 lines (187 loc) · 5.78 KB
/
loading.c
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctosapi.h>
#include "define.h"
#include <openssl/des.h>
USHORT getNewLoadingKey (OUT DES_cblock *stNewLK,OUT DES_cblock *stNewDK,OUT DES_cblock *stNewPK)
{
//用給定的seeding key 初始化
DES_cblock stSLK ;
DES_cblock stSDK ;
DES_cblock stSPK ;
//解密資料 PID
const_DES_cblock stCleartext;
// cblock 轉成 schedule 後拿去加解密
DES_key_schedule stSchedule_LK, stSchedule_DK, stSchedule_PK;
//初始化 key值
memcpy(stSLK, d_LOADING_KEY_LK, 8);
memcpy(stSDK, d_LOADING_KEY_DK, 8);
memcpy(stSPK, d_LOADING_KEY_PK, 8);
memcpy(stCleartext, d_PID, 8);
//cblock 轉換成schedule
DES_set_key_unchecked(&stSLK, &stSchedule_LK);
DES_set_key_unchecked(&stSDK, &stSchedule_DK);
DES_set_key_unchecked(&stSPK, &stSchedule_PK);
//解密 並out 三把key
DES_ecb_encrypt(&stCleartext, stNewLK, &stSchedule_LK, DES_DECRYPT);
DES_ecb_encrypt(&stCleartext, stNewDK, &stSchedule_DK, DES_DECRYPT);
DES_ecb_encrypt(&stCleartext, stNewPK, &stSchedule_PK, DES_DECRYPT);
return d_OK;
}
USHORT loadingLTAC(IN BYTE * baLSN, IN BYTE * baLRn ,IN BYTE *baLV,OUT BYTE *baTAC)
{
//--*Local Variable*--//
//存放 3des cbc 時的in 與out
BYTE baCleantext[24 + 1];
BYTE baCiphertext[24 + 1];
//存初始向量
DES_cblock stIvec;
//存新算出來的key 3把
KeyStructure stNewKey;
//BYTE babuff[8];
//組合三組資料成一組
memset(baCleantext, 0x00, sizeof(baCleantext));
memcpy(baCleantext, baLSN, 8);
memcpy((baCleantext + 8), baLV, 8);
memcpy((baCleantext + 16), baLRn, 8);
//此時baCleantext已建置成功
//初始化stIvec
memcpy(stIvec, d_ICV, 8);
//初始化 stNewKey
memset(&stNewKey, 0x00, sizeof(KeyStructure));
//經過des解密後取得新的 Loading Key
getNewLoadingKey(&stNewKey.stLK, &stNewKey.stDK, &stNewKey.stPK);
//這邊輸出 stNewKey.stLK stNewKey.stDK stNewKey.stPK
//即可看到算出的 LK DK PK
//新取得的new key 轉成schedule
DES_set_key_unchecked(&stNewKey.stLK, &stNewKey.stSchedule_LK);
DES_set_key_unchecked(&stNewKey.stDK, &stNewKey.stSchedule_DK);
DES_set_key_unchecked(&stNewKey.stPK, &stNewKey.stSchedule_PK);
//分段做加解密
//根據陣列長度 ,每八byte做一次加密
int w;
//memset(baCiphertext, 0x00, sizeof(baCiphertext));
for ( w = 0; w < sizeof(baCleantext); w+= 8)
{
//此function 參數 (in 明文, out 結果 ,in 欲加密長度,in key1, in key 2 ,in key 3 ,in [DES_ENCRYPT or DES_DNCRYPT] )
DES_ede3_cbc_encrypt(baCleantext + w,
baCiphertext + w,
8,
&stNewKey.stSchedule_LK, &stNewKey.stSchedule_DK, &stNewKey.stSchedule_PK,
&stIvec,
DES_ENCRYPT);
}
//將結果放入baTAC
int i;
for (i = 0; i < 8; i++)
baTAC [i] = baCiphertext[i + 16];
//最終baTAC建置完成
//這邊printf 可以看到完整baTAC
return d_OK;
}
USHORT LoadingCommand(IN BYTE *baLTAC,IN BYTE *baLV , OUT BYTE *baRecvBuffer,OUT USHORT *usRecvLength)
{
USHORT usReturn;
BYTE baLoadingCommand[d_LOADING_COMMAND_LENGTH];
BYTE baRec[d_LOADING_REC_LENGTH];
USHORT usTotalCommand_Length = 22;
USHORT usRLEN;
memset(baLoadingCommand, 0x00, sizeof(baLoadingCommand));
memcpy(baLoadingCommand, d_LOADING_COMMAND, 5);
memcpy((baLoadingCommand + 5), baLV, 8);
memcpy((baLoadingCommand + 13), baLTAC, 8);
memcpy((baLoadingCommand + 21), d_LOADING_LE, 1);
//baLoadingCommand = 加值指令
//這邊指令已經建置完成
CTOS_LCDTClearDisplay();
memset(baRec, 0x00, sizeof(baRec));
usReturn = CTOS_SCSendAPDU(d_SC_USER, baLoadingCommand, usTotalCommand_Length,baRec, &usRLEN);
if (usReturn != d_OK)
{
return d_SENT_APDU_FAIL;
}
memcpy(baRecvBuffer, baRec, sizeof(baRec));
//*usRecvLength=usRLEN;
return d_OK;
}
USHORT CheckAndLoadingData(IN LONG lRN_LA,IN BYTE *baInputLV,IN int iInputLen,OUT BYTE *baLV,IN BYTE *baLSn)
{
//輸入加值金額錯誤
BYTE baDVBuff[8+1];
BYTE baLSnbuff[8 + 1];
int w;
int index=0;
int iZeroTest=0;
LONG lInput=0;
//stRN.lRN_Input = 0;
for(w=0;w<iInputLen;w++)
{
if(lInput == 0)
{
lInput = baInputLV[w]-48;
}else
{
lInput = lInput*10 ;
lInput += baInputLV[w]-48;
}
}
if(lInput + lRN_LA>d_MAX_LV_DV_VALUE)
{
return d_LOADING_VAULE_OVERFLOW;
}
//建置LV array
memset(baDVBuff, 0x30, 8);
for(w=iInputLen;w>0;w--)
{
baDVBuff[8-w]=baInputLV[index];
index++;
}
for(w=0;w<8;w++)
{
if(baDVBuff[w]=='\x30')
{
iZeroTest++;
}
if(iZeroTest==8 )
{
return d_LOADING_VAULE_INVALID;
}
}
//OUT baLV
memcpy(baLV, baDVBuff, 8);
//
int i;
memset(baLSnbuff, 0x00, 8);
baLSnbuff[8]='\0';
for ( i = 0; i < d_KEY_LENGTH; i++)
baLSnbuff[i] = baLSn[i] - 48;
for (i = d_KEY_LENGTH - 1; i >=0; i--)
{
//從陣列最後面加一
//如果不是則往前
if (baLSnbuff[i] != '\x09')
{
baLSnbuff[i] += '\x01';
break;
}
else
{
baLSnbuff[i] = '\x00';
}
if (i == 0 && baLSnbuff[i]=='\x00')
{
//已經超越加值次數上限
return d_LOADING_COUNT_EXCEED;
}
}
//轉回ascii
for ( i= 0; i < d_KEY_LENGTH; i++)
baLSnbuff[i] += 48;
//重新放入baLSn
//此為+1後的LSN
for (i = 0; i < 8; i++)
baLSn[i] = baLSnbuff[i];
return d_OK;
}