Advertisement
Guest User

sun50iw2p1/ss.c

a guest
Feb 23rd, 2017
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.61 KB | None | 0 0
  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. #include "asm/arch/mmu.h"
  26.  
  27. static int ss_base_mode = 0;
  28. /*
  29. ************************************************************************************************************
  30. *
  31. *                                             function
  32. *
  33. *    name          :
  34. *
  35. *    parmeters     :
  36. *
  37. *    return        :
  38. *
  39. *    note          :
  40. *
  41. *
  42. ************************************************************************************************************
  43. */
  44. static u32 __aw_endian4(u32 data)
  45. {
  46.     u32 d1, d2, d3, d4;
  47.     d1= (data&0xff)<<24;
  48.     d2= (data&0xff00)<<8;
  49.     d3= (data&0xff0000)>>8;
  50.     d4= (data&0xff000000)>>24;
  51.  
  52.     return (d1|d2|d3|d4);
  53. }
  54. /*
  55. ************************************************************************************************************
  56. *
  57. *                                             function
  58. *
  59. *    name          :
  60. *
  61. *    parmeters     :
  62. *
  63. *    return        :
  64. *
  65. *    note          :
  66. *
  67. *
  68. ************************************************************************************************************
  69. */
  70. static u32 __sha_padding(u32 data_size, u8* text, u32 hash_mode)
  71. {
  72.     u32 i;
  73.     u32 k, q;
  74.     u32 size;
  75.     u32 padding_buf[16];
  76.     u8 *ptext;
  77.  
  78.     k = data_size/64;
  79.     q = data_size%64;
  80.  
  81.     ptext = (u8*)padding_buf;
  82.     memset(padding_buf, 0, 16 * sizeof(u32));
  83.     if(q==0){
  84.         padding_buf[0] = 0x00000080;
  85.  
  86.         if(hash_mode)
  87.         {
  88.             padding_buf[14] = data_size>>29;
  89.             padding_buf[15] = data_size<<3;
  90.             padding_buf[14] = __aw_endian4(padding_buf[14]);
  91.             padding_buf[15] = __aw_endian4(padding_buf[15]);
  92.         }
  93.         else
  94.         {
  95.             padding_buf[14] = data_size<<3;
  96.             padding_buf[15] = data_size>>29;
  97.         }
  98.  
  99.         for(i=0; i<64; i++){
  100.             text[k*64 + i] = ptext[i];
  101.         }
  102.         size = (k + 1)*64;
  103.     }else if(q<56)
  104.     {
  105.         for(i=0; i<q; i++){
  106.             ptext[i] = text[k*64 + i];
  107.         }
  108.         ptext[q] = 0x80;
  109.  
  110.         if(hash_mode)
  111.         {
  112.             padding_buf[14] = data_size>>29;
  113.             padding_buf[15] = data_size<<3;
  114.             padding_buf[14] = __aw_endian4(padding_buf[14]);
  115.             padding_buf[15] = __aw_endian4(padding_buf[15]);
  116.         }
  117.         else
  118.         {
  119.             padding_buf[14] = data_size<<3;
  120.             padding_buf[15] = data_size>>29;
  121.         }
  122.  
  123.         for(i=0; i<64; i++){
  124.             text[k*64 + i] = ptext[i];
  125.         }
  126.         size = (k + 1)*64;
  127.     }else{
  128.         for(i=0; i<q; i++){
  129.             ptext[i] = text[k*64 + i];
  130.         }
  131.         ptext[q] = 0x80;
  132.         for(i=0; i<64; i++){
  133.             text[k*64 + i] = ptext[i];
  134.         }
  135.  
  136.         //send last 512-bits text to SHA1/MD5
  137.         for(i=0; i<16; i++){
  138.             padding_buf[i] = 0x0;
  139.         }
  140.  
  141.         if(hash_mode)
  142.         {
  143.             padding_buf[14] = data_size>>29;
  144.             padding_buf[15] = data_size<<3;
  145.             padding_buf[14] = __aw_endian4(padding_buf[14]);
  146.             padding_buf[15] = __aw_endian4(padding_buf[15]);
  147.         }
  148.         else
  149.         {
  150.             padding_buf[14] = data_size<<3;
  151.             padding_buf[15] = data_size>>29;
  152.         }
  153.  
  154.         for(i=0; i<64; i++){
  155.             text[(k + 1)*64 + i] = ptext[i];
  156.         }
  157.         size = (k + 2)*64;
  158.     }
  159.  
  160.     return size;
  161. }
  162. /*
  163. ************************************************************************************************************
  164. *
  165. *                                             function
  166. *
  167. *    name          :
  168. *
  169. *    parmeters     :
  170. *
  171. *    return        :
  172. *
  173. *    note          :
  174. *
  175. *
  176. ************************************************************************************************************
  177. */
  178. static void __ss_encry_decry_end(uint task_id)
  179. {
  180.     uint int_en;
  181.  
  182.     int_en = readl(SS_ICR) & 0xf;
  183.     int_en = int_en&(0x01<<task_id);
  184.     if(int_en!=0)
  185.     {
  186.  
  187.        while((readl(SS_ISR)&(0x01<<task_id))==0) {};
  188.     }
  189. }
  190. //align & padding
  191. /*
  192. ************************************************************************************************************
  193. *
  194. *                                             function
  195. *
  196. *    name          :
  197. *
  198. *    parmeters     :
  199. *
  200. *    return        :
  201. *
  202. *    note          :
  203. *
  204. *
  205. ************************************************************************************************************
  206. */
  207. static void __rsa_padding(u8 *dst_buf, u8 *src_buf, u32 data_len, u32 group_len)
  208. {
  209.     int i = 0;
  210.  
  211.     memset(dst_buf, 0, group_len);
  212.     for(i = group_len - data_len; i < group_len; i++)
  213.     {
  214.         dst_buf[i] = src_buf[group_len - 1 - i];
  215.     }
  216. }
  217. /*
  218. ************************************************************************************************************
  219. *
  220. *                                             function
  221. *
  222. *    name          :
  223. *
  224. *    parmeters     :
  225. *
  226. *    return        :
  227. *
  228. *    note          :
  229. *
  230. *
  231. ************************************************************************************************************
  232. */
  233. void sunxi_ss_open(void)
  234. {
  235.     u32  reg_val;
  236.  
  237.     //enable SS working clock
  238.     reg_val = readl(CCMU_CE_CLK_REG); //SS CLOCK
  239.     reg_val &= ~(0xf<<24);
  240.     reg_val |= 0x1<<24;
  241.     reg_val &= ~(0x3<<16);
  242.     reg_val |= 0x0<<16;         // /1
  243.     reg_val &= ~(0xf);
  244.     reg_val |= (4 -1);          // /4
  245.     reg_val |= 0x1U<<31;
  246.     writel(reg_val,CCMU_CE_CLK_REG);
  247.     //enable SS AHB clock
  248.     reg_val = readl(CCMU_BUS_CLK_GATING_REG0);
  249.     reg_val |= 0x1<<5;      //SS AHB clock on
  250.     writel(reg_val,CCMU_BUS_CLK_GATING_REG0);
  251.     //del-assert SS reset
  252.     reg_val = readl(CCMU_BUS_SOFT_RST_REG0);
  253.     reg_val |= 0x1<<5;      //SS AHB clock reset
  254.     writel(reg_val,CCMU_BUS_SOFT_RST_REG0);
  255. }
  256. /*
  257. ************************************************************************************************************
  258. *
  259. *                                             function
  260. *
  261. *    name          :
  262. *
  263. *    parmeters     :
  264. *
  265. *    return        :
  266. *
  267. *    note          :
  268. *
  269. *
  270. ************************************************************************************************************
  271. */
  272. void sunxi_ss_close(void)
  273. {
  274. }
  275. //src_addr      //32B 对齐
  276. /*
  277. ************************************************************************************************************
  278. *
  279. *                                             function
  280. *
  281. *    name          :
  282. *
  283. *    parmeters     :
  284. *
  285. *    return        :
  286. *
  287. *    note          :
  288. *
  289. *
  290. ************************************************************************************************************
  291. */
  292. int  sunxi_sha_calc(u8 *dst_addr, u32 dst_len,
  293.                     u8 *src_addr, u32 src_len)
  294. {
  295.     u32 reg_val = 0;
  296.     u32 total_len = 0;
  297.     u32 md_size = 32;
  298.     s32 i = 0;
  299.     u8  sign_buff[32 + 32], *p_sign;
  300.     task_queue task0;
  301.  
  302.     memset(sign_buff, 0, sizeof(sign_buff));
  303.     p_sign =  (u8 *)(((u32)sign_buff + 31)&(~31));
  304.  
  305.     total_len = __sha_padding(src_len, (u8 *)src_addr, 1)/4;    //计算明文长度
  306.  
  307.     task0.task_id = 0;
  308.     task0.common_ctl = (19)|(1U << 31);
  309.     task0.symmetric_ctl = 0;
  310.     task0.asymmetric_ctl = 0;
  311.     task0.key_descriptor = 0;
  312.     task0.iv_descriptor = 0;
  313.     task0.ctr_descriptor = 0;
  314.     task0.data_len = total_len;
  315.  
  316.     //task0.source[0].addr = va2pa((uint)src_addr);
  317.     task0.source[0].addr = (uint)src_addr;
  318.     task0.source[0].length = total_len;
  319.  
  320.     for(i=1;i<8;i++)
  321.         task0.source[i].length = 0;
  322.  
  323.     task0.destination[0].addr = (uint)p_sign;
  324.     task0.destination[0].length = 32/4;
  325.     for(i=1;i<8;i++)
  326.          task0.destination[i].length = 0;
  327.     task0.next_descriptor = 0;
  328.  
  329.     writel((uint)&task0, SS_TDQ); //descriptor address
  330.     //enable SS end interrupt
  331.     writel(0x1<<(task0.task_id), SS_ICR);
  332.     //start SS
  333.     writel(0x1, SS_TLR);
  334.     //wait end
  335.     __ss_encry_decry_end(task0.task_id);
  336.  
  337.     //copy data
  338.     for(i=0; i< md_size; i++)
  339.     {
  340.         dst_addr[i] = p_sign[i];   //从目的地址读生成的消息摘要
  341.     }
  342.     //clear pending
  343.     reg_val = readl(SS_ISR);
  344.     if((reg_val&(0x01<<task0.task_id))==(0x01<<task0.task_id))
  345.     {
  346.        reg_val &= ~(0x0f);
  347.        reg_val |= (0x01<<task0.task_id);
  348.     }
  349.     writel(reg_val, SS_ISR);
  350.     //SS engie exit
  351.     writel(readl(SS_TLR) & (~0x1), SS_TLR);
  352.  
  353.     return 0;
  354. }
  355. /*
  356. ************************************************************************************************************
  357. *
  358. *                                             function
  359. *
  360. *    name          :
  361. *
  362. *    parmeters     :
  363. *
  364. *    return        :
  365. *
  366. *    note          :
  367. *
  368. *
  369. ************************************************************************************************************
  370. */
  371. s32 sunxi_rsa_calc(u8 * n_addr,   u32 n_len,
  372.                    u8 * e_addr,   u32 e_len,
  373.                    u8 * dst_addr, u32 dst_len,
  374.                    u8 * src_addr, u32 src_len)
  375. {
  376. /* Here we make are defining a size of block aligned on 32 block boundary
  377.  * as we do not know if the buffer given is aligned on 32 bits*/
  378. #define TEMP_BUFF_LEN   ((2048>>3) + 32)
  379.     uint   i;
  380.     task_queue task0;
  381.     u32 reg_val = 0;
  382.     u8  temp_n_addr[TEMP_BUFF_LEN],   *p_n;
  383.     u8  temp_e_addr[TEMP_BUFF_LEN],   *p_e;
  384.     u8  temp_src_addr[temp_buff_len], *p_src;
  385.     u8  temp_dst_addr[temp_buff_len], *p_dst;
  386.     u32 mod_bit_size = 2048;
  387.  
  388.     u32 mod_size_len_inbytes = mod_bit_size/8;
  389.  
  390.     /* Make sure the block is aligned on 32 bits */
  391.     p_n = (u8 *)(((u32)temp_n_addr + 31)&(~31));
  392.     p_e = (u8 *)(((u32)temp_e_addr + 31)&(~31));
  393.     p_src = (u8 *)(((u32)temp_src_addr + 31)&(~31));
  394.     p_dst = (u8 *)(((u32)temp_dst_addr + 31)&(~31));
  395.  
  396.     __rsa_padding(p_src, src_addr, src_len, mod_size_len_inbytes);
  397.     __rsa_padding(p_n, n_addr, n_len, mod_size_len_inbytes);
  398.     memset(p_e, 0, mod_size_len_inbytes);
  399.     memcpy(p_e, e_addr, e_len);
  400.  
  401.     task0.task_id = 0;
  402.     task0.common_ctl = (32 | (1u<<31));      //ss method:rsa
  403.     task0.symmetric_ctl = 0;
  404.     task0.asymmetric_ctl = (2<<28);
  405.     task0.key_descriptor = (uint)p_e;
  406.     task0.iv_descriptor = (uint)p_n;
  407.     task0.ctr_descriptor = 0;
  408.     task0.data_len = mod_size_len_inbytes/4;     //word in uint
  409.     task0.source[0].addr= (uint)p_src;
  410.     task0.source[0].length = mod_size_len_inbytes/4;
  411.     for(i=1;i<8;i++)
  412.         task0.source[i].length = 0;
  413.     task0.destination[0].addr= (uint)p_dst;
  414.     task0.destination[0].length = mod_size_len_inbytes/4;
  415.     for(i=1;i<8;i++)
  416.         task0.destination[i].length = 0;
  417.     task0.next_descriptor = 0;
  418.  
  419.     writel((uint)&task0, SS_TDQ); //descriptor address
  420.     //enable SS end interrupt
  421.     writel(0x1<<(task0.task_id), SS_ICR);
  422.     //start SS
  423.     writel(0x1, SS_TLR);
  424.     //wait end
  425.     __ss_encry_decry_end(task0.task_id);
  426.  
  427.     __rsa_padding(dst_addr, p_dst, mod_bit_size/64, mod_bit_size/64);
  428.     //clear pending
  429.     reg_val = readl(SS_ISR);
  430.     if((reg_val&(0x01<<task0.task_id))==(0x01<<task0.task_id))
  431.     {
  432.        reg_val &= ~(0x0f);
  433.        reg_val |= (0x01<<task0.task_id);
  434.     }
  435.     writel(reg_val, SS_ISR);
  436.     //SS engie exit
  437.     writel(readl(SS_TLR) & (~0x1), SS_TLR);
  438.  
  439.     return 0;
  440. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement