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) <2012-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. SHA1_BLOCK_SIZE = 64
  20.  
  21. SHA1_ALIGN      = 4
  22. SHA1_ALIGN_MASK = SHA1_ALIGN - 1
  23.  
  24. struct ctx_sha1
  25.         hash            rb SHA1_LEN
  26.         block           rb SHA1_BLOCK_SIZE
  27.         index           rd 1
  28.         msglen_0        rd 1
  29.         msglen_1        rd 1
  30. ends
  31.  
  32. assert sizeof.ctx_sha1 <= LIBCRASH_CTX_LEN
  33.  
  34. proc sha1._.f
  35.         push    ebx ecx edx
  36.         xor     ecx, edx
  37.         and     ebx, ecx
  38.         xor     ebx, edx
  39.         mov     esi, ebx
  40.         pop     edx ecx ebx
  41.         ret
  42. endp
  43.  
  44. proc sha1._.g
  45.         push    ebx ecx edx
  46.         xor     ebx, ecx
  47.         xor     ebx, edx
  48.         mov     esi, ebx
  49.         pop     edx ecx ebx
  50.         ret
  51. endp
  52.  
  53. proc sha1._.h
  54.         push    ebx ecx edx
  55.         mov     esi, ebx
  56.         and     ebx, ecx
  57.         and     ecx, edx
  58.         and     esi, edx
  59.         or      ebx, ecx
  60.         or      esi, ebx
  61.         pop     edx ecx ebx
  62.         ret
  63. endp
  64.  
  65. macro sha1._.round f, k, c
  66. {
  67.         mov     esi, eax
  68.         rol     esi, 5
  69.         mov     [temp], esi
  70.         call    f
  71.  
  72.         add     esi, edi
  73.         add     [temp], esi
  74.         mov     esi, [w + (c)*4]
  75.         add     esi, k
  76.         add     [temp], esi
  77.  
  78.         mov     edi, edx
  79.         mov     edx, ecx
  80.         mov     ecx, ebx
  81.         rol     ecx, 30
  82.         mov     ebx, eax
  83.         mov     eax, [temp]
  84. }
  85.  
  86.  
  87. proc sha1.init uses ebx esi edi, _ctx
  88.         mov     ebx, [_ctx]
  89.         lea     edi, [ebx + ctx_sha1.hash]
  90.         mov     esi, sha1._.hash_init
  91.         mov     ecx, SHA1_LEN/4
  92.         rep movsd
  93.         xor     eax, eax
  94.         mov     [ebx + ctx_sha1.index], eax
  95.         mov     [ebx + ctx_sha1.msglen_0], eax
  96.         mov     [ebx + ctx_sha1.msglen_1], eax
  97.         ret
  98. endp
  99.  
  100.  
  101. proc sha1._.block _hash
  102. locals
  103.         temp     rd 1
  104.         w        rd 80
  105. endl
  106.         lea     edi, [w]
  107.         xor     ecx, ecx
  108. @@:
  109.         mov     eax, [esi]
  110.         add     esi, 4
  111.         bswap   eax
  112.         mov     [edi], eax
  113.         add     edi, 4
  114.         add     ecx, 1
  115.         cmp     ecx, 16
  116.         jne     @b
  117. @@:
  118.         mov     eax, [w + (ecx -  3)*4]
  119.         xor     eax, [w + (ecx -  8)*4]
  120.         xor     eax, [w + (ecx - 14)*4]
  121.         xor     eax, [w + (ecx - 16)*4]
  122.         rol     eax, 1
  123.         mov     [w + ecx*4], eax
  124.         add     ecx, 1
  125.         cmp     ecx, 80
  126.         jne     @b
  127.  
  128.         mov     edi, [_hash]
  129.         mov     eax, [edi + 0x00]
  130.         mov     ebx, [edi + 0x04]
  131.         mov     ecx, [edi + 0x08]
  132.         mov     edx, [edi + 0x0c]
  133.         mov     edi, [edi + 0x10]
  134.  
  135.         push    esi
  136.  
  137. repeat 20
  138.         sha1._.round    sha1._.f, 0x5a827999, %-1
  139. end repeat
  140.  
  141. repeat 20
  142.         sha1._.round    sha1._.g, 0x6ed9eba1, %-1+20
  143. end repeat
  144.  
  145. repeat 20
  146.         sha1._.round    sha1._.h, 0x8f1bbcdc, %-1+40
  147. end repeat
  148.  
  149. repeat 20
  150.         sha1._.round    sha1._.g, 0xca62c1d6, %-1+60
  151. end repeat
  152.  
  153.         pop     esi
  154.  
  155.         mov     [temp], edi
  156.         mov     edi, [_hash]
  157.         add     [edi + 0x00], eax
  158.         add     [edi + 0x04], ebx
  159.         add     [edi + 0x08], ecx
  160.         add     [edi + 0x0c], edx
  161.         mov     eax, [temp]
  162.         add     [edi + 0x10], eax
  163.  
  164.         ret
  165. endp
  166.  
  167.  
  168. proc sha1.update uses ebx esi edi, _ctx, _msg, _size
  169.         mov     ebx, [_ctx]
  170.         mov     ecx, [_size]
  171.         add     [ebx + ctx_sha1.msglen_0], ecx
  172.         adc     [ebx + ctx_sha1.msglen_1], 0
  173.  
  174. .next_block:
  175.         mov     ebx, [_ctx]
  176.         mov     esi, [_msg]
  177.         mov     eax, [ebx + ctx_sha1.index]
  178.         and     eax, SHA1_BLOCK_SIZE-1
  179.         jnz     .copy_to_buf
  180.         test    esi, SHA1_ALIGN_MASK
  181.         jnz     .copy_to_buf
  182. .no_copy:
  183.         ; data is aligned, hash it in place without copying
  184.         mov     ebx, [_ctx]
  185.         cmp     [_size], SHA1_BLOCK_SIZE
  186.         jb      .copy_quit
  187.         lea     eax, [ebx + ctx_sha1.hash]
  188.         stdcall sha1._.block, eax
  189.         sub     [_size], SHA1_BLOCK_SIZE
  190. ;        add     esi, SHA1_BLOCK_SIZE           ; FIXME
  191.         jmp     .no_copy
  192.  
  193. .copy_to_buf:
  194.         lea     edi, [ebx + ctx_sha1.block]
  195.         add     edi, eax
  196.         mov     ecx, SHA1_BLOCK_SIZE
  197.         sub     ecx, eax
  198.         cmp     [_size], ecx
  199.         jb      .copy_quit
  200.         sub     [_size], ecx
  201.         add     [_msg], ecx
  202.         add     [ebx + ctx_sha1.index], ecx
  203.         rep movsb
  204.         lea     eax, [ebx + ctx_sha1.hash]
  205.         lea     esi, [ebx + ctx_sha1.block]
  206.         stdcall sha1._.block, eax
  207.         jmp     .next_block
  208.  
  209. .copy_quit:
  210.         mov     ebx, [_ctx]
  211.         lea     edi, [ebx + ctx_sha1.block]
  212.         mov     eax, [ebx + ctx_sha1.index]
  213.         and     eax, SHA1_BLOCK_SIZE-1
  214.         add     edi, eax
  215.         mov     ecx, [_size]
  216.         add     [ebx + ctx_sha1.index], ecx
  217.         rep movsb
  218. .quit:
  219.  
  220.         ret
  221. endp
  222.  
  223.  
  224. proc sha1.finish uses ebx esi edi, _ctx
  225.         mov     ebx, [_ctx]
  226.         lea     edi, [ebx + ctx_sha1.block]
  227.         mov     ecx, [ebx + ctx_sha1.msglen_0]
  228.         and     ecx, SHA1_BLOCK_SIZE-1
  229.         add     edi, ecx
  230.         mov     byte[edi], 0x80
  231.         inc     edi
  232.         neg     ecx
  233.         add     ecx, SHA1_BLOCK_SIZE
  234.         cmp     ecx, 8
  235.         ja      .last
  236.  
  237.         dec     ecx
  238.         xor     eax, eax
  239.         rep stosb
  240.         lea     esi, [ebx + ctx_sha1.block]
  241.         lea     eax, [ebx + ctx_sha1.hash]
  242.         stdcall sha1._.block, eax
  243.         mov     ebx, [_ctx]
  244.         lea     edi, [ebx + ctx_sha1.block]
  245.         mov     ecx, SHA1_BLOCK_SIZE+1
  246. .last:
  247.         dec     ecx
  248.         sub     ecx, 8
  249.         xor     eax, eax
  250.         rep stosb
  251.         mov     eax, [ebx + ctx_sha1.msglen_0]
  252.         mov     edx, [ebx + ctx_sha1.msglen_1]
  253.         shld    edx, eax, 3
  254.         shl     eax, 3
  255.         bswap   eax
  256.         bswap   edx
  257.         mov     dword[edi], edx
  258.         mov     dword[edi+4], eax
  259.         lea     esi, [ebx + ctx_sha1.block]
  260.         lea     eax, [ebx + ctx_sha1.hash]
  261.         stdcall sha1._.block, eax
  262.  
  263.         mov     ebx, [_ctx]
  264.         lea     eax, [ebx + ctx_sha1.hash]
  265.         stdcall sha1._.postprocess, ebx, eax
  266.  
  267.         ret
  268. endp
  269.  
  270.  
  271. proc sha1._.postprocess _ctx, _hash
  272.         mov     ecx, 5
  273.         mov     esi, [_hash]
  274.         mov     edi, esi
  275. @@:
  276.         lodsd
  277.         bswap   eax
  278.         stosd
  279.         dec     ecx
  280.         jnz     @b
  281.         ret
  282. endp
  283.  
  284.  
  285. proc sha1.oneshot _ctx, _data, _len
  286.         stdcall sha1.init, [_ctx]
  287.         stdcall sha1.update, [_ctx], [_data], [_len]
  288.         stdcall sha1.finish, [_ctx]
  289.         ret
  290. endp
  291.  
  292.  
  293. iglobal
  294. align SHA1_ALIGN
  295. sha1._.hash_init dd 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
  296. endg
  297.