From: phcoder <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: SHA-1 MBR
Date: Fri, 20 Feb 2009 22:50:40 +0100 [thread overview]
Message-ID: <499F25B0.8000202@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 646 bytes --]
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
[-- Attachment #2: sha1.S --]
[-- Type: text/plain, Size: 4946 bytes --]
/* -*-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
[-- Attachment #3: sha1.c --]
[-- Type: text/x-csrc, Size: 2126 bytes --]
/* -*-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;
}
next reply other threads:[~2009-02-20 21:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-20 21:50 phcoder [this message]
2009-02-20 23:06 ` SHA-1 MBR Jan Alsenz
2009-02-20 23:41 ` phcoder
2009-02-21 0:32 ` Jan Alsenz
2009-02-21 1:02 ` Isaac Dupree
2009-02-21 1:21 ` Javier Martín
2009-02-21 9:43 ` phcoder
2009-02-21 8:56 ` Jan Alsenz
2009-02-21 13:27 ` phcoder
2009-02-21 14:12 ` phcoder
-- strict thread matches above, loose matches on Subject: below --
2009-02-21 2:21 Alex Besogonov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=499F25B0.8000202@gmail.com \
--to=phcoder@gmail.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.