mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 02:58:02 -06:00
245 lines
5.1 KiB
NASM
245 lines
5.1 KiB
NASM
;
|
|
; Derived from source code of TrueCrypt 7.1a, which is
|
|
; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
|
|
; by the TrueCrypt License 3.0.
|
|
;
|
|
; Modifications and additions to the original source code (contained in this file)
|
|
; and all other portions of this file are Copyright (c) 2013-2016 IDRIX
|
|
; and are governed by the Apache License 2.0 the full text of which is
|
|
; contained in the file License.txt included in VeraCrypt binary and source
|
|
; code distribution packages.
|
|
;
|
|
|
|
.MODEL tiny
|
|
.386
|
|
_TEXT SEGMENT USE16
|
|
|
|
INCLUDE BootDefs.i
|
|
|
|
ORG 7C00h ; Standard boot sector offset
|
|
|
|
start:
|
|
; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address).
|
|
; Far jump to the next instruction sets IP to the standard offset 7C00.
|
|
db 0EAh ; jmp 0:main
|
|
dw main, 0
|
|
|
|
loader_name_msg:
|
|
db ' VeraCrypt Boot Loader', 13, 10, 0
|
|
|
|
main:
|
|
cli
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov ss, ax
|
|
mov sp, 7C00h
|
|
sti
|
|
|
|
; Display boot loader name
|
|
test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE
|
|
jnz skip_loader_name_msg
|
|
|
|
lea si, loader_name_msg
|
|
call print
|
|
skip_loader_name_msg:
|
|
|
|
; Determine boot loader segment
|
|
mov ax, TC_BOOT_LOADER_SEGMENT
|
|
|
|
; Check available memory
|
|
cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
|
|
jge memory_ok
|
|
|
|
mov ax, TC_BOOT_LOADER_SEGMENT_LOW
|
|
|
|
cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
|
|
jge memory_ok
|
|
|
|
; Insufficient memory
|
|
mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT
|
|
|
|
memory_ok:
|
|
mov es, ax
|
|
|
|
; Clear BSS section
|
|
xor al, al
|
|
mov di, TC_COM_EXECUTABLE_OFFSET
|
|
mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1
|
|
cld
|
|
rep stosb
|
|
|
|
mov ax, es
|
|
sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment
|
|
mov es, ax
|
|
|
|
; Load decompressor
|
|
mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR
|
|
retry_backup:
|
|
mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
|
|
mov bx, TC_COM_EXECUTABLE_OFFSET
|
|
call read_sectors
|
|
|
|
; Decompressor checksum
|
|
xor ebx, ebx
|
|
mov si, TC_COM_EXECUTABLE_OFFSET
|
|
mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE
|
|
call checksum
|
|
push ebx
|
|
|
|
; Load compressed boot loader
|
|
mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
|
|
mov cl, TC_BOOT_LOADER_START_SECTOR
|
|
mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT
|
|
|
|
test backup_loader_used, 1
|
|
jz non_backup
|
|
mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
|
|
mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
|
|
|
|
non_backup:
|
|
call read_sectors
|
|
|
|
; Boot loader checksum
|
|
pop ebx
|
|
mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
|
|
mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
|
|
call checksum
|
|
|
|
; Verify checksum
|
|
cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET]
|
|
je checksum_ok
|
|
|
|
; Checksum incorrect - try using backup if available
|
|
test backup_loader_used, 1
|
|
jnz loader_damaged
|
|
|
|
mov backup_loader_used, 1
|
|
mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
|
|
|
|
test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
|
|
jnz retry_backup
|
|
|
|
loader_damaged:
|
|
lea si, loader_damaged_msg
|
|
call print
|
|
lea si, loader_name_msg
|
|
call print
|
|
jmp $
|
|
checksum_ok:
|
|
|
|
; Set up decompressor segment
|
|
mov ax, es
|
|
mov ds, ax
|
|
cli
|
|
mov ss, ax
|
|
mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
|
|
sti
|
|
|
|
push dx
|
|
|
|
; Decompress boot loader
|
|
mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
|
|
sub cx, TC_GZIP_HEADER_SIZE
|
|
push cx ; Compressed data size
|
|
push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data
|
|
push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size
|
|
push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer
|
|
|
|
push cs
|
|
push decompressor_ret
|
|
push es
|
|
push TC_COM_EXECUTABLE_OFFSET
|
|
retf
|
|
decompressor_ret:
|
|
|
|
add sp, 8
|
|
pop dx
|
|
|
|
; Restore boot sector segment
|
|
push cs
|
|
pop ds
|
|
|
|
; Check decompression result
|
|
test ax, ax
|
|
jz decompression_ok
|
|
|
|
lea si, loader_damaged_msg
|
|
call print
|
|
jmp $
|
|
decompression_ok:
|
|
|
|
; DH = boot sector flags
|
|
mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
|
|
|
|
; Set up boot loader segment
|
|
mov ax, es
|
|
add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16
|
|
mov es, ax
|
|
mov ds, ax
|
|
cli
|
|
mov ss, ax
|
|
mov sp, TC_BOOT_LOADER_STACK_TOP
|
|
sti
|
|
|
|
; Execute boot loader
|
|
push es
|
|
push TC_COM_EXECUTABLE_OFFSET
|
|
retf
|
|
|
|
; Print string
|
|
print:
|
|
xor bx, bx
|
|
mov ah, 0eh
|
|
cld
|
|
|
|
@@: lodsb
|
|
test al, al
|
|
jz print_end
|
|
|
|
int 10h
|
|
jmp @B
|
|
|
|
print_end:
|
|
ret
|
|
|
|
; Read sectors of the first cylinder
|
|
read_sectors:
|
|
mov ch, 0 ; Cylinder
|
|
mov dh, 0 ; Head
|
|
; DL = drive number passed from BIOS
|
|
mov ah, 2
|
|
int 13h
|
|
jnc read_ok
|
|
|
|
lea si, disk_error_msg
|
|
call print
|
|
read_ok:
|
|
ret
|
|
|
|
; Calculate checksum
|
|
checksum:
|
|
push ds
|
|
push es
|
|
pop ds
|
|
xor eax, eax
|
|
cld
|
|
|
|
@@: lodsb
|
|
add ebx, eax
|
|
rol ebx, 1
|
|
loop @B
|
|
|
|
pop ds
|
|
ret
|
|
|
|
backup_loader_used db 0
|
|
|
|
disk_error_msg db 'Disk error', 13, 10, 7, 0
|
|
loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0
|
|
|
|
ORG 7C00h + 510
|
|
dw 0AA55h ; Boot sector signature
|
|
|
|
_TEXT ENDS
|
|
END start
|