This repository has been archived by the owner on Sep 21, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
elf2nxo is drunk. Also, adding a stress-test for the fs stuff
- Loading branch information
Showing
3 changed files
with
271 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
#include<libtransistor/types.h> | ||
#include<libtransistor/util.h> | ||
#include<libtransistor/fs/inode.h> | ||
#include<libtransistor/fs/squashfs.h> | ||
#include<libtransistor/fs/fs.h> | ||
#include<errno.h> | ||
#include<stdio.h> | ||
#include<dirent.h> | ||
#include<fcntl.h> | ||
#include<unistd.h> | ||
|
||
#include"../lib/squashfs/squashfuse.h" | ||
|
||
/********************************************************************* | ||
* Filename: sha256.c | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Implementation of the SHA-256 hashing algorithm. | ||
SHA-256 is one of the three algorithms in the SHA2 | ||
specification. The others, SHA-384 and SHA-512, are not | ||
offered in this implementation. | ||
Algorithm specification can be found here: | ||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf | ||
This implementation uses little endian byte order. | ||
*********************************************************************/ | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include <stdlib.h> | ||
#include <memory.h> | ||
|
||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest | ||
|
||
/**************************** DATA TYPES ****************************/ | ||
typedef unsigned char BYTE; // 8-bit byte | ||
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines | ||
|
||
typedef struct { | ||
BYTE data[64]; | ||
WORD datalen; | ||
unsigned long long bitlen; | ||
WORD state[8]; | ||
} SHA256_CTX; | ||
|
||
/****************************** MACROS ******************************/ | ||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) | ||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) | ||
|
||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) | ||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) | ||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) | ||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) | ||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) | ||
|
||
/**************************** VARIABLES *****************************/ | ||
static const WORD 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 | ||
}; | ||
|
||
/*********************** FUNCTION DEFINITIONS ***********************/ | ||
void sha256_transform(SHA256_CTX *ctx, const BYTE data[]) | ||
{ | ||
WORD 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] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); | ||
for ( ; i < 64; ++i) | ||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; | ||
|
||
a = ctx->state[0]; | ||
b = ctx->state[1]; | ||
c = ctx->state[2]; | ||
d = ctx->state[3]; | ||
e = ctx->state[4]; | ||
f = ctx->state[5]; | ||
g = ctx->state[6]; | ||
h = ctx->state[7]; | ||
|
||
for (i = 0; i < 64; ++i) { | ||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; | ||
t2 = EP0(a) + MAJ(a,b,c); | ||
h = g; | ||
g = f; | ||
f = e; | ||
e = d + t1; | ||
d = c; | ||
c = b; | ||
b = a; | ||
a = t1 + t2; | ||
} | ||
|
||
ctx->state[0] += a; | ||
ctx->state[1] += b; | ||
ctx->state[2] += c; | ||
ctx->state[3] += d; | ||
ctx->state[4] += e; | ||
ctx->state[5] += f; | ||
ctx->state[6] += g; | ||
ctx->state[7] += h; | ||
} | ||
|
||
void sha256_init(SHA256_CTX *ctx) | ||
{ | ||
ctx->datalen = 0; | ||
ctx->bitlen = 0; | ||
ctx->state[0] = 0x6a09e667; | ||
ctx->state[1] = 0xbb67ae85; | ||
ctx->state[2] = 0x3c6ef372; | ||
ctx->state[3] = 0xa54ff53a; | ||
ctx->state[4] = 0x510e527f; | ||
ctx->state[5] = 0x9b05688c; | ||
ctx->state[6] = 0x1f83d9ab; | ||
ctx->state[7] = 0x5be0cd19; | ||
} | ||
|
||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) | ||
{ | ||
WORD i; | ||
|
||
for (i = 0; i < len; ++i) { | ||
ctx->data[ctx->datalen] = data[i]; | ||
ctx->datalen++; | ||
if (ctx->datalen == 64) { | ||
sha256_transform(ctx, ctx->data); | ||
ctx->bitlen += 512; | ||
ctx->datalen = 0; | ||
} | ||
} | ||
} | ||
|
||
void sha256_final(SHA256_CTX *ctx, BYTE hash[]) | ||
{ | ||
WORD i; | ||
|
||
i = ctx->datalen; | ||
|
||
// Pad whatever data is left in the buffer. | ||
if (ctx->datalen < 56) { | ||
ctx->data[i++] = 0x80; | ||
while (i < 56) | ||
ctx->data[i++] = 0x00; | ||
} | ||
else { | ||
ctx->data[i++] = 0x80; | ||
while (i < 64) | ||
ctx->data[i++] = 0x00; | ||
sha256_transform(ctx, ctx->data); | ||
memset(ctx->data, 0, 56); | ||
} | ||
|
||
// Append to the padding the total message's length in bits and transform. | ||
ctx->bitlen += ctx->datalen * 8; | ||
ctx->data[63] = ctx->bitlen; | ||
ctx->data[62] = ctx->bitlen >> 8; | ||
ctx->data[61] = ctx->bitlen >> 16; | ||
ctx->data[60] = ctx->bitlen >> 24; | ||
ctx->data[59] = ctx->bitlen >> 32; | ||
ctx->data[58] = ctx->bitlen >> 40; | ||
ctx->data[57] = ctx->bitlen >> 48; | ||
ctx->data[56] = ctx->bitlen >> 56; | ||
sha256_transform(ctx, ctx->data); | ||
|
||
// Since this implementation uses little endian byte ordering and SHA uses big endian, | ||
// reverse all the bytes when copying the final state to the output hash. | ||
for (i = 0; i < 4; ++i) { | ||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; | ||
} | ||
} | ||
|
||
|
||
void hash_file(char hash[256], int fd) { | ||
char buf[4096]; | ||
ssize_t r; | ||
SHA256_CTX ctx; | ||
|
||
sha256_init(&ctx); | ||
while ((r = read(fd, buf, 4096)) > 0) | ||
sha256_update(&ctx, buf, r); | ||
sha256_final(&ctx, hash); | ||
} | ||
|
||
|
||
void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) | ||
{ | ||
unsigned char * pin = in; | ||
const char * hex = "0123456789ABCDEF"; | ||
char * pout = out; | ||
for(; pin < in+insz; pout +=2, pin++){ | ||
pout[0] = hex[(*pin>>4) & 0xF]; | ||
pout[1] = hex[ *pin & 0xF]; | ||
if (pout + 2 - out > outsz){ | ||
/* Better to truncate output string than overflow buffer */ | ||
/* it would be still better to either return a status */ | ||
/* or ensure the target buffer is large enough and it never happen */ | ||
break; | ||
} | ||
} | ||
pout[-1] = 0; | ||
} | ||
|
||
void print_file(char *name, int indent) { | ||
char hash[256]; | ||
char hashstr[513]; | ||
|
||
int fd = open(name, O_RDONLY); | ||
if (fd < 0) { | ||
perror("error: open"); | ||
exit(0); | ||
} | ||
hash_file(hash, fd); | ||
tohex(hash, 256, hashstr, 513); | ||
printf("%*s- %s: %s\n", indent, "", name, hashstr); | ||
} | ||
|
||
void listdir(const char *name, int indent) | ||
{ | ||
DIR *dir; | ||
struct dirent *entry; | ||
struct stat file_stat; | ||
|
||
if (!(dir = opendir(name))) | ||
return; | ||
|
||
while ((entry = readdir(dir)) != NULL) { | ||
char path[1024]; | ||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | ||
continue; | ||
snprintf(path, sizeof(path), "%s/%s", name, entry->d_name); | ||
|
||
// TODO: Implement d_type in dentry | ||
if (stat(path, &file_stat) == -1) { | ||
perror("Stat error"); | ||
exit(0); | ||
} | ||
|
||
if (S_ISDIR(file_stat.st_mode)) { | ||
printf("%*s[%s]\n", indent, "", entry->d_name); | ||
listdir(path, indent + 2); | ||
} else { | ||
print_file(path, indent); | ||
} | ||
} | ||
closedir(dir); | ||
} | ||
|
||
// Read every file into a buffer. | ||
int main(int argc, char *argv[]) { | ||
listdir("/", 0); | ||
} |