# Phelix for x86_64 # This program is released to the public domain by The TOLIS Group, Inc. # Written by Andy Vaught, andy.vaught@gmail.com. # Offsets for the phelix context structure # Key states: .set keysize, 0 .set macsize, 4 .set X_1_bump, 8 .set X0_0, 12 .set X0_1, 16 .set X0_2, 20 .set X0_3, 24 .set X0_4, 28 .set X0_5, 32 .set X0_6, 36 .set X0_7, 40 .set X1_0, 44 .set X1_1, 48 .set X1_2, 52 .set X1_3, 56 .set X1_4, 60 .set X1_5, 64 .set X1_6, 68 .set X1_7, 72 # Cipher states .set OldZ0, 76 .set OldZ1, 80 .set OldZ2, 84 .set OldZ3, 88 .set Z0, 92 .set Z1, 96 .set Z2, 100 .set Z3, 104 .set Z4, 108 .set i, 112 .set aadlen_l, 116 .set aadlen_h, 120 .set msglen, 124 .set aadxor, 128 .section .rodata encrypt_table: .quad encrypt_0 .quad encrypt_1 .quad encrypt_2 .quad encrypt_3 .quad encrypt_4 .quad encrypt_5 .quad encrypt_6 .quad encrypt_7 decrypt_table: .quad decrypt_0 .quad decrypt_1 .quad decrypt_2 .quad decrypt_3 .quad decrypt_4 .quad decrypt_5 .quad decrypt_6 .quad decrypt_7 .text # init_key()-- Subroutine for key initialization that falls through for # one block encryption. init_key: lea -128(%rsp), %rsi mov %rsi, %rdi movl $0, (%rsi) mov $1, %r9d mov $0, %r10d mov $0, %r11d mov %r10d, X0_0(%r8) mov %r10d, X0_1(%r8) mov %r10d, OldZ0(%r8) mov keysize(%r8), %ebp shr $3, %ebp add $64, %ebp # Register assignments for encrypt/decrypt # This code is like a roundabout, a loop with entry and exit points # at regular intervals. # eax Z0 rsi Source pointer # ebx Z1 rdi Destination pointer # ecx Z2 r8 Points to current phelix context # edx Z3 r9d Word counter # ebp Z4 r10d i value # r11d Keystream # r15d Key word .align 16 encrypt_0: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_0(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ0(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_0(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ0(%r8) dec %r9d je return encrypt_1: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_1(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ1(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_1(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ1(%r8) dec %r9d je return encrypt_2: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_2(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ2(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_2(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ2(%r8) dec %r9d je return encrypt_3: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_3(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ3(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_3(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ3(%r8) dec %r9d je return encrypt_4: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_4(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ0(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_4(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ0(%r8) dec %r9d je return encrypt_5: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_5(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ1(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_5(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ1(%r8) dec %r9d je return encrypt_6: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_6(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ2(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_6(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ2(%r8) dec %r9d je return encrypt_7: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_7(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax add %ebx, %edx rol $11, %ebx mov (%rsi), %r12d add $4, %rsi xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d mov %edx, %r13d add OldZ3(%r8), %r11d # Keystream xor %r12d, %r13d xor %r12d, %r11d add %r13d, %eax rol $15, %edx mov %r11d, (%rdi) add $4, %rdi add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_7(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ3(%r8) dec %r9d jne encrypt_0 return: ret # Decryption roundabout decrypt_0: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_0(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ0(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_0(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ0(%r8) dec %r9d je return decrypt_1: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_1(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ1(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_1(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ1(%r8) dec %r9d je return decrypt_2: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_2(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ2(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_2(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ2(%r8) dec %r9d je return decrypt_3: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_3(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ3(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_3(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ3(%r8) dec %r9d je return decrypt_4: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_4(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ0(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_4(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ0(%r8) dec %r9d je return decrypt_5: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_5(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ1(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_5(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ1(%r8) dec %r9d je return decrypt_6: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_6(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ2(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_6(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ2(%r8) dec %r9d je return decrypt_7: add %edx, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx mov %edx, %r12d add %ecx, %ebp rol $17, %ecx add X0_7(%r8), %r12d xor %ebp, %ebx rol $13, %ebp xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx mov %ebp, %r11d add OldZ3(%r8), %r11d # Keystream add %ebx, %edx rol $11, %ebx xor (%rsi), %r11d add $4, %rsi mov %r11d, (%rdi) add $4, %rdi xor %edx, %r11d add %r11d, %eax rol $15, %edx add %ebp, %ebx rol $25, %ebp xor %eax, %ecx rol $9, %eax xor %ebx, %edx rol $10, %ebx add %ecx, %ebp rol $17, %ecx mov %edx, %r12d add X1_7(%r8), %r12d xor %ebp, %ebx rol $13, %ebp add %r10d, %r12d inc %r10d xor %r12d, %eax rol $30, %edx add %eax, %ecx rol $20, %eax xor %ecx, %ebp rol $5, %ecx add %ebx, %edx rol $11, %ebx mov %ebp, OldZ3(%r8) dec %r9d jne decrypt_0 ret save_regs: mov %rbx, -20(%rsp) mov %rbp, -28(%rsp) mov %r12, -36(%rsp) mov %r13, -44(%rsp) mov %r14, -52(%rsp) mov %r15, -60(%rsp) ret restore_regs: mov -20(%rsp), %rbx mov -28(%rsp), %rbp mov -36(%rsp), %r12 mov -44(%rsp), %r13 mov -52(%rsp), %r14 mov -60(%rsp), %r15 ret load_cipher_state: mov Z0(%r8), %eax mov Z1(%r8), %ebx mov Z2(%r8), %ecx mov Z3(%r8), %edx mov Z4(%r8), %ebp mov i(%r8), %r10d ret save_cipher_state: mov %eax, Z0(%r8) mov %ebx, Z1(%r8) mov %ecx, Z2(%r8) mov %edx, Z3(%r8) mov %ebp, Z4(%r8) mov %r10d, i(%r8) ret # PhelixSetupKey()-- Initialize a context from a key. On entry: # rdi=context rsi=key pointer rdx=key size rcx=iv size r8=mac size .globl PhelixSetupKey PhelixSetupKey: mov %edx, keysize(%rdi) mov %r8d, macsize(%rdi) mov %rdi, %r8 call save_regs sar $1, %edx mov macsize(%r8), %eax and $0x7F, %eax shl $8, %eax add %edx, %eax mov %eax, X_1_bump(%r8) # X[] array is at -120(%rsp) in the red zone. xor %rax, %rax mov %rax, -120(%rsp) mov %rax, -112(%rsp) mov %rax, -104(%rsp) mov %rax, -96(%rsp) cld mov keysize(%r8), %ecx add $0x1f, %ecx shr $5, %ecx # Key words to copy into X[] lea -120(%rsp), %rdi rep movsd mov keysize(%r8), %eax and $0x1f, %eax jz 0f # Zero the non-key material of the last word sub $4, %rdi mov %al, %cl mov $1, %eax shl %cl, %eax dec %eax and %eax, (%rdi) 0: movb $4, %r14b 1: mov -120(%rsp), %eax mov -116(%rsp), %ebx mov -112(%rsp), %ecx mov -108(%rsp), %edx call init_key xor %eax, -104(%rsp) xor %ebx, -100(%rsp) xor %ecx, -96(%rsp) xor %edx, -92(%rsp) mov -104(%rsp), %eax mov -100(%rsp), %ebx mov -96(%rsp), %ecx mov -92(%rsp), %edx call init_key xor %eax, -120(%rsp) xor %ebx, -116(%rsp) xor %ecx, -112(%rsp) xor %edx, -108(%rsp) dec %r14b jne 1b mov -120(%rsp), %eax mov %eax, X0_0(%r8) mov -116(%rsp), %eax mov %eax, X0_1(%r8) mov -112(%rsp), %eax mov %eax, X0_2(%r8) mov -108(%rsp), %eax mov %eax, X0_3(%r8) mov -104(%rsp), %eax mov %eax, X0_4(%r8) mov -100(%rsp), %eax mov %eax, X0_5(%r8) mov -96(%rsp), %eax mov %eax, X0_6(%r8) mov -92(%rsp), %eax mov %eax, X0_7(%r8) call restore_regs ret # PhelixSetupNonce()-- Setup the X1 part of the key with the nonce. On entry: # rdi=context rsi=nonce pointer .global PhelixSetupNonce PhelixSetupNonce: call save_regs mov %rdi, %r8 cld # Unrolled loop, not because it's faster, but because it's simpler to code. mov 0(%rsi), %eax mov X0_4(%r8), %edx add %eax, %edx mov %edx, X1_0(%r8) mov X0_0(%r8), %edx add $0, %edx sub %eax, %edx mov %edx, X1_4(%r8) mov 4(%rsi), %eax mov X0_5(%r8), %edx add %eax, %edx mov %edx, X1_1(%r8) mov X0_1(%r8), %edx add $1, %edx sub %eax, %edx mov %edx, X1_5(%r8) mov 8(%rsi), %eax mov X0_6(%r8), %edx add %eax, %edx mov %edx, X1_2(%r8) mov X0_2(%r8), %edx add $2, %edx sub %eax, %edx mov %edx, X1_6(%r8) mov 12(%rsi), %eax mov X0_7(%r8), %edx add %eax, %edx mov %edx, X1_3(%r8) mov X0_3(%r8), %edx add $3, %edx sub %eax, %edx mov %edx, X1_7(%r8) # Create a block of zeroes to encrypt. lea -120(%rsp), %rdi xor %rax, %rax mov %rax, 0(%rdi) mov %rax, 8(%rdi) mov %rax, 16(%rdi) mov %rax, 24(%rdi) mov X_1_bump(%r8), %eax add %eax, X1_1(%r8) add %eax, X1_5(%r8) xor %eax, %eax mov %eax, aadlen_l(%r8) mov %eax, aadlen_h(%r8) mov %eax, msglen(%r8) mov 0(%rsi), %eax xor X0_3(%r8), %eax mov 4(%rsi), %ebx xor X0_4(%r8), %ebx mov 8(%rsi), %ecx xor X0_5(%r8), %ecx mov 12(%rsi), %edx xor X0_6(%r8), %edx mov X0_7(%r8), %ebp xor %r10d, %r10d mov $8, %r9d mov %rdi, %rsi call encrypt_0 xor $0xAADAADAA, %ebx movl $0xAADAADAA, aadxor(%r8) call save_cipher_state call restore_regs ret # crypt()-- Encryption/Decryption loop. On entry, registers are: # rdi=context rsi=source rdx=destination rcx=length r14=jump table crypt: mov %rcx, %r9 # r9 is length mov %rdi, %r8 # r8 is context mov %rdx, %rdi # rdi is ciphertext testl $0x03, msglen(%r8) je 0f xor %rax, %rax # Dump core mov (%rax), %eax 0: cld add %r9d, msglen(%r8) call load_cipher_state xor aadxor(%r8), %ebx movl $0, aadxor(%r8) shr $2, %r9d # Words to encrypt je 1f # Zero words to encrypt mov %r10, %r13 and $0x07, %r13 call *(%r14, %r13, 8) 1: mov msglen(%r8), %r13d and $0x03, %r13b je 3f # Deal with a partial word movl $0, -100(%rsp) mov 0(%rsi), %r9b mov %r9b, -100(%rsp) cmp $1, %r13b je 2f mov 1(%rsi), %r9b mov %r9b, -99(%rsp) cmp $2, %r13b je 2f mov 2(%rsi), %r9b mov %r9b, -98(%rsp) 2: pushq %rdi lea -92(%rsp), %rdi mov %rdi, %rsi mov $1, %r9d mov %r10, %r13 and $0x07, %r13 call *(%r14, %r13, 8) popq %rdi # Unpack the encrypted word mov msglen(%r8), %r13d and $0x03, %r13b mov -100(%rsp), %r9b mov %r9b, 0(%rdi) cmp $1, %r13b je 3f mov -99(%rsp), %r9b mov %r9b, 1(%rdi) cmp $2, %r13b je 3f mov -98(%rsp), %r9b mov %r9b, 2(%rdi) 3: call save_cipher_state call restore_regs ret # PhelixEncryptBytes()-- Encrypt a block of data. On entry, registers are: # rdi=context rsi=plaintext rdx=ciphertext rcx=length .globl PhelixEncryptBytes PhelixEncryptBytes: call save_regs mov $encrypt_table, %r14 jmp crypt # PhelixDecryptBytes()-- Decrypt a block of data. On entry, registers are: # rdi=context rsi=ciphertext rdx=plaintext rcx=length .globl PhelixDecryptBytes PhelixDecryptBytes: call save_regs mov $decrypt_table, %r14 jmp crypt # PhelixProcessAAD()-- Process Additional Authenticated bytes. This # amounts to encrypting the bytes and throwing the ciphertext away. # We unroll the loop to 128 bytes (=32 words at a time). On entry: # rdi=context rsi=Data rdx=Length .globl PhelixProcessAAD PhelixProcessAAD: cld sub $152, %rsp call save_regs mov %rdi, %r8 mov %rdx, %r15 # r15 is bytes left to process testl $0x03, aadlen_l(%r8) je 0f xor %rax, %rax # Dump core mov (%rax), %eax 0: add %r15, aadlen_l(%r8) call load_cipher_state mov $encrypt_table, %r14 1: cmp $4, %r15d jb 2f mov $128, %r9d cmp $128, %r15d cmovb %r15d, %r9d and $~0x03, %r9d sub %r9d, %r15d shr $2, %r9d mov %rsp, %rdi mov %r10, %r13 and $0x07, %r13 call *(%r14, %r13, 8) jmp 1b 2: cmp $0, %r15d je 4f # All done # Deal with a partial word movl $0, 0(%rsp) mov 0(%rsi), %r9b mov %r9b, 0(%rsp) cmp $1, %r15d je 3f mov 1(%rsi), %r9b mov %r9b, 1(%rsp) cmp $2, %r15d je 3f mov 2(%rsi), %r9b mov %r9b, 2(%rsp) 3: mov %rsp, %rsi mov %rsp, %rdi mov %r10, %r13 and $0x07, %r13 mov $1, %r9 call *(%r14, %r13, 8) 4: call save_cipher_state call restore_regs add $152, %rsp ret # PhelixFinalize()-- Create a MAC for the current cipher state. This # amounts to perturbing the cipher state, then encrypting a block that # also depends on the cipher state. After eight words, the actual four # words of the MAC are calculated. Registers: rdi=context rsi=mac address .globl PhelixFinalize PhelixFinalize: cld sub $256, %rsp call save_regs mov %rdi, %r8 mov %rsi, %r15 call load_cipher_state xor $0x912D94F1, %eax xor aadxor(%r8), %ebx xor aadlen_h(%r8), %ecx xor aadlen_l(%r8), %ebp lea -240(%rsp), %rsi mov %rsi, %rdi mov msglen(%r8), %r9d and $0x03, %r9d mov %r9d, 0(%rsi) mov %r9d, 4(%rsi) mov %r9d, 8(%rsi) mov %r9d, 12(%rsi) mov %r9d, 16(%rsi) mov %r9d, 20(%rsi) mov %r9d, 24(%rsi) mov %r9d, 28(%rsi) mov %r9d, 32(%rsi) mov %r9d, 36(%rsi) mov %r9d, 40(%rsi) mov %r9d, 44(%rsi) mov $12, %r9d mov %r10, %r13 and $0x07, %r13 mov $encrypt_table, %r14 call *(%r14, %r13, 8) # The MAC is the last sixteen bytes, we don't worry about saving the # cipher state. lea -16(%rdi), %rsi mov %r15, %rdi mov macsize(%r8), %ecx add $7, %ecx shr $3, %ecx # Convert bits to bytes, rounding up. rep movsb call restore_regs add $256, %rsp ret