1
2 #include <stdlib.h>
3 #include <string.h>
4 #include "MsCommon.h"
5
6 #include "nsk2hdi_bl.h"
7 #include "nsk_dbg.h"
8 #include "drvCIPHER.h"
9 #include "nsk2hdi_header.h"
10
11 /*****************************************************************************\
12 \Definitions
13 \*****************************************************************************/
14 #define SHA1_SIZE (20)
15 #define SHA256_SIZE (32)
16 #define MD5_SIZE (16)
17
18 #define MaximumHashSize SHA256_SIZE
19
20
21
22 /*****************************************************************************\
23 \ typedef struct
24 \*****************************************************************************/
25
26
27 typedef struct _bl_capability_descriptor {
28 NDS_UBYTE descriptor_tag; // NSK2HDI_BL_CAPABILITY_DESC_TAG
29 NDS_UBYTE len;
30 NDS_UBYTE max_data_size[4];
31 NDS_UBYTE min_data_size[4];
32 NDS_UBYTE data_size_granularity[4];
33 NDS_UBYTE data_alignment[4];
34 } BL_CAPABILITY_DESCRIPTOR;
35
36 typedef struct _bl_hashing_algorithm_descriptor {
37 NDS_UBYTE descriptor_tag; // NSK2HDI_BL_ALGORITHM_DESC_TAG
38 NDS_UBYTE len;
39 NDS_UBYTE algorithm;
40 //NDS_UBYTE hash_block_size[2];
41 } BL_HASHING_ALGORITHM_DESCRIPTOR;
42
43 typedef struct _bl_desc {
44 BL_CAPABILITY_DESCRIPTOR m_cap;
45 BL_HASHING_ALGORITHM_DESCRIPTOR m_algo;
46 } BL_DESC;
47
48
49
50 /*****************************************************************************\
51 \ local variables
52 \*****************************************************************************/
53
54
55 static BL_CAPABILITY_DESCRIPTOR m_cap_des = {
56 .descriptor_tag = NSK2HDI_BL_CAPABILITY_DESC_TAG,
57 .len = sizeof(BL_CAPABILITY_DESCRIPTOR) - 2,
58 .max_data_size[0] = 0,
59 .max_data_size[1] = 0,
60 .max_data_size[2] = 0x80,
61 .max_data_size[3] = 0,
62 .min_data_size[0] = 0x01,
63 .data_size_granularity[0] = 0x10,
64 .data_alignment[0] = 0x10,
65 };
66
67
68 static BL_HASHING_ALGORITHM_DESCRIPTOR m_algo_des[3] = {
69 {
70 .descriptor_tag = NSK2HDI_BL_ALGORITHM_DESC_TAG,
71 .len = sizeof(BL_HASHING_ALGORITHM_DESCRIPTOR) - 2,
72 .algorithm = NSK2HDI_BL_SHA1_HASH_ALG_TYPE,
73 //.hash_block_size[0] = 0x0,
74 //.hash_block_size[1] = 0x1,
75
76 },
77
78 {
79 .descriptor_tag = NSK2HDI_BL_ALGORITHM_DESC_TAG,
80 .len = sizeof(BL_HASHING_ALGORITHM_DESCRIPTOR) - 2,
81 .algorithm = NSK2HDI_BL_SHA256_HASH_ALG_TYPE,
82 //.hash_block_size[0] = 0x0,
83 //.hash_block_size[1] = 0x1,
84
85 },
86
87 {
88 .descriptor_tag = NSK2HDI_BL_ALGORITHM_DESC_TAG,
89 .len = sizeof(BL_HASHING_ALGORITHM_DESCRIPTOR) - 2,
90 .algorithm = NSK2HDI_BL_MD5_HASH_ALG_TYPE,
91 //.hash_block_size[0] = 0x0,
92 //.hash_block_size[1] = 0x1,
93
94 },
95
96 };
97
98
99 static BL_HASHING_ALGORITHM_DESCRIPTOR ghash_algo;
100 static NDS_ULONG ghash_data_size; // IN
101 static NDS_UBYTE *gphash_data; // IN
102
103 static MS_U8 HASH_OUTPUT[MaximumHashSize];
104 static MS_U8 HASH_Middle_OUTPUT[MaximumHashSize];
105 static MS_U32 HASH_ACCU = 0;
106 static NDS_UBYTE manual_mode = FALSE;
107
108 static CIPHER_HASH_STAGE operation_stage = E_CIPHER_HASH_STAGE_FIRST;
109
110 /*****************************************************************************\
111 \ global variables
112 \*****************************************************************************/
113
114
115 /*****************************************************************************\
116 \ NSK2HDI bootloader related functions
117 \*****************************************************************************/
118
119
_DumpBuf(const MS_U8 * buf,MS_U32 len)120 static void _DumpBuf(const MS_U8 *buf, MS_U32 len)
121 {
122 MS_U32 i = 0;
123 for (i = 0; i < len; i++) {
124 printf("0x%02x%c", buf[i], ((i % 16) == 15) ? '\n' : ' ');
125 }
126 printf("\n");
127 }
128
NSK2HDI_CalHASH_Auto(NDS_ULONG data_size,const NDS_UBYTE * data,NDS_ULONG * digest_size,NDS_UBYTE * digest,NDS_ULONG algorithm)129 NSK2HDI_STATUS NSK2HDI_CalHASH_Auto(NDS_ULONG data_size, // IN
130 const NDS_UBYTE *data, // IN
131 NDS_ULONG *digest_size, // IN/OUT
132 NDS_UBYTE *digest,
133 NDS_ULONG algorithm )
134 {
135 DRV_CIPHER_HASHCFG cipher_cfg;
136 DRV_CIPHER_RET ret;
137 NDS_ULONG OutputSize = SHA1_SIZE;
138 MS_U32 u32CmdId,u32Exception;
139
140 NSK_TRACE(("Enter\n"));
141
142 _DumpBuf(data,data_size);
143
144 memset(&cipher_cfg, 0x0, sizeof(DRV_CIPHER_HASHCFG));
145
146 cipher_cfg.u32CAVid = 0xf;
147 if(NSK2HDI_BL_SHA1_HASH_ALG_TYPE == algorithm)
148 {
149 cipher_cfg.eAlgo = E_CIPHER_HASH_ALGO_SHA1;
150 cipher_cfg.u32Digest_Buf_Size = OutputSize = SHA1_SIZE;
151 }
152 else if(NSK2HDI_BL_SHA256_HASH_ALG_TYPE == algorithm)
153 {
154 cipher_cfg.eAlgo = E_CIPHER_HASH_ALGO_SHA256;
155 cipher_cfg.u32Digest_Buf_Size = OutputSize = SHA256_SIZE;
156 }
157 else if(NSK2HDI_BL_MD5_HASH_ALG_TYPE == algorithm)
158 {
159 cipher_cfg.eAlgo = E_CIPHER_HASH_ALGO_MD5;
160 cipher_cfg.u32Digest_Buf_Size = OutputSize = MD5_SIZE;
161 }
162
163 NSK_TRACE(("eAlgo = %d, OutputSize = %x\n",cipher_cfg.eAlgo,OutputSize));
164
165 MS_U8 *pTestInput, *pTestOutput;
166 pTestInput = MApi_NSK2_AllocateMemory(data_size, FALSE);
167 pTestOutput = MApi_NSK2_AllocateMemory(OutputSize, FALSE);
168
169 memcpy(pTestInput,data,data_size);
170
171 cipher_cfg.stInput.u32Addr = MsOS_VA2PA((MS_VIRT)pTestInput);
172 cipher_cfg.stInput.u32Size = data_size;
173 cipher_cfg.pu8Digest_Buf = (MS_U8 *)pTestOutput;
174
175
176 ret = MDrv_CIPHER_HASH(cipher_cfg, &u32CmdId);
177
178 if(ret != 0)
179 {
180 NSK_ERROR(("HASH FAIL!!!\n"));
181 return NSK2HDI_STATUS_FAILED;
182 }
183
184 while(FALSE == MDrv_CIPHER_IsHASHDone(u32CmdId,&u32Exception))
185 {
186 MsOS_DelayTask(20);
187 }
188
189 memcpy(HASH_OUTPUT,pTestOutput,OutputSize);
190
191 _DumpBuf(HASH_OUTPUT, OutputSize);
192
193 memcpy(digest, HASH_OUTPUT, OutputSize);
194 *digest_size = OutputSize;
195
196 MApi_NSK2_FreeMemory(pTestInput, FALSE);
197 MApi_NSK2_FreeMemory(pTestOutput, FALSE);
198
199
200 NSK_TRACE(("Exit\n"));
201
202 return NSK2HDI_STATUS_OK;
203 }
204
205
NSK2HDI_CalHASH_Manual(NDS_ULONG data_size,const NDS_UBYTE * data,NDS_ULONG * digest_size,NDS_UBYTE * digest,NDS_ULONG algorithm,CIPHER_HASH_STAGE stage)206 NSK2HDI_STATUS NSK2HDI_CalHASH_Manual( NDS_ULONG data_size, // IN
207 const NDS_UBYTE *data, // IN
208 NDS_ULONG *digest_size, // IN/OUT
209 NDS_UBYTE *digest,
210 NDS_ULONG algorithm,
211 CIPHER_HASH_STAGE stage)
212 {
213
214 NSK_TRACE(("Enter\n"));
215
216 DRV_CIPHER_HASHCFG_MANUAL cipher_cfg;
217 DRV_CIPHER_RET ret = DRV_CIPHER_OK;
218 NDS_ULONG OutputSize = SHA1_SIZE;
219 MS_U32 u32CmdId,u32Exception;
220
221 memset(&cipher_cfg, 0, sizeof(cipher_cfg));
222
223 if(NSK2HDI_BL_SHA1_HASH_ALG_TYPE == algorithm)
224 {
225 cipher_cfg.eAlgo = E_CIPHER_HASH_ALGO_SHA1;
226 cipher_cfg.u32Digest_Buf_Size = OutputSize = SHA1_SIZE;
227 }
228 else if(NSK2HDI_BL_SHA256_HASH_ALG_TYPE == algorithm)
229 {
230 cipher_cfg.eAlgo = E_CIPHER_HASH_ALGO_SHA256;
231 cipher_cfg.u32Digest_Buf_Size = OutputSize = SHA256_SIZE;
232 }
233 else if(NSK2HDI_BL_MD5_HASH_ALG_TYPE == algorithm)
234 {
235 cipher_cfg.eAlgo = E_CIPHER_HASH_ALGO_MD5;
236 cipher_cfg.u32Digest_Buf_Size = OutputSize = MD5_SIZE;
237 }
238
239 MS_U8 *pTestInput, *pTestOutput, *pTestMidOutput;
240 pTestInput = MApi_NSK2_AllocateMemory(data_size, FALSE);
241 pTestOutput = MApi_NSK2_AllocateMemory(OutputSize, FALSE);
242 pTestMidOutput = MApi_NSK2_AllocateMemory(OutputSize, FALSE);
243
244 memcpy(pTestMidOutput,HASH_Middle_OUTPUT,OutputSize);
245 memcpy(pTestInput,data,data_size);
246
247 cipher_cfg.u32CAVid = 0xf;
248
249 cipher_cfg.stInput.u32Addr = MsOS_VA2PA((MS_VIRT)pTestInput);
250 cipher_cfg.stInput.u32Size = data_size;
251 cipher_cfg.pu8Digest_Buf = (MS_U8 *)pTestOutput;
252
253 NSK_TRACE(("stage = %d, data_size = %x\n",stage, data_size));
254 NSK_TRACE((" HASH_ACCU = %d\n",HASH_ACCU));
255
256 #if 0
257 if(data_size == 1)
258 {
259 printf("final data = %x\n",*data);
260 }
261 #endif
262
263 if(stage == E_CIPHER_HASH_STAGE_FIRST)
264 {
265 NSK_TRACE(("E_CIPHER_HASH_STAGE_FIRST\n"));
266 cipher_cfg.eStage = E_CIPHER_HASH_STAGE_FIRST;
267 cipher_cfg.u32StartByte = 0;
268 cipher_cfg.pu8SetIV = NULL;
269 cipher_cfg.eIVMode = E_CIPHER_HASH_IV_FIPS;
270 ret = MDrv_CIPHER_HASHManual(cipher_cfg, &u32CmdId);
271
272 while(FALSE == MDrv_CIPHER_IsHASHDone(u32CmdId,&u32Exception))
273 {
274 MsOS_DelayTask(20);
275 }
276
277 HASH_ACCU += data_size;
278 }
279 else if (stage == E_CIPHER_HASH_STAGE_UPDATE)
280 {
281 NSK_TRACE(("E_CIPHER_HASH_STAGE_UPDATE\n"));
282 cipher_cfg.eStage = E_CIPHER_HASH_STAGE_UPDATE;
283 cipher_cfg.u32StartByte = HASH_ACCU;
284 cipher_cfg.pu8SetIV = (MS_U8 *)pTestMidOutput;
285 cipher_cfg.eIVMode = E_CIPHER_HASH_IV_CMD;
286
287 ret = MDrv_CIPHER_HASHManual(cipher_cfg, &u32CmdId);
288
289 while(FALSE == MDrv_CIPHER_IsHASHDone(u32CmdId,&u32Exception))
290 {
291 MsOS_DelayTask(20);
292 }
293
294 HASH_ACCU += data_size;
295 }
296 else if (stage == E_CIPHER_HASH_STAGE_LAST)
297 {
298 NSK_TRACE(("E_CIPHER_HASH_STAGE_LAST\n"));
299 cipher_cfg.eStage = E_CIPHER_HASH_STAGE_LAST;
300 cipher_cfg.u32StartByte = HASH_ACCU;
301 cipher_cfg.pu8SetIV = (MS_U8 *)pTestMidOutput;
302 cipher_cfg.eIVMode = E_CIPHER_HASH_IV_CMD;
303
304 ret = MDrv_CIPHER_HASHManual(cipher_cfg, &u32CmdId);
305
306 while(FALSE == MDrv_CIPHER_IsHASHDone(u32CmdId,&u32Exception))
307 {
308 MsOS_DelayTask(20);
309 }
310
311 if(digest != NULL)
312 {
313 memcpy(HASH_OUTPUT,pTestOutput,OutputSize);
314 memcpy(digest, HASH_OUTPUT, OutputSize);
315 }
316 else
317 {
318 NSK_ERROR(("the return buffer is null!!!\n"));
319 }
320
321 if(digest_size != NULL)
322 {
323 *digest_size = OutputSize;
324 }
325 else
326 {
327 NSK_ERROR(("the return buffer size is null!!!\n"));
328 }
329 }
330
331 NSK_TRACE(("ret = %d\n",ret));
332
333 if(ret != 0)
334 {
335 NSK_ERROR(("HASH FAIL!!!\n"));
336 return NSK2HDI_STATUS_FAILED;
337 }
338
339 memcpy(HASH_Middle_OUTPUT, pTestOutput, OutputSize);
340
341 MApi_NSK2_FreeMemory(pTestInput, FALSE);
342 MApi_NSK2_FreeMemory(pTestOutput, FALSE);
343 MApi_NSK2_FreeMemory(pTestMidOutput, FALSE);
344
345 NSK_TRACE(("Exit\n"));
346
347 return NSK2HDI_STATUS_OK;
348 }
349
350
351 //this function is used to query the capabilities of the provided hashing engine.
352 //out--> BL Capability descriptor, BL Algorithm descriptor
NSK2HDI_BL_GetHashCapabilities(NDS_ULONG request_id,NDS_ULONG * desc_size,NDS_UBYTE * desc)353 NSK2HDI_STATUS NSK2HDI_BL_GetHashCapabilities(
354 NDS_ULONG request_id, // IN
355 NDS_ULONG *desc_size, // IN/OUT
356 NDS_UBYTE *desc // OUT
357 )
358 {
359 NSK_TRACE(("Enter\n"));
360
361 if (request_id != NSK2HDI_BL_ALL_DESCRIPTORS_REQUEST)
362 {
363 NSK_ERROR(("Invalid TAG:%x", request_id));
364 return NSK2HDI_STATUS_INVALID_REQUEST;
365 }
366 NSK_PRINT(("desc_size:%d \n", *desc_size ));
367
368 if(desc == NULL)
369 {
370 *desc_size = sizeof(BL_CAPABILITY_DESCRIPTOR) + 3 * sizeof(BL_HASHING_ALGORITHM_DESCRIPTOR) ;
371 NSK_TRACE(("return desc_size = %x\n",*desc_size));
372 return NSK2HDI_STATUS_OK;
373 }
374
375
376 memcpy(desc,&m_cap_des, sizeof(BL_CAPABILITY_DESCRIPTOR));
377
378 memcpy( (desc + sizeof(BL_CAPABILITY_DESCRIPTOR)) ,&m_algo_des[0], 3 * sizeof(BL_HASHING_ALGORITHM_DESCRIPTOR) );
379
380 NSK_TRACE(("Exit\n"));
381 return NSK2HDI_STATUS_OK;
382 }
383
384 //this function shall initialize a hashing operation.
NSK2HDI_BL_InitializeHashOperation(NDS_ULONG desc_size,NDS_UBYTE * desc)385 NSK2HDI_STATUS NSK2HDI_BL_InitializeHashOperation(
386 NDS_ULONG desc_size, // IN
387 NDS_UBYTE *desc // IN
388 )
389 {
390 NSK_TRACE(("Enter\n"));
391 NSK_TRACE(("%s desc_size:%d\n", __FUNCTION__, desc_size));
392
393 MS_U32 size = desc_size;
394 MS_U8 *pBL_buf = (MS_U8*)desc;
395 MS_U8 u8size;
396 MS_U8 TagSwitch;
397 MS_U8 algorithm;
398
399 while(size>=3)
400 {
401 TagSwitch = pBL_buf[0];
402 u8size = pBL_buf[1];
403
404 switch(TagSwitch)
405 {
406 case NSK2HDI_BL_ALGORITHM_DESC_TAG:
407 NSK_TRACE(("NSK2HDI_BL_ALGORITHM_DESC_TAG\n"));
408 algorithm = pBL_buf[2];
409 NSK_TRACE(("algorithm = %x\n",algorithm));
410 ghash_algo.algorithm = algorithm;
411 //memcpy(&ghash_algo, pBL_buf, u8size);
412 break;
413
414 case NSK2HDI_BL_CAPABILITY_DESC_TAG:
415 NSK_TRACE(("NSK2HDI_BL_CAPABILITY_DESC_TAG\n"));
416 break;
417
418 default:
419 NSK_ERROR(("unknown desc tag\n"));
420 break;
421 }
422
423 pBL_buf += 3;
424 size -= 3;
425 }
426
427 memset(HASH_OUTPUT, 0x0, MaximumHashSize);
428 memset(HASH_Middle_OUTPUT, 0x0, MaximumHashSize);
429 operation_stage = E_CIPHER_HASH_STAGE_FIRST;
430
431 HASH_ACCU = 0;
432 manual_mode = FALSE;
433 NSK_TRACE(("Exit\n"));
434 return NSK2HDI_STATUS_OK;
435 }
436
437 //this fcuntion shall performa a hash operation on a chunk of data, or continue a
438 //previous operation. This function shall return only upon completion of the operation.
439 //Other threads may not call any other API from this document during this opration.
NSK2HDI_BL_PerformHashOperation(NDS_ULONG data_size,const NDS_UBYTE * data)440 NSK2HDI_STATUS NSK2HDI_BL_PerformHashOperation(
441 NDS_ULONG data_size, // IN
442 const NDS_UBYTE *data // IN
443 )
444 {
445 NSK_TRACE(("Enter\n"));
446 printf ("%s data_size:%d\n", __FUNCTION__, data_size);
447 MS_U8 algorithm;
448
449 algorithm = ghash_algo.algorithm;
450
451 NSK_TRACE(("algorithm = %x\n",algorithm));
452
453 ghash_data_size = data_size;
454 gphash_data = (NDS_UBYTE *)data;
455
456 if( (NSK2HDI_BL_SHA1_HASH_ALG_TYPE != algorithm) &&
457 (NSK2HDI_BL_SHA256_HASH_ALG_TYPE != algorithm) &&
458 (NSK2HDI_BL_MD5_HASH_ALG_TYPE == algorithm) )
459 {
460 NSK_TRACE(("algorithm not support\n"));
461 }
462
463 NSK2HDI_CalHASH_Manual(data_size, data, NULL, NULL, algorithm, operation_stage);
464 manual_mode = TRUE;
465 if(operation_stage == E_CIPHER_HASH_STAGE_FIRST)
466 {
467 operation_stage = E_CIPHER_HASH_STAGE_UPDATE;
468 }
469
470 NSK_TRACE(("Exit\n"));
471 return NSK2HDI_STATUS_OK;
472 }
473
474
475
476
477 //this function completes a hash operation.
478 //out-->digest_size, actual size in bytes of the hash digest written to buffer.
479 //out-->digest, Buufer with the resulting hash digest.
NSK2HDI_BL_CompleteHashOperation(NDS_ULONG data_size,const NDS_UBYTE * data,NDS_ULONG * digest_size,NDS_UBYTE * digest)480 NSK2HDI_STATUS NSK2HDI_BL_CompleteHashOperation(
481 NDS_ULONG data_size, // IN
482 const NDS_UBYTE *data, // IN
483 NDS_ULONG *digest_size, // IN/OUT
484 NDS_UBYTE *digest // OUT
485 )
486 {
487 NSK_TRACE(("Enter\n"));
488 NDS_ULONG algorithm;
489
490 algorithm = ghash_algo.algorithm;
491
492 NSK_TRACE(("%s data_size:0x%x\n", __FUNCTION__, data_size));
493 NSK_TRACE(("algorithm = %x\n",algorithm));
494
495 if(manual_mode == TRUE)
496 {
497 NSK2HDI_CalHASH_Manual(data_size, data, digest_size, digest, algorithm, E_CIPHER_HASH_STAGE_LAST);
498 }
499 else
500 {
501 NSK2HDI_CalHASH_Auto(data_size, data, digest_size, digest, algorithm);
502 }
503
504 //*digest_size = output_size;
505
506 NSK_TRACE(("Exit\n"));
507 return NSK2HDI_STATUS_OK;
508 }
509
510
511
512
513