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, ®val) == 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