VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Crypto/gost89_x64.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/Crypto/gost89_x64.asm')
-rw-r--r--src/Crypto/gost89_x64.asm481
1 files changed, 481 insertions, 0 deletions
diff --git a/src/Crypto/gost89_x64.asm b/src/Crypto/gost89_x64.asm
new file mode 100644
index 0000000..f2e49cb
--- /dev/null
+++ b/src/Crypto/gost89_x64.asm
@@ -0,0 +1,481 @@
+;
+; GOST89 implementation x64
+;
+; Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
+;
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions
+; of the Apache License, Version 2.0. The full text of the license may be found at
+; https://opensource.org/licenses/Apache-2.0
+;
+; Some ideas from article https://xakep.ru/2013/10/19/shifrovanie-gost-28147-89/
+;
+
+[section .bss align=16]
+
+;///////////////////////////////////////////////////////////////////
+;// Win64 registers to save
+;///////////////////////////////////////////////////////////////////
+%macro SaveRegs 0
+ sub rsp,8*8+10*16
+ mov [rsp], rbx
+ mov [rsp+8], rbp
+ mov [rsp+8*2], rdi
+ mov [rsp+8*3], rsi
+ mov [rsp+8*4], r12
+ mov [rsp+8*5], r13
+ mov [rsp+8*6], r14
+ mov [rsp+8*7], r15
+%endmacro
+
+%macro RestoreRegs 0
+ mov rbx, [rsp]
+ mov rbp, [rsp+8]
+ mov rdi, [rsp+8*2]
+ mov rsi, [rsp+8*3]
+ mov r12, [rsp+8*4]
+ mov r13, [rsp+8*5]
+ mov r14, [rsp+8*6]
+ mov r15, [rsp+8*7]
+ add rsp,8*8+10*16
+%endmacro
+
+[section .text align=16]
+;///////////////////////////////////////////////////////////////////
+;// Crypting 2 blocks
+;///////////////////////////////////////////////////////////////////
+%macro gost_round2 2 ; 1 - pos1, 2 - pos2
+ ; 1st
+ ; 1-2 byte
+ add ecx, r13d ; add key
+ movzx edi, cl
+ movzx esi, ch
+ xor r14d, dword [r8 + 32 + 256*3*4 + rdi*4]
+ xor r14d, dword [r8 + 32 + 256*2*4 + rsi*4]
+ shr ecx, 16
+ ; 3-4 байт
+ movzx edi, cl
+ xor r14d, dword [r8 + 32 + 256*4 + rdi*4]
+ movzx esi, ch
+ xor r14d, dword [r8 + 32 + rsi*4]
+ mov edx, [r8 + %1*4] ; read key for second step
+
+ ; 2nd
+ ; 1-2 byte
+ add eax, r10d ; read key
+ movzx r15d, al
+ movzx ebp, ah
+ xor r11d, dword [r8 + 32 + 256*3*4 + r15*4]
+ xor r11d, dword [r8 + 32 + 256*2*4 + rbp*4]
+ shr eax, 16
+ ; 3-4 байт
+ movzx r15d, al
+ xor r11d, dword [r8 + 32 + 256*4 + r15*4]
+ movzx ebp, ah
+ xor r11d, dword [r8 + 32 + rbp*4]
+ mov ebx, [r8 + %1*4] ; read key for second step
+
+ ; second step
+ ; 1st
+ ; 1-2 byte
+ add edx, r14d ; add key
+ movzx edi, dl
+ movzx esi, dh
+ xor r13d, dword [r8 + 32 + 256*3*4 + rdi*4]
+ xor r13d, dword [r8 + 32 + 256*2*4 + rsi*4]
+ shr edx, 16
+ ; 3-4 байт
+ movzx edi, dl
+ xor r13d, dword [r8 + 32 + 256*4 + rdi*4]
+ movzx esi, dh
+ xor r13d, dword [r8 + 32 + rsi*4]
+ mov ecx, [r8 + %2*4] ; read key
+
+ ; 2nd
+ ; 1-2 byte
+ add ebx, r11d; ; add key
+ movzx r15d, bl;
+ movzx ebp, bh;
+ xor r10d, dword [r8 + 32 + 256*3*4 + r15*4]
+ xor r10d, dword [r8 + 32 + 256*2*4 + rbp*4]
+ shr ebx, 16
+ ; 3-4 байт
+ movzx r15d, bl
+ xor r10d, dword [r8 + 32 + 256*4 + r15*4]
+ movzx ebp, bh
+ xor r10d, dword [r8 + 32 + rbp*4]
+ mov eax, [r8 + %2*4] ; read key
+%endmacro
+
+; input: r8 - &key, rdx - &IN
+; returns: (r13) & (r10)
+GostEncrypt2x64:
+ ; 1st
+ mov r13d, [rdx]
+ mov r14, [rdx]
+ shr r14, 32
+
+ ; 2nd
+ mov r10d, [rdx + 16]
+ mov r11, [rdx + 16]
+ shr r11, 32
+
+ mov ecx, [r8]
+ mov eax, ecx
+
+ gost_round2 1, 2
+ gost_round2 3, 4
+ gost_round2 5, 6
+ gost_round2 7, 0
+
+ gost_round2 1, 2
+ gost_round2 3, 4
+ gost_round2 5, 6
+ gost_round2 7, 0
+
+ gost_round2 1, 2
+ gost_round2 3, 4
+ gost_round2 5, 6
+ gost_round2 7, 7
+
+ gost_round2 6, 5
+ gost_round2 4, 3
+ gost_round2 2, 1
+ gost_round2 0, 0
+
+ shl r13, 32 ; combine
+ or r13, r14
+
+ shl r10, 32 ; combine
+ or r10, r11
+ ret
+
+; input: r8 - &key, rdx - &IN
+; returns: (r13) & (r10)
+GostDecrypt2x64:
+ ; 1st
+ mov r13d, [rdx]
+ mov r14, [rdx]
+ shr r14, 32
+
+ ; 2nd
+ mov r10d, [rdx + 16]
+ mov r11, [rdx + 16]
+ shr r11, 32
+
+ mov ecx, [r8]
+ mov eax, ecx
+
+ gost_round2 1, 2
+ gost_round2 3, 4
+ gost_round2 5, 6
+ gost_round2 7, 7
+
+ gost_round2 6, 5
+ gost_round2 4, 3
+ gost_round2 2, 1
+ gost_round2 0, 7
+
+ gost_round2 6, 5
+ gost_round2 4, 3
+ gost_round2 2, 1
+ gost_round2 0, 7
+
+ gost_round2 6, 5
+ gost_round2 4, 3
+ gost_round2 2, 1
+ gost_round2 0, 0
+
+ shl r13, 32 ; combine
+ or r13, r14
+
+ shl r10, 32 ; combine
+ or r10, r11
+ret
+
+;///////////////////////////////////////////////////////////////////
+;// Crypting 1 block
+;///////////////////////////////////////////////////////////////////
+%macro gost_round1 2 ; 1 - pos1, 2 - pos2
+ ; 1-2 byte
+ add ecx, r13d ; add key
+ movzx edi, cl
+ movzx esi, ch
+ xor r14d, dword [r8 + 32 + 256*3*4 + rdi*4]
+ xor r14d, dword [r8 + 32 + 256*2*4 + rsi*4]
+ shr ecx, 16
+ ; 3-4 байт
+ movzx edi, cl
+ xor r14d, dword [r8 + 32 + 256*4 + rdi*4]
+ movzx esi, ch
+ xor r14d, dword [r8 + 32 + rsi*4]
+ mov edx, [r8 + %1*4] ; read key for second step
+
+ ; second step
+ ; 1-2 byte
+ add edx, r14d ; add key
+ movzx edi, dl
+ movzx esi, dh
+ xor r13d, dword [r8 + 32 + 256*3*4 + rdi*4]
+ xor r13d, dword [r8 + 32 + 256*2*4 + rsi*4]
+ shr edx, 16
+ ; 3-4 байт
+ movzx edi, dl
+ xor r13d, dword [r8 + 32 + 256*4 + rdi*4]
+ movzx esi, dh
+ xor r13d, dword [r8 + 32 + rsi*4]
+ mov ecx, [r8 + %2*4] ; read key
+%endmacro
+
+; input: r8 - &gost_kds rdx - &IN
+; returns: r13
+GostEncrypt1x64:
+ mov r13d, [rdx]
+ mov r14, [rdx]
+ shr r14, 32
+ mov ecx, [r8]
+
+ gost_round1 1, 2
+ gost_round1 3, 4
+ gost_round1 5, 6
+ gost_round1 7, 0
+
+ gost_round1 1, 2
+ gost_round1 3, 4
+ gost_round1 5, 6
+ gost_round1 7, 0
+
+ gost_round1 1, 2
+ gost_round1 3, 4
+ gost_round1 5, 6
+ gost_round1 7, 7
+
+ gost_round1 6, 5
+ gost_round1 4, 3
+ gost_round1 2, 1
+ gost_round1 0, 0
+
+ shl r13, 32 ; combine
+ or r13, r14
+ret
+
+; input: r8 - &gost_kds rdx - IN
+; returns: r13
+GostDecrypt1x64:
+ mov r13d, [rdx]
+ mov r14, [rdx]
+ shr r14, 32
+ mov ecx, [r8]
+
+ gost_round1 1, 2
+ gost_round1 3, 4
+ gost_round1 5, 6
+ gost_round1 7, 7
+
+ gost_round1 6, 5
+ gost_round1 4, 3
+ gost_round1 2, 1
+ gost_round1 0, 7
+
+ gost_round1 6, 5
+ gost_round1 4, 3
+ gost_round1 2, 1
+ gost_round1 0, 7
+
+ gost_round1 6, 5
+ gost_round1 4, 3
+ gost_round1 2, 1
+ gost_round1 0, 0
+
+ shl r13, 32 ; combine
+ or r13, r14
+ret
+
+global gost_encrypt_128_CBC_asm ; gost_encrypt_128_CBC_asm(uint64* out, uint64* in, gost_kds* kds, uint64 count);
+; rcx - &out
+; rdx - &in
+; r8 - &gost_kds
+; r9 - count
+gost_encrypt_128_CBC_asm:
+ SaveRegs ; Saving
+
+ sub rsp, 32
+ mov [rsp], rcx ; Save out addr
+ mov [rsp + 8], rdx ; Save in addr
+ mov [rsp + 16], r8 ; key addr
+
+.do:
+ mov [rsp + 24], r9 ; Save count
+ cmp r9, 2
+ jge .blk2
+ cmp r9, 1
+ jge .blk1
+ jmp .end
+
+; One 128 block encryption
+.blk1:
+ mov rdx, [rsp + 8] ; set in addr
+ call GostEncrypt1x64
+
+ mov rcx, [rsp] ; Restore out
+ mov rdx, [rsp + 8] ; restore in
+
+ mov [rcx], r13
+ mov rax, [rdx + 8]
+ xor rax, r13 ; CBC
+
+ add rcx, 8 ;next 8 bytes
+ mov [rcx], rax
+
+ mov rdx, rcx
+ call GostEncrypt1x64
+
+ mov rcx, [rsp] ; Restore out addr
+ mov rdx, [rsp+8] ; Restore in addr
+
+ mov [rcx + 8], r13
+
+ add rcx,16
+ mov [rsp], rcx
+
+ add rdx, 16
+ mov [rsp+8], rdx
+
+ mov r9, [rsp + 24]
+ dec r9
+
+ jmp .do
+
+.blk2:
+ mov rdx, [rsp + 8] ; set in addr
+ call GostEncrypt2x64
+
+ mov rcx, [rsp] ; Restore out
+ mov rdx, [rsp + 8] ; restore in
+
+ mov [rcx], r13
+
+ mov rax, [rdx + 8]
+ xor rax, r13 ; CBC
+
+ mov [rcx + 16], r10
+
+ mov rbx, [rdx + 24]
+ xor rbx, r10 ; CBC
+
+ mov [rcx + 8], rax
+ mov [rcx + 24], rbx
+
+ add rcx, 8 ;next 8 bytes
+
+ mov rdx, rcx
+ call GostEncrypt2x64
+
+ mov rcx, [rsp] ; Restore out addr
+ mov rdx, [rsp+8] ; Restore in addr
+
+ mov [rcx + 8], r13
+ mov [rcx + 24], r10
+
+ add rcx,32
+ mov [rsp], rcx
+
+ add rdx, 32
+ mov [rsp+8], rdx
+
+ mov r9, [rsp + 24]
+ sub r9, 2
+
+ jmp .do
+
+.end:
+ add rsp, 32 ; Load out addr
+ RestoreRegs ; Load
+ret
+
+global gost_decrypt_128_CBC_asm ; gost_decrypt_128_CBC_asm(uint64* out, uint64* in, const gost_kds* kds, uint64 count);
+; rcx - &out
+; rdx - &in
+; r8 - &gost_kds
+; r9 - count
+gost_decrypt_128_CBC_asm:
+ SaveRegs ; Saving
+
+ sub rsp, 32
+ mov [rsp], rdx ; Save out addr
+ mov [rsp+8], rcx ; Save in addr
+ mov [rsp+16], r8 ; key addr
+
+.do:
+ mov [rsp + 24], r9 ; Save count
+ cmp r9, 2
+ jge .blk2
+ cmp r9, 1
+ jge .blk1
+ jmp .end
+
+; One 128 block decryption
+.blk1:
+ add rdx, 8
+ call GostDecrypt1x64
+ mov rcx, [rsp] ; Restore out
+ mov rdx, [rsp + 8] ; Restore in
+ mov rax, [rdx]
+ xor rax, r13 ; CBC
+ mov [rcx + 8], rax
+
+ call GostDecrypt1x64
+
+ mov rcx, [rsp] ; Restore out addr
+ mov rdx, [rsp+8] ; Restore in addr
+
+ mov [rcx], r13
+
+ add rcx,16
+ mov [rsp], rcx
+
+ add rdx, 16
+ mov [rsp+8], rdx
+
+ mov r9, [rsp + 24]
+ dec r9
+
+ jmp .do
+
+.blk2:
+ add rdx, 8
+ call GostDecrypt2x64
+ mov rcx, [rsp] ; Restore out
+ mov rdx, [rsp + 8] ; Restore in
+
+ mov rax, [rdx]
+ xor rax, r13 ; CBC
+ mov [rcx + 8], rax
+
+ mov rbx, [rdx+16]
+ xor rbx, r10 ; CBC
+ mov [rcx + 24], rbx
+
+ call GostDecrypt2x64
+
+ mov rcx, [rsp] ; Restore out addr
+ mov rdx, [rsp+8] ; Restore in addr
+
+ mov [rcx], r13
+ mov [rcx+16], r10
+
+ add rcx,32
+ mov [rsp], rcx
+
+ add rdx,32
+ mov [rsp+8], rdx
+
+ mov r9, [rsp + 24]
+ sub r9, 2
+
+ jmp .do
+
+.end:
+ add rsp, 32 ; Load out addr
+ RestoreRegs ; Load
+ret