Subversion Repositories Kolibri OS

Rev

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

  1. ;    hmac.inc - HMAC: Keyed-Hashing for Message Authentication
  2. ;
  3. ;    Copyright (C) 2016 Denis Karpenko
  4. ;    Copyright (C) 2016 Jeffrey Amelynck
  5. ;
  6. ;    This program is free software: you can redistribute it and/or modify
  7. ;    it under the terms of the GNU General Public License as published by
  8. ;    the Free Software Foundation, either version 3 of the License, or
  9. ;    (at your option) any later version.
  10. ;
  11. ;    This program is distributed in the hope that it will be useful,
  12. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;    GNU General Public License for more details.
  15. ;
  16. ;    You should have received a copy of the GNU General Public License
  17. ;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. ; Main concept:
  20. ; To compute HMAC over the data `text' we perform
  21. ; H(K XOR opad, H(K XOR ipad, text))
  22.  
  23. struct hmac_sha1_context
  24.         hash            rb SHA1_HASH_SIZE
  25.         ipad_ctx        crash_ctx
  26.         opad_ctx        crash_ctx
  27. ends
  28.  
  29. ; We will precompute partial hashes of K XOR ipad and K XOR opad,
  30. ; and store them in the context structure.
  31.  
  32. proc hmac_sha1_setkey ctx, key, key_length
  33.  
  34. locals
  35.         k_temp  rb SHA1_BLOCK_SIZE
  36. endl
  37.  
  38.         pusha
  39.  
  40. ; input esi = key, ecx=key_length
  41.         mov     ecx, [key_length]
  42.         cmp     ecx, SHA1_BLOCK_SIZE
  43.         ja      .hash_it
  44. ; Key is smaller then or equal to blocksize,
  45. ; copy key to ipad
  46.         mov     esi, [key]
  47.         lea     edi, [k_temp]
  48.         rep movsb
  49.         mov     ecx, SHA1_BLOCK_SIZE
  50.         sub     ecx, [key_length]
  51.         jz      .finish
  52. ; append zeros to the key
  53.         xor     al, al
  54.         rep stosb
  55.         jmp     .finish
  56.  
  57. ; Given key is larger then key size, hash it
  58.   .hash_it:
  59.         invoke  sha1_init, [ctx]
  60.         invoke  sha1_update, [ctx], [key], [key_length]
  61.         invoke  sha1_final, [ctx]
  62.         mov     esi, [ctx]
  63.         lea     edi, [k_temp]
  64.         mov     ecx, SHA1_HASH_SIZE/4
  65.         rep movsd
  66.         xor     eax, eax
  67.         mov     ecx, (SHA1_BLOCK_SIZE-SHA1_HASH_SIZE)/4
  68.         rep stosd
  69.  
  70.   .finish:
  71. ; xor ipad buffer with 0x36363...
  72.         lea     esi, [k_temp]
  73.         mov     ecx, SHA1_BLOCK_SIZE/4
  74.   @@:
  75.         xor     dword[esi], 0x36363636          ; ipad constant
  76.         add     esi, 4
  77.         dec     ecx
  78.         jnz     @r
  79.  
  80. ; Init our hash with k_xor_ipad
  81.         mov     ebx, [ctx]
  82.         lea     edi, [ebx+hmac_sha1_context.ipad_ctx]
  83.         invoke  sha1_init, edi
  84.  
  85.         lea     esi, [k_temp]
  86.         DEBUGF  1, "HASH: "
  87.         stdcall dump_hex, esi, SHA1_BLOCK_SIZE/4
  88.  
  89.         mov     ebx, [ctx]
  90.         lea     edi, [ebx+hmac_sha1_context.ipad_ctx]
  91.         invoke  sha1_update, edi, esi, SHA1_BLOCK_SIZE
  92.  
  93. ; xor opad buffer with 0x5c5c5...
  94.         lea     esi, [k_temp]
  95.         mov     ecx, SHA1_BLOCK_SIZE/4
  96.   @@:
  97.         xor     dword[esi], 0x36363636 xor 0x5c5c5c5c   ; opad constant
  98.         add     esi, 4
  99.         dec     ecx
  100.         jnz     @r
  101.  
  102. ; Init our hash with k_xor_opad
  103.         mov     ebx, [ctx]
  104.         lea     edi, [ebx+hmac_sha1_context.opad_ctx]
  105.         invoke  sha1_init, edi
  106.  
  107.         lea     esi, [k_temp]
  108.         DEBUGF  1, "HASH: "
  109.         stdcall dump_hex, esi, SHA1_BLOCK_SIZE/4
  110.  
  111.         mov     ebx, [ctx]
  112.         lea     edi, [ebx+hmac_sha1_context.opad_ctx]
  113.         invoke  sha1_update, edi, esi, SHA1_BLOCK_SIZE
  114.  
  115.         popa
  116.         ret
  117.  
  118. endp
  119.  
  120. ; Copy our pre-computed partial hashes to the stack, complete and finalize them.
  121. ; TODO: prevent unnescessary copying of output hash
  122. ; TODO: remove unnescessary pushing/popping
  123.  
  124. proc hmac_sha1 ctx, _data, _length
  125.  
  126. locals
  127.         inner_ctx        ctx_sha1
  128.         outer_ctx        ctx_sha1
  129. endl
  130.  
  131.         pusha
  132.         DEBUGF  1, "HMAC: "
  133.         mov     ebx, [_length]
  134.         shr     ebx, 2
  135.         stdcall dump_hex, [_data], ebx
  136.  
  137. ; Copy partial hashes of ipad and opad to our temporary buffers
  138.         mov     esi, [ctx]
  139.         lea     esi, [esi+hmac_sha1_context.ipad_ctx]
  140.         lea     edi, [inner_ctx]
  141. repeat (sizeof.ctx_sha1)/4*2
  142.         movsd
  143. end repeat
  144.  
  145. ; Append provided data to inner hash and finalize
  146.         lea     ebx, [inner_ctx]
  147.         invoke  sha1_update, ebx, [_data], [_length]
  148.         lea     ebx, [inner_ctx]
  149.         invoke  sha1_final, ebx
  150.  
  151.         DEBUGF  1, "Inner Hash: "
  152.         lea     esi, [inner_ctx.hash]
  153.         stdcall dump_hex, esi, SHA1_HASH_SIZE/4
  154.  
  155. ; Calculate outer hash
  156.         lea     ebx, [outer_ctx]
  157.         lea     esi, [inner_ctx.hash]
  158.         invoke  sha1_update, ebx, esi, SHA1_HASH_SIZE
  159.         lea     ebx, [outer_ctx]
  160.         invoke  sha1_final, ebx
  161. ; Copy output hash to ctx structure     ; FIXME
  162.         lea     esi, [outer_ctx.hash]
  163.         mov     edi, [ctx]
  164. repeat SHA1_HASH_SIZE/4
  165.         movsd
  166. end repeat
  167.  
  168.         popa
  169.         ret
  170.  
  171. endp
  172.