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 0x47,0x7a,0x25,0x2f,0x1a,0xc1,0x54,0x00,0x93,0x23,0xbe,0x15,0x32,0x62,0x48,0xed,
142 0x8c,0xb8,0x80,0x61,0x06,0xc1,0x93,0x15,0xab,0xd9,0x3e,0x0f,0x5b,0xb5,0x76,0xcc,
143 0x25,0x01,0xbb,0x51,0xbc,0xbd,0x75,0x71,0x04,0x44,0x82,0xed,0x52,0xc6,0x68,0x11,
144 0x5f,0x24,0xff,0x48,0xac,0x6b,0x79,0xcb,0xf1,0xe8,0x2c,0xc4,0x3a,0x43,0xf0,0x27,
145 0x1d,0x15,0x9b,0x4e,0xa2,0x65,0x08,0x8d,0x69,0x69,0x35,0x1b,0x48,0xf0,0x79,0x57,
146 0x02,0xe5,0x69,0x58,0xa3,0x3e,0x0e,0x31,0xfe,0x8d,0x70,0x3e,0x30,0x21,0xdc,0x48,
147 0x9b,0x08,0xb5,0x2f,0x58,0xd2,0x21,0x67,0xe4,0x67,0x13,0x02,0x92,0x49,0x66,0x6f,
148 0xb6,0xe9,0x25,0x8c,0xa0,0x1f,0xd5,0xeb,0x25,0xbc,0xc6,0xa7,0x89,0x1a,0x33,0x8d,
149 0x50,0xf7,0x1d,0x88,0x18,0x7c,0xd3,0x26,0x80,0xa7,0x4c,0x40,0xae,0xb9,0x99,0x8a,
150 0x97,0x11,0x60,0xb5,0xbc,0x4a,0xce,0x14,0xa5,0x2d,0x86,0x73,0xd6,0xf2,0x45,0x19,
151 0x05,0xa3,0x81,0xa5,0xf3,0x8b,0x09,0xce,0x75,0x66,0xbe,0x17,0x04,0xf2,0x76,0xd9,
152 0x3e,0x53,0xbf,0x02,0x91,0xf7,0xbe,0x3b,0x05,0xfc,0x38,0xd2,0x80,0x7b,0x5a,0x0c,
153 0xb0,0xe8,0xb1,0x56,0x39,0xac,0x16,0x42,0xc2,0x1c,0x57,0x10,0xbd,0xd3,0x98,0x36,
154 0xd0,0x50,0x98,0x2d,0xbb,0x0b,0xd6,0x51,0xf0,0x31,0x0c,0x4f,0xfc,0x0c,0xb2,0xf6,
155 0x81,0x54,0xd4,0x39,0x0d,0xad,0xb8,0x73,0xf0,0x2d,0x47,0x5b,0xa0,0x01,0xe9,0x7f,
156 0x96,0xeb,0xbe,0xba,0xa2,0x82,0xee,0x3a,0x0b,0x11,0xee,0x39,0x93,0xab,0x91,0x63,
157 0xa9,0x25,0x63,0x24,0xcc,0x1f,0x80,0x45,0x56,0xbd,0xb3,0x82,0x7f,0xb3,0x7e,0xd9,
158 0xd1,0xcd,0xd7,0x89,0x0c,0x36,0x88,0x52,0x35,0xbf,0x6c,0xed,0xb3,0xca,0x9c,0x79,
159 0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
160 };
161
162 //-------------------------------------------------------------------------------------------------
163 // Local Variables
164 //-------------------------------------------------------------------------------------------------
165
166 MSTHDMITX_REG_TYPE TxHdcpInitTbl[] =
167 {
168 {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_MODE_01, 0x8000, 0x8000}, // Enable HDCP encryption
169 {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x001C, 0x0000}, //[4]: 1: km new mode; 0: km old mode
170 };
171
172 MSTHDMITX_REG_TYPE TxHdcpEncryptOnTbl[] =
173 {
174 {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x0008, 0x0008},
175 };
176
177 MSTHDMITX_REG_TYPE TxHdcpEncryptOffTbl[] =
178 {
179 {HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x0008, 0x0000},
180 };
181
182 MS_U8 TxHdcpAnTbl[] =
183 {
184 0x03, 0x04, 0x07, 0x0C, 0x13, 0x1C, 0x27, 0x34,
185 };
186
187 MS_U32 sm_K160[4] =
188 {
189 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
190 };
191
192 MS_U32 sm_H160[SHA160LENGTH] =
193 {
194 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
195 };
196
197
198 //-------------------------------------------------------------------------------------------------
199 // Debug Functions
200 //-------------------------------------------------------------------------------------------------
201
202 //-------------------------------------------------------------------------------------------------
203 // Local Functions
204 //-------------------------------------------------------------------------------------------------
205
206 extern MS_BOOL MDrv_EEPROM_Read(MS_U32 u32Addr, MS_U8 *pu8Buf, MS_U32 u32Size);
207
Bytes2Word(MS_U8 const * pcBytes,MS_U32 * ruiWord)208 void Bytes2Word(MS_U8 const * pcBytes, MS_U32 * ruiWord)
209 {
210 *ruiWord = ((MS_U32) pcBytes[3])
211 | (((MS_U32) pcBytes[2]) << 8)
212 | (((MS_U32) pcBytes[1]) << 16)
213 | (((MS_U32) pcBytes[0]) << 24);
214 }
215
216 //#define Bytes2Word(pcBytes) (((MS_U32)pcBytes[3]) | (((MS_U32)pcBytes[2])<<8) | (( (MS_U32)pcBytes[1] )<<16) | (( (MS_U32)pcBytes[0] )<<24))
217
CircularShift(MS_U32 uiBits,MS_U32 uiWord)218 MS_U32 CircularShift(MS_U32 uiBits, MS_U32 uiWord)
219 {
220 return (uiWord << uiBits) | (uiWord >> (32 - uiBits));
221 }
222
Word2Bytes1(MS_U32 const * ruiWord,MS_U8 * pcBytes)223 void Word2Bytes1(MS_U32 const * ruiWord, MS_U8* pcBytes)
224 {
225 pcBytes += 3;
226 *pcBytes = *ruiWord & 0xff;
227 *--pcBytes = (*ruiWord >> 8) & 0xff;
228 *--pcBytes = (*ruiWord >> 16) & 0xff;
229 *--pcBytes = (*ruiWord >> 24) & 0xff;
230 }
231
Word2Bytes(MS_U32 const * ruiWord,MS_U8 * pcBytes)232 void Word2Bytes(MS_U32 const * ruiWord, MS_U8* pcBytes)
233 {
234 pcBytes += 3;
235 *pcBytes = (*ruiWord>>24) & 0xff;
236 *--pcBytes = (*ruiWord >> 16) & 0xff;
237 *--pcBytes = (*ruiWord >> 8) & 0xff;
238 *--pcBytes = (*ruiWord) & 0xff;
239 }
240
241
MHal_HDMITx_HdcpDebugEnable(MS_BOOL benable)242 void MHal_HDMITx_HdcpDebugEnable(MS_BOOL benable)
243 {
244 bDebugHDCPFlag = benable;
245 }
246
MHal_HDMITx_GetHdcpKey(MS_BOOL useinternalkey,MS_U8 * data)247 void MHal_HDMITx_GetHdcpKey(MS_BOOL useinternalkey, MS_U8 *data)
248 {
249 if(!useinternalkey)
250 {
251 memcpy(&HDCP_KEY[0], data, 304*sizeof(MS_U8));
252 {
253 MS_U16 i;
254
255 if(bDebugHDCPFlag)
256 {
257 printf("HDCP key = \n");
258 for(i=0;i<304;i++)
259 {
260 printf("0x%x, ", HDCP_KEY[i]);
261 if ((i - ((i>>4)<<4) == 0) && (i != 0x00))//(i%16 == 15)
262 printf("\n");
263 }
264 }
265 }
266 }
267 }
268
MHal_HDMITx_HdcpKeyInit(MS_BOOL useinternalkey)269 void MHal_HDMITx_HdcpKeyInit(MS_BOOL useinternalkey)
270 {
271 if(!useinternalkey)
272 {
273 MDrv_EEPROM_Read(0x00, HDCP_KEY, 304);
274 #if 1
275 {
276 MS_U16 i;
277
278 if(bDebugHDCPFlag)
279 {
280 printf("HDCP key = \n");
281 for(i=0;i<304;i++)
282 {
283 printf("0x%x, ", HDCP_KEY[i]);
284 if ((i - ((i>>4)<<4) == 0) && (i != 0x00))//(i%16 == 15)
285 printf("\n");
286 }
287 }
288
289 }
290 #endif
291 }
292 }
293
294
295 //******************************************************************************
296 //
297 // [Function Name]:
298 // TxHdcpInit
299 // [Description]:
300 // This routine is the initialization for HDCP module.
301 // [Arguments]:
302 // arg1: tx index
303 // [Return]:
304 // None
305 //
306 //*******************************************************************************
MHal_HDMITx_HdcpInit(void)307 void MHal_HDMITx_HdcpInit(void)
308 {
309 MS_U8 num;
310
311 num = sizeof(TxHdcpInitTbl) / sizeof(MSTHDMITX_REG_TYPE);
312 MHal_HDMITx_RegsTbl_Write(TxHdcpInitTbl, num);
313 }
314
315
316 //******************************************************************************
317 //
318 // [Function Name]:
319 // TxHdcpRxActive
320 // [Description]:
321 // This routine check the HDCP Rx active or not
322 // [Arguments]:
323 // arg1: tx index
324 // [Return]:
325 // FALSE: no HDCP Rx
326 // TRUE: HDCP Rx active
327 //
328 //*******************************************************************************
MHal_HDMITx_HdcpRxActive(void)329 MS_BOOL MHal_HDMITx_HdcpRxActive(void)
330 {
331 MS_U8 regval;
332
333 if (MHal_HDMITx_Rx74ReadByte(0x40, ®val) == TRUE)
334 {
335 if(regval != 0xFF)
336 return TRUE;
337 }
338 return FALSE;
339 }
340
341
342 //******************************************************************************
343 //
344 // [Function Name]:
345 // TxHdcpSetEncrypt
346 // [Description]:
347 // This routine set encryption for HDCP module.
348 // [Arguments]:
349 // arg1: tx index
350 // arg2: 0:disable 1:enable
351 // [Return]:
352 // None
353 //
354 //*******************************************************************************
MHal_HDMITx_HdcpSetEncrypt(MS_BOOL enable)355 void MHal_HDMITx_HdcpSetEncrypt(MS_BOOL enable)
356 {
357 switch (enable)
358 {
359 case 0:
360 MHal_HDMITx_RegsTbl_Write(TxHdcpEncryptOffTbl, 1);
361 break;
362 case 1:
363 MHal_HDMITx_RegsTbl_Write(TxHdcpEncryptOnTbl, 1);
364 break;
365 default:
366 break;
367 }
368 }
369
370
371 //******************************************************************************
372 //
373 // [Function Name]:
374 // TxHdcpCheckBksvLn
375 // [Description]:
376 // This routine check the HDCP Rx's BKSV and calculate the Key
377 // [Arguments]:
378 // arg1: tx index
379 // [Return]:
380 // TRUE: pass
381 // FALSE: fail
382 //
383 //*******************************************************************************
MHal_HDMITx_HdcpCheckBksvLn(void)384 MS_BOOL MHal_HDMITx_HdcpCheckBksvLn(void)
385 {
386 MS_U8 bksv[5] = {0}, Lm[7] = {0};
387 MS_U8 temp, carry_bit, seed;
388 MS_U8 i, j, k, t;
389 MS_U16 offset;
390
391 if(bDebugHDCPFlag)
392 printf("TxHdcpCheckBksvLn()\r\n");
393 // Check BKSV 20 bit1 20 bit0
394 k = 0;
395 for (t = 0; t < 10; t++)
396 {
397 for (i = 0; i < 5; i++)
398 {
399 if(MHal_HDMITx_Rx74ReadByte(i, &bksv[i]) == FALSE)
400 {
401 if(bDebugHDCPFlag)
402 printf("Reading BKSV failed because I2C\r\n");
403 return FALSE;
404 }
405 for (j = 0; j < 8; j++)
406 k += (bksv[i] >> j) & 0x01;
407
408 HDCP_BKSV[i] = bksv[i];
409 }
410 if (k == 20)
411 break;
412 MsOS_DelayTask(20);
413 k=0;
414 }
415
416 if(bDebugHDCPFlag)
417 {
418 printf("Bksv=");
419 for (i = 0; i < 5; i++)
420 printf("0x%x, ", bksv[i]);
421 printf("\r\n");
422 }
423
424 if (k != 20)
425 return FALSE;
426 for (i = 0; i < 7; i++)
427 Lm[i] = 0;
428
429 #if 0
430 for(i=0;i<18;i++)
431 {
432 for(j=0;j<16;j++)
433 {
434 if(HDCP_KEY[(i<<4)+j]!=MHal_HDMITx_Rx74ReadByte((i<<4)+j))
435 DBG_HDCP(printf("\r\nerror address=%x\r\n,",(i<<4)+j));
436 }
437 }
438 #endif
439
440 // Generate cipher infomation from Key & BKSV
441 for (i = 0; i < 5; i++)
442 for (j = 0; j < 8; j++)
443 {
444 //if(RxBksvTbl[4-i] & (1<<j))
445 if (bksv[i] & (1 << j))
446 {
447 carry_bit = 0;
448 offset = (i * 8 + j) * 7 + HDCP_KEY_OFFSET;
449 for (k = 0; k < 7; k++)
450 {
451 seed = (k + HDCP_KEY[7]) % 7;
452 temp = HDCP_KEY[offset + k] ^ HDCP_KEY[seed];
453 Lm[k] = Lm[k] + temp + carry_bit;
454 if (((carry_bit == 0) && (Lm[k] >= temp)) || ((carry_bit == 1) && (Lm[k] > temp)))
455 carry_bit = 0;
456 else
457 carry_bit = 1;
458 }
459 }
460 }
461 temp = HDCP_KEY[288];
462
463 if(bDebugHDCPFlag)
464 printf("Km= ");
465 for (i = 0; i < 7; i++)
466 {
467 if (i < 6)
468 Lm[i] = Lm[i] ^ temp;
469 else
470 Lm[i] = Lm[i] ^ (~temp);
471
472 if(i%2)
473 MHal_HDMITx_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_LN_04+(i/2), (Lm[i]<<8) | Lm[i-1]);
474 if(bDebugHDCPFlag)
475 printf("0x%x, ", Lm[i]);
476 }
477 if(bDebugHDCPFlag)
478 printf("\n");
479 MHal_HDMITx_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_LN_SEED_07, (temp<<8) | Lm[6]);
480 if(bDebugHDCPFlag)
481 printf("Seed=0x%x\r\n", temp);
482
483 return TRUE;
484 }
485
486
487 //******************************************************************************
488 //
489 // [Function Name]:
490 // TxHdcpWriteAn
491 // [Description]:
492 // This routine Write An to the HDCP Rx
493 // [Arguments]:
494 // arg1: tx index
495 // arg2: use internal An or not
496 // [Return]:
497 // None
498 //
499 //*******************************************************************************
MHal_HDMITx_HdcpWriteAn(MS_U8 internal)500 MS_BOOL MHal_HDMITx_HdcpWriteAn(MS_U8 internal)
501 {
502 MS_U16 temp;
503 MS_U8 i;
504
505 if (internal == 1)
506 {
507 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_MODE_01, 0x0100, 0x0100);
508 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, BIT1, BIT1);
509 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, BIT1, 0);
510
511 //Waiting for HW An Auto Gen Ready
512 MsOS_DelayTask(1);
513
514 if(bDebugHDCPFlag)
515 printf("Internal An=");
516 for (i = 0; i < 4; i++)
517 {
518 temp = MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_AN_08+i);
519 if(MHal_HDMITx_Rx74WriteByte(0x18 + (i*2), (MS_U8)(temp & 0x00FF)) == FALSE)
520 {
521 if(bDebugHDCPFlag)
522 printf("Writing An failed because I2C\r\n");
523 return FALSE;
524 }
525 if(MHal_HDMITx_Rx74WriteByte(0x18 + (i*2+1), (MS_U8)((temp & 0xFF00)>>8)) == FALSE)
526 {
527 if(bDebugHDCPFlag)
528 printf("Writing An failed because I2C\r\n");
529 return FALSE;
530 }
531 if(bDebugHDCPFlag)
532 {
533 printf("0x%x, ", temp & 0x00FF);
534 printf("0x%x, ", (temp & 0xFF00)>>8);
535 }
536 }
537 if(bDebugHDCPFlag)
538 printf("\r\n");
539 }
540 else
541 {
542 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_MODE_01, 0x0100, 0x0000);
543 for(i = 0; i < 4; i++)
544 MHal_HDMITx_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_AN_08+i, (TxHdcpAnTbl[2*i+1] <<8) | (TxHdcpAnTbl[2*i]));
545 if(MHal_HDMITx_Rx74WriteBytes(0x18, 8, TxHdcpAnTbl) == FALSE)
546 {
547 if(bDebugHDCPFlag)
548 printf("Writing An failed because I2C\r\n");
549 return FALSE;
550 }
551 if(bDebugHDCPFlag)
552 {
553 printf("External An=");
554 for (i = 0; i < 8; i++)
555 printf("0x%x, ", TxHdcpAnTbl[i]);
556 printf("\r\n");
557 }
558 }
559 return TRUE;
560 }
561
562
563 //******************************************************************************
564 //
565 // [Function Name]:
566 // TxHdcpWriteAksv
567 // [Description]:
568 // This routine Write AKSV to the HDCP Rx
569 // [Arguments]:
570 // arg1: tx index
571 // [Return]:
572 // None
573 //
574 //*******************************************************************************
MHal_HDMITx_HdcpWriteAksv(void)575 MS_BOOL MHal_HDMITx_HdcpWriteAksv(void)
576 {
577 MS_U8 temp;
578 MS_U8 i, k, j;
579
580 if(bDebugHDCPFlag)
581 printf("Aksv=");
582 for (i = 0, k=0; i < 5; i++)
583 {
584 //temp = TxHdcpKeyTbl[i];
585 temp = HDCP_KEY[i];
586 HDCP_AKSV[i] = temp;
587 if(MHal_HDMITx_Rx74WriteByte(0x10 + i, temp) == FALSE)
588 {
589 if(bDebugHDCPFlag)
590 printf("Writing Aksv failed because I2C\r\n");
591 return FALSE;
592 }
593 for (j = 0; j < 8; j++)
594 k += (temp >> j) & 0x01; // check AKSV whether is 20 zeros and 20 ones or not.
595 if(bDebugHDCPFlag)
596 printf("0x%x, ", temp);
597 }
598 if(bDebugHDCPFlag)
599 printf("\r\n");
600 if(k!=20) return FALSE;
601 return TRUE;
602 }
603
604
605 //******************************************************************************
606 //
607 // [Function Name]:
608 // MHal_HDMITx_GET74
609 // [Description]:
610 // This routine get data from 74reg
611 // [Arguments]:
612 //
613 // [Return]:
614 // None
615 //
616 //*******************************************************************************
MHal_HDMITx_GET74(MS_U8 udata,MS_U8 * pdata)617 void MHal_HDMITx_GET74(MS_U8 udata, MS_U8 *pdata)
618 {
619 if(udata == 0x00)
620 memcpy(pdata, &HDCP_BKSV, 5*sizeof(MS_U8));
621 else if(udata == 0x10)
622 memcpy(pdata, &HDCP_AKSV, 5*sizeof(MS_U8));
623 }
624
625
626 //******************************************************************************
627 //
628 // [Function Name]:
629 // TxHdcpStartCipher
630 // [Description]:
631 // This routine Start HDCP Tx Cipher
632 // [Arguments]:
633 // arg1: tx index
634 // [Return]:
635 // None
636 //
637 //*******************************************************************************
MHal_HDMITx_HdcpStartCipher(void)638 void MHal_HDMITx_HdcpStartCipher(void)
639 {
640 MS_U8 count = 0xFF;
641
642 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, 0);
643 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, BIT0);
644 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, 0);
645
646 while (count-- && !(MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02) & BIT8));
647 if (count == 0)
648 {
649 if(bDebugHDCPFlag)
650 printf("Cipher not done!!!\r\n");
651 }
652 }
653
654
655 //******************************************************************************
656 //
657 // [Function Name]:
658 // TxHdcpAuthPass
659 // [Description]:
660 // This routine finish the authentication
661 // [Arguments]:
662 // arg1: tx index
663 // [Return]:
664 // None
665 //
666 //*******************************************************************************
MHal_HDMITx_HdcpAuthPass(void)667 void MHal_HDMITx_HdcpAuthPass(void)
668 {
669 MHal_HDMITx_Mask_Write(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_COMMAND_02, 0x000F, 0x000C);
670 }
671
672
MHal_HDMITx_HdcpSha1Init(SHA1_DATA * dig)673 void MHal_HDMITx_HdcpSha1Init(SHA1_DATA *dig)
674 {
675 MS_U8 i;
676
677 for (i = 0; i < SHA160LENGTH; i++)
678 dig->m_auiBuf[i] = sm_H160[i];
679 dig->m_auiBits[0] = 0;
680 dig->m_auiBits[1] = 0;
681 memset(dig->m_aucIn, 0, BLOCKSIZE) ; // 2006/1/18 3:31PM by Emily
682 }
683
684
685 //******************************************************************************
686 //
687 // [Function Name]:
688 // TxHdcpCheckRi
689 // [Description]:
690 // This routine check the hdcp Ri values
691 // [Arguments]:
692 // arg1: tx index
693 // arg2: output Tx Ri value
694 // arg3: output Rx Ri value
695 // [Return]:
696 // None
697 //
698 //*******************************************************************************
MHal_HDMITx_HdcpCheckRi(MS_U16 * ptx_ri,MS_U16 * prx_ri)699 MS_BOOL MHal_HDMITx_HdcpCheckRi(MS_U16 *ptx_ri, MS_U16 *prx_ri)
700 {
701 *ptx_ri = MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_RI_00);
702 if(MHal_HDMITx_Rx74ReadBytes(0x08, 2, (MS_U8 *)prx_ri) == TRUE)
703 {
704 if (*prx_ri == *ptx_ri)
705 return TRUE;
706 }
707 if(MHal_HDMITx_Rx74ReadBytes(0x08, 2, (MS_U8 *)prx_ri) == TRUE)
708 {
709 if (*prx_ri == *ptx_ri)
710 return TRUE;
711 }
712 *ptx_ri = MHal_HDMITx_Read(HDMITX_HDCP_REG_BASE, REG_HDCP_TX_RI_00);
713 if (*prx_ri == *ptx_ri)
714 return TRUE;
715 else
716 return FALSE;
717 }
718
719
_MHal_HDMITx_HdcpSha1Transform(SHA1_DATA * dig)720 void _MHal_HDMITx_HdcpSha1Transform(SHA1_DATA *dig)
721 {
722 MS_U8 * pucIn = dig->m_aucIn;
723 MS_U32 auiW[80];
724 MS_U8 i;
725 MS_U32 temp;
726 MS_U32 A, B, C, D, E;
727
728 for (i = 0; i < 16; i++,pucIn += 4)
729 auiW[i] = ((MS_U32)pucIn[3]) | ((MS_U32)pucIn[2] << 8) |
730 ((MS_U32)pucIn[1] << 16) | ((MS_U32)pucIn[0] << 24);
731 for (i = 16; i < 80; i++)
732 auiW[i] = ((auiW[i - 3] ^ auiW[i - 8] ^ auiW[i - 14] ^ auiW[i - 16]) << 1) |
733 ((auiW[i - 3] ^ auiW[i - 8] ^ auiW[i - 14] ^ auiW[i - 16]) >> 31);
734
735 A = dig->m_auiBuf[0];
736 B = dig->m_auiBuf[1];
737 C = dig->m_auiBuf[2];
738 D = dig->m_auiBuf[3];
739 E = dig->m_auiBuf[4];
740
741 for (i = 0; i < 20; i++)
742 {
743 temp = ((A << 5) | (A >> 27)) + ((B & C) | ((~B) & D)) + E + auiW[i] + sm_K160[0];
744 E = D;
745 D = C;
746 C = (B << 30) | (B >> 2);
747 B = A;
748 A = temp;
749 }
750 for (i = 20; i < 40; i++)
751 {
752 temp = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + auiW[i] + sm_K160[1];
753 E = D;
754 D = C;
755 C = (B << 30) | (B >> 2);
756 B = A;
757 A = temp;
758 }
759 for (i = 40; i < 60; i++)
760 {
761 temp = ((A << 5) | (A >> 27)) + ((B & C) | (B & D) | (C & D)) + E + auiW[i] + sm_K160[2];
762 E = D;
763 D = C;
764 C = (B << 30) | (B >> 2);
765 B = A;
766 A = temp;
767 }
768 for (i = 60; i < 80; i++)
769 {
770 temp = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + auiW[i] + sm_K160[3];
771 E = D;
772 D = C;
773 C = (B << 30) | (B >> 2);
774 B = A;
775 A = temp;
776 }
777 dig->m_auiBuf[0] += A;
778 dig->m_auiBuf[1] += B;
779 dig->m_auiBuf[2] += C;
780 dig->m_auiBuf[3] += D;
781 dig->m_auiBuf[4] += E;
782 }
783
784
MHal_HDMITx_HdcpSha1AddData(SHA1_DATA * dig,MS_U8 const * pcData,MS_U16 iDataLength)785 void MHal_HDMITx_HdcpSha1AddData(SHA1_DATA *dig, MS_U8 const * pcData, MS_U16 iDataLength)
786 {
787 MS_U32 uiT;
788
789 //Update bitcount
790 uiT = dig->m_auiBits[0];
791 if ((dig->m_auiBits[0] = uiT + ((MS_U32) iDataLength << 3)) < uiT)
792 dig->m_auiBits[1]++; //Carry from low to high
793 //dig->m_auiBits[1] += ((MS_U32) iDataLength) >> 29; //Fix coverity impact : iDataLength >> 29 is 0
794 uiT = (uiT >> 3) & (BLOCKSIZE - 1); //Bytes already
795 //Handle any leading odd-sized chunks
796 if (uiT != 0)
797 {
798 MS_U8 * puc = (MS_U8 *) dig->m_aucIn + uiT;
799 uiT = BLOCKSIZE - uiT;
800 if (iDataLength < uiT)
801 {
802 memcpy(puc, pcData, iDataLength);
803 return;
804 }
805 memcpy(puc, pcData, uiT);
806 _MHal_HDMITx_HdcpSha1Transform(dig);
807 pcData += uiT;
808 iDataLength -= uiT;
809 }
810 //Process data in 64-byte chunks
811 while (iDataLength >= BLOCKSIZE)
812 {
813 memcpy(dig->m_aucIn, pcData, BLOCKSIZE);
814 _MHal_HDMITx_HdcpSha1Transform(dig);
815 pcData += BLOCKSIZE;
816 iDataLength -= BLOCKSIZE;
817 }
818 //Handle any remaining bytes of data
819 memcpy(dig->m_aucIn, pcData, iDataLength);
820 }
821
822
MHal_HDMITx_HdcpSha1FinalDigest(SHA1_DATA * dig,MS_U8 * pcDigest)823 void MHal_HDMITx_HdcpSha1FinalDigest(SHA1_DATA *dig, MS_U8* pcDigest)
824 {
825 MS_U16 uiCount;
826 MS_U8 *puc;
827 MS_U8 i;
828
829 //Compute number of bytes mod 64
830 uiCount = (dig->m_auiBits[0] >> 3) & (BLOCKSIZE - 1);
831 //Set the first char of padding to 0x80. This is safe since there is
832 //always at least one byte free
833 puc = dig->m_aucIn + uiCount;
834 *puc++ = 0x80;
835 //Bytes of padding needed to make 64 bytes
836 uiCount = BLOCKSIZE - uiCount - 1;
837
838 //Pad out to 56 mod 64
839 if (uiCount < 8)
840 {
841 //Two lots of padding: Pad the first block to 64 bytes
842 memset(puc, 0, uiCount);
843 _MHal_HDMITx_HdcpSha1Transform(dig);
844 //Now fill the next block with 56 bytes
845 memset(dig->m_aucIn, 0, BLOCKSIZE - 8);
846 }
847 else
848 {
849 //Pad block to 56 bytes
850 memset(puc, 0, uiCount - 8);
851 }
852
853 //Append length in bits and transform
854 Word2Bytes1(&dig->m_auiBits[1], &dig->m_aucIn[BLOCKSIZE - 8]);
855 Word2Bytes1(&dig->m_auiBits[0], &dig->m_aucIn[BLOCKSIZE - 4]);
856 _MHal_HDMITx_HdcpSha1Transform(dig);
857
858 for (i = 0; i < SHA160LENGTH; i++,pcDigest += 4)
859 Word2Bytes(&dig->m_auiBuf[i], pcDigest);
860 }
861
862
863 // ************* For customer NDS **************//
864
MHal_HDMITx_HDCP_Get_BCaps(MS_U8 * u8bcaps)865 MS_BOOL MHal_HDMITx_HDCP_Get_BCaps(MS_U8 *u8bcaps)
866 {
867 return (MHal_HDMITx_Rx74ReadByte(0x40, u8bcaps));
868 }
869
MHal_HDMITx_HDCP_Get_BStatus(MS_U16 * u16bstatus)870 MS_BOOL MHal_HDMITx_HDCP_Get_BStatus(MS_U16 *u16bstatus)
871 {
872 MS_U8 u8data1 = 0x0;
873 MS_U8 u8data2 = 0x0;
874 MS_BOOL ret = TRUE;
875
876 if(!MHal_HDMITx_Rx74ReadByte(0x42, &u8data2) || !MHal_HDMITx_Rx74ReadByte(0x41, &u8data1))
877 ret = FALSE;
878 *u16bstatus = ((MS_U16) u8data2<< 8) | u8data1;
879 return ret;
880 }
881
MHal_HDMITx_HDCP_Get_BKSV(MS_U8 * u8bksv)882 MS_BOOL MHal_HDMITx_HDCP_Get_BKSV(MS_U8 *u8bksv)
883 {
884 MS_U8 i;
885 MS_BOOL ret = TRUE;
886
887 for(i=0; i<5; i++)
888 {
889 if(!MHal_HDMITx_Rx74ReadByte(0x00+i, u8bksv+i))
890 ret = FALSE;
891 }
892 return ret;
893 }
894
MHal_HDMITx_HDCP_SHA1_Transform(unsigned int * sha1,const MS_U8 * s)895 void MHal_HDMITx_HDCP_SHA1_Transform(unsigned int *sha1, const MS_U8 *s)
896 {
897 SHA1_DATA tdig;
898
899 MHal_HDMITx_HdcpSha1Init(&tdig);
900 // MS_U32 M[2], w[16]
901 // w[0]=M[0];
902 // w[1]=M[1];
903 // w[2]=0x80000000;
904 // 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;
905 // w[14]=0;w[15]=0x00000040;
906 memcpy(&tdig.m_aucIn[0], s, 8*sizeof(MS_U8)); // The first 8 bytes are copy from message
907 tdig.m_aucIn[8] = 0x80; // append the bit "1" and K = 439 bits "0" to the message
908 memset(&tdig.m_aucIn[9], 0, 54*sizeof(MS_U8));
909 tdig.m_aucIn[63] = 0x40; // apppend length of message, 64 bytes
910
911 _MHal_HDMITx_HdcpSha1Transform(&tdig);
912 memcpy(sha1, &tdig.m_auiBuf[0], 5*sizeof(MS_U32));
913 //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]);
914 }
915
916 // ************* end **************//
917
918