Advertisement
Guest User

Untitled

a guest
Aug 17th, 2014
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.80 KB | None | 0 0
  1. #include "crypto.h"
  2. #include "lib.h"
  3.  
  4. #define REG_AESCNT     ((volatile uint32_t*)0x10009000)
  5. #define REG_AESBLKCNT  ((volatile uint32_t*)0x10009004)
  6. #define REG_AESWRFIFO  ((volatile uint32_t*)0x10009008)
  7. #define REG_AESRDFIFO  ((volatile uint32_t*)0x1000900C)
  8. #define REG_AESKEYSEL  ((volatile uint8_t *)0x10009010)
  9. #define REG_AESKEYCNT  ((volatile uint8_t *)0x10009011)
  10. #define REG_AESCTR     ((volatile uint32_t*)0x10009020)
  11. #define REG_AESKEYFIFO ((volatile uint32_t*)0x10009108)
  12.  
  13. #define AES_BIG_INPUT      1
  14. #define AES_LITTLE_INPUT   0
  15. #define AES_NORMAL_INPUT   4
  16. #define AES_REVERSED_INPUT 0
  17. #define AES_BLOCK_SIZE 0x10
  18.  
  19. #define AES_CCM_DECRYPT_MODE (0 << 27)
  20. #define AES_CCM_ENCRYPT_MODE (1 << 27)
  21. #define AES_CTR_MODE         (2 << 27)
  22. #define AES_CTR_MODE         (2 << 27)
  23. #define AES_CBC_DECRYPT_MODE (4 << 27)
  24. #define AES_CBC_ENCRYPT_MODE (5 << 27)
  25.  
  26. #define AES_CNT_START         0x80000000
  27. #define AES_CNT_INPUT_ORDER   0x02000000
  28. #define AES_CNT_OUTPUT_ORDER  0x01000000
  29. #define AES_CNT_INPUT_ENDIAN  0x00800000
  30. #define AES_CNT_OUTPUT_ENDIAN 0x00400000
  31. #define AES_CNT_FLUSH_READ    0x00000800
  32. #define AES_CNT_FLUSH_WRITE   0x00000400
  33.  
  34. void decrypt(void* key, void* iv, void* inbuf, void* outbuf, size_t size)
  35. {
  36.     setup_aeskey(0x3D, AES_BIG_INPUT|AES_NORMAL_INPUT, key);
  37.     use_aeskey(0x3D);
  38.     aes_decrypt(inbuf, outbuf, iv, size / AES_BLOCK_SIZE);
  39. }
  40.  
  41. void setup_aeskey(uint32_t keyno, int value, void* key)
  42. {
  43.     volatile uint32_t* aes_regs[] =
  44.     {
  45.         (volatile uint32_t*)0x19009060,
  46.         (volatile uint32_t*)0x10009090,
  47.         (volatile uint32_t*)0x100090C0,
  48.         (volatile uint32_t*)0x100090F0
  49.     };
  50.     uint32_t * _key = (uint32_t*)key;
  51.     *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN|AES_CNT_INPUT_ORDER)) | (value << 23);
  52.     if (keyno > 3)
  53.     {
  54.         if (keyno > 0x3F)
  55.             return;
  56.         *REG_AESKEYCNT = (*REG_AESKEYCNT & 0x40) | -0x80;
  57.         *REG_AESKEYFIFO = _key[0];
  58.         *REG_AESKEYFIFO = _key[1];
  59.         *REG_AESKEYFIFO = _key[2];
  60.         *REG_AESKEYFIFO = _key[3];
  61.     }
  62.     else
  63.     {
  64.         volatile uint32_t* aes_reg = aes_regs[keyno];
  65.         if (value & 0x4)
  66.         {
  67.             aes_reg[0] = _key[3];
  68.             aes_reg[1] = _key[2];
  69.             aes_reg[2] = _key[1];
  70.             aes_reg[3] = _key[0];
  71.         }
  72.         else
  73.         {
  74.             aes_reg[0] = _key[0];
  75.             aes_reg[1] = _key[1];
  76.             aes_reg[2] = _key[2];
  77.             aes_reg[3] = _key[3];
  78.         }
  79.     }
  80. }
  81.  
  82. void use_aeskey(uint32_t keyno)
  83. {
  84.     if (keyno > 0x3F)
  85.         return;
  86.     *REG_AESKEYSEL = keyno;
  87.     *REG_AESCNT    = *REG_AESCNT | 0x04000000; /* mystery bit */
  88. }
  89.  
  90. void set_iv(int mode, void* iv)
  91. {
  92.     uint32_t * _iv = (uint32_t*)iv;
  93.     *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN|AES_CNT_INPUT_ORDER)) | (mode << 23);
  94.     if (mode & AES_NORMAL_INPUT)
  95.     {
  96.         *(REG_AESCTR + 0) = _iv[3];
  97.         *(REG_AESCTR + 1) = _iv[2];
  98.         *(REG_AESCTR + 2) = _iv[1];
  99.         *(REG_AESCTR + 3) = _iv[0];
  100.     }
  101.     else
  102.     {
  103.         *(REG_AESCTR + 0) = _iv[0];
  104.         *(REG_AESCTR + 1) = _iv[1];
  105.         *(REG_AESCTR + 2) = _iv[2];
  106.         *(REG_AESCTR + 3) = _iv[3];
  107.     }
  108. }
  109.  
  110. void aes_decrypt(void* inbuf, void* outbuf, void* iv, size_t size)
  111. {
  112.     uint32_t in  = (uint32_t)inbuf;
  113.     uint32_t out = (uint32_t)outbuf;
  114.     size_t block_count = size;
  115.     size_t blocks;
  116.     while (block_count != 0)
  117.     {
  118.         blocks = (block_count >= 0xFFFF) ? 0xFFFF : block_count;
  119.         set_iv(AES_BIG_INPUT|AES_NORMAL_INPUT, iv);
  120.         _decrypt(AES_CBC_ENCRYPT_MODE, (void*)in, (void*)out, blocks);
  121.         memcpy(iv, (void*)(((blocks + 0x3FFFFFFF)<<4) + out), AES_BLOCK_SIZE);
  122.         in  += blocks * AES_BLOCK_SIZE;
  123.         out += blocks * AES_BLOCK_SIZE;
  124.         block_count -= blocks;
  125.     }
  126. }
  127.  
  128. void _decrypt(uint32_t value, void* inbuf, void* outbuf, size_t blocks)
  129. {
  130.     *REG_AESCNT = 0;
  131.     *REG_AESBLKCNT = blocks << 16;
  132.     *REG_AESCNT = value |
  133.         AES_CNT_START |
  134.         AES_CNT_INPUT_ORDER |
  135.         AES_CNT_OUTPUT_ORDER |
  136.         AES_CNT_INPUT_ENDIAN |
  137.         AES_CNT_OUTPUT_ENDIAN |
  138.         AES_CNT_FLUSH_READ |
  139.         AES_CNT_FLUSH_WRITE;
  140.     aes_fifos(inbuf, outbuf, blocks);
  141. }
  142.  
  143. void aes_fifos(void* inbuf, void* outbuf, size_t blocks)
  144. {
  145.     uint32_t in  = (uint32_t)inbuf;
  146.     uint32_t out = (uint32_t)outbuf;
  147.     size_t curblock = 0;
  148.     while (curblock != blocks)
  149.     {
  150.         if (in)
  151.         {
  152.             while (aescnt_checkwrite()) ;
  153.             int ii = 0;
  154.             for (ii = in; ii != in + AES_BLOCK_SIZE; ii += 4)
  155.             {
  156.                 set_aeswrfifo( *(uint32_t*)(in) );
  157.             }
  158.             if (out)
  159.             {
  160.                 while (aescnt_checkread()) ;
  161.                 for (ii = out; ii != out + AES_BLOCK_SIZE; ii += 4)
  162.                 {
  163.                     *(uint32_t*)ii = read_aesrdfifo();
  164.                 }
  165.             }
  166.         }
  167.         curblock++;
  168.     }
  169. }
  170.  
  171. void set_aeswrfifo(uint32_t value)
  172. {
  173.     *REG_AESWRFIFO = value;
  174. }
  175.  
  176. uint32_t read_aesrdfifo(void)
  177. {
  178.     return *REG_AESRDFIFO;
  179. }
  180.  
  181. uint32_t aes_getwritecount()
  182. {
  183.     return *REG_AESCNT & 0x1F;
  184. }
  185.  
  186. uint32_t aes_getreadcount()
  187. {
  188.     return (*REG_AESCNT >> 5) & 0x1F;
  189. }
  190.  
  191. uint32_t aescnt_checkwrite()
  192. {
  193.     size_t ret = aes_getwritecount();
  194.     return (ret > 0xF);
  195. }
  196.  
  197. uint32_t aescnt_checkread()
  198. {
  199.     size_t ret = aes_getreadcount();
  200.     return (ret <= 3);
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement