/u-boot-2011.09/arch/arm/cpu/armv7/sun8iw5/spl/ss_spl.c

https://gitlab.com/pine64-android/brandy · C · 414 lines · 208 code · 28 blank · 178 comment · 18 complexity · e862f590d286b7698d202f2bf02a5c3c MD5 · raw file

  1. /*
  2. **********************************************************************************************************************
  3. *
  4. * the Embedded Secure Bootloader System
  5. *
  6. *
  7. * Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
  8. * All Rights Reserved
  9. *
  10. * File :
  11. *
  12. * By :
  13. *
  14. * Version : V2.00
  15. *
  16. * Date :
  17. *
  18. * Descript:
  19. **********************************************************************************************************************
  20. */
  21. #include "common.h"
  22. #include "asm/io.h"
  23. #include "asm/arch/ccmu.h"
  24. #include "asm/arch/ss.h"
  25. /*
  26. ************************************************************************************************************
  27. *
  28. * function
  29. *
  30. * name :
  31. *
  32. * parmeters :
  33. *
  34. * return :
  35. *
  36. * note :
  37. *
  38. *
  39. ************************************************************************************************************
  40. */
  41. static u32 __aw_endian4(u32 data)
  42. {
  43. u32 d1, d2, d3, d4;
  44. d1= (data&0xff)<<24;
  45. d2= (data&0xff00)<<8;
  46. d3= (data&0xff0000)>>8;
  47. d4= (data&0xff000000)>>24;
  48. return (d1|d2|d3|d4);
  49. }
  50. /*
  51. ************************************************************************************************************
  52. *
  53. * function
  54. *
  55. * name :
  56. *
  57. * parmeters :
  58. *
  59. * return :
  60. *
  61. * note :
  62. *
  63. *
  64. ************************************************************************************************************
  65. */
  66. static u32 __sha256_padding(u32 data_size, u8* text)
  67. {
  68. u32 i;
  69. u32 k, q;
  70. u32 size;
  71. u32 padding_buf[16];
  72. u8 *ptext;
  73. k = data_size/64;
  74. q = data_size%64;
  75. ptext = (u8*)padding_buf;
  76. if(q==0){
  77. for(i=0; i<16; i++){
  78. padding_buf[i] = 0x0;
  79. }
  80. padding_buf[0] = 0x00000080;
  81. padding_buf[14] = data_size>>29;
  82. padding_buf[15] = data_size<<3;
  83. padding_buf[14] = __aw_endian4(padding_buf[14]);
  84. padding_buf[15] = __aw_endian4(padding_buf[15]);
  85. for(i=0; i<64; i++){
  86. text[k*64 + i] = ptext[i];
  87. }
  88. size = (k + 1)*64;
  89. }else if(q<56){
  90. for(i=0; i<16; i++){
  91. padding_buf[i] = 0x0;
  92. }
  93. for(i=0; i<q; i++){
  94. ptext[i] = text[k*64 + i];
  95. }
  96. ptext[q] = 0x80;
  97. padding_buf[14] = data_size>>29;
  98. padding_buf[15] = data_size<<3;
  99. padding_buf[14] = __aw_endian4(padding_buf[14]);
  100. padding_buf[15] = __aw_endian4(padding_buf[15]);
  101. for(i=0; i<64; i++){
  102. text[k*64 + i] = ptext[i];
  103. }
  104. size = (k + 1)*64;
  105. }else{
  106. for(i=0; i<16; i++){
  107. padding_buf[i] = 0x0;
  108. }
  109. for(i=0; i<q; i++){
  110. ptext[i] = text[k*64 + i];
  111. }
  112. ptext[q] = 0x80;
  113. for(i=0; i<64; i++){
  114. text[k*64 + i] = ptext[i];
  115. }
  116. //send last 512-bits text to SHA1/MD5
  117. for(i=0; i<16; i++){
  118. padding_buf[i] = 0x0;
  119. }
  120. padding_buf[14] = data_size>>29;
  121. padding_buf[15] = data_size<<3;
  122. padding_buf[14] = __aw_endian4(padding_buf[14]);
  123. padding_buf[15] = __aw_endian4(padding_buf[15]);
  124. for(i=0; i<64; i++){
  125. text[(k + 1)*64 + i] = ptext[i];
  126. }
  127. size = (k + 2)*64;
  128. }
  129. return size;
  130. }
  131. //align & padding
  132. /*
  133. ************************************************************************************************************
  134. *
  135. * function
  136. *
  137. * name :
  138. *
  139. * parmeters :
  140. *
  141. * return :
  142. *
  143. * note :
  144. *
  145. *
  146. ************************************************************************************************************
  147. */
  148. static void __rsa_padding(u8 *dst_buf, u8 *src_buf, u32 data_len, u32 group_len)
  149. {
  150. int i = 0;
  151. memset(dst_buf, 0, group_len);
  152. for(i = group_len - data_len; i < group_len; i++)
  153. {
  154. dst_buf[i] = src_buf[group_len - 1 - i];
  155. }
  156. }
  157. /*
  158. ************************************************************************************************************
  159. *
  160. * function
  161. *
  162. * name :
  163. *
  164. * parmeters :
  165. *
  166. * return :
  167. *
  168. * note :
  169. *
  170. *
  171. ************************************************************************************************************
  172. */
  173. void sunxi_ss_open(void)
  174. {
  175. // u32 reg_val;
  176. //
  177. // //enable SS working clock
  178. // reg_val = readl(CCM_SS_SCLK_CTRL); //SS CLOCK
  179. // reg_val &= ~(0xf<<24);
  180. // reg_val |= 0x1<<24;
  181. // reg_val &= ~(0x3<<16);
  182. // reg_val |= 0x0<<16; // /1
  183. // reg_val &= ~(0xf);
  184. // reg_val |= (4 -1); // /4
  185. // reg_val |= 0x1U<<31;
  186. // writel(reg_val,CCM_SS_SCLK_CTRL);
  187. // //enable SS AHB clock
  188. // reg_val = readl(CCM_AHB0_GATE0_CTRL);
  189. // reg_val |= 0x1<<5; //SS AHB clock on
  190. // writel(reg_val,CCM_AHB0_GATE0_CTRL);
  191. // //del-assert SS reset
  192. // reg_val = readl(CCM_AHB0_RST_REG0);
  193. // reg_val |= 0x1<<5; //SS AHB clock reset
  194. // writel(reg_val,CCM_AHB0_RST_REG0);
  195. }
  196. /*
  197. ************************************************************************************************************
  198. *
  199. * function
  200. *
  201. * name :
  202. *
  203. * parmeters :
  204. *
  205. * return :
  206. *
  207. * note :
  208. *
  209. *
  210. ************************************************************************************************************
  211. */
  212. void sunxi_ss_close(void)
  213. {
  214. }
  215. //src_addr //32B ¶ÔÆë
  216. /*
  217. ************************************************************************************************************
  218. *
  219. * function
  220. *
  221. * name :
  222. *
  223. * parmeters :
  224. *
  225. * return :
  226. *
  227. * note :
  228. *
  229. *
  230. ************************************************************************************************************
  231. */
  232. int sunxi_sha_calc(u8 *dst_addr, u32 dst_len,
  233. u8 *src_addr, u32 src_len)
  234. {
  235. u32 reg_val = 0;
  236. u32 total_len = 0;
  237. u32 md_size = 0;
  238. s32 i = 0;
  239. u8 iv_buff[32 + 32], *p_iv;
  240. u8 sign_buff[32 + 32], *p_sign;
  241. memset(sign_buff, 0, sizeof(sign_buff));
  242. memset(iv_buff, 0, sizeof(iv_buff));
  243. p_iv = (u8 *)(((u32)iv_buff + 31)&(~31));
  244. p_sign = (u8 *)(((u32)sign_buff + 31)&(~31));
  245. //set mode
  246. reg_val = readl(SS_CTL);
  247. reg_val &= ~(0xf<<2);
  248. reg_val &= ~(0x1<<17); //IV steady of its constants
  249. reg_val |= 0x1<<30; // flow0
  250. reg_val |= 0x8<<2; //SHA256
  251. md_size = 32;
  252. writel(reg_val, SS_CTL);
  253. //set src addr
  254. writel((u32)src_addr , SS_DATA_SRC_LOW_ADR);
  255. writel(0 , SS_DATA_SRC_HIGH_ADR);
  256. //set dest addr
  257. writel((u32)p_sign, SS_DATA_DST_LOW_ADR);
  258. writel(0 , SS_DATA_DST_HIGH_ADR);
  259. //set src len
  260. //while((*(volatile int *)0)!=1);
  261. total_len = __sha256_padding(src_len,(u8 *)src_addr); //¼ÆËãÃ÷Îij¤¶È
  262. writel(total_len/4,SS_DATA_LEN);
  263. //set IV
  264. writel((u32)p_iv, SS_PM_LOW_ADR);
  265. writel(0 , SS_PM_HIGH_ADR);
  266. //enable INT
  267. reg_val = readl(SS_INT_CTRL);
  268. reg_val &= ~0x3;
  269. reg_val |= 1;
  270. writel(reg_val , SS_INT_CTRL);
  271. //start SS
  272. reg_val = readl(SS_CTL);
  273. reg_val &= ~(0x1U<<31);
  274. reg_val &= ~(0x1<<30);
  275. reg_val |= 0x1;
  276. writel(reg_val,SS_CTL);
  277. //wait end
  278. while((readl(SS_INT_STATUS)&0x01)==0);
  279. for(i=0; i< md_size; i++)
  280. {
  281. dst_addr[i] = p_sign[i]; //´ÓÄ¿µÄµØÖ·¶ÁÉú³ÉµÄÏûÏ¢ÕªÒª
  282. }
  283. //clear SS end interrupt
  284. reg_val = readl(SS_INT_STATUS);
  285. if((reg_val&0x1)==1)
  286. {
  287. reg_val &= ~(0x3);
  288. reg_val |= 0x1;
  289. }
  290. writel(reg_val,SS_INT_STATUS);
  291. //stop SS
  292. reg_val = readl(SS_CTL);
  293. reg_val &= ~0x1;
  294. writel(reg_val,SS_CTL);
  295. return 0;
  296. }
  297. /*
  298. ************************************************************************************************************
  299. *
  300. * function
  301. *
  302. * name :
  303. *
  304. * parmeters :
  305. *
  306. * return :
  307. *
  308. * note :
  309. *
  310. *
  311. ************************************************************************************************************
  312. */
  313. s32 sunxi_rsa_calc(u8 * n_addr, u32 n_len,
  314. u8 * e_addr, u32 e_len,
  315. u8 * dst_addr, u32 dst_len,
  316. u8 * src_addr, u32 src_len)
  317. {
  318. #define TEMP_BUFF_LEN ((2048>>3) + 32)
  319. u32 reg_val = 0;
  320. u8 temp_n_addr[TEMP_BUFF_LEN], *p_n;
  321. u8 temp_e_addr[TEMP_BUFF_LEN], *p_e;
  322. u8 temp_src_addr[TEMP_BUFF_LEN], *p_src;
  323. u8 temp_dst_addr[TEMP_BUFF_LEN], *p_dst;
  324. u32 mod_bit_size = 2048;
  325. u32 mod_size_len_inbytes = mod_bit_size/8;
  326. p_n = (u8 *)(((u32)temp_n_addr + 31)&(~31));
  327. p_e = (u8 *)(((u32)temp_e_addr + 31)&(~31));
  328. p_src = (u8 *)(((u32)temp_src_addr + 31)&(~31));
  329. p_dst = (u8 *)(((u32)temp_dst_addr + 31)&(~31));
  330. __rsa_padding(p_src, src_addr, src_len, mod_size_len_inbytes);
  331. __rsa_padding(p_n, n_addr, n_len, mod_size_len_inbytes);
  332. memset(p_e, 0, mod_size_len_inbytes);
  333. memcpy(p_e, e_addr, e_len);
  334. //setting
  335. reg_val = readl(SS_CTL);
  336. reg_val &= ~(0xf<<2);
  337. reg_val |= 9<<2;
  338. reg_val &= ~(0x1<<6); //RSA encrypt
  339. reg_val &= ~(0x3<<9);
  340. reg_val |= 0x2<<9; //RSA 2048
  341. reg_val &= ~(0x3U<<30);
  342. reg_val |= 0x1<<30;
  343. writel(reg_val, SS_CTL);
  344. //data len
  345. writel(mod_bit_size/32, SS_DATA_LEN);
  346. //src
  347. writel((u32)p_src, SS_DATA_SRC_LOW_ADR);
  348. writel(0 , SS_DATA_SRC_HIGH_ADR);
  349. //key addr
  350. writel((u32)p_e , SS_KEY_LOW_ADR);
  351. writel(0 , SS_KEY_HIGH_ADR);
  352. //dest
  353. writel((u32)p_dst, SS_DATA_DST_LOW_ADR);
  354. writel(0 , SS_DATA_DST_HIGH_ADR);
  355. //mod
  356. writel((u32)p_n , SS_PM_LOW_ADR);
  357. writel(0 , SS_PM_HIGH_ADR);
  358. //enable INT
  359. reg_val = readl(SS_INT_CTRL);
  360. reg_val &= ~0x3;
  361. reg_val |= 1;
  362. writel(reg_val, SS_INT_CTRL);
  363. //start SS
  364. reg_val = readl(SS_CTL);
  365. reg_val &= ~(0x1U<<31);
  366. reg_val &= ~(0x1<<30);
  367. reg_val |= 0x1;
  368. writel(reg_val,SS_CTL);
  369. //wait end
  370. while((readl(SS_INT_STATUS)&0x01)==0);
  371. //read dst data
  372. __rsa_padding(dst_addr, p_dst, mod_bit_size/64, mod_bit_size/64);
  373. //clear SS end interrupt
  374. reg_val = readl(SS_INT_STATUS);
  375. if((reg_val&0x1)==1)
  376. {
  377. reg_val &= ~(0x3);
  378. reg_val |= 0x1;
  379. }
  380. writel(reg_val,SS_INT_STATUS);
  381. //stop SS
  382. reg_val = readl(SS_CTL);
  383. reg_val &= ~0x1;
  384. writel(reg_val,SS_CTL);
  385. return 0;
  386. }