Subversion Repositories Kolibri OS

Rev

Rev 7698 | Go to most recent revision | Blame | 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. MD5_BLOCK_SIZE = 64
  24.  
  25. struct hmac_md5_context
  26.         hash            rb MD5_LEN
  27.         ipad_ctx        rb LIBCRASH_CTX_LEN
  28.         opad_ctx        rb LIBCRASH_CTX_LEN
  29. ends
  30.  
  31. ; We will precompute partial hashes of K XOR ipad and K XOR opad,
  32. ; and store them in the context structure.
  33.  
  34. proc hmac_md5_setkey ctx, key, key_length
  35.  
  36. locals
  37.         k_temp  rb MD5_BLOCK_SIZE
  38. endl
  39.  
  40.         pusha
  41.  
  42. ; input esi = key, ecx=key_length
  43.         mov     ecx, [key_length]
  44.         cmp     ecx, MD5_BLOCK_SIZE
  45.         ja      .hash_it
  46. ; Key is smaller then or equal to blocksize,
  47. ; copy key to ipad
  48.         mov     esi, [key]
  49.         lea     edi, [k_temp]
  50.         rep movsb
  51.         mov     ecx, MD5_BLOCK_SIZE
  52.         sub     ecx, [key_length]
  53.         jz      .finish
  54. ; append zeros to the key
  55.         xor     al, al
  56.         rep stosb
  57.         jmp     .finish
  58.  
  59. ; Given key is larger then key size, hash it
  60.   .hash_it:
  61.         invoke  md5_init, [ctx]
  62.         invoke  md5_update, [ctx], [key], [key_length]
  63.         invoke  md5_final, [ctx]
  64.         mov     esi, [ctx]
  65.         lea     edi, [k_temp]
  66.         mov     ecx, MD5_HASH_SIZE/4
  67.         rep movsd
  68.         xor     eax, eax
  69.         mov     ecx, (MD5_BLOCK_SIZE-MD5_HASH_SIZE)/4
  70.         rep stosd
  71.  
  72.   .finish:
  73. ; xor ipad buffer with 0x36363...
  74.         lea     esi, [k_temp]
  75.         mov     ecx, MD5_BLOCK_SIZE/4
  76.   @@:
  77.         xor     dword[esi], 0x36363636          ; ipad constant
  78.         add     esi, 4
  79.         dec     ecx
  80.         jnz     @r
  81.  
  82. ; Init our hash with k_xor_ipad
  83.         mov     ebx, [ctx]
  84.         lea     edi, [ebx+hmac_md5_context.ipad_ctx]
  85.         invoke  md5_init, edi
  86.  
  87.         lea     esi, [k_temp]
  88.         DEBUGF  1, "HASH: "
  89.         stdcall dump_hex, esi, MD5_BLOCK_SIZE/4
  90.  
  91.         mov     ebx, [ctx]
  92.         lea     edi, [ebx+hmac_md5_context.ipad_ctx]
  93.         invoke  md5_update, edi, esi, MD5_BLOCK_SIZE
  94.  
  95. ; xor opad buffer with 0x5c5c5...
  96.         lea     esi, [k_temp]
  97.         mov     ecx, MD5_BLOCK_SIZE/4
  98.   @@:
  99.         xor     dword[esi], 0x36363636 xor 0x5c5c5c5c   ; opad constant
  100.         add     esi, 4
  101.         dec     ecx
  102.         jnz     @r
  103.  
  104. ; Init our hash with k_xor_opad
  105.         mov     ebx, [ctx]
  106.         lea     edi, [ebx+hmac_md5_context.opad_ctx]
  107.         invoke  md5_init, edi
  108.  
  109.         lea     esi, [k_temp]
  110.         DEBUGF  1, "HASH: "
  111.         stdcall dump_hex, esi, MD5_BLOCK_SIZE/4
  112.  
  113.         mov     ebx, [ctx]
  114.         lea     edi, [ebx+hmac_md5_context.opad_ctx]
  115.         invoke  md5_update, edi, esi, MD5_BLOCK_SIZE
  116.  
  117.         popa
  118.         ret
  119.  
  120. endp
  121.  
  122. ; Copy our pre-computed partial hashes to the stack, complete and finalize them.
  123. ; TODO: prevent unnescessary copying of output hash
  124. ; TODO: remove unnescessary pushing/popping
  125.  
  126. proc hmac_md5 ctx, _data, _length
  127.  
  128. locals
  129.         inner_ctx        ctx_md5
  130.         outer_ctx        ctx_md5
  131. endl
  132.  
  133.         pusha
  134.         DEBUGF  1, "HMAC: "
  135.         mov     ebx, [_length]
  136.         shr     ebx, 2
  137.         stdcall dump_hex, [_data], ebx
  138.  
  139. ; Copy partial hashes of ipad and opad to our temporary buffers
  140.         mov     esi, [ctx]
  141.         lea     esi, [esi+hmac_md5_context.ipad_ctx]
  142.         lea     edi, [inner_ctx]
  143. repeat (sizeof.ctx_md5)/4*2
  144.         movsd
  145. end repeat
  146.  
  147. ; Append provided data to inner hash and finalize
  148.         lea     ebx, [inner_ctx]
  149.         invoke  md5_update, ebx, [_data], [_length]
  150.         lea     ebx, [inner_ctx]
  151.         invoke  md5_final, ebx
  152.  
  153.         DEBUGF  1, "Inner Hash: "
  154.         lea     esi, [inner_ctx.hash]
  155.         stdcall dump_hex, esi, MD5_HASH_SIZE/4
  156.  
  157. ; Calculate outer hash
  158.         lea     ebx, [outer_ctx]
  159.         lea     esi, [inner_ctx.hash]
  160.         invoke  md5_update, ebx, esi, MD5_HASH_SIZE
  161.         lea     ebx, [outer_ctx]
  162.         invoke  md5_final, ebx
  163. ; Copy output hash to ctx structure     ; FIXME
  164.         lea     esi, [outer_ctx.hash]
  165.         mov     edi, [ctx]
  166. repeat MD5_HASH_SIZE/4
  167.         movsd
  168. end repeat
  169.  
  170.         popa
  171.         ret
  172.  
  173. endp
  174.