xref: /utopia/UTPA2-700.0.x/modules/dscmb/api/nsk2hdi/nsk2hdi_bl.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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