xref: /utopia/UTPA2-700.0.x/modules/ipauth/drv/ipauth/drvIPAUTH.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 //  Copyright (c) 2008-2009 MStar Semiconductor, Inc.
80 //  All rights reserved.
81 //
82 //  [Module Name]:
83 //      drvIPAUTH.c
84 //  [Abstract]:
85 //      This module contains code for Data Security .
86 //  [Author(s)]:
87 //      Hank Kuo
88 //  [Reversion History]:
89 //      Initial release:    15 Aprial, 2009
90 //
91 //  [Doxygen]
92 /// @file drvIPAUTH.h
93 /// @brief Subroutine for sound effect
94 /// @author MStarSemi Inc.
95 //*******************************************************************************
96 #define _DRVIPAUTH_C
97 
98 //------------------------------------------------------------------------------
99 // Header Files
100 //------------------------------------------------------------------------------
101 #include "ULog.h"
102 #include "MsCommon.h"
103 #include "MsVersion.h"
104 #include "drvIPAUTH.h"
105 #ifdef MSOS_TYPE_LINUX_KERNEL
106 #include <linux/string.h>
107 #else
108 #include <string.h>
109 #endif
110 
111 #ifndef _DRV_SYS_H_
112 #include "drvSYS.h"
113 #endif
114 
115 #define S_11 7
116 #define S_12 12
117 #define S_13 17
118 #define S_14 22
119 #define S_21 5
120 #define S_22 9
121 #define S_23 14
122 #define S_24 20
123 #define S_31 4
124 #define S_32 11
125 #define S_33 16
126 #define S_34 23
127 #define S_41 6
128 #define S_42 10
129 #define S_43 15
130 #define S_44 21
131 
132 #define IPAUTH_LOGD(fmt,...)  //printf(fmt, ##__VA_ARGS__)
133 typedef MS_U8 *POINTER;
134 
135 // MD5 context.
136 typedef struct
137 {
138     MS_U32 state[4];        //state (ABCD)
139     MS_U32 count[2];        //number of bits, modulo 2^64 (lsb first)
140     MS_U8 buffer[64];       //input buffer
141 } MD5_CTX;
142 
143 
144 static MS_U8 IPAuthState = 0;
145 static MS_U8 DolbyVersionState = 0;
146 static MS_U8 IPControl[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
147 
148 static MS_U8 gCusID[] = {0x00,0x00};
149 static MS_U8 gCusHash[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150                      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
151 
152 static void MDrv_AUTH_MD5Transform (MS_U32 [4], MS_U8 [64]);
153 static void MDrv_AUTH_Encode (MS_U8 *, MS_U32 *, MS_U16);
154 static void MDrv_AUTH_Decode (MS_U32 *, MS_U8 *, MS_U16);
155 static void MDrv_AUTH_MD5_memcpy (POINTER, POINTER, MS_U16);
156 static void MDrv_AUTH_MD5_memset (POINTER, MS_S32, MS_U16);
157 static void MDrv_AUTH_MDString (MS_U8 *, MS_U8 *, MS_U8 *);
158 static MS_U8 MDrv_AUTH_Char2Int(MS_U8 c);
159 
160 static void MDrv_AUTH_MD5Init (MD5_CTX *);
161 static void MDrv_AUTH_MD5Update (MD5_CTX *context, MS_U8 *input, MS_U16 inputLen);
162 static void MDrv_AUTH_MD5Final (MS_U8 [16], MD5_CTX *);
163 
164 static MS_U8 CONTEXT_PADDING[64] =
165 {
166     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
169 };
170 
171 static MSIF_Version _drv_ipauth_version = {
172     .MW = { IPAUTH_VER },
173 };
174 
175 #define ROTATION_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
176 
177 #define P(x, y, z) (((x) & (y)) | ((~x) & (z)))
178 #define Q(x, y, z) (((x) & (z)) | ((y) & (~z)))
179 #define R(x, y, z) ((x) ^ (y) ^ (z))
180 #define S(x, y, z) ((y) ^ ((x) | (~z)))
181 
182 #define PP(a, b, c, d, x, s, ac) { \
183     (a) += P ((b), (c), (d)) + (x) + (MS_U32)(ac); \
184     (a) = ROTATION_LEFT ((a), (s)); (a) += (b); \
185 }
186 #define QQ(a, b, c, d, x, s, ac) { \
187     (a) += Q ((b), (c), (d)) + (x) + (MS_U32)(ac); \
188     (a) = ROTATION_LEFT ((a), (s)); (a) += (b); \
189 }
190 #define RR(a, b, c, d, x, s, ac) { \
191     (a) += R ((b), (c), (d)) + (x) + (MS_U32)(ac); \
192     (a) = ROTATION_LEFT ((a), (s)); (a) += (b); \
193 }
194 #define SS(a, b, c, d, x, s, ac) { \
195     (a) += S ((b), (c), (d)) + (x) + (MS_U32)(ac); \
196     (a) = ROTATION_LEFT ((a), (s)); (a) += (b); \
197 }
198 
199 extern MS_U16 MDrv_SYS_GetChipID(void);
200 extern MS_BOOL MDrv_SYS_Init(void);
201 static MS_BOOL  g_bInitShmFlag = FALSE;
202 ST_IPAUTH_SHARED_VARS * g_IpAuthVars = NULL;
203 #ifndef MSOS_TYPE_LINUX
204 ST_IPAUTH_SHARED_VARS   g_ipauthShared;
205 #endif
206 
207 extern MS_U32 UtopiaSetIPAUTH(ST_IPAUTH_SHARED_VARS *IpControl, MS_U8 *gCusID, MS_U8 *gCusHush);
208 extern void MDrv_SYS_GetDolbyKeyCustomer (MS_U8 *key);
209 //static MS_U8 Dolbybits[] = {11,12,13,14,17,56,57,80,81,82,83,84};
210 static MS_U8 DolbyInvalid[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFD,0x87,0xFF};
211 
212 
213 
214 //-------------------------------------------------------------------------------------------------
215 //  Global Functions
216 //-------------------------------------------------------------------------------------------------
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// @brief \b Function \b Name: MDrv_AUTH_MD5Init()
220 /// @brief \b Function \b Description: MD5 initialization. Begins an MD5 operation, writing a new context.
221 /// @param <IN>        \b NONE    :
222 /// @param <OUT>       \b NONE    :
223 /// @param <RET>       \b NONE    :
224 /// @param <GLOBAL>    \b NONE    :
225 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MD5Init(MD5_CTX * context)226 void MDrv_AUTH_MD5Init(MD5_CTX *context)
227 {
228     context->count[0] = context->count[1] = 0;
229     /* Load magic initialization constants.*/
230     //context->state[0] = 0x67452301;
231     //context->state[1] = 0xefcdab89;
232     //context->state[2] = 0x98badcfe;
233     //context->state[3] = 0x10325476;
234     context->state[0] = 0xc6f75b28;
235     context->state[1] = 0x6b2ccf94;
236     context->state[2] = 0xdaff678b;
237     context->state[3] = 0x4518c0e8;
238 }
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 /// @brief \b Function \b Name: MDrv_AUTH_MD5Update()
242 /// @brief \b Function \b Description:  MD5 block update operation. Continues an MD5 message-digest
243 ///                                                   operation, processing another message block, and updating the
244 ///                                                   context.
245 /// @param <IN>        \b NONE    :
246 /// @param <OUT>       \b NONE    :
247 /// @param <RET>       \b NONE    :
248 /// @param <GLOBAL>    \b NONE    :
249 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MD5Update(MD5_CTX * context,MS_U8 * input,MS_U16 inputLen)250 void MDrv_AUTH_MD5Update (MD5_CTX *context, MS_U8 *input, MS_U16 inputLen)
251 {
252     MS_U16 i, index, partLen;
253 
254     // Compute number of bytes mod 64
255     index = (MS_U16)((context->count[0] >> 3) & 0x3F);
256 
257     // Update number of bits
258     if ((context->count[0] += ((MS_U32)inputLen << 3))
259      < ((MS_U32)inputLen << 3))
260         context->count[1]++;
261     context->count[1] += ((MS_U32)inputLen >> 29);
262 
263     partLen = 64 - index;
264 
265     // Transform as many times as possible.
266     if (inputLen >= partLen)
267     {
268         MDrv_AUTH_MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
269         MDrv_AUTH_MD5Transform (context->state, context->buffer);
270 
271         for (i = partLen; i + 63 < inputLen; i += 64)
272             MDrv_AUTH_MD5Transform (context->state, &input[i]);
273 
274         index = 0;
275     }
276     else
277         i = 0;
278 
279     // Buffer remaining input
280     MDrv_AUTH_MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
281 }
282 
283 // MD5 finalization. Ends an MD5 message-digest operation, writing the
284 // the message digest and zeroizing the context.
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// @brief \b Function \b Name: MDrv_AUTH_MD5Final()
288 /// @brief \b Function \b Description: This routine is the initialization for KTV sound effect module.
289 /// @param <IN>        \b NONE    :
290 /// @param <OUT>       \b NONE    :
291 /// @param <RET>       \b NONE    :
292 /// @param <GLOBAL>    \b NONE    :
293 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MD5Final(MS_U8 digest[16],MD5_CTX * context)294 void MDrv_AUTH_MD5Final(MS_U8 digest[16], MD5_CTX *context)
295 {
296     MS_U8 bits[8];
297     MS_U16 index, padLen;
298 
299     // Save number of bits
300     MDrv_AUTH_Encode (bits, context->count, 8);
301 
302     // Pad out to 56 mod 64.
303     index = (MS_U16)((context->count[0] >> 3) & 0x3f);
304     padLen = (index < 56) ? (56 - index) : (120 - index);
305     MDrv_AUTH_MD5Update (context, CONTEXT_PADDING, padLen);
306 
307     // Append length (before padding)
308     MDrv_AUTH_MD5Update (context, bits, 8);
309 
310     // Store state in digest
311     MDrv_AUTH_Encode (digest, context->state, 16);
312 
313     // Zeroize sensitive information.
314     MDrv_AUTH_MD5_memset ((POINTER)context, 0, sizeof (*context));
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// @brief \b Function \b Name: MDrv_AUTH_MD5Transform()
319 /// @brief \b Function \b Description: MD5 basic transformation. Transforms state based on block.
320 /// @param <IN>        \b NONE    :
321 /// @param <OUT>       \b NONE    :
322 /// @param <RET>       \b NONE    :
323 /// @param <GLOBAL>    \b NONE    :
324 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MD5Transform(MS_U32 state[4],MS_U8 block[64])325 static void MDrv_AUTH_MD5Transform(MS_U32 state[4], MS_U8 block[64])
326 {
327     MS_U32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
328     MS_U8 i;
329 
330     for(i=0;i<=15;i++)
331     {
332         x[i] = 0;
333     }
334 
335     MDrv_AUTH_Decode (x, block, 64);
336 
337     // 1st Round
338     PP (a, b, c, d, x[ 0], S_11, 0xd76aa478);
339     PP (d, a, b, c, x[ 1], S_12, 0xe8c7b756);
340     PP (c, d, a, b, x[ 2], S_13, 0x242070db);
341     PP (b, c, d, a, x[ 3], S_14, 0xc1bdceee);
342     PP (a, b, c, d, x[ 4], S_11, 0xf57c0faf);
343     PP (d, a, b, c, x[ 5], S_12, 0x4787c62a);
344     PP (c, d, a, b, x[ 6], S_13, 0xa8304613);
345     PP (b, c, d, a, x[ 7], S_14, 0xfd469501);
346     PP (a, b, c, d, x[ 8], S_11, 0x698098d8);
347     PP (d, a, b, c, x[ 9], S_12, 0x8b44f7af);
348     PP (c, d, a, b, x[10], S_13, 0xffff5bb1);
349     PP (b, c, d, a, x[11], S_14, 0x895cd7be);
350     PP (a, b, c, d, x[12], S_11, 0x6b901122);
351     PP (d, a, b, c, x[13], S_12, 0xfd987193);
352     PP (c, d, a, b, x[14], S_13, 0xa679438e);
353     PP (b, c, d, a, x[15], S_14, 0x49b40821);
354 
355     // 2nd Round
356     QQ (a, b, c, d, x[ 1], S_21, 0xf61e2562);
357     QQ (d, a, b, c, x[ 6], S_22, 0xc040b340);
358     QQ (c, d, a, b, x[11], S_23, 0x265e5a51);
359     QQ (b, c, d, a, x[ 0], S_24, 0xe9b6c7aa);
360     QQ (a, b, c, d, x[ 5], S_21, 0xd62f105d);
361     QQ (d, a, b, c, x[10], S_22,  0x2441453);
362     QQ (c, d, a, b, x[15], S_23, 0xd8a1e681);
363     QQ (b, c, d, a, x[ 4], S_24, 0xe7d3fbc8);
364     QQ (a, b, c, d, x[ 9], S_21, 0x21e1cde6);
365     QQ (d, a, b, c, x[14], S_22, 0xc33707d6);
366     QQ (c, d, a, b, x[ 3], S_23, 0xf4d50d87);
367     QQ (b, c, d, a, x[ 8], S_24, 0x455a14ed);
368     QQ (a, b, c, d, x[13], S_21, 0xa9e3e905);
369     QQ (d, a, b, c, x[ 2], S_22, 0xfcefa3f8);
370     QQ (c, d, a, b, x[ 7], S_23, 0x676f02d9);
371     QQ (b, c, d, a, x[12], S_24, 0x8d2a4c8a);
372 
373     // 3rd Round
374     RR (a, b, c, d, x[ 5], S_31, 0xfffa3942);
375     RR (d, a, b, c, x[ 8], S_32, 0x8771f681);
376     RR (c, d, a, b, x[11], S_33, 0x6d9d6122);
377     RR (b, c, d, a, x[14], S_34, 0xfde5380c);
378     RR (a, b, c, d, x[ 1], S_31, 0xa4beea44);
379     RR (d, a, b, c, x[ 4], S_32, 0x4bdecfa9);
380     RR (c, d, a, b, x[ 7], S_33, 0xf6bb4b60);
381     RR (b, c, d, a, x[10], S_34, 0xbebfbc70);
382     RR (a, b, c, d, x[13], S_31, 0x289b7ec6);
383     RR (d, a, b, c, x[ 0], S_32, 0xeaa127fa);
384     RR (c, d, a, b, x[ 3], S_33, 0xd4ef3085);
385     RR (b, c, d, a, x[ 6], S_34,  0x4881d05);
386     RR (a, b, c, d, x[ 9], S_31, 0xd9d4d039);
387     RR (d, a, b, c, x[12], S_32, 0xe6db99e5);
388     RR (c, d, a, b, x[15], S_33, 0x1fa27cf8);
389     RR (b, c, d, a, x[ 2], S_34, 0xc4ac5665);
390 
391     // 4th Round
392     SS (a, b, c, d, x[ 0], S_41, 0xf4292244);
393     SS (d, a, b, c, x[ 7], S_42, 0x432aff97);
394     SS (c, d, a, b, x[14], S_43, 0xab9423a7);
395     SS (b, c, d, a, x[ 5], S_44, 0xfc93a039);
396     SS (a, b, c, d, x[12], S_41, 0x655b59c3);
397     SS (d, a, b, c, x[ 3], S_42, 0x8f0ccc92);
398     SS (c, d, a, b, x[10], S_43, 0xffeff47d);
399     SS (b, c, d, a, x[ 1], S_44, 0x85845dd1);
400     SS (a, b, c, d, x[ 8], S_41, 0x6fa87e4f);
401     SS (d, a, b, c, x[15], S_42, 0xfe2ce6e0);
402     SS (c, d, a, b, x[ 6], S_43, 0xa3014314);
403     SS (b, c, d, a, x[13], S_44, 0x4e0811a1);
404     SS (a, b, c, d, x[ 4], S_41, 0xf7537e82);
405     SS (d, a, b, c, x[11], S_42, 0xbd3af235);
406     SS (c, d, a, b, x[ 2], S_43, 0x2ad7d2bb);
407     SS (b, c, d, a, x[ 9], S_44, 0xeb86d391);
408 
409     state[0] += a;
410     state[1] += b;
411     state[2] += c;
412     state[3] += d;
413 
414     // Zeroize sensitive information.
415     MDrv_AUTH_MD5_memset ((POINTER)x, 0, sizeof (x));
416 }
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// @brief \b Function \b Name: MDrv_AUTH_Encode()
420 /// @brief \b Function \b Description: Encodes input (MS_U32) into output (MS_U8).
421 ///                                    Assumes len is a multiple of 4.
422 /// @param <IN>        \b NONE    :
423 /// @param <OUT>       \b NONE    :
424 /// @param <RET>       \b NONE    :
425 /// @param <GLOBAL>    \b NONE    :
426 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_Encode(MS_U8 * output,MS_U32 * input,MS_U16 len)427 static void MDrv_AUTH_Encode(MS_U8 *output, MS_U32 *input, MS_U16 len)
428 {
429     MS_U16 i, j;
430 
431     for (i = 0, j = 0; j < len; i++, j += 4)
432     {
433         output[j] = (MS_U8)(input[i] & 0xff);
434         output[j+1] = (MS_U8)((input[i] >> 8) & 0xff);
435         output[j+2] = (MS_U8)((input[i] >> 16) & 0xff);
436         output[j+3] = (MS_U8)((input[i] >> 24) & 0xff);
437     }
438 }
439 
440 ////////////////////////////////////////////////////////////////////////////////
441 /// @brief \b Function \b Name: MDrv_AUTH_Decode()
442 /// @brief \b Function \b Description: Decodes input (MS_U8) into output (MS_U32).
443 /// Assumes len is a multiple of 4.
444 /// @param <IN>        \b NONE    :
445 /// @param <OUT>       \b NONE    :
446 /// @param <RET>       \b NONE    :
447 /// @param <GLOBAL>    \b NONE    :
448 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_Decode(MS_U32 * output,MS_U8 * input,MS_U16 len)449 static void MDrv_AUTH_Decode(MS_U32 *output, MS_U8 *input, MS_U16 len)
450 {
451     MS_U16 i, j;
452 
453     for (i = 0, j = 0; j < len; i++, j += 4)
454         output[i] = ((MS_U32)input[j]) | (((MS_U32)input[j+1]) << 8) |
455             (((MS_U32)input[j+2]) << 16) | (((MS_U32)input[j+3]) << 24);
456 }
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 /// @brief \b Function \b Name: MDrv_AUTH_MD5_memcpy()
460 /// @brief \b Function \b Description: Replace "for loop" with standard memcpy if possible.
461 /// @param <IN>        \b NONE    :
462 /// @param <OUT>       \b NONE    :
463 /// @param <RET>       \b NONE    :
464 /// @param <GLOBAL>    \b NONE    :
465 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MD5_memcpy(POINTER output,POINTER input,MS_U16 len)466 static void MDrv_AUTH_MD5_memcpy(POINTER output, POINTER input, MS_U16 len)
467 {
468     MS_U16 i;
469 
470     for (i = 0; i < len; i++)
471         output[i] = input[i];
472 }
473 
474 // Note: Replace "for loop" with standard memset if possible.
475 
476 ////////////////////////////////////////////////////////////////////////////////
477 /// @brief \b Function \b Name: MDrv_AUTH_MD5_memset()
478 /// @brief \b Function \b Description:
479 /// @param <IN>        \b NONE    :
480 /// @param <OUT>       \b NONE    :
481 /// @param <RET>       \b NONE    :
482 /// @param <GLOBAL>    \b NONE    :
483 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MD5_memset(POINTER output,MS_S32 value,MS_U16 len)484 static void MDrv_AUTH_MD5_memset(POINTER output, MS_S32 value, MS_U16 len)
485 {
486     MS_U16 i;
487 
488     for (i = 0; i < len; i++)
489         ((char *)output)[i] = (char)value;
490 }
491 
492 ////////////////////////////////////////////////////////////////////////////////
493 /// @brief \b Function \b Name: MDrv_AUTH_MDString()
494 /// @brief \b Function \b Description:
495 /// @param <IN>        \b NONE    :
496 /// @param <OUT>       \b NONE    :
497 /// @param <RET>       \b NONE    :
498 /// @param <GLOBAL>    \b NONE    :
499 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_MDString(MS_U8 * string,MS_U8 * digest,MS_U8 * key)500 void MDrv_AUTH_MDString(MS_U8 *string, MS_U8 *digest, MS_U8 *key)
501 {
502     MD5_CTX context;
503     MS_U16 len = strlen ((char*)string);
504     MDrv_AUTH_MD5Init (&context);
505 
506     context.state[0] = key[0]+key[1]*256+key[2]*256*256+key[3]*256*256*256;
507     context.state[1] = key[4]+key[5]*256+key[6]*256*256+key[7]*256*256*256;
508     context.state[2] = key[8]+key[9]*256+key[10]*256*256+key[11]*256*256*256;
509     context.state[3] = key[12]+key[13]*256+key[14]*256*256+key[15]*256*256*256;
510 
511     MDrv_AUTH_MD5Update (&context, string, len);
512     MDrv_AUTH_MD5Final (digest, &context);
513 }
514 
515 ////////////////////////////////////////////////////////////////////////////////
516 /// @brief \b Function \b Name: MApi_AUTH_Process()
517 /// @brief \b Function \b Description: This routine is the initialization for KTV sound effect module.
518 /// @param <IN>        \b NONE    :
519 /// @param <OUT>       \b NONE    :
520 /// @param <RET>       \b NONE    :
521 /// @param <GLOBAL>    \b NONE    :
522 ////////////////////////////////////////////////////////////////////////////////
MApi_AUTH_Process(MS_U8 * string,MS_U8 * hash)523 void MApi_AUTH_Process(MS_U8 *string, MS_U8 *hash)
524 {
525     MS_U8 digest[16];
526     MS_U16 customerid;
527     MS_U16 modelid;
528     MS_U16 chipid;
529     MS_U32 dolbyversion;
530     MS_U32 dolbycontrol;
531     MS_U32 reverse;
532     MS_U8 chiptype;
533     MS_U8 KeyCustomer[17] = {0x28,0x5b,0xf7,0xc6,0x94,0xcf,0x2c,0x6b,0x8b,0x67,0xff,0xda,0xe8,0xc0,0x18,0x45,0x00};
534     MS_S32 n, i;
535     ST_AES_CONTEXT ctx;
536     //MS_U8 buf[17] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
537     MS_U8 buf[17] = {0x65,0x85,0x68,0xba,0xcb,0xee,0x16,0xc7,0x3c,0x30,0xe8,0xb5,0x44,0x0b,0x95,0x3a};
538     MS_U8 enkey[17] = {0x4d,0x53,0x54,0x41,0x52,0x53,0x45,0x4d,0x49,0x24,0x44,0x4f,0x4c,0x42,0x59,0x23,0x00};//MSTARSEMI$DOLBY#
539     MS_U8 authmode = 0;
540     char t[49];
541 
542     MDrv_AUTH_InitialVars();
543     MDrv_SYS_Init();
544 
545     IPAUTH_LOGD("string len:%d\n",(MS_S32)strlen((char*)string));
546 
547     if(strlen((char*)string) == 80)
548     {
549        strncpy(t, (char*)string + 16, 32);
550        t[32] = 0;
551        IPAUTH_LOGD("%s\n", t);
552        if(strcmp(t,"00000000000000000000000000000000")==0)
553        {
554           IPAUTH_LOGD("128bit\n");
555           strncpy(t, (char*)string, 16);
556           strncpy(t+16, (char*)string+48, 32);
557           t[48] = 0;
558           strncpy((char*)string, t, 49);
559        }
560     }
561 
562     IPAUTH_LOGD("\n");
563     dolbycontrol = MDrv_SYS_QueryDolbyHashInfo(E_SYS_DOLBY_CONTROL_BIT);
564     IPAUTH_LOGD("E_SYS_DOLBY_CONTROL_BIT:%4x\n",dolbycontrol);
565     chiptype = MDrv_SYS_GetChipType();
566     IPAUTH_LOGD("GetChipType:%x\n",chiptype);
567     reverse = MDrv_SYS_QueryDolbyHashInfo(E_SYS_DOLBY_REVERSE_BIT);
568     IPAUTH_LOGD("E_SYS_DOLBY_REVERSE_BIT:%4x\n",reverse);
569 
570     if(dolbycontrol == 1 && chiptype == 1 && reverse == 0)
571     {
572         MDrv_SYS_GetDolbyKeyCustomer(buf);
573         IPAUTH_LOGD("enKeyCustomer: ");
574         for(i=0; i<16; i++)
575         {
576            IPAUTH_LOGD("%x ",buf[i]);
577         }
578         IPAUTH_LOGD("\n");
579 
580         n = 0;
581         MDrv_AUTH_AES_Set_Key( &ctx, enkey, 128 + n * 64 );
582         MDrv_AUTH_AES_Decrypt( &ctx, buf, buf );
583         IPAUTH_LOGD("decrypted keycustome:");
584         for(i=0; i<16; i++)
585         {
586            IPAUTH_LOGD("%x ",buf[i]);
587            KeyCustomer[i] = buf[i];
588         }
589         IPAUTH_LOGD("\n");
590         authmode = 1;
591     }
592     else
593     {
594         IPAUTH_LOGD("dkeycustome:");
595         for(i=0; i<16; i++)
596         {
597            IPAUTH_LOGD("%x ",KeyCustomer[i]);
598         }
599         IPAUTH_LOGD("\n");
600     }
601 
602     IPAUTH_LOGD("string:%s\n",string);
603 
604     IPAUTH_LOGD("hash:");
605     for(i=0; i<16; i++)
606     {
607        IPAUTH_LOGD("%02x ",hash[i]);
608     }
609     IPAUTH_LOGD("\n");
610 
611     for(i=0;i<16;i++)
612     {
613         digest[i] = 0;   // fix the coverity issue
614     }
615 
616     MDrv_AUTH_MDString (string, digest, KeyCustomer);
617 
618     IPAUTH_LOGD("digest:");
619     for(i=0; i<16; i++)
620     {
621        IPAUTH_LOGD("%02x ",digest[i]);
622     }
623     IPAUTH_LOGD("\n");
624 
625     IPAuthState = 1;
626 
627     for(i=0;i<16;i++)
628     {
629         gCusHash[i] = hash[i];
630     }
631 
632     for(i=0;i<16;i++)
633     {
634         if(digest[i]!=hash[i])
635         {
636             IPAuthState = 0;
637             ULOGI("IPAUTH","Wrong hash key\n");
638             break;
639         }
640     }
641 
642     customerid = (MDrv_AUTH_Char2Int(string[0])<<12) + (MDrv_AUTH_Char2Int(string[1])<<8) + (MDrv_AUTH_Char2Int(string[2])<<4) + MDrv_AUTH_Char2Int(string[3]);
643     modelid = (MDrv_AUTH_Char2Int(string[4])<<12) + (MDrv_AUTH_Char2Int(string[5])<<8) + (MDrv_AUTH_Char2Int(string[6])<<4) + MDrv_AUTH_Char2Int(string[7]);
644     chipid = (MDrv_AUTH_Char2Int(string[8])<<12) + (MDrv_AUTH_Char2Int(string[9])<<8) + (MDrv_AUTH_Char2Int(string[10])<<4) + MDrv_AUTH_Char2Int(string[11]);
645     dolbyversion = (MDrv_AUTH_Char2Int(string[14])<<4) + MDrv_AUTH_Char2Int(string[15]);
646 
647     gCusID[0] = (MDrv_AUTH_Char2Int(string[0])<<4) + MDrv_AUTH_Char2Int(string[1]);
648     gCusID[1] = (MDrv_AUTH_Char2Int(string[2])<<4) + MDrv_AUTH_Char2Int(string[3]);
649 
650     ULOGI("IPAUTH","\n%04x%04x%04x\n",customerid,modelid,chipid);
651 
652     if((chipid != 0x6666) && (chipid != 0x6667))
653     {
654         if(chipid != MDrv_SYS_GetChipID())
655         {
656             IPAuthState = 0;
657             ULOGI("IPAUTH","MDrv_SYS_GetChipID:%x\n",MDrv_SYS_GetChipID());
658             ULOGI("IPAUTH","Wrong Chip ID\n");
659         }
660         if(authmode == 1)
661         {
662             if(dolbyversion != MDrv_SYS_QueryDolbyHashInfo(E_SYS_DOLBY_VERSION))
663             {
664                 DolbyVersionState = 1;
665                 ULOGI("IPAUTH","Wrong Dolby Version\n");
666             }
667         }
668     }
669 
670     if(IPAuthState != 0)
671     {
672         ULOGI("IPAUTH","Auth OK\n");
673         if(strlen((char*)string) == 48)
674         {
675             for(i=0 ;i<16; i++)
676             {
677                 g_IpAuthVars->g_IpControl[i] = 0;
678             }
679 
680             for(i=16 ;i<32; i++)
681             {
682                 IPControl[i] = (MDrv_AUTH_Char2Int(string[16 + (i-16)*2])<<4) + MDrv_AUTH_Char2Int(string[16 + (i-16)*2 + 1]);
683                 g_IpAuthVars->g_IpControl[i] = (MDrv_AUTH_Char2Int(string[16 + (i-16)*2])<<4) + MDrv_AUTH_Char2Int(string[16 + (i-16)*2 + 1]);
684             }
685             if(DolbyVersionState == 1)
686             {
687                 for(i=0 ;i<32; i++)
688                 {
689                     IPControl[i] = IPControl[i]&DolbyInvalid[i];
690                     g_IpAuthVars->g_IpControl[i] = IPControl[i];
691                 }
692             }
693         }
694         else {
695             for(i=0 ;i<32; i++)
696             {
697                 IPControl[i] = (MDrv_AUTH_Char2Int(string[16 + i*2])<<4) + MDrv_AUTH_Char2Int(string[16 + i*2 + 1]);
698                 g_IpAuthVars->g_IpControl[i] = (MDrv_AUTH_Char2Int(string[16 + i*2])<<4) + MDrv_AUTH_Char2Int(string[16 + i*2 + 1]);
699             }
700             if(DolbyVersionState == 1)
701             {
702                 for(i=0 ;i<32; i++)
703                 {
704                     IPControl[i] = IPControl[i]&DolbyInvalid[i];
705                     g_IpAuthVars->g_IpControl[i] = IPControl[i];
706                 }
707             }
708         }
709     }
710     else
711     {
712         ULOGI("IPAUTH","Auth NG\n");
713         for(i=0 ;i<32; i++)
714         {
715             IPControl[i] = 0;
716             g_IpAuthVars->g_IpControl[i] = 0;
717         }
718     }
719 
720     IPAUTH_LOGD("\n");
721 
722     IPAUTH_LOGD("IPCheck:");
723     for(i=0;i<256;i++)
724     {
725        if(MDrv_AUTH_IPCheck(i)==0) IPAUTH_LOGD("%d ",0);
726     	 else IPAUTH_LOGD("%d ",1);
727     }
728 
729     IPAUTH_LOGD("\n");
730 #ifdef CONFIG_UTOPIA_FRAMEWORK_KERNEL_DRIVER
731     UtopiaSetIPAUTH(g_IpAuthVars, gCusID, gCusHash);
732 #endif
733 }
734 
735 
736 ////////////////////////////////////////////////////////////////////////////////
737 /// @brief \b Function \b Name: MApi_AUTH_State()
738 /// @brief \b Function \b Description: This routine is for returning AUTH state.
739 /// @param <IN>        \b NONE    :
740 /// @param <OUT>       \b NONE    :
741 /// @param <RET>       \b NONE    :
742 /// @param <GLOBAL>    \b NONE    :
743 ////////////////////////////////////////////////////////////////////////////////
MApi_AUTH_State(void)744 MS_U8 MApi_AUTH_State(void)
745 {
746     return IPAuthState;
747 }
748 
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// @brief \b Function \b Name: MDrv_AUTH_Char2Int()
752 /// @brief \b Function \b Description:
753 /// @param <IN>        \b NONE    :
754 /// @param <OUT>       \b NONE    :
755 /// @param <RET>       \b NONE    :
756 /// @param <GLOBAL>    \b NONE    :
757 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_Char2Int(MS_U8 c)758 MS_U8 MDrv_AUTH_Char2Int(MS_U8 c)
759 {
760     if(c>=0x61) c = c-0x57;
761     else if( c > 0x39) c = c - 0x37;
762     else c = c-0x30;
763 
764     return (MS_U8)c;
765 }
766 
767 ////////////////////////////////////////////////////////////////////////////////
768 /// @brief \b Function \b Name: MDrv_AUTH_IPCheck()
769 /// @brief \b Function \b Description:
770 /// @param <IN>        \b NONE    :
771 /// @param <OUT>       \b NONE    :
772 /// @param <RET>       \b NONE    :
773 /// @param <GLOBAL>    \b NONE    :
774 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_IPCheck(MS_U8 u8Bit)775 MS_U8 MDrv_AUTH_IPCheck(MS_U8 u8Bit)
776 {
777     MS_U8 rval;
778 
779     MDrv_AUTH_InitialVars();
780 
781     if (g_IpAuthVars == NULL)
782     {
783         ULOGI("IPAUTH","%s() : invalid g_IpAuthVars!\n", __FUNCTION__);
784         return 0;
785     }
786 
787     //rval = IPControl[15 - u8Bit/8] & (1<< (u8Bit % 8));
788     //rval = g_IpAuthVars->g_IpControl[15 - u8Bit/8] & (1<< (u8Bit % 8));
789     rval = g_IpAuthVars->g_IpControl[31 - u8Bit/8] & (1<< (u8Bit % 8));
790     if (rval) rval = 1;
791 
792     if(u8Bit == IPAUTH_CONTROL_VIDEO_H264)
793     {
794         //rval = 1;
795         if(MDrv_SYS_Query(E_SYS_QUERY_H264_SUPPORTED) == FALSE)
796         {
797             rval = 0;
798         }
799     }
800     else if(u8Bit == IPAUTH_CONTROL_XC_DVBC)
801     {
802         rval = 1;
803         if(MDrv_SYS_Query(E_SYS_QUERY_DVBC_SUPPORTED) == FALSE)
804         {
805             rval = 0;
806         }
807     }
808     return rval;
809 }
810 
811 ////////////////////////////////////////////////////////////////////////////////
812 /// @brief \b Function \b Name: MApp_IPAUTH_GetLibVer()
813 /// @brief \b Function \b Description:
814 /// @param <IN>        \b NONE    :
815 /// @param <OUT>       \b NONE    :
816 /// @param <RET>       \b NONE    :
817 /// @param <GLOBAL>    \b NONE    :
818 ////////////////////////////////////////////////////////////////////////////////
MApp_IPAUTH_GetLibVer(const MSIF_Version ** ppVersion)819 MS_BOOL MApp_IPAUTH_GetLibVer(const MSIF_Version **ppVersion)
820 {
821     if (!ppVersion)
822         return false;
823     *ppVersion = &_drv_ipauth_version;
824     return true;
825 }
826 
827 ////////////////////////////////////////////////////////////////////////////////
828 /// @brief \b Function \b Name: MDrv_AUTH_InitialVars()
829 /// @brief \b Function \b Description: This routine set ip control share memory.
830 /// @param <IN>        \b NONE    :
831 /// @param <OUT>       \b NONE    :
832 /// @param <RET>       \b NONE    :
833 /// @param <GLOBAL>    \b NONE    :
834 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_InitialVars(void)835 MS_BOOL MDrv_AUTH_InitialVars(void)
836 {
837     if (g_IpAuthVars == NULL)
838     {
839         g_IpAuthVars = MDrv_AUTH_AllocateVars();
840         if (g_IpAuthVars == NULL)
841         {
842             return FALSE;
843         }
844     }
845     return TRUE;
846 }
847 
848 ////////////////////////////////////////////////////////////////////////////////
849 /// @brief \b Function \b Name: MDrv_AUTH_AllocateVars()
850 /// @brief \b Function \b Description: This routine allocate ip control share memory.
851 /// @param <IN>        \b NONE    :
852 /// @param <OUT>       \b NONE    :
853 /// @param <RET>       \b NONE    :
854 /// @param <GLOBAL>    \b NONE    :
855 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_AllocateVars(void)856 ST_IPAUTH_SHARED_VARS * MDrv_AUTH_AllocateVars(void)
857 {
858     ST_IPAUTH_SHARED_VARS * pIPAUTHShared = NULL;
859 
860 #ifdef MSOS_TYPE_LINUX
861     MS_U32 u32ShmId = 0;
862     MS_VIRT u32Addr = 0;
863     MS_U32 u32BufSize = 0;
864 
865 //    MsOS_SHM_Init();
866     if (MsOS_SHM_GetId((MS_U8 *)IPAUTH_SHM_NAME, sizeof(ST_IPAUTH_SHARED_VARS), &u32ShmId, &u32Addr, &u32BufSize, MSOS_SHM_QUERY) == TRUE)
867     {
868         pIPAUTHShared = (ST_IPAUTH_SHARED_VARS *) u32Addr;
869 
870         if (pIPAUTHShared->g_u32ClientCounter == 0)
871         {
872             IPAUTH_LOGD("reset IP AUTH SHM data ...\n");
873             MDrv_AUTH_ResetDefaultVars(pIPAUTHShared);
874         }
875     }
876     else
877     {
878         IPAUTH_LOGD("create IP AUTH SHM data ...\n");
879 
880         if (MsOS_SHM_GetId((MS_U8 *)IPAUTH_SHM_NAME, sizeof(ST_IPAUTH_SHARED_VARS), &u32ShmId, &u32Addr, &u32BufSize, MSOS_SHM_CREATE) == TRUE)
881         {
882             IPAUTH_LOGD("Ip auth SHM data is created\n");
883             pIPAUTHShared = (ST_IPAUTH_SHARED_VARS *) u32Addr;
884 
885             IPAUTH_LOGD("reset Ip auth SHM data ...\n");
886             MDrv_AUTH_ResetDefaultVars(pIPAUTHShared);
887         }
888         else
889         {
890             IPAUTH_LOGD("IPAUTH SHM allocation failed!\n");
891             return NULL;
892         }
893     }
894 
895     if (g_bInitShmFlag == FALSE)
896     {
897         g_bInitShmFlag = TRUE;
898         pIPAUTHShared->g_u32ClientCounter++;
899     }
900 #else
901     pIPAUTHShared = &g_ipauthShared;
902 
903     if (g_bInitShmFlag == FALSE)
904     {
905         IPAUTH_LOGD("create Ipauth SHM data ...\n");
906         g_bInitShmFlag = TRUE;
907 
908         MDrv_AUTH_ResetDefaultVars(pIPAUTHShared);
909 
910         pIPAUTHShared->g_u32ClientCounter++;
911     }
912 #endif
913 
914     return pIPAUTHShared;
915 }
916 
917 ////////////////////////////////////////////////////////////////////////////////
918 /// @brief \b Function \b Name: MDrv_AUTH_ResetDefaultVars()
919 /// @brief \b Function \b Description: This routine reset ip control share memory.
920 /// @param <IN>        \b NONE    :
921 /// @param <OUT>       \b NONE    :
922 /// @param <RET>       \b NONE    :
923 /// @param <GLOBAL>    \b NONE    :
924 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_ResetDefaultVars(ST_IPAUTH_SHARED_VARS * pIPAUTHShared)925 MS_BOOL MDrv_AUTH_ResetDefaultVars(ST_IPAUTH_SHARED_VARS * pIPAUTHShared)
926 {
927     if (pIPAUTHShared == NULL)
928     {
929         return FALSE;
930     }
931     memset(pIPAUTHShared, 0x00, sizeof(ST_IPAUTH_SHARED_VARS));
932     return TRUE;
933 }
934 
935 ////////////////////////////////////////////////////////////////////////////////
936 /// @brief \b Function \b Name: MDrv_AUTH_GetHashInfo()
937 /// @brief \b Function \b Description: This routine reports hashinfo for audit.
938 /// @param <IN>        \b NONE    :
939 /// @param <OUT>       \b NONE    :
940 /// @param <RET>       \b NONE    :
941 /// @param <GLOBAL>    \b NONE    :
942 ////////////////////////////////////////////////////////////////////////////////
MDrv_AUTH_GetHashInfo(MS_U8 * hashinfo)943 void MDrv_AUTH_GetHashInfo (MS_U8 *hashinfo)
944 {
945     int i;
946     hashinfo[0] = gCusID[0];
947     hashinfo[1] = gCusID[1];
948 
949     for(i=0;i<16;i++)
950     {
951         hashinfo[i+2] = gCusHash[i];
952     }
953 }
954 
955 ////////////////////////////////////////////////////////////////////////////////
956 /// AES function
957 ////////////////////////////////////////////////////////////////////////////////
958 static MS_U32 MS_AUTH_FSb[256];
959 static MS_U32 MS_AUTH_FT0[256];
960 static MS_U32 MS_AUTH_FT1[256];
961 static MS_U32 MS_AUTH_FT2[256];
962 static MS_U32 MS_AUTH_FT3[256];
963 
964 /* reverse S-box & tables */
965 
966 static MS_U32 MS_AUTH_RSb[256];
967 static MS_U32 MS_AUTH_RT0[256];
968 static MS_U32 MS_AUTH_RT1[256];
969 static MS_U32 MS_AUTH_RT2[256];
970 static MS_U32 MS_AUTH_RT3[256];
971 
972 /* round constants */
973 
974 static MS_U32 MS_AUTH_RCON[10];
975 
976 /* tables generation flag */
977 
978 static MS_S32 do_init = 1;
979 
980 /* tables generation routine */
981 
982 #define MS_AUTH_XTIME(a) ( ( ( 0x80 & a ) ? 0x1B : 0x00 ) ^ ( a << 1 ) )
983 #define MS_AUTH_MUL(a,b) ( !( a && b ) ? 0 : pow[(log[a] + log[b]) % 255])
984 #define MS_AUTH_ROTR8(a) ( ( ( 0xFFFFFFFF & a ) >>  8 ) | ( 0xFFFFFFFF & ( a << 24 ) ) )
985 
MDrv_AUTH_AES_Gen_Tables(void)986 void MDrv_AUTH_AES_Gen_Tables( void )
987 {
988     MS_S32 i;
989     MS_U8 x, y;
990     MS_U8 pow[256];
991     MS_U8 log[256];
992 
993     /* compute pow and log tables over GF(2^8) */
994 
995     for( i = 0, x = 1; i < 256; i++, x ^= MS_AUTH_XTIME( x ) )
996     {
997         pow[i] = x;
998         log[x] = i;
999     }
1000 
1001     /* calculate the round constants */
1002 
1003     for( i = 0, x = 1; i < 10; i++, x = MS_AUTH_XTIME( x ) )
1004     {
1005         MS_AUTH_RCON[i] = (MS_U32) x << 24;
1006     }
1007 
1008     /* generate the forward and reverse S-boxes */
1009 
1010     MS_AUTH_FSb[0x00] = 0x63;
1011     MS_AUTH_RSb[0x63] = 0x00;
1012 
1013     for( i = 1; i < 256; i++ )
1014     {
1015         x = pow[255 - log[i]];
1016 
1017         y = x;  y = ( y << 1 ) | ( y >> 7 );
1018         x ^= y; y = ( y << 1 ) | ( y >> 7 );
1019         x ^= y; y = ( y << 1 ) | ( y >> 7 );
1020         x ^= y; y = ( y << 1 ) | ( y >> 7 );
1021         x ^= y ^ 0x63;
1022 
1023         MS_AUTH_FSb[i] = x;
1024         MS_AUTH_RSb[x] = i;
1025     }
1026 
1027     /* generate the forward and reverse tables */
1028 
1029     for( i = 0; i < 256; i++ )
1030     {
1031         x = (MS_U8) MS_AUTH_FSb[i]; y = MS_AUTH_XTIME( x );
1032 
1033         MS_AUTH_FT0[i] =   (MS_U32) ( x ^ y ) ^
1034                  ( (MS_U32) x <<  8 ) ^
1035                  ( (MS_U32) x << 16 ) ^
1036                  ( (MS_U32) y << 24 );
1037 
1038         MS_AUTH_FT0[i] &= 0xFFFFFFFF;
1039 
1040         MS_AUTH_FT1[i] = MS_AUTH_ROTR8( MS_AUTH_FT0[i] );
1041         MS_AUTH_FT2[i] = MS_AUTH_ROTR8( MS_AUTH_FT1[i] );
1042         MS_AUTH_FT3[i] = MS_AUTH_ROTR8( MS_AUTH_FT2[i] );
1043 
1044         y = (MS_U8) MS_AUTH_RSb[i];
1045 
1046         MS_AUTH_RT0[i] = ( (MS_U32) MS_AUTH_MUL( 0x0B, y )       ) ^
1047                  ( (MS_U32) MS_AUTH_MUL( 0x0D, y ) <<  8 ) ^
1048                  ( (MS_U32) MS_AUTH_MUL( 0x09, y ) << 16 ) ^
1049                  ( (MS_U32) MS_AUTH_MUL( 0x0E, y ) << 24 );
1050 
1051         MS_AUTH_RT0[i] &= 0xFFFFFFFF;
1052 
1053         MS_AUTH_RT1[i] = MS_AUTH_ROTR8( MS_AUTH_RT0[i] );
1054         MS_AUTH_RT2[i] = MS_AUTH_ROTR8( MS_AUTH_RT1[i] );
1055         MS_AUTH_RT3[i] = MS_AUTH_ROTR8( MS_AUTH_RT2[i] );
1056     }
1057 }
1058 
1059 /* platform-independant 32-bit integer manipulation macros */
1060 
1061 #define GET_UINT32(n,b,i)                       \
1062 {                                               \
1063     (n) = ( (MS_U32) (b)[(i)    ] << 24 )       \
1064         | ( (MS_U32) (b)[(i) + 1] << 16 )       \
1065         | ( (MS_U32) (b)[(i) + 2] <<  8 )       \
1066         | ( (MS_U32) (b)[(i) + 3]       );      \
1067 }
1068 
1069 #define PUT_UINT32(n,b,i)                       \
1070 {                                               \
1071     (b)[(i)    ] = (MS_U8) ( (n) >> 24 );       \
1072     (b)[(i) + 1] = (MS_U8) ( (n) >> 16 );       \
1073     (b)[(i) + 2] = (MS_U8) ( (n) >>  8 );       \
1074     (b)[(i) + 3] = (MS_U8) ( (n)       );       \
1075 }
1076 
1077 /* decryption key schedule tables */
1078 
1079 static MS_S32 KT_init = 1;
1080 
1081 static MS_U32 MS_AUTH_KT0[256];
1082 static MS_U32 MS_AUTH_KT1[256];
1083 static MS_U32 MS_AUTH_KT2[256];
1084 static MS_U32 MS_AUTH_KT3[256];
1085 
1086 /* AES key scheduling routine */
1087 
MDrv_AUTH_AES_Set_Key(ST_AES_CONTEXT * ctx,MS_U8 * key,MS_S32 nbits)1088 MS_S32 MDrv_AUTH_AES_Set_Key( ST_AES_CONTEXT *ctx, MS_U8 *key, MS_S32 nbits )
1089 {
1090     MS_S32 i;
1091     MS_U32 *RK, *SK;
1092 
1093     if( do_init )
1094     {
1095         MDrv_AUTH_AES_Gen_Tables();
1096 
1097         do_init = 0;
1098     }
1099 
1100     switch( nbits )
1101     {
1102         case 128: ctx->nr = 10; break;
1103         case 192: ctx->nr = 12; break;
1104         case 256: ctx->nr = 14; break;
1105         default : return( 1 );
1106     }
1107 
1108     RK = ctx->erk;
1109 
1110     for( i = 0; i < (nbits >> 5); i++ )
1111     {
1112         GET_UINT32( RK[i], key, i * 4 );
1113     }
1114 
1115     /* setup encryption round keys */
1116 
1117     switch( nbits )
1118     {
1119     case 128:
1120 
1121         for( i = 0; i < 10; i++, RK += 4 )
1122         {
1123             RK[4]  = RK[0] ^ MS_AUTH_RCON[i] ^
1124                         ( MS_AUTH_FSb[ (MS_U8) ( RK[3] >> 16 ) ] << 24 ) ^
1125                         ( MS_AUTH_FSb[ (MS_U8) ( RK[3] >>  8 ) ] << 16 ) ^
1126                         ( MS_AUTH_FSb[ (MS_U8) ( RK[3]       ) ] <<  8 ) ^
1127                         ( MS_AUTH_FSb[ (MS_U8) ( RK[3] >> 24 ) ]       );
1128 
1129             RK[5]  = RK[1] ^ RK[4];
1130             RK[6]  = RK[2] ^ RK[5];
1131             RK[7]  = RK[3] ^ RK[6];
1132         }
1133         break;
1134 
1135     case 192:
1136 
1137         for( i = 0; i < 8; i++, RK += 6 )
1138         {
1139             RK[6]  = RK[0] ^ MS_AUTH_RCON[i] ^
1140                         ( MS_AUTH_FSb[ (MS_U8) ( RK[5] >> 16 ) ] << 24 ) ^
1141                         ( MS_AUTH_FSb[ (MS_U8) ( RK[5] >>  8 ) ] << 16 ) ^
1142                         ( MS_AUTH_FSb[ (MS_U8) ( RK[5]       ) ] <<  8 ) ^
1143                         ( MS_AUTH_FSb[ (MS_U8) ( RK[5] >> 24 ) ]       );
1144 
1145             RK[7]  = RK[1] ^ RK[6];
1146             RK[8]  = RK[2] ^ RK[7];
1147             RK[9]  = RK[3] ^ RK[8];
1148             RK[10] = RK[4] ^ RK[9];
1149             RK[11] = RK[5] ^ RK[10];
1150         }
1151         break;
1152 
1153     case 256:
1154 
1155         for( i = 0; i < 7; i++, RK += 8 )
1156         {
1157             RK[8]  = RK[0] ^ MS_AUTH_RCON[i] ^
1158                         ( MS_AUTH_FSb[ (MS_U8) ( RK[7] >> 16 ) ] << 24 ) ^
1159                         ( MS_AUTH_FSb[ (MS_U8) ( RK[7] >>  8 ) ] << 16 ) ^
1160                         ( MS_AUTH_FSb[ (MS_U8) ( RK[7]       ) ] <<  8 ) ^
1161                         ( MS_AUTH_FSb[ (MS_U8) ( RK[7] >> 24 ) ]       );
1162 
1163             RK[9]  = RK[1] ^ RK[8];
1164             RK[10] = RK[2] ^ RK[9];
1165             RK[11] = RK[3] ^ RK[10];
1166 
1167             RK[12] = RK[4] ^
1168                         ( MS_AUTH_FSb[ (MS_U8) ( RK[11] >> 24 ) ] << 24 ) ^
1169                         ( MS_AUTH_FSb[ (MS_U8) ( RK[11] >> 16 ) ] << 16 ) ^
1170                         ( MS_AUTH_FSb[ (MS_U8) ( RK[11] >>  8 ) ] <<  8 ) ^
1171                         ( MS_AUTH_FSb[ (MS_U8) ( RK[11]       ) ]       );
1172 
1173             RK[13] = RK[5] ^ RK[12];
1174             RK[14] = RK[6] ^ RK[13];
1175             RK[15] = RK[7] ^ RK[14];
1176         }
1177         break;
1178     }
1179 
1180     /* setup decryption round keys */
1181 
1182     if( KT_init )
1183     {
1184         for( i = 0; i < 256; i++ )
1185         {
1186             MS_AUTH_KT0[i] = MS_AUTH_RT0[ MS_AUTH_FSb[i] ];
1187             MS_AUTH_KT1[i] = MS_AUTH_RT1[ MS_AUTH_FSb[i] ];
1188             MS_AUTH_KT2[i] = MS_AUTH_RT2[ MS_AUTH_FSb[i] ];
1189             MS_AUTH_KT3[i] = MS_AUTH_RT3[ MS_AUTH_FSb[i] ];
1190         }
1191 
1192         KT_init = 0;
1193     }
1194 
1195     SK = ctx->drk;
1196 
1197     *SK++ = *RK++;
1198     *SK++ = *RK++;
1199     *SK++ = *RK++;
1200     *SK++ = *RK++;
1201 
1202     for( i = 1; i < ctx->nr; i++ )
1203     {
1204         RK -= 8;
1205 
1206         *SK++ = MS_AUTH_KT0[ (MS_U8) ( *RK >> 24 ) ] ^
1207                 MS_AUTH_KT1[ (MS_U8) ( *RK >> 16 ) ] ^
1208                 MS_AUTH_KT2[ (MS_U8) ( *RK >>  8 ) ] ^
1209                 MS_AUTH_KT3[ (MS_U8) ( *RK       ) ]; RK++;
1210 
1211         *SK++ = MS_AUTH_KT0[ (MS_U8) ( *RK >> 24 ) ] ^
1212                 MS_AUTH_KT1[ (MS_U8) ( *RK >> 16 ) ] ^
1213                 MS_AUTH_KT2[ (MS_U8) ( *RK >>  8 ) ] ^
1214                 MS_AUTH_KT3[ (MS_U8) ( *RK       ) ]; RK++;
1215 
1216         *SK++ = MS_AUTH_KT0[ (MS_U8) ( *RK >> 24 ) ] ^
1217                 MS_AUTH_KT1[ (MS_U8) ( *RK >> 16 ) ] ^
1218                 MS_AUTH_KT2[ (MS_U8) ( *RK >>  8 ) ] ^
1219                 MS_AUTH_KT3[ (MS_U8) ( *RK       ) ]; RK++;
1220 
1221         *SK++ = MS_AUTH_KT0[ (MS_U8) ( *RK >> 24 ) ] ^
1222                 MS_AUTH_KT1[ (MS_U8) ( *RK >> 16 ) ] ^
1223                 MS_AUTH_KT2[ (MS_U8) ( *RK >>  8 ) ] ^
1224                 MS_AUTH_KT3[ (MS_U8) ( *RK       ) ]; RK++;
1225     }
1226 
1227     RK -= 8;
1228 
1229     *SK++ = *RK++;
1230     *SK++ = *RK++;
1231     *SK++ = *RK++;
1232     *SK++ = *RK++;
1233 
1234     return( 0 );
1235 }
1236 
1237 /* AES 128-bit block encryption routine */
1238 
MDrv_AUTH_AES_Encrypt(ST_AES_CONTEXT * ctx,MS_U8 input[16],MS_U8 output[16])1239 void MDrv_AUTH_AES_Encrypt( ST_AES_CONTEXT *ctx, MS_U8 input[16], MS_U8 output[16] )
1240 {
1241     MS_U32 *RK, A0, A1, A2, A3, B0, B1, B2, B3;
1242 
1243     RK = ctx->erk;
1244 
1245     GET_UINT32( A0, input,  0 ); A0 ^= RK[0];
1246     GET_UINT32( A1, input,  4 ); A1 ^= RK[1];
1247     GET_UINT32( A2, input,  8 ); A2 ^= RK[2];
1248     GET_UINT32( A3, input, 12 ); A3 ^= RK[3];
1249 
1250 #define MS_AUTH_AES_FRND(A0,A1,A2,A3,B0,B1,B2,B3)     \
1251 {                                               \
1252     RK += 4;                                    \
1253                                                 \
1254     A0 = RK[0] ^ MS_AUTH_FT0[ (MS_U8) ( B0 >> 24 ) ] ^  \
1255                  MS_AUTH_FT1[ (MS_U8) ( B1 >> 16 ) ] ^  \
1256                  MS_AUTH_FT2[ (MS_U8) ( B2 >>  8 ) ] ^  \
1257                  MS_AUTH_FT3[ (MS_U8) ( B3       ) ];   \
1258                                                 \
1259     A1 = RK[1] ^ MS_AUTH_FT0[ (MS_U8) ( B1 >> 24 ) ] ^  \
1260                  MS_AUTH_FT1[ (MS_U8) ( B2 >> 16 ) ] ^  \
1261                  MS_AUTH_FT2[ (MS_U8) ( B3 >>  8 ) ] ^  \
1262                  MS_AUTH_FT3[ (MS_U8) ( B0       ) ];   \
1263                                                 \
1264     A2 = RK[2] ^ MS_AUTH_FT0[ (MS_U8) ( B2 >> 24 ) ] ^  \
1265                  MS_AUTH_FT1[ (MS_U8) ( B3 >> 16 ) ] ^  \
1266                  MS_AUTH_FT2[ (MS_U8) ( B0 >>  8 ) ] ^  \
1267                  MS_AUTH_FT3[ (MS_U8) ( B1       ) ];   \
1268                                                 \
1269     A3 = RK[3] ^ MS_AUTH_FT0[ (MS_U8) ( B3 >> 24 ) ] ^  \
1270                  MS_AUTH_FT1[ (MS_U8) ( B0 >> 16 ) ] ^  \
1271                  MS_AUTH_FT2[ (MS_U8) ( B1 >>  8 ) ] ^  \
1272                  MS_AUTH_FT3[ (MS_U8) ( B2       ) ];   \
1273 }
1274 
1275     MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 1 */
1276     MS_AUTH_AES_FRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 2 */
1277     MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 3 */
1278     MS_AUTH_AES_FRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 4 */
1279     MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 5 */
1280     MS_AUTH_AES_FRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 6 */
1281     MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 7 */
1282     MS_AUTH_AES_FRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 8 */
1283     MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 9 */
1284 
1285     if( ctx->nr > 10 )
1286     {
1287         MS_AUTH_AES_FRND( A0, A1, A2, A3, B0, B1, B2, B3 );   /* round 10 */
1288         MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );   /* round 11 */
1289     }
1290 
1291     if( ctx->nr > 12 )
1292     {
1293         MS_AUTH_AES_FRND( A0, A1, A2, A3, B0, B1, B2, B3 );   /* round 12 */
1294         MS_AUTH_AES_FRND( B0, B1, B2, B3, A0, A1, A2, A3 );   /* round 13 */
1295     }
1296 
1297     /* last round */
1298 
1299     RK += 4;
1300 
1301     A0 = RK[0] ^ ( MS_AUTH_FSb[ (MS_U8) ( B0 >> 24 ) ] << 24 ) ^
1302                  ( MS_AUTH_FSb[ (MS_U8) ( B1 >> 16 ) ] << 16 ) ^
1303                  ( MS_AUTH_FSb[ (MS_U8) ( B2 >>  8 ) ] <<  8 ) ^
1304                  ( MS_AUTH_FSb[ (MS_U8) ( B3       ) ]       );
1305 
1306     A1 = RK[1] ^ ( MS_AUTH_FSb[ (MS_U8) ( B1 >> 24 ) ] << 24 ) ^
1307                  ( MS_AUTH_FSb[ (MS_U8) ( B2 >> 16 ) ] << 16 ) ^
1308                  ( MS_AUTH_FSb[ (MS_U8) ( B3 >>  8 ) ] <<  8 ) ^
1309                  ( MS_AUTH_FSb[ (MS_U8) ( B0       ) ]       );
1310 
1311     A2 = RK[2] ^ ( MS_AUTH_FSb[ (MS_U8) ( B2 >> 24 ) ] << 24 ) ^
1312                  ( MS_AUTH_FSb[ (MS_U8) ( B3 >> 16 ) ] << 16 ) ^
1313                  ( MS_AUTH_FSb[ (MS_U8) ( B0 >>  8 ) ] <<  8 ) ^
1314                  ( MS_AUTH_FSb[ (MS_U8) ( B1       ) ]       );
1315 
1316     A3 = RK[3] ^ ( MS_AUTH_FSb[ (MS_U8) ( B3 >> 24 ) ] << 24 ) ^
1317                  ( MS_AUTH_FSb[ (MS_U8) ( B0 >> 16 ) ] << 16 ) ^
1318                  ( MS_AUTH_FSb[ (MS_U8) ( B1 >>  8 ) ] <<  8 ) ^
1319                  ( MS_AUTH_FSb[ (MS_U8) ( B2       ) ]       );
1320 
1321     PUT_UINT32( A0, output,  0 );
1322     PUT_UINT32( A1, output,  4 );
1323     PUT_UINT32( A2, output,  8 );
1324     PUT_UINT32( A3, output, 12 );
1325 }
1326 
1327 /* AES 128-bit block decryption routine */
1328 
MDrv_AUTH_AES_Decrypt(ST_AES_CONTEXT * ctx,MS_U8 input[16],MS_U8 output[16])1329 void MDrv_AUTH_AES_Decrypt( ST_AES_CONTEXT *ctx, MS_U8 input[16], MS_U8 output[16] )
1330 {
1331     MS_U32 *RK, A0, A1, A2, A3, B0, B1, B2, B3;
1332 
1333     RK = ctx->drk;
1334 
1335     GET_UINT32( A0, input,  0 ); A0 ^= RK[0];
1336     GET_UINT32( A1, input,  4 ); A1 ^= RK[1];
1337     GET_UINT32( A2, input,  8 ); A2 ^= RK[2];
1338     GET_UINT32( A3, input, 12 ); A3 ^= RK[3];
1339 
1340 #define MS_AUTH_AES_RRND(A0,A1,A2,A3,B0,B1,B2,B3)     \
1341 {                                               \
1342     RK += 4;                                    \
1343                                                 \
1344     A0 = RK[0] ^ MS_AUTH_RT0[ (MS_U8) ( B0 >> 24 ) ] ^  \
1345                  MS_AUTH_RT1[ (MS_U8) ( B3 >> 16 ) ] ^  \
1346                  MS_AUTH_RT2[ (MS_U8) ( B2 >>  8 ) ] ^  \
1347                  MS_AUTH_RT3[ (MS_U8) ( B1       ) ];   \
1348                                                 \
1349     A1 = RK[1] ^ MS_AUTH_RT0[ (MS_U8) ( B1 >> 24 ) ] ^  \
1350                  MS_AUTH_RT1[ (MS_U8) ( B0 >> 16 ) ] ^  \
1351                  MS_AUTH_RT2[ (MS_U8) ( B3 >>  8 ) ] ^  \
1352                  MS_AUTH_RT3[ (MS_U8) ( B2       ) ];   \
1353                                                 \
1354     A2 = RK[2] ^ MS_AUTH_RT0[ (MS_U8) ( B2 >> 24 ) ] ^  \
1355                  MS_AUTH_RT1[ (MS_U8) ( B1 >> 16 ) ] ^  \
1356                  MS_AUTH_RT2[ (MS_U8) ( B0 >>  8 ) ] ^  \
1357                  MS_AUTH_RT3[ (MS_U8) ( B3       ) ];   \
1358                                                 \
1359     A3 = RK[3] ^ MS_AUTH_RT0[ (MS_U8) ( B3 >> 24 ) ] ^  \
1360                  MS_AUTH_RT1[ (MS_U8) ( B2 >> 16 ) ] ^  \
1361                  MS_AUTH_RT2[ (MS_U8) ( B1 >>  8 ) ] ^  \
1362                  MS_AUTH_RT3[ (MS_U8) ( B0       ) ];   \
1363 }
1364 
1365     MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 1 */
1366     MS_AUTH_AES_RRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 2 */
1367     MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 3 */
1368     MS_AUTH_AES_RRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 4 */
1369     MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 5 */
1370     MS_AUTH_AES_RRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 6 */
1371     MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 7 */
1372     MS_AUTH_AES_RRND( A0, A1, A2, A3, B0, B1, B2, B3 );       /* round 8 */
1373     MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );       /* round 9 */
1374 
1375     if( ctx->nr > 10 )
1376     {
1377         MS_AUTH_AES_RRND( A0, A1, A2, A3, B0, B1, B2, B3 );   /* round 10 */
1378         MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );   /* round 11 */
1379     }
1380 
1381     if( ctx->nr > 12 )
1382     {
1383         MS_AUTH_AES_RRND( A0, A1, A2, A3, B0, B1, B2, B3 );   /* round 12 */
1384         MS_AUTH_AES_RRND( B0, B1, B2, B3, A0, A1, A2, A3 );   /* round 13 */
1385     }
1386 
1387     /* last round */
1388 
1389     RK += 4;
1390 
1391     A0 = RK[0] ^ ( MS_AUTH_RSb[ (MS_U8) ( B0 >> 24 ) ] << 24 ) ^
1392                  ( MS_AUTH_RSb[ (MS_U8) ( B3 >> 16 ) ] << 16 ) ^
1393                  ( MS_AUTH_RSb[ (MS_U8) ( B2 >>  8 ) ] <<  8 ) ^
1394                  ( MS_AUTH_RSb[ (MS_U8) ( B1       ) ]       );
1395 
1396     A1 = RK[1] ^ ( MS_AUTH_RSb[ (MS_U8) ( B1 >> 24 ) ] << 24 ) ^
1397                  ( MS_AUTH_RSb[ (MS_U8) ( B0 >> 16 ) ] << 16 ) ^
1398                  ( MS_AUTH_RSb[ (MS_U8) ( B3 >>  8 ) ] <<  8 ) ^
1399                  ( MS_AUTH_RSb[ (MS_U8) ( B2       ) ]       );
1400 
1401     A2 = RK[2] ^ ( MS_AUTH_RSb[ (MS_U8) ( B2 >> 24 ) ] << 24 ) ^
1402                  ( MS_AUTH_RSb[ (MS_U8) ( B1 >> 16 ) ] << 16 ) ^
1403                  ( MS_AUTH_RSb[ (MS_U8) ( B0 >>  8 ) ] <<  8 ) ^
1404                  ( MS_AUTH_RSb[ (MS_U8) ( B3       ) ]       );
1405 
1406     A3 = RK[3] ^ ( MS_AUTH_RSb[ (MS_U8) ( B3 >> 24 ) ] << 24 ) ^
1407                  ( MS_AUTH_RSb[ (MS_U8) ( B2 >> 16 ) ] << 16 ) ^
1408                  ( MS_AUTH_RSb[ (MS_U8) ( B1 >>  8 ) ] <<  8 ) ^
1409                  ( MS_AUTH_RSb[ (MS_U8) ( B0       ) ]       );
1410 
1411     PUT_UINT32( A0, output,  0 );
1412     PUT_UINT32( A1, output,  4 );
1413     PUT_UINT32( A2, output,  8 );
1414     PUT_UINT32( A3, output, 12 );
1415 }
1416 
1417 
1418