xref: /OK3568_Linux_fs/external/security/librkcrypto/test/c_mode/aes_cmac.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "aes_core.h"
6 
rk_left_shift(int len,unsigned char * add,unsigned char * des)7 static void rk_left_shift(int len, unsigned char* add, unsigned char*des)
8 {
9     int i;
10     for (i = 0; i < len - 1; i++)
11     {
12         des[i] = (add[i] << 1) + (add[i + 1] >= 0x80?1:0);
13     }
14     des[len - 1] = add[len - 1] << 1;
15 }
16 
rk_array_xor(int len,const unsigned char * a1,const unsigned char * a2,unsigned char * des)17 static void rk_array_xor(int len, const unsigned char*a1, const unsigned char*a2, unsigned char*des)
18 {
19     int i;
20     for (i = 0; i < len; i++)
21     {
22         des[i] = a1[i] ^ a2[i];
23     }
24 }
25 
rk_derive_mac_key(RK_AES_KEY * key,unsigned char * k1,unsigned char * k2)26 static void rk_derive_mac_key(RK_AES_KEY *key, unsigned char *k1, unsigned char *k2)
27 {
28     unsigned char plain[AES_BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
29     unsigned char Rb[AES_BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 };
30     unsigned char c0[AES_BLOCK_SIZE];
31 
32     rk_aes_encrypt(plain, c0, key);
33     if (c0[0]<0x80)    //generate k1
34     {
35         rk_left_shift(AES_BLOCK_SIZE, c0, k1);
36     }
37     else
38     {
39         rk_left_shift(AES_BLOCK_SIZE, c0, k1);
40         rk_array_xor(AES_BLOCK_SIZE, k1, Rb, k1);
41     }
42 
43     if (k1[0] < 0x80)   //generate k2
44     {
45         rk_left_shift(AES_BLOCK_SIZE, k1, k2);
46     }
47     else
48     {
49         rk_left_shift(AES_BLOCK_SIZE, k1, k2);
50         rk_array_xor(AES_BLOCK_SIZE, k2, Rb, k2);
51     }
52 }
53 
rk_aes_genarate_cmac(const unsigned char * key,unsigned int key_len,const unsigned char * msg,unsigned int msg_len,unsigned char * macvalue)54 int rk_aes_genarate_cmac(const unsigned char *key, unsigned int key_len, const unsigned char *msg, unsigned int msg_len, unsigned char *macvalue)
55 {
56     int i,block;
57     unsigned char IVtemp[AES_BLOCK_SIZE];
58     unsigned char Blocktemp[AES_BLOCK_SIZE];
59 	unsigned char k1[AES_BLOCK_SIZE], k2[AES_BLOCK_SIZE];
60 	RK_AES_KEY aes_key;
61 	int result;
62 
63   	memset(IVtemp, 0x00, sizeof(IVtemp));
64 	memset(Blocktemp, 0x00, sizeof(Blocktemp));
65 	memset(k1, 0x00, sizeof(k1));
66 	memset(k2, 0x00, sizeof(k2));
67 
68 	result = rk_aes_set_encrypt_key(key, key_len*8, &aes_key);
69 	if(result != 0)
70 		return result;
71 
72 	rk_derive_mac_key(&aes_key, k1, k2);
73     if (msg_len % AES_BLOCK_SIZE == 0 && msg_len!=0)
74     {
75         block = msg_len / AES_BLOCK_SIZE;
76         for (i = 0; i < block-1; i++)
77         {
78             rk_array_xor(16, &msg[i * AES_BLOCK_SIZE], IVtemp, Blocktemp);
79 			rk_aes_encrypt(Blocktemp, IVtemp, &aes_key);
80         }
81         rk_array_xor(16, &msg[(block-1)*AES_BLOCK_SIZE], IVtemp, Blocktemp);
82         rk_array_xor(16, Blocktemp, k1, Blocktemp);
83 		rk_aes_encrypt(Blocktemp, macvalue, &aes_key);
84     }
85     else
86     {
87         if (msg_len==0)
88         {
89             block = 1;
90             Blocktemp[0] = 0x80;//padding the first bit with 1
91             rk_array_xor(16, Blocktemp, k2, Blocktemp);
92 			rk_aes_encrypt(Blocktemp, macvalue, &aes_key);
93         }
94         else
95         {
96             unsigned char remain = msg_len % AES_BLOCK_SIZE;
97             block = msg_len / AES_BLOCK_SIZE + 1;
98             for (i = 0; i < block - 1; i++)
99             {
100                 rk_array_xor(AES_BLOCK_SIZE, &msg[i * AES_BLOCK_SIZE], IVtemp, Blocktemp);
101 				rk_aes_encrypt(Blocktemp, IVtemp, &aes_key);
102             }
103             // the last block padding
104             for (i = 0; i < remain; i++)
105             {
106                 Blocktemp[i] = msg[(block - 1) * AES_BLOCK_SIZE + i];
107             }
108             Blocktemp[remain] = 0x80;
109             for (i = remain + 1; i < AES_BLOCK_SIZE; i++)
110             {
111                 Blocktemp[i] = 0;
112             }
113             // end of the last block padding
114 
115             rk_array_xor(AES_BLOCK_SIZE, Blocktemp, k2, Blocktemp);
116             rk_array_xor(AES_BLOCK_SIZE, Blocktemp, IVtemp, Blocktemp);
117 			rk_aes_encrypt(Blocktemp, macvalue, &aes_key);
118         }
119 
120     }
121 	return 0;
122 }
123 
rk_aes_verify_cmac(const unsigned char * key,unsigned int key_len,const unsigned char * msg,unsigned int msg_len,unsigned char * macvalue)124 int rk_aes_verify_cmac(const unsigned char *key, unsigned int key_len, const unsigned char *msg, unsigned int msg_len, unsigned char *macvalue)
125 {
126     int i, block;
127 	int result=-1;
128 	unsigned char IVtemp[AES_BLOCK_SIZE];
129     unsigned char Blocktemp[AES_BLOCK_SIZE];
130 	unsigned char k1[AES_BLOCK_SIZE], k2[AES_BLOCK_SIZE];
131 	unsigned char tmp_macvalue[AES_BLOCK_SIZE];
132 	RK_AES_KEY aes_key;
133 
134   	memset(IVtemp, 0x00, sizeof(IVtemp));
135 	memset(Blocktemp, 0x00, sizeof(Blocktemp));
136 	memset(k1, 0x00, sizeof(k1));
137 	memset(k2, 0x00, sizeof(k2));
138 
139   	result = rk_aes_set_encrypt_key(key, key_len*8, &aes_key);
140 	if(result != 0)
141 		return result;
142 
143 	rk_derive_mac_key(&aes_key, k1, k2);
144     if (msg_len % AES_BLOCK_SIZE == 0 && msg_len != 0)
145     {
146         block = msg_len / AES_BLOCK_SIZE;
147         for (i = 0; i < block - 1; i++)
148         {
149             rk_array_xor(AES_BLOCK_SIZE, &msg[i * AES_BLOCK_SIZE], IVtemp, Blocktemp);
150 			rk_aes_encrypt(Blocktemp, IVtemp, &aes_key);
151         }
152         rk_array_xor(AES_BLOCK_SIZE, &msg[(block - 1) * AES_BLOCK_SIZE], IVtemp, Blocktemp);
153         rk_array_xor(AES_BLOCK_SIZE, Blocktemp, k1, Blocktemp);
154 		rk_aes_encrypt(Blocktemp, tmp_macvalue, &aes_key);
155     }
156     else
157     {
158         if (msg_len == 0)
159         {
160             block = 1;
161             Blocktemp[0] = 0x80;//padding the first bit with 1
162             rk_array_xor(AES_BLOCK_SIZE, Blocktemp, k2, Blocktemp);
163             rk_aes_encrypt(Blocktemp, tmp_macvalue, &aes_key);
164         }
165         else
166         {
167             unsigned char remain = msg_len % AES_BLOCK_SIZE;
168             block = msg_len / AES_BLOCK_SIZE + 1;
169             for (i = 0; i < block - 1; i++)
170             {
171                 rk_array_xor(AES_BLOCK_SIZE, &msg[i * AES_BLOCK_SIZE], IVtemp, Blocktemp);
172                 rk_aes_encrypt(Blocktemp, IVtemp, &aes_key);
173             }
174             // the last block padding
175             for (i = 0; i < remain; i++)
176             {
177                 Blocktemp[i] = msg[(block - 1) * AES_BLOCK_SIZE + i];
178             }
179             Blocktemp[remain] = 0x80;
180             for (i = remain + 1; i < AES_BLOCK_SIZE; i++)
181             {
182                 Blocktemp[i] = 0;
183             }
184             // end of the last block padding
185 
186             rk_array_xor(AES_BLOCK_SIZE, Blocktemp, k2, Blocktemp);
187             rk_array_xor(AES_BLOCK_SIZE, Blocktemp, IVtemp, Blocktemp);
188 			rk_aes_encrypt(Blocktemp, tmp_macvalue, &aes_key);
189         }
190 
191     }
192     result = -1;
193     for (i = 0; i < AES_BLOCK_SIZE; i++)
194     {
195         if (tmp_macvalue[i] != macvalue[i])
196         {
197             return(result);
198         }
199     }
200     result = 0;
201     return(result);
202 }
203