[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SHA-1 MBR
From: |
phcoder |
Subject: |
SHA-1 MBR |
Date: |
Fri, 20 Feb 2009 22:50:40 +0100 |
User-agent: |
Thunderbird 2.0.0.19 (X11/20090105) |
Hello, as promised I wrote an mbr which performs SHA-1. To squeeze the
code I had to remove chs and to change the bootdrive installer will have
to overwrite corresponding instruction. SHA-1 implemented in it is
little-endian and without padding. Standard version is big-endian and
with padding. In this case padding is unnecessary since a sector is
always 512 bytes. Litt-le endian means just that data isn't byte-swapped
before hashing. And the hash in sector has to be written in little
endian and the double should be in order
h1,h2,h3,h4,h0
I also implemented the same thing as standalone program
Regards
Vladimir 'phcoder' Serbinenko
/* -*-Asm-*- */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/* The signature for bootloader. */
#define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55
/* The offset of a magic number used by Windows NT. */
#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC 0x1b8
/* The offset of the start of the partition table. */
#define GRUB_BOOT_MACHINE_PART_START 0x1be
/* The offset of the end of the partition table. */
#define GRUB_BOOT_MACHINE_PART_END 0x1fe
/* The stack segment. */
#define GRUB_BOOT_MACHINE_STACK_SEG 0x2000
/* The segment of disk buffer. The disk buffer MUST be 32K long and
cannot straddle a 64K boundary. */
#define GRUB_BOOT_MACHINE_BUFFER_SEG 0x7000
/* The flag for BIOS drive number to designate a hard disk vs. a
floppy. */
#define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80
/* The segment where the kernel is loaded. */
#define GRUB_BOOT_MACHINE_KERNEL_SEG 0x800
/* The address where the kernel is loaded. */
#define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4)
/* The size of a block list used in the kernel startup code. */
#define GRUB_BOOT_MACHINE_LIST_SIZE 12
#define ABS(x) (x-_start+0x7c00)
.code16
.globl _start; _start:
jmp real_start
stack:
packet:
.byte 0x10
.byte 0
.word 1
.word 0,GRUB_BOOT_MACHINE_KERNEL_SEG
kernel_sector:
.long 1, 0
h1:
.long 0xefcdab89
h2:
.long 0x98badcfe
h3:
.long 0x10325476
h4:
.long 0xc3d2e1f0
h0:
.long 0x67452301
real_start:
cli
xorw %ax, %ax
movb $0x80, %dl
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
mov $ABS(stack), %sp
movw %sp, %si
movb $0x42, %ah
int $0x13
add $0x10,%sp
mov ABS(byteshashed), %si
block32:
movw $GRUB_BOOT_MACHINE_KERNEL_SEG, %ax
movw %ax, %ds
incb %ah
movw %ax, %es
xor %ax,%ax
mov %ax, %di
mov $0x40, %cx
push %cx
cld
rep movsb
pop %cx
movw $(GRUB_BOOT_MACHINE_KERNEL_SEG+0x100), %ax
movw %ax, %ds
expand:
movl -12(%di), %eax
xorl -32(%di), %eax
xorl -56(%di), %eax
xorl -64(%di), %eax
shl $1, %eax
adc $0, %al
mov %eax, (%di)
add $4, %di
decw %cx
test %cx, %cx
jnz expand
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
movb $0x14, %cl
movw %sp, %si
subw %cx, %sp
movw %sp, %di
cld
rep movsb
mov %sp, %bp
xor %ax, %ax
mov %ax, %si
main_loop:
pop %eax
pop %ebx
pop %ecx
push %ecx
push %ebx
push %eax
cmp $320, %si
je hashed64
cmp $240, %si
jge phase4
cmp $160, %si
jge phase3
cmp $80, %si
jge phase2
phase1:
//(b&c)|(~b & d)
and %eax, %ebx
not %eax
and %ecx, %eax
or %ebx, %eax
add $0x5a827999, %eax
jmp sharedphase
phase2:
xor %ebx, %eax
xor %ecx, %eax
add $0x6ed9eba1, %eax
jmp sharedphase
phase3:
mov %eax, %edx
and %ebx, %edx
and %ecx, %eax
and %ecx, %ebx
or %ebx, %eax
or %edx, %eax
add $0x8f1bbcdc, %eax
jmp sharedphase
phase4:
xor %ebx, %eax
xor %ecx, %eax
add $0xca62c1d6, %eax
sharedphase:
// here we have on stack: b,c,d,e,a
// f+k in eax
mov %bp, %di
push %si
xor %cx,%cx
mov %cx, %ds
mov %cx, %es
mov %di, %si
std
mov $4, %cx
add $12, %si
add $16, %di
mov (%di), %ebx
rep movsl
mov %ebx, (%bp)
pop %si
movw $(GRUB_BOOT_MACHINE_KERNEL_SEG+0x100), %cx
movw %cx, %ds
// here we have on stack: b'=a,b,d'=c,e'=d,e
// f+k in eax
mov (%si), %ecx
add %ecx, %eax
add 16(%bp), %eax
mov (%bp), %ecx
mov %ecx, %ebx
shl $5, %ecx
shr $27, %ebx
or %ecx, %ebx
add %ebx, %eax
mov %eax, 16(%bp)
// here we have on stack: b'=a,b,d'=c,e'=d,a'
mov 4(%bp), %eax
mov %eax, %ebx
shl $30, %ebx
shr $2, %eax
or %ebx, %eax
mov %eax, 4(%bp)
add $4, %si
jmp main_loop
hashed64:
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw $5, %cx
addv:
movl (%bp), %eax
addl %eax, 20(%bp)
addw $4, %bp
decw %cx
test %cx, %cx
jnz addv
mov %bp, %sp
add $64, ABS(byteshashed)
mov ABS(byteshashed), %si
cmpw $512, %si
jl block32
mov $ABS(hash), %si
mov %sp, %di
mov $20, %cx
cld
repe cmpsb
self:
jnz self
ljmp $0, $GRUB_BOOT_MACHINE_KERNEL_ADDR
byteshashed: .word 0
. = _start + 0x1a4
hash:
.long 0
.long 0
.long 0
.long 0
.long 0
. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
nt_magic:
.long 0
.word 0
part_start:
. = _start + GRUB_BOOT_MACHINE_PART_START
. = _start + GRUB_BOOT_MACHINE_PART_END
/* the last 2 bytes in the sector 0 contain the signature */
.word GRUB_BOOT_MACHINE_SIGNATURE
/* -*-Asm-*- */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
unsigned
cs (unsigned a, unsigned b)
{
return (a<<b)|(a>>(32-b));
}
#define grub_cputole32(x) (x)
int
main ()
{
char buf[512];
unsigned w[80];
int i;
unsigned h0 = 0x67452301;
unsigned h1 = 0xefcdab89;
unsigned h2 = 0x98badcfe;
unsigned h3 = 0x10325476;
unsigned h4 = 0xc3d2e1f0;
unsigned a,b,c,d,e,f,k,t;
while (fread (buf,1,64,stdin) == 64)
{
for (i = 0; i < 16; i++)
{
w[i] = grub_cputole32 (((unsigned *)buf)[i]);
// printf ("%08x, ", w[i]);
}
// printf ("\n\n");
for (;i<80;i++)
{
w[i] = cs(w[i-3]^w[i-8]^w[i-14]^w[i-16],1);
// printf ("%08x, ", w[i]);
}
// printf ("\n\n");
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for (i=0;i<80;i++)
{
if (0 <= i && i<=19)
{
f = (b&c)|(~b & d);
k = 0x5a827999;
}
if (20 <= i && i<=39)
{
f = b^c^d;
k = 0x6ed9eba1;
}
if (40 <= i && i<=59)
{
f = (b & c) | (b & d) | (c & d);
k = 0x8f1bbcdc;
}
if (60 <= i && i<=79)
{
f = b^c^d;
k = 0xca62c1d6;
}
t = cs(a,5)+f+e+k+w[i];
e=d;
d=c;
c=cs(b,30);
b=a;
a=t;
}
h0 += a;
h1 += b;
h2 += c;
h3 += d;
h4 += e;
}
printf ("%08x,%08x,%08x,%08x,%08x\n", h1, h2, h3, h4, h0);
return 0;
}