Merge branch 'ib-mfd-iio-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee...
[firefly-linux-kernel-4.4.55.git] / drivers / staging / vt6655 / aes_ccmp.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: aes_ccmp.c
21  *
22  * Purpose: AES_CCMP decryption
23  *
24  * Author: Warren Hsu
25  *
26  * Date: Feb 15, 2005
27  *
28  * Functions:
29  *      AESbGenCCMP - Parsing RX-packet
30  *
31  *
32  * Revision History:
33  *
34  */
35
36 #include "device.h"
37 #include "80211hdr.h"
38 #include "aes_ccmp.h"
39
40 /*---------------------  Static Definitions -------------------------*/
41
42 /*---------------------  Static Classes  ----------------------------*/
43
44 /*---------------------  Static Variables  --------------------------*/
45
46 /*
47  * SBOX Table
48  */
49
50 static unsigned char sbox_table[256] = {
51         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
52         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
53         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
54         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
55         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
56         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
57         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
58         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
59         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
60         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
61         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
62         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
63         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
64         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
65         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
66         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
67 };
68
69 static unsigned char dot2_table[256] = {
70         0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
71         0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
72         0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
73         0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
74         0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
75         0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
76         0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
77         0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
78         0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
79         0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
80         0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
81         0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
82         0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
83         0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
84         0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
85         0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
86 };
87
88 static unsigned char dot3_table[256] = {
89         0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
90         0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
91         0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
92         0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
93         0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
94         0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
95         0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
96         0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
97         0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
98         0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
99         0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
100         0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
101         0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
102         0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
103         0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
104         0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
105 };
106
107 /*---------------------  Static Functions  --------------------------*/
108
109 /*---------------------  Export Variables  --------------------------*/
110
111 /*---------------------  Export Functions  --------------------------*/
112
113 static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
114 {
115         unsigned long *dwPtrA = (unsigned long *)a;
116         unsigned long *dwPtrB = (unsigned long *)b;
117         unsigned long *dwPtrOut = (unsigned long *)out;
118
119         (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
120         (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
121         (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
122         (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
123 }
124
125 static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
126 {
127         unsigned long *dwPtrA = (unsigned long *)a;
128         unsigned long *dwPtrB = (unsigned long *)b;
129         unsigned long *dwPtrOut = (unsigned long *)out;
130
131         (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
132 }
133
134 static void AddRoundKey(unsigned char *key, int round)
135 {
136         unsigned char sbox_key[4];
137         unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
138
139         sbox_key[0] = sbox_table[key[13]];
140         sbox_key[1] = sbox_table[key[14]];
141         sbox_key[2] = sbox_table[key[15]];
142         sbox_key[3] = sbox_table[key[12]];
143
144         key[0] = key[0] ^ rcon_table[round];
145         xor_32(&key[0], sbox_key, &key[0]);
146
147         xor_32(&key[4], &key[0], &key[4]);
148         xor_32(&key[8], &key[4], &key[8]);
149         xor_32(&key[12], &key[8], &key[12]);
150 }
151
152 static void SubBytes(unsigned char *in, unsigned char *out)
153 {
154         int i;
155
156         for (i = 0; i < 16; i++)
157                 out[i] = sbox_table[in[i]];
158 }
159
160 static void ShiftRows(unsigned char *in, unsigned char *out)
161 {
162         out[0]  = in[0];
163         out[1]  = in[5];
164         out[2]  = in[10];
165         out[3]  = in[15];
166         out[4]  = in[4];
167         out[5]  = in[9];
168         out[6]  = in[14];
169         out[7]  = in[3];
170         out[8]  = in[8];
171         out[9]  = in[13];
172         out[10] = in[2];
173         out[11] = in[7];
174         out[12] = in[12];
175         out[13] = in[1];
176         out[14] = in[6];
177         out[15] = in[11];
178 }
179
180 static void MixColumns(unsigned char *in, unsigned char *out)
181 {
182         out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
183         out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
184         out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
185         out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
186 }
187
188 static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
189 {
190         int  i;
191         int  round;
192         unsigned char TmpdataA[16];
193         unsigned char TmpdataB[16];
194         unsigned char abyRoundKey[16];
195
196         for (i = 0; i < 16; i++)
197                 abyRoundKey[i] = key[i];
198
199         for (round = 0; round < 11; round++) {
200                 if (round == 0) {
201                         xor_128(abyRoundKey, data, ciphertext);
202                         AddRoundKey(abyRoundKey, round);
203                 } else if (round == 10) {
204                         SubBytes(ciphertext, TmpdataA);
205                         ShiftRows(TmpdataA, TmpdataB);
206                         xor_128(TmpdataB, abyRoundKey, ciphertext);
207                 } else /* round 1 ~ 9 */{
208                         SubBytes(ciphertext, TmpdataA);
209                         ShiftRows(TmpdataA, TmpdataB);
210                         MixColumns(&TmpdataB[0], &TmpdataA[0]);
211                         MixColumns(&TmpdataB[4], &TmpdataA[4]);
212                         MixColumns(&TmpdataB[8], &TmpdataA[8]);
213                         MixColumns(&TmpdataB[12], &TmpdataA[12]);
214                         xor_128(TmpdataA, abyRoundKey, ciphertext);
215                         AddRoundKey(abyRoundKey, round);
216                 }
217         }
218 }
219
220 /*
221  * Description: AES decryption
222  *
223  * Parameters:
224  *  In:
225  *      pbyRxKey            - The key used to decrypt
226  *      pbyFrame            - Starting address of packet header
227  *      wFrameSize          - Total packet size including CRC
228  *  Out:
229  *      none
230  *
231  * Return Value: MIC compare result
232  *
233  */
234 bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize)
235 {
236         unsigned char abyNonce[13];
237         unsigned char MIC_IV[16];
238         unsigned char MIC_HDR1[16];
239         unsigned char MIC_HDR2[16];
240         unsigned char abyMIC[16];
241         unsigned char abyCTRPLD[16];
242         unsigned char abyTmp[16];
243         unsigned char abyPlainText[16];
244         unsigned char abyLastCipher[16];
245
246         PS802_11Header  pMACHeader = (PS802_11Header) pbyFrame;
247         unsigned char *pbyIV;
248         unsigned char *pbyPayload;
249         unsigned short wHLen = 22;
250         unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;/* 8 is IV, 8 is MIC, 4 is CRC */
251         bool bA4 = false;
252         unsigned char byTmp;
253         unsigned short wCnt;
254         int ii, jj, kk;
255
256         pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
257         if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) &&
258             WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) {
259                 bA4 = true;
260                 pbyIV += 6;             /* 6 is 802.11 address4 */
261                 wHLen += 6;
262                 wPayloadSize -= 6;
263         }
264         pbyPayload = pbyIV + 8; /* IV-length */
265
266         abyNonce[0]  = 0x00; /* now is 0, if Qos here will be priority */
267         memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN);
268         abyNonce[7]  = pbyIV[7];
269         abyNonce[8]  = pbyIV[6];
270         abyNonce[9]  = pbyIV[5];
271         abyNonce[10] = pbyIV[4];
272         abyNonce[11] = pbyIV[1];
273         abyNonce[12] = pbyIV[0];
274
275         /* MIC_IV */
276         MIC_IV[0] = 0x59;
277         memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
278         MIC_IV[14] = (unsigned char)(wPayloadSize >> 8);
279         MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff);
280
281         /* MIC_HDR1 */
282         MIC_HDR1[0] = (unsigned char)(wHLen >> 8);
283         MIC_HDR1[1] = (unsigned char)(wHLen & 0xff);
284         byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff);
285         MIC_HDR1[2] = byTmp & 0x8f;
286         byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8);
287         byTmp &= 0x87;
288         MIC_HDR1[3] = byTmp | 0x40;
289         memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN);
290         memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN);
291
292         /* MIC_HDR2 */
293         memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN);
294         byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff);
295         MIC_HDR2[6] = byTmp & 0x0f;
296         MIC_HDR2[7] = 0;
297         if (bA4) {
298                 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN);
299         } else {
300                 MIC_HDR2[8]  = 0x00;
301                 MIC_HDR2[9]  = 0x00;
302                 MIC_HDR2[10] = 0x00;
303                 MIC_HDR2[11] = 0x00;
304                 MIC_HDR2[12] = 0x00;
305                 MIC_HDR2[13] = 0x00;
306         }
307         MIC_HDR2[14] = 0x00;
308         MIC_HDR2[15] = 0x00;
309
310         /* CCMP */
311         AESv128(pbyRxKey, MIC_IV, abyMIC);
312         for (kk = 0; kk < 16; kk++)
313                 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
314         AESv128(pbyRxKey, abyTmp, abyMIC);
315         for (kk = 0; kk < 16; kk++)
316                 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
317         AESv128(pbyRxKey, abyTmp, abyMIC);
318
319         wCnt = 1;
320         abyCTRPLD[0] = 0x01;
321         memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
322
323         for (jj = wPayloadSize; jj > 16; jj = jj - 16) {
324                 abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
325                 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
326
327                 AESv128(pbyRxKey, abyCTRPLD, abyTmp);
328
329                 for (kk = 0; kk < 16; kk++)
330                         abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
331                 for (kk = 0; kk < 16; kk++)
332                         abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
333                 AESv128(pbyRxKey, abyTmp, abyMIC);
334
335                 memcpy(pbyPayload, abyPlainText, 16);
336                 wCnt++;
337                 pbyPayload += 16;
338         } /* for wPayloadSize */
339
340         /* last payload */
341         memcpy(&(abyLastCipher[0]), pbyPayload, jj);
342         for (ii = jj; ii < 16; ii++)
343                 abyLastCipher[ii] = 0x00;
344
345         abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
346         abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
347
348         AESv128(pbyRxKey, abyCTRPLD, abyTmp);
349         for (kk = 0; kk < 16; kk++)
350                 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
351         memcpy(pbyPayload, abyPlainText, jj);
352         pbyPayload += jj;
353
354         /* for MIC calculation */
355         for (ii = jj; ii < 16; ii++)
356                 abyPlainText[ii] = 0x00;
357         for (kk = 0; kk < 16; kk++)
358                 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
359         AESv128(pbyRxKey, abyTmp, abyMIC);
360
361         /* =>above is the calculate MIC */
362         /* -------------------------------------------- */
363
364         wCnt = 0;
365         abyCTRPLD[14] = (unsigned char)(wCnt >> 8);
366         abyCTRPLD[15] = (unsigned char)(wCnt & 0xff);
367         AESv128(pbyRxKey, abyCTRPLD, abyTmp);
368         for (kk = 0; kk < 8; kk++)
369                 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
370         /* =>above is the dec-MIC from packet */
371         /* -------------------------------------------- */
372
373         return !memcmp(abyMIC, abyTmp, 8);
374 }