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