tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc9630 / sec_boot.c
1 #include <common.h>
2 #include <malloc.h>
3 #include <asm/arch/common.h>
4 #include <asm/arch/sprd_reg.h>
5 #include <asm/arch/secure_boot.h>
6 #include <asm/arch/chip_drv_common_io.h>
7
8 #define EFUSE_HASH_STARTID 2
9 /**************************************************************/
10
11 #define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
12 #define F0_19(A,B,C,D,E,Wt,Kn) \
13                 E += SHA1CircularShift(5,A) + ((B & C) | ((~B) & D));\
14                 E += Wt + Kn; \
15                 B = SHA1CircularShift(30,B);
16 #define F20_39(A,B,C,D,E,Wt,Kn) \
17                 E += SHA1CircularShift(5,A) + (B ^ C ^ D);\
18                 E += Wt + Kn; \
19                 B = SHA1CircularShift(30,B);
20 #define F40_59(A,B,C,D,E,Wt,Kn) \
21                 E += SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D));\
22                 E += Wt + Kn; \
23                 B = SHA1CircularShift(30,B);
24 #define F60_79(A,B,C,D,E,Wt,Kn) \
25                 E += SHA1CircularShift(5,A) + (B ^ C ^ D);\
26                 E += Wt + Kn; \
27                 B = SHA1CircularShift(30,B);
28
29 PUBLIC int SHA1Reset_32(SHA1Context_32 * context32)
30 {
31         context32->Length_Low = 0;
32         context32->Length_High = 0;
33         context32->Message_Block_Index = 0;
34         context32->Intermediate_Hash[0] = 0x67452301;
35         context32->Intermediate_Hash[1] = 0xEFCDAB89;
36         context32->Intermediate_Hash[2] = 0x98BADCFE;
37         context32->Intermediate_Hash[3] = 0x10325476;
38         context32->Intermediate_Hash[4] = 0xC3D2E1F0;
39         return 0;
40 }
41
42 int SHA1ProcessMessageBlock_32(SHA1Context_32 * context)
43 {
44         const unsigned int K[] = {      /* Constants defined in SHA-1 */
45                 0x5A827999,
46                 0x6ED9EBA1,
47                 0x8F1BBCDC,
48                 0xCA62C1D6
49         };
50         int t;                  /* Loop counter */
51         unsigned int A, B, C, D, E;     /* Word buffers */
52         unsigned int *W;
53         unsigned int *H;
54         W = context->W;
55         H = context->Intermediate_Hash;
56         /*
57          * Initialize the first 16 words in the array W
58          */
59         for (t = 16; t < 80; t++) {
60                 context->W[t] = SHA1CircularShift(1, context->W[t - 3] ^ context->W[t - 8] ^ context->W[t - 14] ^ context->W[t - 16]);
61         }
62         A = H[0];
63         B = H[1];
64         C = H[2];
65         D = H[3];
66         E = H[4];
67
68         F0_19(A, B, C, D, E, W[0], K[0])
69             F0_19(E, A, B, C, D, W[1], K[0])
70             F0_19(D, E, A, B, C, W[2], K[0])
71             F0_19(C, D, E, A, B, W[3], K[0])
72             F0_19(B, C, D, E, A, W[4], K[0])
73             F0_19(A, B, C, D, E, W[5], K[0])
74             F0_19(E, A, B, C, D, W[6], K[0])
75             F0_19(D, E, A, B, C, W[7], K[0])
76             F0_19(C, D, E, A, B, W[8], K[0])
77             F0_19(B, C, D, E, A, W[9], K[0])
78             F0_19(A, B, C, D, E, W[10], K[0])
79             F0_19(E, A, B, C, D, W[11], K[0])
80             F0_19(D, E, A, B, C, W[12], K[0])
81             F0_19(C, D, E, A, B, W[13], K[0])
82             F0_19(B, C, D, E, A, W[14], K[0])
83             F0_19(A, B, C, D, E, W[15], K[0])
84             F0_19(E, A, B, C, D, W[16], K[0])
85             F0_19(D, E, A, B, C, W[17], K[0])
86             F0_19(C, D, E, A, B, W[18], K[0])
87             F0_19(B, C, D, E, A, W[19], K[0])
88
89             F20_39(A, B, C, D, E, W[20], K[1])
90             F20_39(E, A, B, C, D, W[21], K[1])
91             F20_39(D, E, A, B, C, W[22], K[1])
92             F20_39(C, D, E, A, B, W[23], K[1])
93             F20_39(B, C, D, E, A, W[24], K[1])
94             F20_39(A, B, C, D, E, W[25], K[1])
95             F20_39(E, A, B, C, D, W[26], K[1])
96             F20_39(D, E, A, B, C, W[27], K[1])
97             F20_39(C, D, E, A, B, W[28], K[1])
98             F20_39(B, C, D, E, A, W[29], K[1])
99             F20_39(A, B, C, D, E, W[30], K[1])
100             F20_39(E, A, B, C, D, W[31], K[1])
101             F20_39(D, E, A, B, C, W[32], K[1])
102             F20_39(C, D, E, A, B, W[33], K[1])
103             F20_39(B, C, D, E, A, W[34], K[1])
104             F20_39(A, B, C, D, E, W[35], K[1])
105             F20_39(E, A, B, C, D, W[36], K[1])
106             F20_39(D, E, A, B, C, W[37], K[1])
107             F20_39(C, D, E, A, B, W[38], K[1])
108             F20_39(B, C, D, E, A, W[39], K[1])
109
110             F40_59(A, B, C, D, E, W[40], K[2])
111             F40_59(E, A, B, C, D, W[41], K[2])
112             F40_59(D, E, A, B, C, W[42], K[2])
113             F40_59(C, D, E, A, B, W[43], K[2])
114             F40_59(B, C, D, E, A, W[44], K[2])
115             F40_59(A, B, C, D, E, W[45], K[2])
116             F40_59(E, A, B, C, D, W[46], K[2])
117             F40_59(D, E, A, B, C, W[47], K[2])
118             F40_59(C, D, E, A, B, W[48], K[2])
119             F40_59(B, C, D, E, A, W[49], K[2])
120             F40_59(A, B, C, D, E, W[50], K[2])
121             F40_59(E, A, B, C, D, W[51], K[2])
122             F40_59(D, E, A, B, C, W[52], K[2])
123             F40_59(C, D, E, A, B, W[53], K[2])
124             F40_59(B, C, D, E, A, W[54], K[2])
125             F40_59(A, B, C, D, E, W[55], K[2])
126             F40_59(E, A, B, C, D, W[56], K[2])
127             F40_59(D, E, A, B, C, W[57], K[2])
128             F40_59(C, D, E, A, B, W[58], K[2])
129             F40_59(B, C, D, E, A, W[59], K[2])
130
131             F60_79(A, B, C, D, E, W[60], K[3])
132             F60_79(E, A, B, C, D, W[61], K[3])
133             F60_79(D, E, A, B, C, W[62], K[3])
134             F60_79(C, D, E, A, B, W[63], K[3])
135             F60_79(B, C, D, E, A, W[64], K[3])
136             F60_79(A, B, C, D, E, W[65], K[3])
137             F60_79(E, A, B, C, D, W[66], K[3])
138             F60_79(D, E, A, B, C, W[67], K[3])
139             F60_79(C, D, E, A, B, W[68], K[3])
140             F60_79(B, C, D, E, A, W[69], K[3])
141             F60_79(A, B, C, D, E, W[70], K[3])
142             F60_79(E, A, B, C, D, W[71], K[3])
143             F60_79(D, E, A, B, C, W[72], K[3])
144             F60_79(C, D, E, A, B, W[73], K[3])
145             F60_79(B, C, D, E, A, W[74], K[3])
146             F60_79(A, B, C, D, E, W[75], K[3])
147             F60_79(E, A, B, C, D, W[76], K[3])
148             F60_79(D, E, A, B, C, W[77], K[3])
149             F60_79(C, D, E, A, B, W[78], K[3])
150             F60_79(B, C, D, E, A, W[79], K[3])
151             H[0] += A;
152         H[1] += B;
153         H[2] += C;
154         H[3] += D;
155         H[4] += E;
156         return 0;
157 }
158
159 PUBLIC int SHA1Input_32(SHA1Context_32 * context, const unsigned int *message_array, unsigned int length)
160 {
161         while (length--) {
162                 context->W[context->Message_Block_Index++] = *message_array;
163                 message_array++;
164                 context->Length_Low += 32;
165                 if (context->Length_Low == 0) {
166                         context->Length_High++;
167                 }
168                 if (context->Message_Block_Index == 16) {
169                         SHA1ProcessMessageBlock_32(context);
170                         context->Message_Block_Index = 0;
171                 }
172         }
173         return 0;
174 }
175
176 int SHA1PadMessage_32(SHA1Context_32 * context)
177 {
178         /*
179          * Check to see if the current message block is too small to hold
180          * the initial padding bits and length. If so, we will pad the
181          * block, process it, and then continue padding into a second
182          * block.
183          */
184         unsigned int i, cnt = context->Message_Block_Index;
185         context->W[cnt++] = 0x80000000;
186         for (i = cnt; i < 16; i++) {
187                 context->W[i] = 0;
188         }
189
190         if (cnt > 14) {
191                 SHA1ProcessMessageBlock_32(context);
192                 for (i = 0; i < 14; i++) {
193                         context->W[i] = 0;
194                 }
195         }
196         /*
197          * Store the message length as the last 8 octets
198          */
199         context->W[14] = context->Length_High;
200         context->W[15] = context->Length_Low;
201         SHA1ProcessMessageBlock_32(context);
202         return 0;
203 }
204
205 PUBLIC int SHA1Result_32(SHA1Context_32 * context, unsigned char *Message_Digest)
206 {
207         int i;
208         uint32_t *ptr;
209         ptr = (uint32_t *) context->W;
210         SHA1PadMessage_32(context);
211         for (i = 0; i < 16; ++i) {
212                 /* message may be sensitive, clear it out */
213                 *(ptr + i) = 0;
214         }
215         context->Length_Low = 0;        /* and clear length */
216         context->Length_High = 0;
217         for (i = 0; i < SHA1HashSize; ++i) {
218                 Message_Digest[i] = context->Intermediate_Hash[i >> 2]
219                     >> 8 * (3 - (i & 0x03));
220         }
221         return 0;
222 }
223
224 /******************************************************************/
225
226 rom_callback_func_t *get_rom_callback(void)
227 {
228         rom_callback_func_t *rom_callback = NULL;
229         rom_callback = (rom_callback_func_t *) (*((unsigned int *)0xFFFF0020));
230         return rom_callback;
231 }
232
233 int secureboot_enabled(void)
234 {
235 #ifdef CONFIG_SECURE_BOOT
236         uint32_t reg = 0;
237         uint32_t bonding = REG32(REG_AON_APB_BOND_OPT0);
238         if (bonding & BIT_2) {
239 //              reg = sci_efuse_read(EFUSE_HASH_STARTID);
240                 reg = __ddie_efuse_read(EFUSE_HASH_STARTID);
241                 if ((reg >> 31) & 0x1)
242                         return 1;
243         }
244 #endif
245         return 0;
246 }
247
248 #define MAKE_DWORD(a,b,c,d) (uint32_t)(((uint32_t)(a)<<24) | (uint32_t)(b)<<16 | ((uint32_t)(c)<<8) | ((uint32_t)(d)))
249
250 void RSA_Decrypt(unsigned char *p, unsigned char *m, unsigned char *r2, unsigned char *e)
251 {
252         rom_callback_func_t *rom_callback = NULL;
253         unsigned int _e = 0;
254         unsigned int _m[32];
255         unsigned int _p[32];
256         unsigned int _r2[32];
257         int i = 0;
258
259         rom_callback = get_rom_callback();
260
261         _e = MAKE_DWORD(e[0], e[1], e[2], e[3]);
262
263         for (i = 31; i >= 0; i--) {
264                 _m[31 - i] = MAKE_DWORD(m[4 * i], m[4 * i + 1], m[4 * i + 2], m[4 * i + 3]);
265                 _p[31 - i] = MAKE_DWORD(p[4 * i], p[4 * i + 1], p[4 * i + 2], p[4 * i + 3]);
266                 _r2[31 - i] = MAKE_DWORD(r2[4 * i], r2[4 * i + 1], r2[4 * i + 2], r2[4 * i + 3]);
267         }
268
269         rom_callback->rsa_modpower(_p, _m, _r2, _e);
270
271         for (i = 31; i >= 0; i--) {
272                 p[4 * (31 - i)] = (unsigned char)(_p[i] >> 24);
273                 p[4 * (31 - i) + 1] = (unsigned char)(_p[i] >> 16);
274                 p[4 * (31 - i) + 2] = (unsigned char)(_p[i] >> 8);
275                 p[4 * (31 - i) + 3] = (unsigned char)(_p[i]);
276         }
277 }
278
279 int harshVerify(uint8_t * data, uint32_t data_len, uint8_t * data_hash, uint8_t * data_key)
280 {
281         uint32_t i, soft_hash_data[32];
282         uint32_t *data_ptr;
283         vlr_info_t *vlr_info;
284         bsc_info_t *bsc_info;
285         SHA1Context_32 sha;
286         uint8_t hash_copy[128] = { 0 };
287
288         vlr_info = (vlr_info_t *) data_hash;
289
290         if (vlr_info->magic != VLR_MAGIC) {
291                 printf("harshVerify, vlr magic mismatch\r\n");
292                 return 0;
293         }
294
295         bsc_info = (bsc_info_t *) data_key;
296         SHA1Reset_32(&sha);
297         SHA1Input_32(&sha, (uint32_t *) data, data_len >> 2);
298         SHA1Result_32(&sha, soft_hash_data);
299         memcpy(hash_copy, vlr_info->hash, sizeof(vlr_info->hash));
300
301         RSA_Decrypt(hash_copy, bsc_info->key.m, bsc_info->key.r2, (unsigned char *)(&bsc_info->key.e));
302         data_ptr = (uint32_t *) (&hash_copy[108]);
303         for (i = 0; i < 5; i++) {
304                 //printf("[%3d] : %02X, %02X . \r\n", i, soft_hash_data[i], data_ptr[i]);
305                 if (soft_hash_data[i] != data_ptr[i]) {
306                         printf("harshVerify, mismatch\r\n");
307                         return 0;
308                 }
309         }
310         printf("harshVerify, succ\r\n");
311         return 1;
312 }
313
314 void secure_check(uint8_t * data, uint32_t data_len, uint8_t * data_hash, uint8_t * data_key)
315 {
316         if (0 == harshVerify(data, data_len, data_hash, data_key)) {
317                 while (1) ;
318         }
319 }
320
321 void get_sec_callback(sec_callback_func_t * sec_callfunc)
322 {
323         sec_callfunc->rom_callback = get_rom_callback();
324         sec_callfunc->secure_check = secure_check;
325 }
326
327 int cal_sha1(void *data, uint32_t orig_len, void *hash_data)
328 {
329         SHA1Context_32 sha;
330
331         SHA1Reset_32(&sha);
332         SHA1Input_32(&sha, (uint32_t *) data, orig_len >> 2);
333         SHA1Result_32(&sha, hash_data);
334         return 1;
335 }
336
337 #ifndef CONFIG_NAND_SPL
338 int cal_md5(void *data, uint32_t orig_len, void *harsh_data)
339 {
340         return 0;
341 }
342 #endif