Subversion Repositories Kolibri OS

Rev

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

  1. ; Implementation of AES crypto algorithm.
  2. ; Buffer size is 0x10 bytes (128 bits), key size is not fixed.
  3. ; Written by diamond in 2007.
  4. uglobal
  5. aes.pow_table   rb      256     ; pow[a] = 3^a
  6. aes.log_table   rb      256     ; log[3^a] = a
  7. aes.sbox        rb      256     ; ShiftBytes(a)
  8. aes.sbox_rev    rb      256     ; ShiftBytes^{-1}(a)
  9. aes.mctable     rd      256     ; MixColumns(ShiftBytes(a,0,0,0))
  10. aes.mcrtable    rd      256     ; MixColumns^{-1}(a,0,0,0)
  11. endg
  12.  
  13. init_aes:
  14. ; Byte values in SubBytes transform are interpreted as items of
  15. ;   GF(2^8) \cong F_2[x]/(x^8+x^4+x^3+x+1)F_2[x].
  16. ; x+1 is primitive item in this field.
  17.         xor     ebx, ebx
  18.         push    1
  19.         pop     eax
  20. .1:
  21.         mov     [aes.pow_table+ebx], al
  22.         mov     [aes.log_table+eax], bl
  23. ; Multiplication by x+1...
  24.         mov     cl, al  ; save value
  25. ; ...multiply by x with mod (x^8+x^4+x^3+x+1) = 0x11B...
  26.         add     al, al
  27.         jnc     @f
  28.         xor     al, 0x1B
  29. @@:
  30. ; ...and add operand
  31.         xor     al, cl
  32.         inc     bl
  33.         jnz     .1
  34. ; generate table for SubBytes transform
  35.         mov     [aes.sbox+0], 0x63
  36.         mov     [aes.sbox_rev+0x63], bl
  37.         inc     ebx
  38. .2:
  39. ; calculate inverse in GF(2^8)
  40.         mov     al, [aes.log_table+ebx]
  41.         xor     al, 0xFF        ; equivalent to "al = 0xFF - al"
  42.         mov     cl, [aes.pow_table+eax]
  43. ; linear transform of byte as vector over F_2
  44.         mov     al, cl
  45.         rol     cl, 1
  46.         xor     al, cl
  47.         rol     cl, 1
  48.         xor     al, cl
  49.         rol     cl, 1
  50.         xor     al, cl
  51.         rol     cl, 1
  52.         xor     al, cl
  53.         xor     al, 0x63
  54.         mov     [aes.sbox+ebx], al
  55.         mov     [aes.sbox_rev+eax], bl
  56.         inc     bl
  57.         jnz     .2
  58. ; generate table for SubBytes + MixColumn transforms
  59. .3:
  60.         mov     al, [aes.sbox+ebx]      ; SubBytes transform
  61.         mov     cl, al
  62.         add     cl, cl
  63.         jnc     @f
  64.         xor     cl, 0x1B
  65. @@:
  66.         mov     byte [aes.mctable+ebx*4], cl    ; low byte of MixColumn(a,0,0,0)
  67.         mov     byte [aes.mctable+ebx*4+1], al
  68.         mov     byte [aes.mctable+ebx*4+2], al
  69.         xor     cl, al
  70.         mov     byte [aes.mctable+ebx*4+3], cl  ; high byte of MixColumn(a,0,0,0)
  71.         inc     bl
  72.         jnz     .3
  73. ; generate table for reverse MixColumn transform
  74.         mov     dword [aes.mcrtable+0], ebx
  75.         inc     ebx
  76. .4:
  77. ; log_table[9]=0xC7, log_table[0xB]=0x68, log_table[0xD]=0xEE, log_table[0xE]=0xDF
  78.         mov     cl, [aes.log_table+ebx]
  79.         mov     al, cl
  80.         add     al, 0xDF
  81.         adc     al, 0
  82.         mov     al, [aes.pow_table+eax]
  83.         mov     byte [aes.mcrtable+ebx*4], al
  84.         mov     al, cl
  85.         add     al, 0xC7
  86.         adc     al, 0
  87.         mov     al, [aes.pow_table+eax]
  88.         mov     byte [aes.mcrtable+ebx*4+1], al
  89.         mov     al, cl
  90.         add     al, 0xEE
  91.         adc     al, 0
  92.         mov     al, [aes.pow_table+eax]
  93.         mov     byte [aes.mcrtable+ebx*4+2], al
  94.         mov     al, cl
  95.         add     al, 0x68
  96.         adc     al, 0
  97.         mov     al, [aes.pow_table+eax]
  98.         mov     byte [aes.mcrtable+ebx*4+3], al
  99.         inc     bl
  100.         jnz     .4
  101.         ret
  102.  
  103. aes_setkey:
  104. ; in: esi->key, edx=key size in dwords, edi->AES data struc
  105.         lea     eax, [edx+6]    ; calc number of rounds (buffer size=4)
  106.         stosd
  107.         shl     eax, 4
  108.         lea     ebx, [edi+eax+16]
  109.         mov     ecx, edx
  110.         rep     movsd
  111.         push    ebx
  112.         mov     bl, 1
  113. .0:
  114.         push    4
  115.         pop     ecx
  116. @@:
  117.         movzx   esi, byte [edi-5+ecx]
  118.         mov     al, [aes.sbox+esi]
  119.         rol     eax, 8
  120.         loop    @b
  121.         ror     eax, 16
  122.         mov     esi, edx
  123.         neg     esi
  124.         xor     eax, [edi+esi*4]
  125.         xor     al, bl
  126.         add     bl, bl
  127.         jnc     @f
  128.         xor     bl, 0x1B
  129. @@:
  130.         stosd
  131.         lea     ecx, [edx-1]
  132. .1:
  133.         cmp     edi, [esp]
  134.         jz      .ret
  135.         cmp     edx, 8
  136.         jnz     @f
  137.         cmp     ecx, 4
  138.         jnz     @f
  139.         push    eax
  140.         movzx   eax, al
  141.         mov     al, [aes.sbox+eax]
  142.         mov     [esp], al
  143.         mov     al, byte [esp+1]
  144.         mov     al, [aes.sbox+eax]
  145.         mov     [esp+1], al
  146.         mov     al, byte [esp+2]
  147.         mov     al, [aes.sbox+eax]
  148.         mov     [esp+2], al
  149.         mov     al, byte [esp+3]
  150.         mov     al, [aes.sbox+eax]
  151.         mov     [esp+3], al
  152.         pop     eax
  153. @@:
  154.         xor     eax, [edi+esi*4]
  155.         stosd
  156.         loop    .1
  157.         cmp     edi, [esp]
  158.         jnz     .0
  159. .ret:
  160.         pop     eax
  161.         ret
  162.  
  163. aes_decode:
  164. ; in: esi->in, ebx->out, edi->AES state
  165.         push    ebx ebp
  166.         push    dword [esi+12]
  167.         push    dword [esi+8]
  168.         push    dword [esi+4]
  169.         push    dword [esi]
  170.         mov     esi, esp
  171. ; reverse final round
  172.         mov     ebp, [edi]      ; number of rounds
  173.         mov     ecx, ebp
  174.         shl     ecx, 4
  175.         lea     edi, [edi+ecx+4]        ; edi->last round key
  176. ; load buffer into registers
  177.         mov     eax, [esi]
  178.         mov     ebx, [esi+4]
  179.         mov     ecx, [esi+8]
  180.         mov     edx, [esi+12]
  181. ; (AddRoundKey)
  182.         xor     eax, [edi]
  183.         xor     ebx, [edi+4]
  184.         xor     ecx, [edi+8]
  185.         xor     edx, [edi+12]
  186. ; (ShiftRows)
  187. .loop0:
  188.         xchg    ch, dh
  189.         xchg    bh, ch
  190.         xchg    ah, bh
  191.         rol     eax, 16
  192.         rol     ebx, 16
  193.         rol     ecx, 16
  194.         rol     edx, 16
  195.         xchg    al, cl
  196.         xchg    bl, dl
  197.         xchg    ah, bh
  198.         xchg    bh, ch
  199.         xchg    ch, dh
  200.         rol     eax, 16
  201.         rol     ebx, 16
  202.         rol     ecx, 16
  203.         rol     edx, 16
  204. ; (SubBytes)
  205.         mov     [esi], eax
  206.         mov     [esi+4], ebx
  207.         mov     [esi+8], ecx
  208.         mov     [esi+12], edx
  209.         mov     ecx, 16
  210. @@:
  211.         movzx   eax, byte [esi]
  212.         mov     al, [aes.sbox_rev+eax]
  213.         mov     byte [esi], al
  214.         add     esi, 1
  215.         sub     ecx, 1
  216.         jnz     @b
  217.         sub     esi, 16
  218.         sub     edi, 16
  219. ; reverse normal rounds
  220.         sub     ebp, 1
  221.         jz      .done
  222.         mov     eax, [esi]
  223.         mov     ebx, [esi+4]
  224.         mov     ecx, [esi+8]
  225.         mov     edx, [esi+12]
  226.         push    esi edi
  227. ; (AddRoundKey)
  228.         xor     eax, [edi]
  229.         xor     ebx, [edi+4]
  230.         xor     ecx, [edi+8]
  231.         xor     edx, [edi+12]
  232. ; (MixColumns)
  233. macro mix_reg reg {
  234.         movzx   esi, reg#l
  235.         mov     edi, [aes.mcrtable+esi*4]
  236.         movzx   esi, reg#h
  237.         rol     e#reg#x, 16
  238.         mov     esi, [aes.mcrtable+esi*4]
  239.         rol     esi, 8
  240.         xor     edi, esi
  241.         movzx   esi, reg#l
  242.         mov     esi, [aes.mcrtable+esi*4]
  243.         rol     esi, 16
  244.         xor     edi, esi
  245.         movzx   esi, reg#h
  246.         mov     esi, [aes.mcrtable+esi*4]
  247.         ror     esi, 8
  248.         xor     edi, esi
  249.         mov     e#reg#x, edi
  250. }
  251.         mix_reg a
  252.         mix_reg b
  253.         mix_reg c
  254.         mix_reg d
  255. purge mix_reg
  256.         pop     edi esi
  257.         jmp     .loop0
  258. .done:
  259. ; (AddRoundKey)
  260.         mov     esi, [esp+20]
  261.         pop     eax
  262.         xor     eax, [edi]
  263.         mov     [esi], eax
  264.         pop     eax
  265.         xor     eax, [edi+4]
  266.         mov     [esi+4], eax
  267.         pop     eax
  268.         xor     eax, [edi+8]
  269.         mov     [esi+8], eax
  270.         pop     eax
  271.         xor     eax, [edi+12]
  272.         mov     [esi+12], eax
  273.         pop     ebp ebx
  274.         ret
  275.