1
0
Fork 0
mirror of https://gitlab.com/bztsrc/bootboot.git synced 2023-02-13 20:54:32 -05:00

Booting from encrypted initrd

This commit is contained in:
bzt 2018-11-09 11:59:14 +01:00
parent 1460834bdb
commit 3076de4209
11 changed files with 990 additions and 97 deletions

View file

@ -5,14 +5,14 @@ I provide pre-compiled images ready for use.
1. *x86_64-efi* the preferred way of booting on x86_64 architecture.
Standard GNU toolchain and a few files from gnuefi (included).
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (76k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (76k)
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (81k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (81k)
2. *x86_64-bios* BIOS, Multiboot (GRUB) and El Torito (CDROM) compatible, OBSOLETE loader.
If you want to recompile this, you'll need fasm (not included).
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR, VBR and CDROM boot record too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (8k, loaded by boot.bin, also BBS Expansion ROM and Multiboot compliant)
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR, VBR and CDROM boot record too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (10k, loaded by boot.bin, also BBS Expansion ROM and Multiboot compliant)
3. *aarch64-rpi* ARMv8 boot loader for Raspberry Pi 3
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (27k)
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (30k)
4. *mykernel* an example BOOTBOOT [compatible kernel](https://gitlab.com/bztsrc/bootboot/tree/master/mykernel) in C which draws lines and boxes
@ -396,4 +396,11 @@ The first part of the message varies on different platforms. It means that the l
framebuffer with packed 32 bit pixels in the requested resolution. Possible solution is to modify screen to
`screen=800x600` or `screen=1024x768` in environment.
```
BOOTBOOT-PANIC: Unsupported cipher
```
This message is shown if the initrd is encrypted with a cipher that the loader does not support. Solution:
regenerate and encrypt the initrd image with SHA-XOR-CBC cipher, supported by all three implementations.
That's all, hope it will be useful!

View file

@ -27,6 +27,7 @@
* @brief Boot loader for the Raspberry Pi 3+ ARMv8
*
*/
#define DEBUG 1
//#define SD_DEBUG DEBUG
//#define INITRD_DEBUG DEBUG
@ -42,6 +43,9 @@
/* get BOOTBOOT structure */
#include "../bootboot.h"
// comment out this include if you don't want FS/Z support
#include "../../osZ/etc/include/sys/fsZ.h"
/* aligned buffers */
volatile uint32_t __attribute__((aligned(16))) mbox[36];
@ -130,6 +134,7 @@ typedef struct {
int32_t code_base; /* relative code addr in ram */
} pe_hdr;
/*** Raspberry Pi specific defines ***/
#define MMIO_BASE 0x3F000000
@ -665,11 +670,6 @@ int sd_init()
return SD_OK;
}
// comment out this include if you don't want FS/Z support
#include "../../osZ/etc/include/sys/fsZ.h"
// get filesystem drivers for initrd
#include "fs.h"
/*** other defines and structs ***/
#define COREMMIO_BASE 0xFFFFFFFFF8000000
@ -689,7 +689,8 @@ typedef struct {
uint8_t spc;
uint16_t rsc;
uint8_t nf;
uint16_t nr;
uint8_t nr0;
uint8_t nr1;
uint16_t ts16;
uint8_t media;
uint16_t spf16;
@ -732,6 +733,14 @@ typedef struct {
extern volatile unsigned char _binary_font_psf_start;
/**
* return type for fs drivers
*/
typedef struct {
uint8_t *ptr;
uint64_t size;
} file_t;
/*** common variables ***/
file_t env; // environment file descriptor
file_t initrd; // initrd file descriptor
@ -746,6 +755,158 @@ unsigned char *kne;
// alternative environment name
char *cfgname="sys/config";
#ifdef _FS_Z_H_
/**
* SHA-256
*/
typedef struct {
uint8_t d[64];
uint32_t l;
uint32_t b[2];
uint32_t s[8];
} SHA256_CTX;
#define SHA_ADD(a,b,c) if(a>0xffffffff-(c))b++;a+=c;
#define SHA_ROTL(a,b) (((a)<<(b))|((a)>>(32-(b))))
#define SHA_ROTR(a,b) (((a)>>(b))|((a)<<(32-(b))))
#define SHA_CH(x,y,z) (((x)&(y))^(~(x)&(z)))
#define SHA_MAJ(x,y,z) (((x)&(y))^((x)&(z))^((y)&(z)))
#define SHA_EP0(x) (SHA_ROTR(x,2)^SHA_ROTR(x,13)^SHA_ROTR(x,22))
#define SHA_EP1(x) (SHA_ROTR(x,6)^SHA_ROTR(x,11)^SHA_ROTR(x,25))
#define SHA_SIG0(x) (SHA_ROTR(x,7)^SHA_ROTR(x,18)^((x)>>3))
#define SHA_SIG1(x) (SHA_ROTR(x,17)^SHA_ROTR(x,19)^((x)>>10))
static uint32_t sha256_k[64]={
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
void sha256_t(SHA256_CTX *ctx)
{
uint32_t a,b,c,d,e,f,g,h,i,j,t1,t2,m[64];
for(i=0,j=0;i<16;i++,j+=4) m[i]=(ctx->d[j]<<24)|(ctx->d[j+1]<<16)|(ctx->d[j+2]<<8)|(ctx->d[j+3]);
for(;i<64;i++) m[i]=SHA_SIG1(m[i-2])+m[i-7]+SHA_SIG0(m[i-15])+m[i-16];
a=ctx->s[0];b=ctx->s[1];c=ctx->s[2];d=ctx->s[3];
e=ctx->s[4];f=ctx->s[5];g=ctx->s[6];h=ctx->s[7];
for(i=0;i<64;i++) {
t1=h+SHA_EP1(e)+SHA_CH(e,f,g)+sha256_k[i]+m[i];
t2=SHA_EP0(a)+SHA_MAJ(a,b,c);h=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;
}
ctx->s[0]+=a;ctx->s[1]+=b;ctx->s[2]+=c;ctx->s[3]+=d;
ctx->s[4]+=e;ctx->s[5]+=f;ctx->s[6]+=g;ctx->s[7]+=h;
}
void SHA256_Init(SHA256_CTX *ctx)
{
ctx->l=0;ctx->b[0]=ctx->b[1]=0;
ctx->s[0]=0x6a09e667;ctx->s[1]=0xbb67ae85;ctx->s[2]=0x3c6ef372;ctx->s[3]=0xa54ff53a;
ctx->s[4]=0x510e527f;ctx->s[5]=0x9b05688c;ctx->s[6]=0x1f83d9ab;ctx->s[7]=0x5be0cd19;
}
void SHA256_Update(SHA256_CTX *ctx, const void *data, int len)
{
uint8_t *d=(uint8_t *)data;
for(;len--;d++) {
ctx->d[ctx->l++]=*d;
if(ctx->l==64) {sha256_t(ctx);SHA_ADD(ctx->b[0],ctx->b[1],512);ctx->l=0;}
}
}
void SHA256_Final(unsigned char *h, SHA256_CTX *ctx)
{
uint32_t i=ctx->l;
ctx->d[i++]=0x80;
if(ctx->l<56) {while(i<56) ctx->d[i++]=0x00;}
else {while(i<64) ctx->d[i++]=0x00;sha256_t(ctx);memset(ctx->d,0,56);}
SHA_ADD(ctx->b[0],ctx->b[1],ctx->l*8);
ctx->d[63]=ctx->b[0];ctx->d[62]=ctx->b[0]>>8;ctx->d[61]=ctx->b[0]>>16;ctx->d[60]=ctx->b[0]>>24;
ctx->d[59]=ctx->b[1];ctx->d[58]=ctx->b[1]>>8;ctx->d[57]=ctx->b[1]>>16;ctx->d[56]=ctx->b[1]>>24;
sha256_t(ctx);
for(i=0;i<4;i++) {
h[i] =(ctx->s[0]>>(24-i*8)); h[i+4] =(ctx->s[1]>>(24-i*8));
h[i+8] =(ctx->s[2]>>(24-i*8)); h[i+12]=(ctx->s[3]>>(24-i*8));
h[i+16]=(ctx->s[4]>>(24-i*8)); h[i+20]=(ctx->s[5]>>(24-i*8));
h[i+24]=(ctx->s[6]>>(24-i*8)); h[i+28]=(ctx->s[7]>>(24-i*8));
}
}
/**
* precalculated CRC32c lookup table for polynomial 0x1EDC6F41 (castagnoli-crc)
*/
uint32_t crc32c_lookup[256]={
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
};
uint32_t crc32_calc(char *start,int length)
{
uint32_t crc32_val=0;
while(length--) crc32_val=(crc32_val>>8)^crc32c_lookup[(crc32_val&0xff)^(unsigned char)*start++];
return crc32_val;
}
/**
* Read a line from UART
*/
int ReadLine(unsigned char *buf, int l)
{
int i=0;
char c;
while(1) {
c=uart_getc();
if(c=='\n' || c=='\r') {
break;
} else
if(c==8) {
if(i) i--;
buf[i]=0;
continue;
} else
if(c==27) {
buf[0]=0;
return 0;
} else
if(c && i<l-1) {
buf[i++]=c;
buf[i]=0;
}
}
return i;
}
#endif
// get filesystem drivers for initrd
#include "fs.h"
/* current cursor position */
int kx, ky;
/* maximum coordinates */
@ -968,7 +1129,6 @@ int bootboot_main(uint64_t hcl)
#if CONSOLE == UART1
*AUX_ENABLE |=1; // enable UART1, AUX mini uart
*AUX_MU_IER = 0;
*AUX_MU_CNTL = 0;
*AUX_MU_LCR = 3; // 8 bits
*AUX_MU_MCR = 0;
@ -1099,14 +1259,15 @@ diskerr:
r=sd_readblock(part->start,(unsigned char*)&_end,1);
if(r==0) goto diskerr;
initrd.ptr=NULL; initrd.size=0;
// wait keypress with timeout
mp=50;
// wait keypress with timeout, half a sec
mp=500;
#if CONSOLE == UART1
r=(char)(*AUX_MU_IO);do{delaym(5);}while(--mp>0 && !(*AUX_MU_LSR&0x01));
r=(char)(*AUX_MU_IO);do{delaym(1000);}while(--mp>0 && !(*AUX_MU_LSR&0x01));
#else
r=(char)(*UART0_DR);do{delaym(5);}while(--mp>0 && *UART0_FR&0x10);
r=(char)(*UART0_DR);do{delaym(1000);}while(--mp>0 && *UART0_FR&0x10);
#endif
if(mp!=0) {
//if user pressed a key, fallback to backup initrd
if(mp>0) {
puts(" * Backup initrd\n");
bkp=1;
}
@ -1121,10 +1282,7 @@ diskerr:
uint8_t *ptr;
data_sec=root_sec=((bpb->spf16?bpb->spf16:bpb->spf32)*bpb->nf)+bpb->rsc;
//WARNING gcc generates a code for bpb->nr that cause unaligned exception
s=*((uint32_t*)&bpb->nf);
s>>=8;
s&=0xFFFF;
s<<=5;
s=(bpb->nr0+(bpb->nr1<<8))*sizeof(fatdir_t);
if(bpb->spf16>0) {
data_sec+=(s+511)>>9;
} else {
@ -1291,7 +1449,7 @@ gzerr: puts("BOOTBOOT-PANIC: Unable to uncompress\n");
core.size=1;
break;
}
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && pehdr->magic == PE_MAGIC &&
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
pehdr->machine == IMAGE_FILE_MACHINE_ARM64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS) {
core.size=1;
break;
@ -1324,7 +1482,7 @@ gzerr: puts("BOOTBOOT-PANIC: Unable to uncompress\n");
phdr=(Elf64_Phdr *)((uint8_t *)phdr+ehdr->e_phentsize);
}
} else
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && pehdr->magic == PE_MAGIC &&
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
pehdr->machine == IMAGE_FILE_MACHINE_ARM64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS &&
(int64_t)pehdr->code_base>>48==0xffff) {
DBG(" * Parsing PE32+\n");

View file

@ -28,17 +28,6 @@
*
*/
/**
* return type for fs drivers
*/
typedef struct {
uint8_t *ptr;
uint64_t size;
} file_t;
extern int oct2bin(unsigned char *str,int size);
extern int hex2bin(unsigned char *str,int size);
#ifdef _FS_Z_H_
/**
* FS/Z initrd (OS/Z's native file system)
@ -46,17 +35,60 @@ extern int hex2bin(unsigned char *str,int size);
file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
{
FSZ_SuperBlock *sb = (FSZ_SuperBlock *)initrd_p;
FSZ_DirEnt *ent;
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+sb->rootdirfid*FSZ_SECSIZE);
file_t ret = { NULL, 0 };
if(initrd_p==NULL || memcmp(sb->magic,FSZ_MAGIC,4) || kernel==NULL){
return ret;
}
unsigned char passphrase[256],chk[32],iv[32];
int i,j,k,l,ss=1<<(sb->logsec+11);
FSZ_DirEnt *ent;
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+sb->rootdirfid*ss);
SHA256_CTX ctx;
DBG(" * FS/Z ");
DBG(kernel);
DBG("\n");
//decrypt initrd
if(sb->enchash!=0 && FSZ_SB_EALG(sb->flags)!=0) {
puts("BOOTBOOT-PANIC: Unsupported cipher\n");
return ret;
}
while(sb->enchash!=0) {
puts(" * Passphrase? ");
l=ReadLine(passphrase,sizeof(passphrase));
if(!l) {
puts("\n");
return ret;
}
if(sb->enchash!=crc32_calc((char*)passphrase,l)) {
puts("\rBOOTBOOT-ERROR: Bad passphrase\n");
continue;
}
puts("\r * Decrypting...\r");
SHA256_Init(&ctx);
SHA256_Update(&ctx,passphrase,l);
SHA256_Update(&ctx,&sb->magic,6);
SHA256_Final(chk,&ctx);
for(i=0;i<sizeof(sb->encrypt);i++) sb->encrypt[i]^=chk[i];
SHA256_Init(&ctx);
SHA256_Update(&ctx,&sb->encrypt,sizeof(sb->encrypt));
SHA256_Final(iv,&ctx);
for(k=ss,j=1;j<sb->numsec;j++) {
memcpy(chk,iv,32);
for(i=0;i<ss;i++) {
if(i%32==0) {
SHA256_Init(&ctx);
SHA256_Update(&ctx,&chk,32);
SHA256_Update(&ctx,&j,4);
SHA256_Final(chk,&ctx);
}
initrd_p[k++]^=chk[i%32];
}
}
memset(sb->encrypt,0,sizeof(sb->encrypt)+4);
sb->checksum=crc32_calc((char *)sb->magic,508);
puts(" \r");
}
// Get the inode
int i,ss=1<<(sb->logsec+11);
char *s,*e;
s=e=kernel;
i=0;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -275,13 +275,11 @@ realmode_start:
mov word [lbapacket.count], 8
;-----initialize serial port COM1,115200,8N1------
if DEBUG eq 1
mov ax, 0401h
xor bx, bx
mov cx, 030Bh
xor dx, dx
int 14h
end if
real_print starting
in al, 060h ; read key
@ -396,7 +394,7 @@ end if
.a20ok:
; wait for a key press, if so use backup initrd
mov ecx, dword [046Ch]
add ecx, 5 ; ~250ms, 18.2/4
add ecx, 10 ; ~500ms, 18.2/2
sti
.waitkey: pause
in al, 064h
@ -691,13 +689,36 @@ real_diefunc:
real_print panic
pop si
call real_printfunc
sti
xor ax, ax
int 16h
call real_getchar
mov al, 0FEh
out 64h, al
jmp far 0FFFFh:0 ;invoke BIOS POST routine
; get a character from keyboard or from serial line
real_getchar:
pushf
sti
push si
push di
.chkser: mov ah, byte 03h
xor dx, dx
int 14h
bt ax, 8
jnc @f
mov ah, byte 02h
xor dx, dx
int 14h
@@: mov ah, byte 01h
int 16h
jnz .chkser
xor ah, ah
int 16h
.gotch: pop di
pop si
popf
xor ah, ah
ret
;ds:si zero terminated string to write
real_printfunc:
lodsb
@ -709,11 +730,9 @@ real_printfunc:
mov bx, word 11
int 10h
pop ax
if DEBUG eq 1
mov ah, byte 01h
xor dx, dx
int 14h
end if
pop si
jmp real_printfunc
.end: ret
@ -961,7 +980,7 @@ end if
jne .note
cmp dword [esi+4], edx
je .loadesp
.note: cmp dword [esi], 'OS/Z' ;or OS/Z root partition for this archicture?
.note: cmp dword [esi], 'OS/Z' ;or OS/Z root partition for this architecture?
jne .noto
cmp word [esi+4], 08664h
jne .noto
@ -1462,6 +1481,8 @@ end if
cmp word [esi], 5A4Dh ; MZ magic
jne @b
mov eax, dword [esi+0x3c]
cmp eax, 65536
jnl @b
add eax, esi
cmp dword [eax], 00004550h ; PE magic
jne @b
@ -1480,6 +1501,8 @@ end if
cmp word [esi], 5A4Dh ; MZ magic
jne .tryelf
mov ebx, esi
cmp dword [esi+0x3c], 65536
jnl .badcore
add esi, dword [esi+0x3c]
cmp dword [esi], 00004550h ; PE magic
jne .badcore
@ -1642,7 +1665,6 @@ end if
xor ax, ax
mov es, ax
mov word [vbememsize], ax
;get VESA VBE2.0 info
mov ax, 4f00h
mov di, 0A000h
@ -1653,13 +1675,6 @@ end if
je @f
.viderr: mov si, novbe
jmp real_diefunc
;get video memory size in MiB
@@: mov ax, word [0A000h+12h]
shr ax, 4
or ax, ax
jnz @f
inc ax
@@: mov word [vbememsize], ax
;read dword pointer and copy string to 1st 64k
;available video modes
@@: xor esi, esi
@ -1907,6 +1922,268 @@ longmode_init:
include "fs.inc"
include "tinf.inc"
;encryption support for FS/Z
if FSZ_SUPPORT eq 1
; --- SHA-256 ---
sha_init: xor eax, eax
mov dword [sha_l], eax
mov dword [sha_b], eax
mov dword [sha_b+4], eax
mov dword [sha_s ], 06a09e667h
mov dword [sha_s+ 4], 0bb67ae85h
mov dword [sha_s+ 8], 03c6ef372h
mov dword [sha_s+12], 0a54ff53ah
mov dword [sha_s+16], 0510e527fh
mov dword [sha_s+20], 09b05688ch
mov dword [sha_s+24], 01f83d9abh
mov dword [sha_s+28], 05be0cd19h
ret
; IN: ebx = buffer, ecx = length
sha_upd: push esi
mov esi, ebx
mov edi, dword [sha_l]
add edi, sha_d
; for(;len--;d++) {
; ctx->d[ctx->l++]=*d;
.next: movsb
inc byte [sha_l]
; if(ctx->l==64) {
cmp byte [sha_l], 64
jne @f
; sha256_t(ctx);
call sha_final.sha_t
; SHA_ADD(ctx->b[0],ctx->b[1],512);
add dword [sha_b], 512
adc dword [sha_b+4], 0
; ctx->l=0;
mov byte [sha_l], 0
; }
@@: dec ecx
jnz .next
pop esi
ret
; IN: edi = output buffer
sha_final: push esi
push edi
mov ebx, edi
; i=ctx->l; ctx->d[i++]=0x80;
mov edi, dword [sha_l]
mov ecx, edi
add edi, sha_d
mov al, 80h
stosb
xor eax, eax
; if(ctx->l<56) {while(i<56) ctx->d[i++]=0x00;}
cmp cl, 56
jae @f
neg ecx
add ecx, 63
xor al, al
repnz stosb
jmp .padded
@@: ; else {while(i<64) ctx->d[i++]=0x00;sha256_t(ctx);memset(ctx->d,0,56);}
stosb
call .sha_t
push ecx
mov ecx, 56/4
repnz stosd
pop ecx
inc cl
cmp cl, 64
jne @b
.padded: ; SHA_ADD(ctx->b[0],ctx->b[1],ctx->l*8);
mov eax, dword [sha_l]
shl eax, 3
add dword [sha_b], eax
adc dword [sha_b+4], 0
; ctx->d[63]=ctx->b[0];ctx->d[62]=ctx->b[0]>>8;ctx->d[61]=ctx->b[0]>>16;ctx->d[60]=ctx->b[0]>>24;
mov eax, dword [sha_b]
bswap eax
mov dword [sha_d+60], eax
; ctx->d[59]=ctx->b[1];ctx->d[58]=ctx->b[1]>>8;ctx->d[57]=ctx->b[1]>>16;ctx->d[56]=ctx->b[1]>>24;
mov eax, dword [sha_b+4]
bswap eax
mov dword [sha_d+56], eax
; sha256_t(ctx);
call .sha_t
; for(i=0;i<4;i++) {
; h[i] =(ctx->s[0]>>(24-i*8)); h[i+4] =(ctx->s[1]>>(24-i*8));
; h[i+8] =(ctx->s[2]>>(24-i*8)); h[i+12]=(ctx->s[3]>>(24-i*8));
; h[i+16]=(ctx->s[4]>>(24-i*8)); h[i+20]=(ctx->s[5]>>(24-i*8));
; h[i+24]=(ctx->s[6]>>(24-i*8)); h[i+28]=(ctx->s[7]>>(24-i*8));
; }
mov edi, ebx
mov esi, sha_s
mov cl, 8
@@: lodsd
bswap eax
stosd
dec cl
jnz @b
pop edi
pop esi
ret
; private func, sha transform
.sha_t: push esi
push edi
push edx
push ecx
push ebx
; for(i=0,j=0;i<16;i++,j+=4) m[i]=(ctx->d[j]<<24)|(ctx->d[j+1]<<16)|(ctx->d[j+2]<<8)|(ctx->d[j+3]);
mov cl, 16
mov edi, _m
mov esi, sha_d
@@: lodsd
bswap eax
stosd
dec cl
jnz @b
; for(;i<64;i++) m[i]=SHA_SIG1(m[i-2])+m[i-7]+SHA_SIG0(m[i-15])+m[i-16];
mov cl, 48
; SHA_SIG0[m[i-15]) (SHA_ROTR(x,7)^SHA_ROTR(x,18)^((x)>>3))
@@: mov eax, dword [edi-15*4]
mov ebx, eax
mov edx, eax
ror eax, 7
ror ebx, 18
shr edx, 3
xor eax, ebx
xor eax, edx
; SHA_SIG1(m[i-2]) (SHA_ROTR(x,17)^SHA_ROTR(x,19)^((x)>>10))
mov ebx, dword [edi-2*4]
mov edx, ebx
ror ebx, 17
ror edx, 19
xor ebx, edx
rol edx, 19
shr edx, 10
xor ebx, edx
add eax, ebx
; m[i-7]
add eax, dword [edi-7*4]
; m[i-16]
add eax, dword [edi-16*4]
stosd
dec cl
jnz @b
; a=ctx->s[0];b=ctx->s[1];c=ctx->s[2];d=ctx->s[3];
; e=ctx->s[4];f=ctx->s[5];g=ctx->s[6];h=ctx->s[7];
xor ecx, ecx
mov cl, 8
mov esi, sha_s
mov edi, _a
repnz movsd
; for(i=0;i<64;i++) {
mov esi, _m
@@: ; t1=h+SHA_EP1(e)+SHA_CH(e,f,g)+sha256_k[i]+m[i];
mov eax, dword [_h]
mov dword [t1], eax
; SHA_EP1(e) (SHA_ROTR(x,6)^SHA_ROTR(x,11)^SHA_ROTR(x,25))
mov eax, dword [_e]
mov ebx, eax
ror eax, 6
ror ebx, 11
xor eax, ebx
ror ebx, 14 ; 25 = 11+14
xor eax, ebx
add dword [t1], eax
; SHA_CH(e,f,g) (((x)&(y))^(~(x)&(z)))
mov eax, dword [_e]
mov ebx, eax
not ebx
and eax, dword [_f]
and ebx, dword [_g]
xor eax, ebx
add dword [t1], eax
; sha256_k[i]
mov eax, dword [sha256_k+4*ecx]
add dword [t1], eax
; m[i]
lodsd
add dword [t1], eax
; t2=SHA_EP0(a)+SHA_MAJ(a,b,c);
; SHA_EP0(a) (SHA_ROTR(x,2)^SHA_ROTR(x,13)^SHA_ROTR(x,22))
mov eax, dword [_a]
mov ebx, eax
ror eax, 2
ror ebx, 13
xor eax, ebx
ror ebx, 9 ; 22 = 13+9
xor eax, ebx
mov dword [t2], eax
; SHA_MAJ(a,b,c) (((x)&(y))^((x)&(z))^((y)&(z)))
mov eax, dword [_a]
mov edx, dword [_c]
mov ebx, eax
and eax, dword [_b]
and ebx, edx
xor eax, ebx
mov ebx, dword [_b]
and ebx, edx
xor eax, ebx
add dword [t2], eax
; h=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;
mov eax, dword [_g]
mov dword [_h], eax
mov eax, dword [_f]
mov dword [_g], eax
mov eax, dword [_e]
mov dword [_f], eax
mov eax, dword [_d]
add eax, dword [t1]
mov dword [_e], eax
mov eax, dword [_c]
mov dword [_d], eax
mov eax, dword [_b]
mov dword [_c], eax
mov eax, dword [_a]
mov dword [_b], eax
mov eax, dword [t1]
add eax, dword [t2]
mov dword [_a], eax
; }
inc cl
cmp cl, 64
jne @b
; ctx->s[0]+=a;ctx->s[1]+=b;ctx->s[2]+=c;ctx->s[3]+=d;
; ctx->s[4]+=e;ctx->s[5]+=f;ctx->s[6]+=g;ctx->s[7]+=h;
mov cl, 8
mov esi, _a
mov edi, sha_s
@@: lodsd
add dword [edi], eax
add edi, 4
dec cl
jnz @b
pop ebx
pop ecx
pop edx
pop edi
pop esi
xor eax, eax
ret
; --- CRC-32c ---
; IN: esi = buffer, ecx = length
; OUT: edx = crc
crc32_calc: xor edx, edx
xor eax, eax
xor ebx, ebx
or cx, cx
jz .end
.next: lodsb
mov bl, dl
xor bl, al
mov eax, edx
shr edx, 8
xor edx, dword [crclkp+4*ebx]
dec cx
jnz .next
.end: ret
end if
;*********************************************************************
;* Data *
;*********************************************************************
@ -1923,7 +2200,51 @@ CODE_PROT = $-GDT_table
GDT_value: dw $-GDT_table
dd GDT_table
dd 0,0
align 16
;lookup tables for initrd encryption
if FSZ_SUPPORT eq 1
dw 0
crclkp: dd 000000000h, 0F26B8303h, 0E13B70F7h, 01350F3F4h, 0C79A971Fh, 035F1141Ch, 026A1E7E8h, 0D4CA64EBh
dd 08AD958CFh, 078B2DBCCh, 06BE22838h, 09989AB3Bh, 04D43CFD0h, 0BF284CD3h, 0AC78BF27h, 05E133C24h
dd 0105EC76Fh, 0E235446Ch, 0F165B798h, 0030E349Bh, 0D7C45070h, 025AFD373h, 036FF2087h, 0C494A384h
dd 09A879FA0h, 068EC1CA3h, 07BBCEF57h, 089D76C54h, 05D1D08BFh, 0AF768BBCh, 0BC267848h, 04E4DFB4Bh
dd 020BD8EDEh, 0D2D60DDDh, 0C186FE29h, 033ED7D2Ah, 0E72719C1h, 0154C9AC2h, 0061C6936h, 0F477EA35h
dd 0AA64D611h, 0580F5512h, 04B5FA6E6h, 0B93425E5h, 06DFE410Eh, 09F95C20Dh, 08CC531F9h, 07EAEB2FAh
dd 030E349B1h, 0C288CAB2h, 0D1D83946h, 023B3BA45h, 0F779DEAEh, 005125DADh, 01642AE59h, 0E4292D5Ah
dd 0BA3A117Eh, 04851927Dh, 05B016189h, 0A96AE28Ah, 07DA08661h, 08FCB0562h, 09C9BF696h, 06EF07595h
dd 0417B1DBCh, 0B3109EBFh, 0A0406D4Bh, 0522BEE48h, 086E18AA3h, 0748A09A0h, 067DAFA54h, 095B17957h
dd 0CBA24573h, 039C9C670h, 02A993584h, 0D8F2B687h, 00C38D26Ch, 0FE53516Fh, 0ED03A29Bh, 01F682198h
dd 05125DAD3h, 0A34E59D0h, 0B01EAA24h, 042752927h, 096BF4DCCh, 064D4CECFh, 077843D3Bh, 085EFBE38h
dd 0DBFC821Ch, 02997011Fh, 03AC7F2EBh, 0C8AC71E8h, 01C661503h, 0EE0D9600h, 0FD5D65F4h, 00F36E6F7h
dd 061C69362h, 093AD1061h, 080FDE395h, 072966096h, 0A65C047Dh, 05437877Eh, 04767748Ah, 0B50CF789h
dd 0EB1FCBADh, 0197448AEh, 00A24BB5Ah, 0F84F3859h, 02C855CB2h, 0DEEEDFB1h, 0CDBE2C45h, 03FD5AF46h
dd 07198540Dh, 083F3D70Eh, 090A324FAh, 062C8A7F9h, 0B602C312h, 044694011h, 05739B3E5h, 0A55230E6h
dd 0FB410CC2h, 0092A8FC1h, 01A7A7C35h, 0E811FF36h, 03CDB9BDDh, 0CEB018DEh, 0DDE0EB2Ah, 02F8B6829h
dd 082F63B78h, 0709DB87Bh, 063CD4B8Fh, 091A6C88Ch, 0456CAC67h, 0B7072F64h, 0A457DC90h, 0563C5F93h
dd 0082F63B7h, 0FA44E0B4h, 0E9141340h, 01B7F9043h, 0CFB5F4A8h, 03DDE77ABh, 02E8E845Fh, 0DCE5075Ch
dd 092A8FC17h, 060C37F14h, 073938CE0h, 081F80FE3h, 055326B08h, 0A759E80Bh, 0B4091BFFh, 0466298FCh
dd 01871A4D8h, 0EA1A27DBh, 0F94AD42Fh, 00B21572Ch, 0DFEB33C7h, 02D80B0C4h, 03ED04330h, 0CCBBC033h
dd 0A24BB5A6h, 0502036A5h, 04370C551h, 0B11B4652h, 065D122B9h, 097BAA1BAh, 084EA524Eh, 07681D14Dh
dd 02892ED69h, 0DAF96E6Ah, 0C9A99D9Eh, 03BC21E9Dh, 0EF087A76h, 01D63F975h, 00E330A81h, 0FC588982h
dd 0B21572C9h, 0407EF1CAh, 0532E023Eh, 0A145813Dh, 0758FE5D6h, 087E466D5h, 094B49521h, 066DF1622h
dd 038CC2A06h, 0CAA7A905h, 0D9F75AF1h, 02B9CD9F2h, 0FF56BD19h, 00D3D3E1Ah, 01E6DCDEEh, 0EC064EEDh
dd 0C38D26C4h, 031E6A5C7h, 022B65633h, 0D0DDD530h, 00417B1DBh, 0F67C32D8h, 0E52CC12Ch, 01747422Fh
dd 049547E0Bh, 0BB3FFD08h, 0A86F0EFCh, 05A048DFFh, 08ECEE914h, 07CA56A17h, 06FF599E3h, 09D9E1AE0h
dd 0D3D3E1ABh, 021B862A8h, 032E8915Ch, 0C083125Fh, 0144976B4h, 0E622F5B7h, 0F5720643h, 007198540h
dd 0590AB964h, 0AB613A67h, 0B831C993h, 04A5A4A90h, 09E902E7Bh, 06CFBAD78h, 07FAB5E8Ch, 08DC0DD8Fh
dd 0E330A81Ah, 0115B2B19h, 0020BD8EDh, 0F0605BEEh, 024AA3F05h, 0D6C1BC06h, 0C5914FF2h, 037FACCF1h
dd 069E9F0D5h, 09B8273D6h, 088D28022h, 07AB90321h, 0AE7367CAh, 05C18E4C9h, 04F48173Dh, 0BD23943Eh
dd 0F36E6F75h, 00105EC76h, 012551F82h, 0E03E9C81h, 034F4F86Ah, 0C69F7B69h, 0D5CF889Dh, 027A40B9Eh
dd 079B737BAh, 08BDCB4B9h, 0988C474Dh, 06AE7C44Eh, 0BE2DA0A5h, 04C4623A6h, 05F16D052h, 0AD7D5351h
sha256_k: dd 0428a2f98h, 071374491h, 0b5c0fbcfh, 0e9b5dba5h, 03956c25bh, 059f111f1h, 0923f82a4h, 0ab1c5ed5h
dd 0d807aa98h, 012835b01h, 0243185beh, 0550c7dc3h, 072be5d74h, 080deb1feh, 09bdc06a7h, 0c19bf174h
dd 0e49b69c1h, 0efbe4786h, 00fc19dc6h, 0240ca1cch, 02de92c6fh, 04a7484aah, 05cb0a9dch, 076f988dah
dd 0983e5152h, 0a831c66dh, 0b00327c8h, 0bf597fc7h, 0c6e00bf3h, 0d5a79147h, 006ca6351h, 014292967h
dd 027b70a85h, 02e1b2138h, 04d2c6dfch, 053380d13h, 0650a7354h, 0766a0abbh, 081c2c92eh, 092722c85h
dd 0a2bfe8a1h, 0a81a664bh, 0c24b8b70h, 0c76c51a3h, 0d192e819h, 0d6990624h, 0f40e3585h, 0106aa070h
dd 019a4c116h, 01e376c08h, 02748774ch, 034b0bcb5h, 0391c0cb3h, 04ed8aa4ah, 05b9cca4fh, 0682e6ff3h
dd 0748f82eeh, 078a5636fh, 084c87814h, 08cc70208h, 090befffah, 0a4506cebh, 0bef9a3f7h, 0c67178f2h
end if
lbapacket: ;lba packet for BIOS
.size: dw 10h
.count: dw 8
@ -1931,9 +2252,6 @@ lbapacket: ;lba packet for BIOS
.sect0: dd 0
.sect1: dd 0
spc_packet: db 18h dup 0
entrypoint: dq 0
core_ptr: dd 0
core_len: dd 0
reqwidth: dd 1024
reqheight: dd 768
ebdaptr: dd 0
@ -1942,16 +2260,12 @@ bpb_sec: dd 0 ;ESP's first sector
root_sec: dd 0 ;root directory's first sector
data_sec: dd 0 ;first data sector
clu_sec: dd 0 ;sector per cluster
gpt_ptr: dd 0
gpt_num: dd 0
gpt_ent: dd 0
origcount: dw 0
bootdev: db 0
readdev: db 0
hasinitrd: db 0
iscdrom: db 0
fattype: db 0
vbememsize: dw 0
bkp: dd ' '
if DEBUG eq 1
dbg_cpu db " * Detecting CPU",10,13,0
@ -1969,6 +2283,9 @@ dbg_pe db " * Parsing PE32+",10,13,0
dbg_vesa db " * Screen VESA VBE",10,13,0
end if
backup: db " * Backup initrd",10,13,0
passphrase: db " * Passphrase? ",0
decrypting: db 13," * Decrypting...",0
clrdecrypt: db 13," ",13,0
starting: db "Booting OS...",10,13,0
panic: db "-PANIC: ",0
noarch: db "Hardware not supported",0
@ -1985,9 +2302,11 @@ badcore: db "Kernel is not a valid executable",0
novbe: db "VESA VBE error, no framebuffer",0
nogzip: db "Unable to uncompress",0
notcdsect: db "Not 2048 sector aligned",0
nocipher: db "Unsupported cipher",10,13,0
badpass: db 13,"BOOTBOOT-ERROR: Bad passphrase",10,13,0
cfgfile: db "sys/config",0,0,0
kernel: db "sys/core"
db (128-($-kernel)) dup 0
db (64-($-kernel)) dup 0
;-----------padding to be multiple of 512----------
db (511-($-loader+511) mod 512) dup 0
loader_end:
@ -2001,6 +2320,12 @@ end repeat
store byte (100h-chksum) at (loader.checksum)
;-----------bss area-----------
entrypoint: dq ?
core_ptr: dd ?
core_len: dd ?
gpt_ptr: dd ?
gpt_num: dd ?
gpt_ent: dd ?
tinf_bss_start:
d_end: dd ?
d_lzOff: dd ?
@ -2029,6 +2354,31 @@ hdist: dw ?
hclen: dw ?
tinf_bss_end:
if FSZ_SUPPORT eq 1
virtual at tinf_bss_start
pass: db 256 dup ?
sha_d: db 64 dup ?
sha_l: dd ?
sha_b: dd 2 dup ?
sha_s: dd 8 dup ?
_a: dd ?
_b: dd ?
_c: dd ?
_d: dd ?
_e: dd ?
_f: dd ?
_g: dd ?
_h: dd ?
t1: dd ?
t2: dd ?
_m: dd 64 dup ?
chk: db 32 dup ?
iv: db 32 dup ?
pl: dd ?
_i: dd ?
end virtual
end if
;-----------bound check-------------
;fasm will generate an error if the code
;is bigger than it should be

View file

@ -46,7 +46,7 @@ end if
if FSZ_SUPPORT eq 1
; ----------- FS/Z ----------
; Find the kernel on initrd
; Find the kernel on initrd (only supports 4096 logical sector sizes)
; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
; OUT: On Success
; esi: pointer to the first byte, ecx: size in bytes
@ -56,8 +56,151 @@ fsz_initrd:
mov ebx, ecx
xor ecx, ecx
; FS/Z superblock
cmp dword [esi+512], 'FS/Z' ; FSZ_SuperBlock.magic
jne .nolib
; encrypted initrd?
cmp dword [esi+708], 0 ; FSZ_SuperBlock.enchash
jz .noenc
mov al, byte [esi+518] ; FSZ_SuperBlock.flags
shr al, 2
and al, 7
or al, al
jz @f
prot_realmode
real_print loader.name
real_print panic
mov esi, nocipher
call real_printfunc
real_protmode
jmp .err
@@: push edi
prot_realmode
.passagain: real_print passphrase
; get passphrase from user
mov di, pass
mov byte [di], 0
.getchar: call real_getchar
cmp al, 27 ; Esc
jne @f
real_print clrdecrypt
jmp .err
@@: cmp al, 8 ; Backspace
jne @f
cmp di, pass
je .getchar
mov byte [di], 0
dec di
jmp .getchar
@@: cmp al, 13 ; Enter
je .gotpass
cmp al, 10
je .gotpass
cmp al, ' '
jb .getchar
cmp di, pass+255
jge .getchar
mov word [di], ax
inc di
jmp .getchar
.gotpass: push esi
real_protmode
mov esi, pass
mov ecx, edi
sub ecx, esi
mov dword [pl], ecx
call crc32_calc
prot_realmode
pop esi
cmp dword [esi+708], edx
je .passok
real_print badpass
jmp .passagain
.passok: real_print decrypting
real_protmode
; decrypt initrd
call sha_init
mov ecx, dword [pl]
mov ebx, pass
call sha_upd
mov ecx, 6
mov ebx, esi
add ebx, 512 ; FSZ_SuperBlock.magic
call sha_upd
mov edi, chk
call sha_final
mov edi, esi
add edi, 680 ; FSZ_SuperBlock.encrypt
mov cl, 28
xor ebx, ebx
@@: mov al, byte [edi]
xor byte [chk+ebx], al
xor eax, eax
stosb
inc ebx
dec cl
jnz @b
stosd
call sha_init
mov ecx, 28
mov ebx, chk
call sha_upd
mov edi, iv
call sha_final
mov eax, dword [esi+528] ; FSZ_SuperBlock.numsec
mov dword [pl], eax
xor eax, eax
inc eax
mov dword [_i], eax ; skip first sector
mov ebx, esi
add ebx, 4096
push esi
.decrypt: mov esi, iv
mov edi, chk
xor ecx, ecx
mov cl, 32/4
repnz movsd
mov cx, 4096
.nextblk: mov al, bl
and al, 31
jnz @f
push ebx
push ecx
call sha_init
mov ecx, 32
mov ebx, chk
call sha_upd
mov ecx, 4
mov ebx, _i
call sha_upd
mov edi, chk
call sha_final
pop ecx
pop ebx
mov edx, edi
@@: mov al, byte [edx]
xor byte [ebx], al
inc ebx
inc edx
dec cx
jnz .nextblk
inc dword [_i]
mov eax, dword [_i]
cmp eax, dword [pl]
jne .decrypt
mov esi, dword [esp]
add esi, 512
mov ecx, 508
call crc32_calc
pop esi
mov dword [esi+1020], edx ; FSZ_SuperBlock.chksum
; clear console message
prot_realmode
real_print clrdecrypt
real_protmode
pop edi
; get root dir inode
mov eax, dword [esi+560] ; FSZ_SuperBlock.rootdirfid
.noenc: mov eax, dword [esi+560] ; FSZ_SuperBlock.rootdirfid
shl eax, 12
add esi, eax
cmp dword [esi], 'FSIN'

View file

@ -28,7 +28,7 @@
*
*/
// DEBUG defined in efidebug.h
// DEBUG already defined in efidebug.h
#define BBDEBUG 1
//#define GOP_DEBUG BBDEBUG
@ -42,6 +42,7 @@
// get UEFI functions and environment
#include <efi.h>
#include <efilib.h>
#include <eficon.h>
#include <efiprot.h>
#include <efigpt.h>
// get BOOTBOOT specific stuff
@ -49,8 +50,6 @@
#include "tinf.h"
// comment out this include if you don't want FS/Z support
#include "../../osZ/etc/include/sys/fsZ.h"
// get filesystem drivers for initrd
#include "fs.h"
/*** ELF64 defines and structs ***/
#define ELFMAG "\177ELF"
@ -193,6 +192,14 @@ typedef struct {
#define PAGESIZE 4096
/**
* return type for fs drivers
*/
typedef struct {
UINT8 *ptr;
UINTN size;
} file_t;
/*** common variables ***/
file_t env; // environment file descriptor
file_t initrd; // initrd file descriptor
@ -203,6 +210,7 @@ UINT64 entrypoint; // kernel entry point
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
EFI_FILE_HANDLE RootDir;
EFI_FILE_PROTOCOL *Root;
SIMPLE_INPUT_INTERFACE *CI;
unsigned char *kne;
// default environment variables. M$ states that 1024x768 must be supported
@ -212,6 +220,166 @@ char *kernelname="sys/core";
// alternative environment name
char *cfgname="sys/config";
#ifdef _FS_Z_H_
/**
* SHA-256
*/
typedef struct {
UINT8 d[64];
UINT32 l;
UINT32 b[2];
UINT32 s[8];
} SHA256_CTX;
#define SHA_ADD(a,b,c) if(a>0xffffffff-(c))b++;a+=c;
#define SHA_ROTL(a,b) (((a)<<(b))|((a)>>(32-(b))))
#define SHA_ROTR(a,b) (((a)>>(b))|((a)<<(32-(b))))
#define SHA_CH(x,y,z) (((x)&(y))^(~(x)&(z)))
#define SHA_MAJ(x,y,z) (((x)&(y))^((x)&(z))^((y)&(z)))
#define SHA_EP0(x) (SHA_ROTR(x,2)^SHA_ROTR(x,13)^SHA_ROTR(x,22))
#define SHA_EP1(x) (SHA_ROTR(x,6)^SHA_ROTR(x,11)^SHA_ROTR(x,25))
#define SHA_SIG0(x) (SHA_ROTR(x,7)^SHA_ROTR(x,18)^((x)>>3))
#define SHA_SIG1(x) (SHA_ROTR(x,17)^SHA_ROTR(x,19)^((x)>>10))
static UINT32 sha256_k[64]={
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
void sha256_t(SHA256_CTX *ctx)
{
UINT32 a,b,c,d,e,f,g,h,i,j,t1,t2,m[64];
for(i=0,j=0;i<16;i++,j+=4) m[i]=(ctx->d[j]<<24)|(ctx->d[j+1]<<16)|(ctx->d[j+2]<<8)|(ctx->d[j+3]);
for(;i<64;i++) m[i]=SHA_SIG1(m[i-2])+m[i-7]+SHA_SIG0(m[i-15])+m[i-16];
a=ctx->s[0];b=ctx->s[1];c=ctx->s[2];d=ctx->s[3];
e=ctx->s[4];f=ctx->s[5];g=ctx->s[6];h=ctx->s[7];
for(i=0;i<64;i++) {
t1=h+SHA_EP1(e)+SHA_CH(e,f,g)+sha256_k[i]+m[i];
t2=SHA_EP0(a)+SHA_MAJ(a,b,c);h=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;
}
ctx->s[0]+=a;ctx->s[1]+=b;ctx->s[2]+=c;ctx->s[3]+=d;
ctx->s[4]+=e;ctx->s[5]+=f;ctx->s[6]+=g;ctx->s[7]+=h;
}
void SHA256_Init(SHA256_CTX *ctx)
{
ctx->l=0;ctx->b[0]=ctx->b[1]=0;
ctx->s[0]=0x6a09e667;ctx->s[1]=0xbb67ae85;ctx->s[2]=0x3c6ef372;ctx->s[3]=0xa54ff53a;
ctx->s[4]=0x510e527f;ctx->s[5]=0x9b05688c;ctx->s[6]=0x1f83d9ab;ctx->s[7]=0x5be0cd19;
}
void SHA256_Update(SHA256_CTX *ctx, const void *data, int len)
{
UINT8 *d=(UINT8 *)data;
for(;len--;d++) {
ctx->d[ctx->l++]=*d;
if(ctx->l==64) {sha256_t(ctx);SHA_ADD(ctx->b[0],ctx->b[1],512);ctx->l=0;}
}
}
void SHA256_Final(unsigned char *h, SHA256_CTX *ctx)
{
UINT32 i=ctx->l;
ctx->d[i++]=0x80;
if(ctx->l<56) {while(i<56) ctx->d[i++]=0x00;}
else {while(i<64) ctx->d[i++]=0x00;sha256_t(ctx);ZeroMem(ctx->d,56);}
SHA_ADD(ctx->b[0],ctx->b[1],ctx->l*8);
ctx->d[63]=ctx->b[0];ctx->d[62]=ctx->b[0]>>8;ctx->d[61]=ctx->b[0]>>16;ctx->d[60]=ctx->b[0]>>24;
ctx->d[59]=ctx->b[1];ctx->d[58]=ctx->b[1]>>8;ctx->d[57]=ctx->b[1]>>16;ctx->d[56]=ctx->b[1]>>24;
sha256_t(ctx);
for(i=0;i<4;i++) {
h[i] =(ctx->s[0]>>(24-i*8)); h[i+4] =(ctx->s[1]>>(24-i*8));
h[i+8] =(ctx->s[2]>>(24-i*8)); h[i+12]=(ctx->s[3]>>(24-i*8));
h[i+16]=(ctx->s[4]>>(24-i*8)); h[i+20]=(ctx->s[5]>>(24-i*8));
h[i+24]=(ctx->s[6]>>(24-i*8)); h[i+28]=(ctx->s[7]>>(24-i*8));
}
}
/**
* precalculated CRC32c lookup table for polynomial 0x1EDC6F41 (castagnoli-crc)
*/
UINT32 crc32c_lookup[256]={
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
};
UINT32 crc32_calc(char *start,int length)
{
UINT32 crc32_val=0;
while(length--) crc32_val=(crc32_val>>8)^crc32c_lookup[(crc32_val&0xff)^(unsigned char)*start++];
return crc32_val;
}
/**
* Read a line from ConIn
*/
int ReadLine(unsigned char *buf, int l)
{
int i=0;
EFI_INPUT_KEY key;
while(1) {
if(!uefi_call_wrapper(CI->ReadKeyStroke, 2, CI, &key)) {
if(key.UnicodeChar==CHAR_LINEFEED || key.UnicodeChar==CHAR_CARRIAGE_RETURN) {
break;
} else
if(key.UnicodeChar==CHAR_BACKSPACE || key.ScanCode==SCAN_DELETE) {
if(i) i--;
buf[i]=0;
continue;
} else
if(key.ScanCode==SCAN_ESC) {
buf[0]=0;
return 0;
} else
if(key.UnicodeChar && i<l-1) {
// convert unicode to utf-8
if(key.UnicodeChar<0x80)
buf[i++]=key.UnicodeChar;
else if(key.UnicodeChar<0x800) {
buf[i++]=((key.UnicodeChar>>6)&0x1F)|0xC0;
buf[i++]=(key.UnicodeChar&0x3F)|0x80;
} else {
buf[i++]=((key.UnicodeChar>>12)&0xF)|0xE0;
buf[i++]=((key.UnicodeChar>>6)&0x3F)|0x80;
buf[i++]=(key.UnicodeChar&0x3F)|0x80;
}
buf[i]=0;
}
}
}
return i;
}
#endif
/**
* function to convert ascii to number
*/
@ -282,6 +450,9 @@ int hex2bin(unsigned char *str, int size)
return v;
}
// get filesystem drivers for initrd
#include "fs.h"
/**
* Parse FS0:\BOOTBOOT\CONFIG or /sys/config
*/
@ -527,7 +698,7 @@ LoadCore()
ehdr->e_phnum>0){
break;
}
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && pehdr->magic == PE_MAGIC &&
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
pehdr->machine == IMAGE_FILE_MACHINE_AMD64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS) {
break;
}
@ -556,7 +727,7 @@ LoadCore()
}
phdr=(Elf64_Phdr *)((UINT8 *)phdr+ehdr->e_phentsize);
}
} else if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && pehdr->magic == PE_MAGIC &&
} else if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
pehdr->machine == IMAGE_FILE_MACHINE_AMD64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS &&
(INT64)pehdr->code_base>>48==0xffff) {
//Parse PE32+
@ -615,6 +786,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
// Initialize UEFI Library
InitializeLib(image, systab);
BS = systab->BootServices;
CI = systab->ConIn;
// Parse command line arguments
// BOOTBOOT.EFI [-?|-h|/?|/h] [initrd [config [key=value...]]
@ -711,15 +883,15 @@ foundinrom:
// fall back to INITRD on filesystem
if(EFI_ERROR(status) || initrd.ptr==NULL){
// if the user presses any key now, we fallback to backup initrd
for(i=0;i<50;i++) {
// delay 5ms
uefi_call_wrapper(BS->Stall, 1, 5000);
status=uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
if(status!=EFI_NOT_READY) {
for(i=0;i<500;i++) {
if(!uefi_call_wrapper(BS->CheckEvent, 1, CI->WaitForKey)) {
uefi_call_wrapper(CI->ReadKeyStroke, 2, CI, &key);
Print(L" * Backup initrd\n");
initrdfile=L"\\BOOTBOOT\\INITRD.BAK";
break;
}
// delay 1ms
uefi_call_wrapper(BS->Stall, 1, 1000);
}
DBG(L" * Locate initrd in %s\n",initrdfile);
// Initialize FS with the DeviceHandler from loaded image protocol

View file

@ -28,18 +28,6 @@
*
*/
/**
* return type for fs drivers
*/
typedef struct {
UINT8 *ptr;
UINTN size;
} file_t;
extern int oct2bin(unsigned char *str,int size);
extern int hex2bin(unsigned char *str,int size);
extern CHAR16 *a2u (char *str);
#ifdef _FS_Z_H_
/**
* FS/Z initrd (OS/Z's native file system)
@ -47,15 +35,58 @@ extern CHAR16 *a2u (char *str);
file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
{
FSZ_SuperBlock *sb = (FSZ_SuperBlock *)initrd_p;
FSZ_DirEnt *ent;
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+sb->rootdirfid*FSZ_SECSIZE);
file_t ret = { NULL, 0 };
if(initrd_p==NULL || CompareMem(sb->magic,FSZ_MAGIC,4) || kernel==NULL){
return ret;
}
unsigned char passphrase[256],chk[32],iv[32];
UINT64 i,j,k,l,ss=1<<(sb->logsec+11);
FSZ_DirEnt *ent;
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+sb->rootdirfid*ss);
SHA256_CTX ctx;
DBG(L" * FS/Z %s\n",a2u(kernel));
//decrypt initrd
if(sb->enchash!=0 && FSZ_SB_EALG(sb->flags)!=0) {
Print(L"BOOTBOOT-PANIC: Unsupported cipher\n");
return ret;
}
while(sb->enchash!=0) {
Print(L" * Passphrase? ");
l=ReadLine(passphrase,sizeof(passphrase));
if(!l) {
Print(L"\n");
return ret;
}
if(sb->enchash!=crc32_calc((char*)passphrase,l)) {
Print(L"\rBOOTBOOT-ERROR: Bad passphrase\n");
continue;
}
Print(L"\r * Decrypting...\r");
SHA256_Init(&ctx);
SHA256_Update(&ctx,passphrase,l);
SHA256_Update(&ctx,&sb->magic,6);
SHA256_Final(chk,&ctx);
for(i=0;i<sizeof(sb->encrypt);i++) sb->encrypt[i]^=chk[i];
SHA256_Init(&ctx);
SHA256_Update(&ctx,&sb->encrypt,sizeof(sb->encrypt));
SHA256_Final(iv,&ctx);
for(k=ss,j=1;j<sb->numsec;j++) {
CopyMem(chk,iv,32);
for(i=0;i<ss;i++) {
if(i%32==0) {
SHA256_Init(&ctx);
SHA256_Update(&ctx,&chk,32);
SHA256_Update(&ctx,&j,4);
SHA256_Final(chk,&ctx);
}
initrd_p[k++]^=chk[i%32];
}
}
ZeroMem(sb->encrypt,sizeof(sb->encrypt)+4);
sb->checksum=crc32_calc((char *)sb->magic,508);
Print(L" \r");
}
// Get the inode
int i,ss=1<<(sb->logsec+11);
char *s,*e;
s=e=kernel;
i=0;