grub-devel
[Top][All Lists]
Advanced

[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;
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]