xref: /utopia/UTPA2-700.0.x/modules/hdmi/hal/curry/hdmitx/halHDCPTx.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (��MStar Confidential Information��) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    halHDCPTx.c
98 /// @author MStar Semiconductor Inc.
99 /// @brief  HDMITx HDCP HAL
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 
103 //-------------------------------------------------------------------------------------------------
104 //  Include Files
105 //-------------------------------------------------------------------------------------------------
106 #ifdef MSOS_TYPE_LINUX_KERNEL
107 #include <linux/string.h>
108 #else
109 #include <string.h>
110 #endif
111 #include "MsCommon.h"
112 #include "halHDMIUtilTx.h"
113 #include "regHDMITx.h"
114 #include "halHDCPTx.h"
115 
116 //-------------------------------------------------------------------------------------------------
117 //  Driver Compiler Options
118 //-------------------------------------------------------------------------------------------------
119 
120 
121 //-------------------------------------------------------------------------------------------------
122 //  Local Defines
123 //-------------------------------------------------------------------------------------------------
124 
125 #define HDCP_KEY_OFFSET         8U
126 
127 //-------------------------------------------------------------------------------------------------
128 //  Local Structures
129 //-------------------------------------------------------------------------------------------------
130 
131 //-------------------------------------------------------------------------------------------------
132 //  Global Variables
133 //-------------------------------------------------------------------------------------------------
134 
135 MS_BOOL bDebugHDCPFlag = FALSE;
136 MS_U8 HDCP_AKSV[5] = {0, 0, 0, 0, 0,};
137 MS_U8 HDCP_BKSV[5] = {0, 0, 0, 0, 0,};
138 
139 MS_U8 HDCP_KEY[304];
140 
141 //-------------------------------------------------------------------------------------------------
142 //  Local Variables
143 //-------------------------------------------------------------------------------------------------
144 
145 MSTHDMITX_REG_TYPE TxHdcpInitTbl[] =
146 {
147     {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_MODE_01, 0x8000, 0x8000}, // Enable HDCP encryption
148     {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x001C, 0x0000}, //[4]: 1: km new mode; 0: km old mode
149 };
150 
151 MSTHDMITX_REG_TYPE TxHdcpEncryptOnTbl[] =
152 {
153     {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x0008, 0x0008},
154 };
155 
156 MSTHDMITX_REG_TYPE TxHdcpEncryptOffTbl[] =
157 {
158     {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x0008, 0x0000},
159 };
160 
161 MS_U8 TxHdcpAnTbl[] =
162 {
163     0x03, 0x04, 0x07, 0x0C, 0x13, 0x1C, 0x27, 0x34,
164 };
165 
166 MS_U32 sm_K160[4] =
167 {
168     0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
169 };
170 
171 MS_U32 sm_H160[SHA160LENGTH] =
172 {
173     0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
174 };
175 
176 
177 //-------------------------------------------------------------------------------------------------
178 //  Debug Functions
179 //-------------------------------------------------------------------------------------------------
180 
181 //-------------------------------------------------------------------------------------------------
182 //  Local Functions
183 //-------------------------------------------------------------------------------------------------
184 
185 extern MS_BOOL MDrv_EEPROM_Read(MS_U32 u32Addr, MS_U8 *pu8Buf, MS_U32 u32Size);
186 
Bytes2Word(MS_U8 const * pcBytes,MS_U32 * ruiWord)187 void Bytes2Word(MS_U8 const * pcBytes, MS_U32  * ruiWord)
188 {
189     *ruiWord = ((MS_U32) pcBytes[3])
190              | (((MS_U32) pcBytes[2]) << 8)
191              | (((MS_U32) pcBytes[1]) << 16)
192              | (((MS_U32) pcBytes[0]) << 24);
193 }
194 
195 //#define   Bytes2Word(pcBytes) (((MS_U32)pcBytes[3]) | (((MS_U32)pcBytes[2])<<8) |       (( (MS_U32)pcBytes[1] )<<16) | (( (MS_U32)pcBytes[0] )<<24))
196 
CircularShift(MS_U32 uiBits,MS_U32 uiWord)197 MS_U32 CircularShift(MS_U32 uiBits, MS_U32 uiWord)
198 {
199     return (uiWord << uiBits) | (uiWord >> (32 - uiBits));
200 }
201 
Word2Bytes1(MS_U32 const * ruiWord,MS_U8 * pcBytes)202 void Word2Bytes1(MS_U32 const * ruiWord, MS_U8* pcBytes)
203 {
204 	pcBytes += 3;
205 	*pcBytes = *ruiWord & 0xff;
206 	*--pcBytes = (*ruiWord >> 8) & 0xff;
207 	*--pcBytes = (*ruiWord >> 16) & 0xff;
208 	*--pcBytes = (*ruiWord >> 24) & 0xff;
209 }
210 
Word2Bytes(MS_U32 const * ruiWord,MS_U8 * pcBytes)211 void Word2Bytes(MS_U32 const * ruiWord, MS_U8* pcBytes)
212 {
213     pcBytes += 3;
214     *pcBytes = (*ruiWord>>24) & 0xff;
215     *--pcBytes = (*ruiWord >> 16) & 0xff;
216     *--pcBytes = (*ruiWord >> 8) & 0xff;
217     *--pcBytes = (*ruiWord) & 0xff;
218 }
219 
220 
MHal_HDMITx_HdcpDebugEnable(MS_BOOL benable)221 void MHal_HDMITx_HdcpDebugEnable(MS_BOOL benable)
222 {
223     bDebugHDCPFlag = benable;
224 }
225 
MHal_HDMITx_GetHdcpKey(MS_BOOL useinternalkey,MS_U8 * data)226 void MHal_HDMITx_GetHdcpKey(MS_BOOL useinternalkey, MS_U8 *data)
227 {
228     if(!useinternalkey)
229     {
230         memcpy(&HDCP_KEY[0], data, 304*sizeof(MS_U8));
231     	{
232             MS_U16 i;
233 
234             if(bDebugHDCPFlag)
235             {
236                 printf("HDCP key = \n");
237                 for(i=0;i<304;i++)
238                 {
239                     printf("0x%x, ", HDCP_KEY[i]);
240                     if(i%16 == 15)
241                         printf("\n");
242                 }
243             }
244         }
245     }
246 }
247 
MHal_HDMITx_HdcpKeyInit(MS_BOOL useinternalkey)248 void MHal_HDMITx_HdcpKeyInit(MS_BOOL useinternalkey)
249 {
250     if(!useinternalkey)
251     {
252         MDrv_EEPROM_Read(0x00, HDCP_KEY, 304);
253     #if 1
254     	{
255             MS_U16 i;
256 
257             if(bDebugHDCPFlag)
258             {
259                 printf("HDCP key = \n");
260                 for(i=0;i<304;i++)
261                 {
262                     printf("0x%x, ", HDCP_KEY[i]);
263                     if(i%16 == 15)
264                         printf("\n");
265                 }
266             }
267 
268 	}
269     #endif
270     }
271 }
272 
273 
274 //******************************************************************************
275 //
276 //  [Function Name]:
277 //      TxHdcpInit
278 //  [Description]:
279 //      This routine is the initialization for HDCP module.
280 //  [Arguments]:
281 //      arg1:   tx index
282 //  [Return]:
283 //      None
284 //
285 //*******************************************************************************
MHal_HDMITx_HdcpInit(void)286 void MHal_HDMITx_HdcpInit(void)
287 {
288     MS_U8 num;
289 
290     num = sizeof(TxHdcpInitTbl) / sizeof(MSTHDMITX_REG_TYPE);
291     MHal_HDMITx_RegsTbl_Write(TxHdcpInitTbl, num);
292 }
293 
294 
295 //******************************************************************************
296 //
297 //  [Function Name]:
298 //      TxHdcpRxActive
299 //  [Description]:
300 //      This routine check the HDCP Rx active or not
301 //  [Arguments]:
302 //      arg1:   tx index
303 //  [Return]:
304 //      FALSE:      no HDCP Rx
305 //      TRUE:       HDCP Rx active
306 //
307 //*******************************************************************************
MHal_HDMITx_HdcpRxActive(void)308 MS_BOOL MHal_HDMITx_HdcpRxActive(void)
309 {
310     MS_U8 regval;
311 
312     if (MHal_HDMITx_Rx74ReadByte(0x40, &regval) == TRUE)
313     {
314         if(regval != 0xFF)
315             return TRUE;
316     }
317     return FALSE;
318 }
319 
320 
321 //******************************************************************************
322 //
323 //  [Function Name]:
324 //      TxHdcpSetEncrypt
325 //  [Description]:
326 //      This routine set encryption for HDCP module.
327 //  [Arguments]:
328 //      arg1:   tx index
329 //      arg2:   0:disable 1:enable
330 //  [Return]:
331 //      None
332 //
333 //*******************************************************************************
MHal_HDMITx_HdcpSetEncrypt(MS_BOOL enable)334 void MHal_HDMITx_HdcpSetEncrypt(MS_BOOL enable)
335 {
336     switch (enable)
337     {
338         case 0:
339             MHal_HDMITx_RegsTbl_Write(TxHdcpEncryptOffTbl, 1);
340             break;
341         case 1:
342             MHal_HDMITx_RegsTbl_Write(TxHdcpEncryptOnTbl, 1);
343             break;
344         default:
345             break;
346     }
347 }
348 
349 
350 //******************************************************************************
351 //
352 //  [Function Name]:
353 //      TxHdcpCheckBksvLn
354 //  [Description]:
355 //      This routine check the HDCP Rx's BKSV and calculate the Key
356 //  [Arguments]:
357 //      arg1:   tx index
358 //  [Return]:
359 //      TRUE:   pass
360 //      FALSE:  fail
361 //
362 //*******************************************************************************
MHal_HDMITx_HdcpCheckBksvLn(void)363 MS_BOOL MHal_HDMITx_HdcpCheckBksvLn(void)
364 {
365     MS_U8 bksv[5] = {0}, Lm[7] = {0};
366     MS_U8 temp, carry_bit, seed;
367     MS_U8 i, j, k, t;
368     MS_U16 offset;
369 
370     if(bDebugHDCPFlag)
371         printf("TxHdcpCheckBksvLn()\r\n");
372     // Check BKSV 20 bit1 20 bit0
373     k = 0;
374     for (t = 0; t < 10; t++)
375     {
376         for (i = 0; i < 5; i++)
377         {
378             if(MHal_HDMITx_Rx74ReadByte(i, &bksv[i]) == FALSE)
379             {
380                 if(bDebugHDCPFlag)
381                     printf("Reading BKSV failed because I2C\r\n");
382                 return FALSE;
383             }
384             for (j = 0; j < 8; j++)
385                 k += (bksv[i] >> j) & 0x01;
386 
387 			HDCP_BKSV[i] = bksv[i];
388         }
389         if (k == 20)
390             break;
391         MsOS_DelayTask(20);
392         k=0;
393     }
394 
395     if(bDebugHDCPFlag)
396     {
397         printf("Bksv=");
398         for (i = 0; i < 5; i++)
399             printf("0x%x, ", bksv[i]);
400         printf("\r\n");
401     }
402 
403     if (k != 20)
404         return FALSE;
405     for (i = 0; i < 7; i++)
406         Lm[i] = 0;
407 
408 #if 0
409     for(i=0;i<18;i++)
410     {
411         for(j=0;j<16;j++)
412         {
413             if(HDCP_KEY[(i<<4)+j]!=MHal_HDMITx_Rx74ReadByte((i<<4)+j))
414             DBG_HDCP(printf("\r\nerror address=%x\r\n,",(i<<4)+j));
415         }
416     }
417 #endif
418 
419     // Generate cipher infomation from Key & BKSV
420     for (i = 0; i < 5; i++)
421         for (j = 0; j < 8; j++)
422         {
423             //if(RxBksvTbl[4-i] & (1<<j))
424             if (bksv[i] & (1 << j))
425             {
426                 carry_bit = 0;
427                 offset = (i * 8 + j) * 7 + HDCP_KEY_OFFSET;
428                 for (k = 0; k < 7; k++)
429                 {
430                     seed = (k + HDCP_KEY[7]) % 7;
431                     temp = HDCP_KEY[offset + k] ^ HDCP_KEY[seed];
432                     Lm[k] = Lm[k] + temp + carry_bit;
433                     if (((carry_bit == 0) && (Lm[k] >= temp)) || ((carry_bit == 1) && (Lm[k] > temp)))
434                         carry_bit = 0;
435                     else
436                         carry_bit = 1;
437                 }
438             }
439         }
440     temp = HDCP_KEY[288];
441 
442     if(bDebugHDCPFlag)
443         printf("Km= ");
444     for (i = 0; i < 7; i++)
445     {
446         if (i < 6)
447             Lm[i] = Lm[i] ^ temp;
448         else
449             Lm[i] = Lm[i] ^ (~temp);
450 
451         if(i%2)
452             MHal_HDMITx_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_LN_04+(i/2), (Lm[i]<<8) | Lm[i-1]);
453         if(bDebugHDCPFlag)
454             printf("0x%x, ", Lm[i]);
455     }
456     if(bDebugHDCPFlag)
457         printf("\n");
458     MHal_HDMITx_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_LN_SEED_07, (temp<<8) | Lm[6]);
459     if(bDebugHDCPFlag)
460         printf("Seed=0x%x\r\n", temp);
461 
462     return TRUE;
463 }
464 
465 
466 //******************************************************************************
467 //
468 //  [Function Name]:
469 //      TxHdcpWriteAn
470 //  [Description]:
471 //      This routine Write An to the HDCP Rx
472 //  [Arguments]:
473 //      arg1:   tx index
474 //      arg2:   use internal An or not
475 //  [Return]:
476 //      None
477 //
478 //*******************************************************************************
MHal_HDMITx_HdcpWriteAn(MS_U8 internal)479 MS_BOOL MHal_HDMITx_HdcpWriteAn(MS_U8 internal)
480 {
481     MS_U16 temp;
482     MS_U8 i;
483 
484     if (internal == 1)
485     {
486         MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_MODE_01, 0x0100, 0x0100);
487         MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, BIT1, BIT1);
488         MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, BIT1, 0);
489 
490         //Waiting for HW An Auto Gen Ready
491         MsOS_DelayTaskUs(1);
492 
493         if(bDebugHDCPFlag)
494             printf("Internal An=");
495         for (i = 0; i < 4; i++)
496         {
497             temp = MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_AN_08+i);
498             if(MHal_HDMITx_Rx74WriteByte(0x18 + (i*2), (MS_U8)(temp & 0x00FF)) == FALSE)
499             {
500                 if(bDebugHDCPFlag)
501                     printf("Writing An failed because I2C\r\n");
502                 return FALSE;
503             }
504             if(MHal_HDMITx_Rx74WriteByte(0x18 + (i*2+1), (MS_U8)((temp & 0xFF00)>>8)) == FALSE)
505             {
506                 if(bDebugHDCPFlag)
507                     printf("Writing An failed because I2C\r\n");
508                 return FALSE;
509             }
510             if(bDebugHDCPFlag)
511             {
512                 printf("0x%x, ", temp & 0x00FF);
513                 printf("0x%x, ", (temp & 0xFF00)>>8);
514             }
515         }
516         if(bDebugHDCPFlag)
517             printf("\r\n");
518     }
519     else
520     {
521         MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_MODE_01, 0x0100, 0x0000);
522         for(i = 0; i < 4; i++)
523             MHal_HDMITx_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_AN_08+i, (TxHdcpAnTbl[2*i+1] <<8) | (TxHdcpAnTbl[2*i]));
524         if(MHal_HDMITx_Rx74WriteBytes(0x18, 8, TxHdcpAnTbl) == FALSE)
525         {
526             if(bDebugHDCPFlag)
527                 printf("Writing An failed because I2C\r\n");
528             return FALSE;
529         }
530         if(bDebugHDCPFlag)
531         {
532              printf("External An=");
533              for (i = 0; i < 8; i++)
534                  printf("0x%x, ", TxHdcpAnTbl[i]);
535              printf("\r\n");
536         }
537     }
538     return TRUE;
539 }
540 
541 
542 //******************************************************************************
543 //
544 //  [Function Name]:
545 //      TxHdcpWriteAksv
546 //  [Description]:
547 //      This routine Write AKSV to the HDCP Rx
548 //  [Arguments]:
549 //      arg1:   tx index
550 //  [Return]:
551 //      None
552 //
553 //*******************************************************************************
MHal_HDMITx_HdcpWriteAksv(void)554 MS_BOOL MHal_HDMITx_HdcpWriteAksv(void)
555 {
556     MS_U8 temp;
557     MS_U8 i, k, j;
558 
559     if(bDebugHDCPFlag)
560         printf("Aksv=");
561     for (i = 0, k=0; i < 5; i++)
562     {
563         //temp = TxHdcpKeyTbl[i];
564         temp = HDCP_KEY[i];
565         HDCP_AKSV[i] = temp;
566         if(MHal_HDMITx_Rx74WriteByte(0x10 + i, temp) == FALSE)
567         {
568             if(bDebugHDCPFlag)
569                 printf("Writing Aksv failed because I2C\r\n");
570             return FALSE;
571         }
572         for (j = 0; j < 8; j++)
573             k += (temp >> j) & 0x01; // check AKSV whether is 20 zeros and 20 ones or not.
574         if(bDebugHDCPFlag)
575             printf("0x%x, ", temp);
576     }
577     if(bDebugHDCPFlag)
578         printf("\r\n");
579     if(k!=20)	return FALSE;
580     return TRUE;
581 }
582 
583 
584 //******************************************************************************
585 //
586 //  [Function Name]:
587 //      MHal_HDMITx_GET74
588 //  [Description]:
589 //      This routine get data from 74reg
590 //  [Arguments]:
591 //
592 //  [Return]:
593 //      None
594 //
595 //*******************************************************************************
MHal_HDMITx_GET74(MS_U8 udata,MS_U8 * pdata)596 void MHal_HDMITx_GET74(MS_U8 udata, MS_U8 *pdata)
597 {
598    if(udata == 0x00)
599        memcpy(pdata, &HDCP_BKSV, 5*sizeof(MS_U8));
600    else if(udata == 0x10)
601        memcpy(pdata, &HDCP_AKSV, 5*sizeof(MS_U8));
602 }
603 
604 
605 //******************************************************************************
606 //
607 //  [Function Name]:
608 //      TxHdcpStartCipher
609 //  [Description]:
610 //      This routine Start HDCP Tx Cipher
611 //  [Arguments]:
612 //      arg1:   tx index
613 //  [Return]:
614 //      None
615 //
616 //*******************************************************************************
MHal_HDMITx_HdcpStartCipher(void)617 void MHal_HDMITx_HdcpStartCipher(void)
618 {
619     MS_U8 count = 0xFF;
620 
621     MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, 0);
622     MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, BIT0);
623     MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, 0);
624 
625     while (count-- && !(MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02) & BIT8));
626     if (count == 0)
627     {
628         if(bDebugHDCPFlag)
629             printf("Cipher not done!!!\r\n");
630     }
631 }
632 
633 
634 //******************************************************************************
635 //
636 //  [Function Name]:
637 //      TxHdcpAuthPass
638 //  [Description]:
639 //      This routine finish the authentication
640 //  [Arguments]:
641 //      arg1:   tx index
642 //  [Return]:
643 //      None
644 //
645 //*******************************************************************************
MHal_HDMITx_HdcpAuthPass(void)646 void MHal_HDMITx_HdcpAuthPass(void)
647 {
648     MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, 0x000C);
649 }
650 
651 
MHal_HDMITx_HdcpSha1Init(SHA1_DATA * dig)652 void MHal_HDMITx_HdcpSha1Init(SHA1_DATA *dig)
653 {
654     MS_U8 i;
655 
656     for (i = 0; i < SHA160LENGTH; i++)
657         dig->m_auiBuf[i] = sm_H160[i];
658     dig->m_auiBits[0] = 0;
659     dig->m_auiBits[1] = 0;
660     memset(dig->m_aucIn, 0, BLOCKSIZE) ;  // 2006/1/18 3:31PM by Emily
661 }
662 
663 
664 //******************************************************************************
665 //
666 //  [Function Name]:
667 //      TxHdcpCheckRi
668 //  [Description]:
669 //      This routine check the hdcp Ri values
670 //  [Arguments]:
671 //      arg1:   tx index
672 //      arg2:   output Tx Ri value
673 //      arg3:   output Rx Ri value
674 //  [Return]:
675 //      None
676 //
677 //*******************************************************************************
MHal_HDMITx_HdcpCheckRi(MS_U16 * ptx_ri,MS_U16 * prx_ri)678 MS_BOOL MHal_HDMITx_HdcpCheckRi(MS_U16 *ptx_ri, MS_U16 *prx_ri)
679 {
680     *ptx_ri = MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_RI_00);
681     if(MHal_HDMITx_Rx74ReadBytes(0x08, 2, (MS_U8 *)prx_ri) == TRUE)
682     {
683         if (*prx_ri == *ptx_ri)
684             return TRUE;
685     }
686     if(MHal_HDMITx_Rx74ReadBytes(0x08, 2, (MS_U8 *)prx_ri) == TRUE)
687     {
688         if (*prx_ri == *ptx_ri)
689             return TRUE;
690     }
691     *ptx_ri = MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_RI_00);
692     if (*prx_ri == *ptx_ri)
693         return TRUE;
694     else
695         return FALSE;
696 }
697 
698 
_MHal_HDMITx_HdcpSha1Transform(SHA1_DATA * dig)699 void _MHal_HDMITx_HdcpSha1Transform(SHA1_DATA *dig)
700 {
701     MS_U8 * pucIn = dig->m_aucIn;
702     MS_U32 auiW[80];
703     MS_U8 i;
704     MS_U32 temp;
705     MS_U32 A, B, C, D, E;
706 
707     for (i = 0; i < 16; i++,pucIn += 4)
708         auiW[i] = ((MS_U32)pucIn[3]) | ((MS_U32)pucIn[2] << 8) |
709                   ((MS_U32)pucIn[1] << 16) | ((MS_U32)pucIn[0] << 24);
710     for (i = 16; i < 80; i++)
711         auiW[i] = ((auiW[i - 3] ^ auiW[i - 8] ^ auiW[i - 14] ^ auiW[i - 16]) << 1) |
712                   ((auiW[i - 3] ^ auiW[i - 8] ^ auiW[i - 14] ^ auiW[i - 16]) >> 31);
713 
714     A = dig->m_auiBuf[0];
715     B = dig->m_auiBuf[1];
716     C = dig->m_auiBuf[2];
717     D = dig->m_auiBuf[3];
718     E = dig->m_auiBuf[4];
719 
720     for (i = 0; i < 20; i++)
721     {
722         temp = ((A << 5) | (A >> 27)) + ((B & C) | ((~B) & D)) + E + auiW[i] + sm_K160[0];
723         E = D;
724         D = C;
725 		C = (B << 30) | (B >> 2);
726         B = A;
727         A = temp;
728     }
729     for (i = 20; i < 40; i++)
730     {
731         temp = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + auiW[i] + sm_K160[1];
732         E = D;
733         D = C;
734 		C = (B << 30) | (B >> 2);
735         B = A;
736         A = temp;
737     }
738     for (i = 40; i < 60; i++)
739     {
740         temp = ((A << 5) | (A >> 27)) + ((B & C) | (B & D) | (C & D)) + E + auiW[i] + sm_K160[2];
741         E = D;
742         D = C;
743 		C = (B << 30) | (B >> 2);
744         B = A;
745         A = temp;
746     }
747     for (i = 60; i < 80; i++)
748     {
749         temp = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + auiW[i] + sm_K160[3];
750         E = D;
751         D = C;
752 		C = (B << 30) | (B >> 2);
753         B = A;
754         A = temp;
755     }
756     dig->m_auiBuf[0] += A;
757     dig->m_auiBuf[1] += B;
758     dig->m_auiBuf[2] += C;
759     dig->m_auiBuf[3] += D;
760     dig->m_auiBuf[4] += E;
761 }
762 
763 
MHal_HDMITx_HdcpSha1AddData(SHA1_DATA * dig,MS_U8 const * pcData,MS_U16 iDataLength)764 void MHal_HDMITx_HdcpSha1AddData(SHA1_DATA *dig, MS_U8 const * pcData, MS_U16  iDataLength)
765 {
766     MS_U32  uiT;
767 
768     //Update bitcount
769     uiT = dig->m_auiBits[0];
770     if ((dig->m_auiBits[0] = uiT + ((MS_U32) iDataLength << 3)) < uiT)
771         dig->m_auiBits[1]++; //Carry from low to high
772     //dig->m_auiBits[1] += ((MS_U32) iDataLength) >> 29;  //Fix coverity impact : iDataLength >> 29 is 0
773     uiT = (uiT >> 3) & (BLOCKSIZE - 1); //Bytes already
774     //Handle any leading odd-sized chunks
775     if (uiT != 0)
776     {
777         MS_U8 * puc = (MS_U8 *) dig->m_aucIn + uiT;
778         uiT = BLOCKSIZE - uiT;
779         if (iDataLength < uiT)
780         {
781             memcpy(puc, pcData, iDataLength);
782             return;
783         }
784         memcpy(puc, pcData, uiT);
785         _MHal_HDMITx_HdcpSha1Transform(dig);
786         pcData += uiT;
787         iDataLength -= uiT;
788     }
789     //Process data in 64-byte chunks
790     while (iDataLength >= BLOCKSIZE)
791     {
792         memcpy(dig->m_aucIn, pcData, BLOCKSIZE);
793         _MHal_HDMITx_HdcpSha1Transform(dig);
794         pcData += BLOCKSIZE;
795         iDataLength -= BLOCKSIZE;
796     }
797     //Handle any remaining bytes of data
798     memcpy(dig->m_aucIn, pcData, iDataLength);
799 }
800 
801 
MHal_HDMITx_HdcpSha1FinalDigest(SHA1_DATA * dig,MS_U8 * pcDigest)802 void MHal_HDMITx_HdcpSha1FinalDigest(SHA1_DATA *dig, MS_U8* pcDigest)
803 {
804     MS_U16  uiCount;
805     MS_U8   *puc;
806     MS_U8   i;
807 
808     //Compute number of bytes mod 64
809     uiCount = (dig->m_auiBits[0] >> 3) & (BLOCKSIZE - 1);
810     //Set the first char of padding to 0x80. This is safe since there is
811     //always at least one byte free
812     puc = dig->m_aucIn + uiCount;
813     *puc++ = 0x80;
814     //Bytes of padding needed to make 64 bytes
815     uiCount = BLOCKSIZE - uiCount - 1;
816 
817     //Pad out to 56 mod 64
818     if (uiCount < 8)
819     {
820         //Two lots of padding: Pad the first block to 64 bytes
821         memset(puc, 0, uiCount);
822         _MHal_HDMITx_HdcpSha1Transform(dig);
823         //Now fill the next block with 56 bytes
824         memset(dig->m_aucIn, 0, BLOCKSIZE - 8);
825     }
826     else
827     {
828         //Pad block to 56 bytes
829         memset(puc, 0, uiCount - 8);
830     }
831 
832     //Append length in bits and transform
833     Word2Bytes1(&dig->m_auiBits[1], &dig->m_aucIn[BLOCKSIZE - 8]);
834     Word2Bytes1(&dig->m_auiBits[0], &dig->m_aucIn[BLOCKSIZE - 4]);
835     _MHal_HDMITx_HdcpSha1Transform(dig);
836 
837     for (i = 0; i < SHA160LENGTH; i++,pcDigest += 4)
838         Word2Bytes(&dig->m_auiBuf[i], pcDigest);
839 }
840 
841 
842 // *************  For customer NDS **************//
843 
MHal_HDMITx_HDCP_Get_BCaps(MS_U8 * u8bcaps)844 MS_BOOL MHal_HDMITx_HDCP_Get_BCaps(MS_U8 *u8bcaps)
845 {
846     return (MHal_HDMITx_Rx74ReadByte(0x40, u8bcaps));
847 }
848 
MHal_HDMITx_HDCP_Get_BStatus(MS_U16 * u16bstatus)849 MS_BOOL MHal_HDMITx_HDCP_Get_BStatus(MS_U16 *u16bstatus)
850 {
851     MS_U8 u8data1 = 0x0;
852 	MS_U8 u8data2 = 0x0;
853     MS_BOOL ret = TRUE;
854 
855     if(!MHal_HDMITx_Rx74ReadByte(0x42, &u8data2) || !MHal_HDMITx_Rx74ReadByte(0x41, &u8data1))
856         ret = FALSE;
857     *u16bstatus = ((MS_U16) u8data2<< 8) | u8data1;
858     return ret;
859 }
860 
MHal_HDMITx_HDCP_Get_BKSV(MS_U8 * u8bksv)861 MS_BOOL MHal_HDMITx_HDCP_Get_BKSV(MS_U8 *u8bksv)
862 {
863     MS_U8 i;
864     MS_BOOL ret = TRUE;
865 
866     for(i=0; i<5; i++)
867     {
868         if(!MHal_HDMITx_Rx74ReadByte(0x00+i, u8bksv+i))
869             ret = FALSE;
870     }
871     return ret;
872 }
873 
MHal_HDMITx_HDCP_SHA1_Transform(unsigned int * sha1,const MS_U8 * s)874 void MHal_HDMITx_HDCP_SHA1_Transform(unsigned int *sha1, const MS_U8 *s)
875 {
876     SHA1_DATA tdig;
877 
878     MHal_HDMITx_HdcpSha1Init(&tdig);
879     // MS_U32 M[2], w[16]
880     // w[0]=M[0];
881     // w[1]=M[1];
882     // w[2]=0x80000000;
883     // w[3]=0;w[4]=0;w[5]=0;w[6]=0;w[7]=0;w[8]=0;w[9]=0;w[10]=0;w[11]=0;w[12]=0;w[13]=0;
884     // w[14]=0;w[15]=0x00000040;
885     memcpy(&tdig.m_aucIn[0], s, 8*sizeof(MS_U8)); // The first 8 bytes are copy from message
886     tdig.m_aucIn[8] = 0x80; // append the bit "1" and K = 439 bits "0" to the message
887     memset(&tdig.m_aucIn[9], 0, 54*sizeof(MS_U8));
888     tdig.m_aucIn[63] = 0x40; // apppend length of message, 64 bytes
889 
890     _MHal_HDMITx_HdcpSha1Transform(&tdig);
891     memcpy(sha1, &tdig.m_auiBuf[0], 5*sizeof(MS_U32));
892     //printf("@@SRM - Trans Msg= %8x%8x%8x%8x%8x\r\n", tdig.m_auiBuf[0],tdig.m_auiBuf[1],tdig.m_auiBuf[2],tdig.m_auiBuf[3],tdig.m_auiBuf[4]);
893 }
894 
895 // *************  end  **************//
896 
897