Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; libcrash -- cryptographic hash (and other) functions
  2. ;
  3. ; Copyright (C) <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. ; https://datatracker.ietf.org/doc/html/rfc7539
  20.  
  21. CHACHA20_BLOCK_SIZE = 64
  22. CHACHA20_KEY_SIZE = 32
  23. CHACHA20_NONCE_SIZE = 12
  24. CHACHA20_IV_SIZE = 16
  25.  
  26. struct ctx_chacha20
  27.         state rd CHACHA20_BLOCK_SIZE/4
  28.         key rd CHACHA20_KEY_SIZE/4
  29.         block_counter dd ?
  30.         nonce rd CHACHA20_NONCE_SIZE/4
  31.         partial_cnt dd ?
  32. ends
  33.  
  34. assert sizeof.ctx_chacha20 <= LIBCRASH_CTX_LEN
  35.  
  36. proc chacha20.init uses ebx esi edi, _ctx, _key, _iv, _flags
  37.         mov     ebx, [_ctx]
  38.         mov     esi, [_key]
  39.         lea     edi, [ebx+ctx_chacha20.key]
  40.         mov     ecx, CHACHA20_KEY_SIZE/4
  41.         rep movsd
  42.         mov     esi, [_iv]
  43.         lea     edi, [ebx+ctx_chacha20.block_counter]
  44.         mov     ecx, CHACHA20_IV_SIZE/4
  45.         rep movsd
  46.         mov     [ebx+ctx_chacha20.partial_cnt], 0
  47.         ret
  48. endp
  49.  
  50. macro chacha20._.quarter_round a, b, c, d {
  51.         ; a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
  52.         mov     eax, [esi+a*4]
  53.         add     eax, [esi+b*4]
  54.         mov     [esi+a*4], eax
  55.         xor     eax, [esi+d*4]
  56.         rol     eax, 16
  57.         mov     [esi+d*4], eax
  58.         ; c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
  59.         mov     eax, [esi+c*4]
  60.         add     eax, [esi+d*4]
  61.         mov     [esi+c*4], eax
  62.         xor     eax, [esi+b*4]
  63.         rol     eax, 12
  64.         mov     [esi+b*4], eax
  65.         ; a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
  66.         mov     eax, [esi+a*4]
  67.         add     eax, [esi+b*4]
  68.         mov     [esi+a*4], eax
  69.         xor     eax, [esi+d*4]
  70.         rol     eax, 8
  71.         mov     [esi+d*4], eax
  72.         ; c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
  73.         mov     eax, [esi+c*4]
  74.         add     eax, [esi+d*4]
  75.         mov     [esi+c*4], eax
  76.         xor     eax, [esi+b*4]
  77.         rol     eax, 7
  78.         mov     [esi+b*4], eax
  79. }
  80.  
  81. proc chacha20._.inner_block _state
  82.         mov     esi, [_state]
  83.         chacha20._.quarter_round 0, 4,  8, 12
  84.         chacha20._.quarter_round 1, 5,  9, 13
  85.         chacha20._.quarter_round 2, 6, 10, 14
  86.         chacha20._.quarter_round 3, 7, 11, 15
  87.         chacha20._.quarter_round 0, 5, 10, 15
  88.         chacha20._.quarter_round 1, 6, 11, 12
  89.         chacha20._.quarter_round 2, 7,  8, 13
  90.         chacha20._.quarter_round 3, 4,  9, 14
  91.         ret
  92. endp
  93.  
  94. proc chacha20._.block_init _ctx
  95.         mov     edi, [_ctx]
  96.         lea     esi, [edi+ctx_chacha20.key]
  97.         mov     [edi+ctx_chacha20.state+0*4], 'expa'    ; magic
  98.         mov     [edi+ctx_chacha20.state+1*4], 'nd 3'    ; constants
  99.         mov     [edi+ctx_chacha20.state+2*4], '2-by'    ; from
  100.         mov     [edi+ctx_chacha20.state+3*4], 'te k'    ; the RFC
  101.         add     edi, 4*4
  102.         mov     ecx, CHACHA20_BLOCK_SIZE/4-4    ; the four dwords above
  103.         rep movsd
  104.         ret
  105. endp
  106.  
  107.  
  108. proc chacha20._.block _state
  109. locals
  110.         .working_state rd CHACHA20_BLOCK_SIZE/4
  111.         .i dd ?
  112. endl
  113.         stdcall chacha20._.block_init, [_state]
  114.  
  115.         mov     esi, [_state]
  116.         lea     edi, [.working_state]
  117.         mov     ecx, CHACHA20_BLOCK_SIZE/4
  118.         rep movsd
  119.  
  120.         mov     [.i], 10
  121. @@:
  122.         lea     eax, [.working_state]
  123.         stdcall chacha20._.inner_block, eax
  124.         dec     [.i]
  125.         jnz     @b
  126.  
  127.         lea     esi, [.working_state]
  128.         mov     edi, [_state]
  129.         mov     ecx, CHACHA20_BLOCK_SIZE/4-1
  130. @@:
  131.         mov     eax, [esi+ecx*4]
  132.         add     [edi+ecx*4], eax
  133.         dec     ecx
  134.         jns     @b
  135.  
  136.         ret
  137. endp
  138.  
  139. proc chacha20.update uses ebx esi edi, _ctx, _in, _len, _out
  140. locals
  141.         .bytes_done dd ?
  142. endl
  143.         mov     eax, [_len]
  144.         mov     [.bytes_done], eax
  145.         mov     ebx, [_ctx]
  146.         mov     edx, [ebx+ctx_chacha20.partial_cnt]
  147. .next_chunk:
  148.         mov     ecx, [_len]
  149.         test    ecx, ecx
  150.         jz      .done
  151.         test    edx, edx
  152.         jnz     @f
  153.         pushad
  154.         stdcall chacha20._.block, [_ctx]
  155.         popad
  156.         mov     edx, CHACHA20_BLOCK_SIZE
  157.         inc     [ebx+ctx_chacha20.block_counter]
  158. @@:
  159.         cmp     ecx, edx
  160.         jbe     @f
  161.         mov     ecx, edx
  162. @@:
  163.         lea     esi, [ebx+ctx_chacha20.state]
  164.         add     esi, CHACHA20_BLOCK_SIZE
  165.         sub     esi, edx
  166.         sub     [_len], ecx
  167.         sub     edx, ecx
  168.         push    ebx
  169.         mov     edi, [_out]
  170.         mov     ebx, [_in]
  171.         add     [_in], ecx
  172.         add     [_out], ecx
  173. @@:
  174.         lodsb
  175.         xor     al, [ebx]
  176.         inc     ebx
  177.         stosb
  178.         loop    @b
  179.         pop     ebx
  180.         jmp     .next_chunk
  181. .done:
  182.         mov     [ebx+ctx_chacha20.partial_cnt], edx
  183.         mov     eax, [.bytes_done]
  184.         ret
  185. endp
  186.  
  187. proc chacha20.finish _ctx, _out
  188.         xor     eax, eax
  189.         ret
  190. endp
  191.  
  192. proc chacha20.oneshot _ctx, _key, _iv, _flags, _in, _len, _out
  193. locals
  194.         .done dd ?
  195. endl
  196.         mov     [.done], 0
  197.         stdcall chacha20.init, [_ctx], [_key], [_iv], [_flags]
  198.         stdcall chacha20.update, [_ctx], [_in], [_len], [_out]
  199.         add     [_out], eax
  200.         add     [.done], eax
  201.         stdcall chacha20.finish, [_ctx], [_out]
  202.         add     eax, [.done]
  203.         ret
  204. endp
  205.