xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/aes_cmac_rom.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file aes_cmac_rom.c
2  *
3  *  @brief This file defines aes cmac related function
4  *
5  * Copyright (C) 2014-2017, Marvell International Ltd.
6  *
7  * This software file (the "File") is distributed by Marvell International
8  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9  * (the "License").  You may use, redistribute and/or modify this File in
10  * accordance with the terms and conditions of the License, a copy of which
11  * is available by writing to the Free Software Foundation, Inc.,
12  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14  *
15  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
18  * this warranty disclaimer.
19  */
20 
21 /******************************************************
22 Change log:
23     03/07/2014: Initial version
24 ******************************************************/
25 #include "wl_macros.h"
26 #include "wltypes.h"
27 #include "hostsa_ext_def.h"
28 #include "authenticator.h"
29 
30 #include "crypt_new_rom.h"
31 #include "aes_cmac_rom.h"
32 
33 //#pragma diag_default 144
34 //#pragma arm section rwdata
35 // End - patch table entries
36 
37 /* For CMAC Calculation */
38 static UINT8 const_Rb[16] = {
39 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
41 };
42 
43 void
mrvl_aes_128(UINT8 * key,UINT8 * input,UINT8 * output)44 mrvl_aes_128(UINT8 *key, UINT8 *input, UINT8 *output)
45 {
46 //    BOOLEAN weuEnabled;
47 
48 #if 0
49 	if (IS_AEU_CLK_ENBLD()) {
50 		weuEnabled = TRUE;
51 	} else {
52 		weuEnabled = FALSE;
53 	}
54 #endif
55 	/* keyLen = 128 bit / 8 bits/byte / 8 for MRVL API encoding == 2 */
56 	MRVL_AesEncrypt(key, (128 / 8) / 8, input, output);
57 
58 }
59 
60 /* Basic Functions */
61 void
xor_128(UINT8 * a,UINT8 * b,UINT8 * out)62 xor_128(UINT8 *a, UINT8 *b, UINT8 *out)
63 {
64 	int i;
65 	for (i = 0; i < 16; i++) {
66 		out[i] = a[i] ^ b[i];
67 	}
68 }
69 
70 /* AES-CMAC Generation Function */
71 
72 void
leftshift_onebit(UINT8 * input,UINT8 * output)73 leftshift_onebit(UINT8 *input, UINT8 *output)
74 {
75 	int i;
76 	UINT8 overflow = 0;
77 
78 	for (i = 15; i >= 0; i--) {
79 		output[i] = input[i] << 1;
80 		output[i] |= overflow;
81 		overflow = (input[i] & 0x80) ? 1 : 0;
82 	}
83 }
84 
85 void
generate_subkey(phostsa_private priv,UINT8 * key,UINT8 * K1,UINT8 * K2)86 generate_subkey(phostsa_private priv, UINT8 *key, UINT8 *K1, UINT8 *K2)
87 {
88 	hostsa_util_fns *util_fns = &priv->util_fns;
89 
90 	UINT8 L[16];
91 	UINT8 Z[16];
92 	UINT8 tmp[16];
93 
94 	memset(util_fns, Z, 0x00, sizeof(Z));
95 
96 	mrvl_aes_128(key, Z, L);
97 
98 	if ((L[0] & 0x80) == 0) {
99 		/* If MSB(L) = 0, then K1 = L << 1 */
100 		leftshift_onebit(L, K1);
101 	} else {
102 		/* Else K1 = ( L << 1 ) (+) Rb */
103 		leftshift_onebit(L, tmp);
104 		xor_128(tmp, const_Rb, K1);
105 	}
106 
107 	if ((K1[0] & 0x80) == 0) {
108 		leftshift_onebit(K1, K2);
109 	} else {
110 		leftshift_onebit(K1, tmp);
111 		xor_128(tmp, const_Rb, K2);
112 	}
113 }
114 
115 void
padding(UINT8 * lastb,UINT8 * pad,int length)116 padding(UINT8 *lastb, UINT8 *pad, int length)
117 {
118 	int j;
119 
120 	/* original last block */
121 	for (j = 0; j < 16; j++) {
122 		if (j < length) {
123 			pad[j] = lastb[j];
124 		} else if (j == length) {
125 			pad[j] = 0x80;
126 		} else {
127 			pad[j] = 0x00;
128 		}
129 	}
130 }
131 
132 void
mrvl_aes_cmac(phostsa_private priv,UINT8 * key,UINT8 * input,int length,UINT8 * mac)133 mrvl_aes_cmac(phostsa_private priv, UINT8 *key, UINT8 *input, int length,
134 	      UINT8 *mac)
135 {
136 	hostsa_util_fns *util_fns = &priv->util_fns;
137 	UINT8 X[16];
138 	UINT8 Y[16];
139 	UINT8 M_last[16];
140 	UINT8 padded[16];
141 	UINT8 K1[16];
142 	UINT8 K2[16];
143 	int n, i, flag;
144 
145 	generate_subkey(priv, key, K1, K2);
146 
147 	n = (length + 15) / 16;	/* n is number of rounds */
148 
149 	if (n == 0) {
150 		n = 1;
151 		flag = 0;
152 	} else {
153 		if ((length % 16) == 0) {
154 			/* last block is a complete block */
155 			flag = 1;
156 		} else {
157 			/* last block is not complete block */
158 			flag = 0;
159 		}
160 	}
161 
162 	if (flag) {
163 		/* last block is complete block */
164 		xor_128(&input[16 * (n - 1)], K1, M_last);
165 	} else {
166 		padding(&input[16 * (n - 1)], padded, length % 16);
167 		xor_128(padded, K2, M_last);
168 	}
169 
170 	memset(util_fns, X, 0x00, sizeof(X));
171 
172 	for (i = 0; i < n - 1; i++) {
173 		xor_128(X, &input[16 * i], Y);	/* Y := Mi (+) X  */
174 		mrvl_aes_128(key, Y, X);	/* X := AES-128(KEY, Y); */
175 	}
176 
177 	xor_128(X, M_last, Y);
178 	mrvl_aes_128(key, Y, X);
179 
180 	for (i = 0; i < 16; i++) {
181 		mac[i] = X[i];
182 	}
183 }
184