change source file mode to 0644 instead of 0755
[profile/mobile/platform/kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8810 / sec_boot.c
1 #include <common.h>
2 #include <asm/arch/common.h>
3 #include <malloc.h>
4
5 #ifdef CONFIG_NAND_SPL
6 #define panic(x...) do{}while(0)
7 #define printf(x...) do{}while(0)
8 #endif
9 int test_rsa(void);
10 #if 1
11 //#ifdef CONFIG_NAND_SPL 
12 #define dump_all_buffer(x...) do{}while(0)
13 #else
14 void dump_all_buffer(unsigned char *buf, unsigned long len)
15 {
16     unsigned long row, col;
17     unsigned int offset;
18     unsigned long total_row, remain_col;
19     unsigned long flag = 1;
20
21     total_row = len / 16;
22     remain_col = len - total_row * 16;
23     offset = 0;
24     for (row = 0; row < total_row; row ++) {
25         if (flag == 1) {
26             printf("%08xh: ", offset);
27             for (col = 0; col < 16; col ++)
28                 printf("%02x ", buf[offset + col]);
29             printf("\n");
30         }
31         offset += 16;
32     }
33
34     if (remain_col > 0) {
35         if (flag == 1) {
36             printf("%08xh: ", offset);
37             for (col = 0; col < remain_col; col ++)
38                 printf("%02x ", buf[offset + col]);
39             printf("\n");
40         }
41     }
42
43     printf("\n");
44 }
45
46 #endif
47
48 #define MD5NUM_SZ (16)
49
50 typedef struct{
51         struct{
52                 uint32_t e;
53                 uint8_t m[128];
54                 uint8_t r2[128];
55         }key;
56         uint8_t reserved[4];
57 }bsc_info_t;
58
59 #define VLR_MAGIC (0x524c56ff)
60 typedef struct {
61         uint32_t magic;
62         uint8_t hash[128];
63         uint32_t setting;
64         uint32_t length;
65         uint8_t reserved[4];
66 }vlr_info_t;
67
68 typedef struct {
69         uint32_t *g_TraceValue;
70         uint8_t *efuse_harsh_data;
71         uint8_t *soft_harsh_data;
72         int (*CheckSecureBootEnable)(void);
73         int (*HarshVerify)(uint32_t *, uint32_t);
74         void (*RSA_ModPower)(uint32_t *p, uint32_t *m, uint32_t *r2, uint32_t e);
75         void (*MD5Init)(unsigned int *g_data_prt);
76         void (*MD5Final)(unsigned int *input, unsigned int inputLen, unsigned int *g_data_ptr);
77 }harsh_func_t;
78
79 const uint32_t mf__harsh_func_hack[] ={
80         0x40006000,
81         0x40006658,
82         0x40006668,
83         0xffff1405,
84         0xffff1481,
85         0xffff2604,
86         0xffff26ec,
87         0xffff314c,
88 };
89 const uint32_t v0__harsh_func_hack[] ={
90         0x40006000,
91         0x40006658,
92         0x40006668,
93         0xffff1439,
94         0xffff14b5,
95         0xffff2638,
96         0xffff2720,
97         0xffff3180,
98 };
99
100 harsh_func_t * get_harsh_func(void)
101 {
102         uint32_t chip_type = 0;
103         static harsh_func_t * harsh_func = NULL;
104         if(harsh_func != NULL)
105                 return harsh_func;
106
107         chip_type = CHIP_REG_GET(CHIP_TYPE);
108
109         if(chip_type == CHIP_ID_VER_0 || chip_type == CHIP_ID_VER_1 || chip_type == CHIP_ID_7710_VER_0)
110                 harsh_func = (harsh_func_t *) v0__harsh_func_hack;
111         else if(chip_type == CHIP_ID_VER_MF)
112                 harsh_func = (harsh_func_t *) mf__harsh_func_hack;
113         else {
114                 /* not supported chip id */
115                 while(1){}
116         }
117
118         return harsh_func;
119 }
120
121 /*
122  * p 128B
123  * m 128B
124  * r2 128B
125  * e 4B
126  */
127 #define MAKE_DWORD(a,b,c,d) (uint32_t)(((uint32_t)(a)<<24) | (uint32_t)(b)<<16 | ((uint32_t)(c)<<8) | ((uint32_t)(d)))
128
129 void RSA_Decrypt(unsigned char *p, unsigned char *m, unsigned char *r2, unsigned char *e)
130 {
131         unsigned int _e = 0;
132         unsigned int _m[32] = {0};
133         unsigned int _p[32] = {0};
134         unsigned int _r2[32] = {0};
135         int i = 0;
136         harsh_func_t *harsh = get_harsh_func();
137
138         _e = MAKE_DWORD(e[0], e[1], e[2], e[3]);
139
140         for(i=31; i>=0; i--){
141                 _m[31-i] = MAKE_DWORD(m[4*i], m[4*i+1], m[4*i+2], m[4*i+3]); 
142                 _p[31-i] = MAKE_DWORD(p[4*i], p[4*i+1], p[4*i+2], p[4*i+3]); 
143                 _r2[31-i] = MAKE_DWORD(r2[4*i], r2[4*i+1], r2[4*i+2], r2[4*i+3]); 
144         }
145
146         harsh->RSA_ModPower(_p, _m, _r2, _e);
147
148         for(i=31;i>=0;i--){
149                 p[4*(31-i)] = (unsigned char)(_p[i]>>24);
150                 p[4*(31-i)+1] = (unsigned char)(_p[i]>>16);
151                 p[4*(31-i)+2] = (unsigned char)(_p[i]>>8);
152                 p[4*(31-i)+3] = (unsigned char)(_p[i]);
153         }
154 }
155
156 int secureboot_enabled(void)
157 {
158 #ifdef SECURE_BOOT_ENABLE
159         harsh_func_t *harsh = get_harsh_func();
160         return harsh->CheckSecureBootEnable();
161 #else
162         return 0;
163 #endif
164 }
165 unsigned int md5_buf[20] = {0};
166 int harshVerify(uint8_t *data, uint32_t data_len, uint8_t *data_hash, uint8_t *data_key)
167 {
168         int ret = 1;
169         harsh_func_t *harsh = get_harsh_func();
170
171         //test_rsa();
172
173         printf("check secure boot enable %d\n", secureboot_enabled());
174         if(!secureboot_enabled()) return ret;
175
176         if(!data_hash && !data_key) 
177                 return harsh->HarshVerify(data, data_len >> 2);
178         else{
179                 bsc_info_t *bsc = (bsc_info_t *)data_key;
180                 printf("data key\n");
181                 dump_all_buffer(data_key, 512);
182                 if(data_len) 
183                         memcpy(harsh->efuse_harsh_data, data_hash, MD5NUM_SZ);
184                 else{
185                         printf("data_hash\n");
186                         dump_all_buffer(data_hash, 512);
187                         vlr_info_t *vlr = (vlr_info_t *)data_hash;
188                         if(vlr->magic != VLR_MAGIC) {
189                                 printf("magic verify fail\n");
190                                 return 0;
191                         }
192
193                         data_len = vlr->length;
194
195 #ifndef CONFIG_NAND_SPL
196                         cal_md5(data, data_len, md5_buf); 
197 #endif
198                         printf("hash before decrypt\n");
199                         dump_all_buffer(vlr->hash, 512);
200                         RSA_Decrypt(vlr->hash, bsc->key.m, bsc->key.r2, &bsc->key.e);
201                         printf("hash after decrypt\n");
202                         dump_all_buffer(vlr->hash, 512);
203                         memcpy(harsh->efuse_harsh_data, &vlr->hash[sizeof(vlr->hash)-MD5NUM_SZ], MD5NUM_SZ);
204                         printf("efuse harsh data\n");
205                         dump_all_buffer(harsh->efuse_harsh_data, MD5NUM_SZ);
206                 }
207                 ret = harsh->HarshVerify(data, data_len >> 2);
208         }
209         return ret;
210 }
211
212 void secure_check(uint8_t *data, uint32_t data_len, uint8_t *data_hash, uint8_t *data_key)
213 {
214         printf("secure_check: data %p len %u hash %p key %p\n", data, data_len, data_hash, data_key);
215         if(0 == harshVerify(data, data_len, data_hash, data_key)){
216                 printf("secure boot check fail\n");
217                 while(1){}
218         }
219 }
220
221 #ifndef CONFIG_NAND_SPL
222 int cal_md5(void *data, uint32_t orig_len, void *harsh_data)
223 {
224 #ifdef SECURE_BOOT_ENABLE
225         int i;
226         unsigned int *harsh_p = (unsigned int *)harsh_data;
227         harsh_func_t *harsh = get_harsh_func();
228         uint32_t len = orig_len/4;
229
230         if(secureboot_enabled()) return 0;
231
232         harsh->MD5Init((unsigned int *)harsh_data);
233         harsh->MD5Final((unsigned int *)data, len, harsh_p);
234         for(i = 0; i<4; i++)
235         {
236                 printf("md5 harsh data[%d] 0x%08x\n", i, harsh_p[i]);
237         }
238
239         return 1;
240 #else
241         return 0;
242 #endif
243 }
244 #endif
245