Subversion Repositories Kolibri OS

Rev

Rev 7698 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; libcrash -- cryptographic hash (and other) functions
  2. ;
  3. ; Copyright (C) <2013,2016,2019,2021> Ivan Baravy
  4. ;
  5. ; SPDX-License-Identifier: GPL-2.0-or-later
  6. ;
  7. ; This program is free software: you can redistribute it and/or modify it under
  8. ; the terms of the GNU General Public License as published by the Free Software
  9. ; Foundation, either version 2 of the License, or (at your option) any later
  10. ; version.
  11. ;
  12. ; This program is distributed in the hope that it will be useful, but WITHOUT
  13. ; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  14. ; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  15. ;
  16. ; You should have received a copy of the GNU General Public License along with
  17. ; this program. If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. SHA3_224_BLOCK_SIZE = 144
  20. SHA3_256_BLOCK_SIZE = 136
  21. SHA3_384_BLOCK_SIZE = 104
  22. SHA3_512_BLOCK_SIZE = 72
  23. SHA3_MAX_BLOCK_SIZE = SHA3_224_BLOCK_SIZE
  24.  
  25. SHA3_INIT_SIZE          = 200
  26. SHA3_ALIGN              = 16
  27. SHA3_ALIGN_MASK         = SHA3_ALIGN-1
  28.  
  29. struct ctx_sha3
  30.         hash            rb SHA3_INIT_SIZE
  31.                         rb SHA3_ALIGN - (SHA3_INIT_SIZE mod SHA3_ALIGN)
  32.         block           rb SHA3_MAX_BLOCK_SIZE
  33.                         rb SHA3_ALIGN - (SHA3_MAX_BLOCK_SIZE mod SHA3_ALIGN)
  34.         index           rd 1
  35.         block_size      rd 1
  36.         rounds_cnt      rd 1
  37.                         rd 1    ; align
  38.         ; tmp vars
  39.         C               rq 5
  40.         D               rq 5
  41. ends
  42.  
  43. assert sizeof.ctx_sha3 <= LIBCRASH_CTX_LEN
  44.  
  45. macro sha3._.rol_xor nd, ncl, ncr
  46. {
  47.         movq    mm0, [C + 8*(ncl)]
  48.         movq    mm1, mm0
  49.         psllq   mm0, 1
  50.         psrlq   mm1, 63
  51.         por     mm0, mm1
  52.         pxor    mm0, [C + 8*(ncr)]
  53.         movq    [D + 8*(nd)], mm0
  54. }
  55.  
  56. proc sha3._.theta
  57. ;locals
  58. ;        C       rq 5
  59. ;        D       rq 5
  60. ;endl
  61. C equ ebx + ctx_sha3.C
  62. D equ ebx + ctx_sha3.D
  63.  
  64. repeat 5
  65.         movq    mm0, [edi + 8*(%-1 +  0)]
  66.         pxor    mm0, [edi + 8*(%-1 +  5)]
  67.         pxor    mm0, [edi + 8*(%-1 + 10)]
  68.         pxor    mm0, [edi + 8*(%-1 + 15)]
  69.         pxor    mm0, [edi + 8*(%-1 + 20)]
  70.         movq    [C + 8*(%-1)], mm0
  71. end repeat
  72.  
  73.         sha3._.rol_xor  0, 1, 4
  74.         sha3._.rol_xor  1, 2, 0
  75.         sha3._.rol_xor  2, 3, 1
  76.         sha3._.rol_xor  3, 4, 2
  77.         sha3._.rol_xor  4, 0, 3
  78.  
  79. repeat 5
  80.         movq    mm1, [D + 8*(%-1)]
  81.         movq    mm0, mm1
  82.         pxor    mm0, [edi + 8*(%-1 +  0)]
  83.         movq    [edi + 8*(%-1 +  0)], mm0
  84.         movq    mm0, mm1
  85.         pxor    mm0, [edi + 8*(%-1 +  5)]
  86.         movq    [edi + 8*(%-1 +  5)], mm0
  87.         movq    mm0, mm1
  88.         pxor    mm0, [edi + 8*(%-1 + 10)]
  89.         movq    [edi + 8*(%-1 + 10)], mm0
  90.         movq    mm0, mm1
  91.         pxor    mm0, [edi + 8*(%-1 + 15)]
  92.         movq    [edi + 8*(%-1 + 15)], mm0
  93.         movq    mm0, mm1
  94.         pxor    mm0, [edi + 8*(%-1 + 20)]
  95.         movq    [edi + 8*(%-1 + 20)], mm0
  96. end repeat
  97.  
  98. restore C,D
  99.         ret
  100. endp
  101.  
  102.  
  103. proc sha3._.pi
  104.         movq    mm1, [edi + 8*1]
  105.         movq    mm0, [edi + 8*6]
  106.         movq    [edi + 8*1], mm0
  107.         movq    mm0, [edi + 8*9]
  108.         movq    [edi + 8*6], mm0
  109.         movq    mm0, [edi + 8*22]
  110.         movq    [edi + 8*9], mm0
  111.         movq    mm0, [edi + 8*14]
  112.         movq    [edi + 8*22], mm0
  113.         movq    mm0, [edi + 8*20]
  114.         movq    [edi + 8*14], mm0
  115.         movq    mm0, [edi + 8*2]
  116.         movq    [edi + 8*20], mm0
  117.         movq    mm0, [edi + 8*12]
  118.         movq    [edi + 8*2], mm0
  119.         movq    mm0, [edi + 8*13]
  120.         movq    [edi + 8*12], mm0
  121.         movq    mm0, [edi + 8*19]
  122.         movq    [edi + 8*13], mm0
  123.         movq    mm0, [edi + 8*23]
  124.         movq    [edi + 8*19], mm0
  125.         movq    mm0, [edi + 8*15]
  126.         movq    [edi + 8*23], mm0
  127.         movq    mm0, [edi + 8*4]
  128.         movq    [edi + 8*15], mm0
  129.         movq    mm0, [edi + 8*24]
  130.         movq    [edi + 8*4], mm0
  131.         movq    mm0, [edi + 8*21]
  132.         movq    [edi + 8*24], mm0
  133.         movq    mm0, [edi + 8*8]
  134.         movq    [edi + 8*21], mm0
  135.         movq    mm0, [edi + 8*16]
  136.         movq    [edi + 8*8], mm0
  137.         movq    mm0, [edi + 8*5]
  138.         movq    [edi + 8*16], mm0
  139.         movq    mm0, [edi + 8*3]
  140.         movq    [edi + 8*5], mm0
  141.         movq    mm0, [edi + 8*18]
  142.         movq    [edi + 8*3], mm0
  143.         movq    mm0, [edi + 8*17]
  144.         movq    [edi + 8*18], mm0
  145.         movq    mm0, [edi + 8*11]
  146.         movq    [edi + 8*17], mm0
  147.         movq    mm0, [edi + 8*7]
  148.         movq    [edi + 8*11], mm0
  149.         movq    mm0, [edi + 8*10]
  150.         movq    [edi + 8*7], mm0
  151.         movq    [edi + 8*10], mm1
  152.  
  153.         ret
  154. endp
  155.  
  156.  
  157. proc sha3._.chi
  158.  
  159.         mov     eax, 0xffffffff
  160.         movd    mm0, eax
  161.         movq    mm2, mm0
  162.         punpckldq mm2, mm0
  163.  
  164. repeat 5
  165.         movq    mm6, [edi + 8*(0 + 5*(%-1))]
  166.         movq    mm7, [edi + 8*(1 + 5*(%-1))]
  167.  
  168.         movq    mm0, [edi + 8*(0 + 5*(%-1))]
  169.         movq    mm1, mm7
  170.         pandn   mm1, mm2
  171.         pand    mm1, [edi + 8*(2 + 5*(%-1))]
  172.         pxor    mm0, mm1
  173.         movq    [edi + 8*(0 + 5*(%-1))], mm0
  174.  
  175.         movq    mm0, [edi + 8*(1 + 5*(%-1))]
  176.         movq    mm1, [edi + 8*(2 + 5*(%-1))]
  177.         pandn   mm1, mm2
  178.         pand    mm1, [edi + 8*(3 + 5*(%-1))]
  179.         pxor    mm0, mm1
  180.         movq    [edi + 8*(1 + 5*(%-1))], mm0
  181.  
  182.         movq    mm0, [edi + 8*(2 + 5*(%-1))]
  183.         movq    mm1, [edi + 8*(3 + 5*(%-1))]
  184.         pandn   mm1, mm2
  185.         pand    mm1, [edi + 8*(4 + 5*(%-1))]
  186.         pxor    mm0, mm1
  187.         movq    [edi + 8*(2 + 5*(%-1))], mm0
  188.  
  189.         movq    mm0, [edi + 8*(3 + 5*(%-1))]
  190.         movq    mm1, [edi + 8*(4 + 5*(%-1))]
  191.         pandn   mm1, mm2
  192.         pand    mm1, mm6
  193.         pxor    mm0, mm1
  194.         movq    [edi + 8*(3 + 5*(%-1))], mm0
  195.  
  196.         movq    mm0, [edi + 8*(4 + 5*(%-1))]
  197.         movq    mm1, mm6
  198.         pandn   mm1, mm2
  199.         pand    mm1, mm7
  200.         pxor    mm0, mm1
  201.         movq    [edi + 8*(4 + 5*(%-1))], mm0
  202. end repeat
  203.         ret
  204. endp
  205.  
  206.  
  207. macro sha3._.rol_mov n, c
  208. {
  209.         movq    mm0, [edi + 8*(n)]
  210.         movq    mm1, mm0
  211.         psllq   mm0, (c)
  212.         psrlq   mm1, (64-(c))
  213.         por     mm0, mm1
  214.         movq    [edi + 8*(n)], mm0
  215. }
  216.  
  217. proc sha3._.permutation
  218.  
  219. repeat 24
  220.         stdcall sha3._.theta
  221.  
  222.         sha3._.rol_mov   1,  1
  223.         sha3._.rol_mov   2, 62
  224.         sha3._.rol_mov   3, 28
  225.         sha3._.rol_mov   4, 27
  226.         sha3._.rol_mov   5, 36
  227.         sha3._.rol_mov   6, 44
  228.         sha3._.rol_mov   7,  6
  229.         sha3._.rol_mov   8, 55
  230.         sha3._.rol_mov   9, 20
  231.         sha3._.rol_mov  10,  3
  232.         sha3._.rol_mov  11, 10
  233.         sha3._.rol_mov  12, 43
  234.         sha3._.rol_mov  13, 25
  235.         sha3._.rol_mov  14, 39
  236.         sha3._.rol_mov  15, 41
  237.         sha3._.rol_mov  16, 45
  238.         sha3._.rol_mov  17, 15
  239.         sha3._.rol_mov  18, 21
  240.         sha3._.rol_mov  19,  8
  241.         sha3._.rol_mov  20, 18
  242.         sha3._.rol_mov  21,  2
  243.         sha3._.rol_mov  22, 61
  244.         sha3._.rol_mov  23, 56
  245.         sha3._.rol_mov  24, 14
  246.  
  247.         stdcall sha3._.pi
  248.         stdcall sha3._.chi
  249.  
  250.         movq    mm0, [edi + 8*(0)]
  251.         pxor    mm0, [sha3._.round + 8*(%-1)]
  252.         movq    [edi + 8*(0)], mm0
  253. end repeat
  254.  
  255.         ret
  256. endp
  257.  
  258.  
  259. proc sha3._.init uses edi
  260.         mov     [ebx + ctx_sha3.block_size], eax
  261.         shr     eax, 3
  262.         dec     eax
  263.         mov     [ebx + ctx_sha3.rounds_cnt], eax
  264.         xor     eax, eax
  265.         lea     edi, [ebx + ctx_sha3.hash]
  266.         mov     ecx, SHA3_INIT_SIZE/4
  267.         rep stosd
  268.         mov     [ebx + ctx_sha3.index], eax
  269.         ret
  270. endp
  271.  
  272.  
  273. proc sha3_224.init uses ebx, _ctx
  274.         mov     ebx, [_ctx]
  275.         mov     eax, SHA3_224_BLOCK_SIZE
  276.         stdcall sha3._.init
  277.         ret
  278. endp
  279.  
  280.  
  281. proc sha3_256.init uses ebx, _ctx
  282.         mov     ebx, [_ctx]
  283.         mov     eax, SHA3_256_BLOCK_SIZE
  284.         stdcall sha3._.init
  285.         ret
  286. endp
  287.  
  288.  
  289. proc sha3_384.init uses ebx, _ctx
  290.         mov     ebx, [_ctx]
  291.         mov     eax, SHA3_384_BLOCK_SIZE
  292.         stdcall sha3._.init
  293.         ret
  294. endp
  295.  
  296.  
  297. proc sha3_512.init uses ebx, _ctx
  298.         mov     ebx, [_ctx]
  299.         mov     eax, SHA3_512_BLOCK_SIZE
  300.         stdcall sha3._.init
  301.         ret
  302. endp
  303.  
  304.  
  305. proc sha3._.block _hash
  306.         mov     ecx, [ebx + ctx_sha3.rounds_cnt]
  307.         mov     edi, [_hash]
  308.  
  309.     @@:
  310.         movq    mm0, [esi + 8*ecx]
  311.         pxor    mm0, [edi + 8*ecx]
  312.         movq    [edi + 8*ecx], mm0
  313.         dec     ecx
  314.         jns     @b
  315.  
  316.         stdcall sha3._.permutation
  317.  
  318.         ret
  319. endp
  320.  
  321.  
  322. sha3_224.update = sha3.update
  323. sha3_256.update = sha3.update
  324. sha3_384.update = sha3.update
  325. sha3_512.update = sha3.update
  326. proc sha3.update uses ebx esi edi, _ctx, _msg, _size
  327. .next_block:
  328.         mov     ebx, [_ctx]
  329.         mov     esi, [_msg]
  330.         mov     eax, [ebx + ctx_sha3.index]
  331.         test    eax, eax
  332.         jnz     .copy_to_buf
  333.         test    esi, SHA3_ALIGN_MASK
  334.         jnz     .copy_to_buf
  335. .no_copy:
  336.         ; data is aligned, hash it in place without copying
  337.         mov     ebx, [_ctx]
  338.         mov     eax, [ebx + ctx_sha3.block_size]
  339.         cmp     [_size], eax
  340.         jb      .copy_quit
  341.         lea     eax, [ebx + ctx_sha3.hash]
  342.         push    ebx esi
  343.         stdcall sha3._.block, eax
  344.         pop     esi ebx
  345.         mov     eax, [ebx + ctx_sha3.block_size]
  346.         sub     [_size], eax
  347.         add     esi, [ebx + ctx_sha3.block_size]
  348.         jmp     .no_copy
  349.  
  350. .copy_to_buf:
  351.         lea     edi, [ebx + ctx_sha3.block]
  352.         add     edi, eax
  353.         mov     ecx, [ebx + ctx_sha3.block_size]
  354.         sub     ecx, eax
  355.         cmp     [_size], ecx
  356.         jb      .copy_quit
  357.         sub     [_size], ecx
  358.         add     [_msg], ecx
  359.         add     [ebx + ctx_sha3.index], ecx
  360.         mov     eax, [ebx + ctx_sha3.block_size]
  361.         cmp     [ebx + ctx_sha3.index], eax
  362.         jb      @f
  363.         sub     [ebx + ctx_sha3.index], eax
  364.     @@:
  365.         rep movsb
  366.         lea     eax, [ebx + ctx_sha3.hash]
  367.         lea     esi, [ebx + ctx_sha3.block]
  368.         stdcall sha3._.block, eax
  369.         jmp     .next_block
  370.  
  371. .copy_quit:
  372.         mov     ebx, [_ctx]
  373.         lea     edi, [ebx + ctx_sha3.block]
  374.         mov     eax, [ebx + ctx_sha3.index]
  375.         add     edi, eax
  376.         mov     ecx, [_size]
  377.         add     [ebx + ctx_sha3.index], ecx
  378.         rep movsb
  379. .quit:
  380.         ret
  381. endp
  382.  
  383.  
  384. sha3_224.finish = sha3.finish
  385. sha3_256.finish = sha3.finish
  386. sha3_384.finish = sha3.finish
  387. sha3_512.finish = sha3.finish
  388. proc sha3.finish uses ebx esi edi, _ctx
  389.         mov     ebx, [_ctx]
  390.         mov     eax, [ebx + ctx_sha3.index]
  391.         mov     ecx, [ebx + ctx_sha3.block_size]
  392.         sub     ecx, eax
  393.         lea     edi, [ebx+ctx_sha3.block]
  394.         add     edi, eax
  395.         mov     byte[edi], 0x06
  396.         inc     edi
  397.         dec     ecx
  398.         xor     eax, eax
  399.         rep stosb
  400.         or      byte[edi - 1], 0x80
  401.  
  402.         mov     ebx, [_ctx]
  403.         lea     esi, [ebx + ctx_sha3.block]
  404.         lea     eax, [ebx + ctx_sha3.hash]
  405.         stdcall sha3._.block, eax
  406.  
  407.         mov     ebx, [_ctx]
  408.         lea     eax, [ebx + ctx_sha3.hash]
  409.         stdcall sha3._.postprocess, ebx, eax
  410.         ret
  411. endp
  412.  
  413.  
  414. proc sha3._.postprocess _ctx, _hash
  415.         emms
  416.         ret
  417. endp
  418.  
  419.  
  420. proc sha3_224.oneshot _ctx, _data, _len
  421.         stdcall sha3_224.init, [_ctx]
  422.         stdcall sha3.update, [_ctx], [_data], [_len]
  423.         stdcall sha3.finish, [_ctx]
  424.         ret
  425. endp
  426.  
  427.  
  428. proc sha3_256.oneshot _ctx, _data, _len
  429.         stdcall sha3_256.init, [_ctx]
  430.         stdcall sha3.update, [_ctx], [_data], [_len]
  431.         stdcall sha3.finish, [_ctx]
  432.         ret
  433. endp
  434.  
  435.  
  436. proc sha3_384.oneshot _ctx, _data, _len
  437.         stdcall sha3_384.init, [_ctx]
  438.         stdcall sha3.update, [_ctx], [_data], [_len]
  439.         stdcall sha3.finish, [_ctx]
  440.         ret
  441. endp
  442.  
  443.  
  444. proc sha3_512.oneshot _ctx, _data, _len
  445.         stdcall sha3_512.init, [_ctx]
  446.         stdcall sha3.update, [_ctx], [_data], [_len]
  447.         stdcall sha3.finish, [_ctx]
  448.         ret
  449. endp
  450.  
  451.  
  452. iglobal
  453. align SHA3_ALIGN
  454. sha3._.round    dq 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,\
  455.                    0x8000000080008000, 0x000000000000808B, 0x0000000080000001,\
  456.                    0x8000000080008081, 0x8000000000008009, 0x000000000000008A,\
  457.                    0x0000000000000088, 0x0000000080008009, 0x000000008000000A,\
  458.                    0x000000008000808B, 0x800000000000008B, 0x8000000000008089,\
  459.                    0x8000000000008003, 0x8000000000008002, 0x8000000000000080,\
  460.                    0x000000000000800A, 0x800000008000000A, 0x8000000080008081,\
  461.                    0x8000000000008080, 0x0000000080000001, 0x8000000080008008
  462. endg
  463.