Skip to content

Commit 9da4446

Browse files
author
bmax
committed
feat: hash superkey
1 parent f5e6a01 commit 9da4446

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1199
-677
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ jobs:
6464
make
6565
mv syscallhook.kpm demo-syscallhook.kpm
6666
67-
cd ../make-shamiko-happy
68-
make
69-
mv syscallhook.kpm demo-make-shamiko-happy.kpm
70-
7167
- name: Upload elf
7268
uses: actions/upload-artifact@v3
7369
with:
@@ -87,7 +83,6 @@ jobs:
8783
kpms/demo-hello/demo-hello.kpm
8884
kpms/demo-inlinehook/demo-inlinehook.kpm
8985
kpms/demo-syscallhook/demo-syscallhook.kpm
90-
kpms/make-shamiko-happy/demo-make-shamiko-happy.kpm
9186
generateReleaseNotes: true
9287
omitBodyDuringUpdate: true
9388
allowUpdates: true

.github/workflows/build_dev.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ jobs:
7272
make
7373
mv syscallhook.kpm demo-syscallhook.kpm
7474
75-
cd ../make-shamiko-happy
76-
make
77-
7875
- name: Upload elf
7976
uses: actions/upload-artifact@v3
8077
with:
@@ -95,7 +92,6 @@ jobs:
9592
kpms/demo-hello/demo-hello.kpm
9693
kpms/demo-inlinehook/demo-inlinehook.kpm
9794
kpms/demo-syscallhook/demo-syscallhook.kpm
98-
kpms/make-shamiko-happy/shamiko.kpm
9995
generateReleaseNotes: true
10096
allowUpdates: true
10197
replacesArtifacts: true

kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ BASE_SRCS += base/hmem.c
3535
BASE_SRCS += base/predata.c
3636
BASE_SRCS += base/symbol.c
3737
BASE_SRCS += base/baselib.c
38+
BASE_SRCS += base/sha256.c
3839

3940
BASE_SRCS += $(wildcard patch/*.c)
4041
BASE_SRCS += $(wildcard patch/common/*.c)

kernel/base/baselib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ char *lib_strncpy(char *dst, const char *src, size_t n)
277277
*q++ = ch = *p++;
278278
if (!ch) break;
279279
}
280-
lib_memset(q, 0, n);
280+
*q = '\0';
281281
return dst;
282282
}
283283

kernel/base/predata.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <predata.h>
77
#include <common.h>
88
#include <log.h>
9+
#include <sha256.h>
910

1011
#include "start.h"
1112
#include "pgtable.h"
@@ -14,11 +15,54 @@
1415
extern start_preset_t start_preset;
1516

1617
static char *superkey = 0;
18+
static char *root_superkey = 0;
1719
static struct patch_symbol *patch_symbol = 0;
1820

19-
int superkey_auth(const char *key)
21+
static const char bstr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
22+
23+
static uint64_t _rand_next = 1000000007;
24+
static int enable_root_key = 1;
25+
26+
int auth_superkey(const char *key)
27+
{
28+
int rc = 0;
29+
rc = lib_strncmp(superkey, key, SUPER_KEY_LEN);
30+
if (!rc) return rc;
31+
32+
if (!enable_root_key) return rc;
33+
34+
BYTE hash[SHA256_BLOCK_SIZE];
35+
SHA256_CTX ctx;
36+
sha256_init(&ctx);
37+
sha256_update(&ctx, (const BYTE *)key, lib_strnlen(key, SUPER_KEY_LEN));
38+
sha256_final(&ctx, hash);
39+
int len = SHA256_BLOCK_SIZE > ROOT_SUPER_KEY_HASH_LEN ? ROOT_SUPER_KEY_HASH_LEN : SHA256_BLOCK_SIZE;
40+
rc = lib_memcmp(root_superkey, hash, len);
41+
42+
static int first_time = 1;
43+
if (!rc && first_time) {
44+
first_time = 0;
45+
reset_superkey(key);
46+
}
47+
48+
return rc;
49+
}
50+
51+
void reset_superkey(const char *key)
2052
{
21-
return lib_strncmp(superkey, key, SUPER_KEY_LEN);
53+
lib_strncpy(superkey, key, SUPER_KEY_LEN - 1);
54+
superkey[SUPER_KEY_LEN - 1] = '\0';
55+
}
56+
57+
void enable_auth_root_key(int enable)
58+
{
59+
enable_root_key = enable;
60+
}
61+
62+
uint64_t rand_next()
63+
{
64+
_rand_next = 1103515245 * _rand_next + 12345;
65+
return _rand_next;
2266
}
2367

2468
const char *get_superkey()
@@ -56,6 +100,29 @@ int on_each_extra_item(int (*callback)(const patch_extra_item_t *extra, const ch
56100
void predata_init()
57101
{
58102
superkey = (char *)start_preset.superkey;
103+
root_superkey = (char *)start_preset.root_superkey;
104+
char *compile_time = start_preset.header.compile_time;
105+
106+
// RNG
107+
_rand_next *= kernel_va;
108+
_rand_next *= kver;
109+
_rand_next *= kpver;
110+
_rand_next *= _kp_region_start;
111+
_rand_next *= _kp_region_end;
112+
if (*(uint64_t *)compile_time) _rand_next *= *(uint64_t *)compile_time;
113+
if (*(uint64_t *)(superkey)) _rand_next *= *(uint64_t *)(superkey);
114+
if (*(uint64_t *)(root_superkey)) _rand_next *= *(uint64_t *)(root_superkey);
115+
116+
// random key
117+
if (lib_strnlen(superkey, SUPER_KEY_LEN) <= 0) {
118+
int len = SUPER_KEY_LEN > 16 ? 16 : SUPER_KEY_LEN;
119+
len--;
120+
for (int i = 0; i < len; ++i) {
121+
uint64_t rand = rand_next() % (sizeof(bstr) - 1);
122+
superkey[i] = bstr[rand];
123+
}
124+
}
125+
log_boot("gen rand key: %s\n", superkey);
59126

60127
patch_symbol = &start_preset.patch_symbol;
61128

@@ -64,4 +131,6 @@ void predata_init()
64131
uintptr_t *p = (uintptr_t *)addr;
65132
if (*p) *p += kernel_va;
66133
}
134+
135+
dsb(ish);
67136
}

kernel/base/setup1.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ start_prepare:
103103
mov x2, #SUPER_KEY_LEN
104104
bl memcpy8
105105

106+
// memcpy(start_preset.root_superkey, setup_preset.root_superkey, ROOT_SUPER_KEY_HASH_LEN);
107+
add x0, x11, #start_root_superkey_offset;
108+
add x1, x10, #setup_root_superkey_offset
109+
mov x2, #ROOT_SUPER_KEY_HASH_LEN
110+
bl memcpy8
111+
106112
// memcpy(&start_preset.patch_symbol, &setup_preset.patch_symbol, sizeof(header.patch_symbol));
107113
add x0, x11, #start_patch_symbol_offset;
108114
add x1, x10, #setup_patch_symbol_offset

kernel/base/sha256.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*********************************************************************
2+
* Filename: sha256.c
3+
* Author: Brad Conte (brad AT bradconte.com)
4+
* Copyright:
5+
* Disclaimer: This code is presented "as is" without any guarantees.
6+
* Details: Implementation of the SHA-256 hashing algorithm.
7+
SHA-256 is one of the three algorithms in the SHA2
8+
specification. The others, SHA-384 and SHA-512, are not
9+
offered in this implementation.
10+
Algorithm specification can be found here:
11+
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
12+
This implementation uses little endian byte order.
13+
*********************************************************************/
14+
15+
/*************************** HEADER FILES ***************************/
16+
#include "sha256.h"
17+
18+
/****************************** MACROS ******************************/
19+
#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
20+
#define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
21+
22+
#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
23+
#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
24+
#define EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22))
25+
#define EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25))
26+
#define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3))
27+
#define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10))
28+
29+
/**************************** VARIABLES *****************************/
30+
static const WORD k[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
31+
0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
32+
0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
33+
0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
34+
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
35+
0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
36+
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
37+
0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
38+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
39+
0xc67178f2 };
40+
41+
/*********************** FUNCTION DEFINITIONS ***********************/
42+
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
43+
{
44+
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
45+
46+
for (i = 0, j = 0; i < 16; ++i, j += 4)
47+
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
48+
for (; i < 64; ++i)
49+
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
50+
51+
a = ctx->state[0];
52+
b = ctx->state[1];
53+
c = ctx->state[2];
54+
d = ctx->state[3];
55+
e = ctx->state[4];
56+
f = ctx->state[5];
57+
g = ctx->state[6];
58+
h = ctx->state[7];
59+
60+
for (i = 0; i < 64; ++i) {
61+
t1 = h + EP1(e) + CH(e, f, g) + k[i] + m[i];
62+
t2 = EP0(a) + MAJ(a, b, c);
63+
h = g;
64+
g = f;
65+
f = e;
66+
e = d + t1;
67+
d = c;
68+
c = b;
69+
b = a;
70+
a = t1 + t2;
71+
}
72+
73+
ctx->state[0] += a;
74+
ctx->state[1] += b;
75+
ctx->state[2] += c;
76+
ctx->state[3] += d;
77+
ctx->state[4] += e;
78+
ctx->state[5] += f;
79+
ctx->state[6] += g;
80+
ctx->state[7] += h;
81+
}
82+
83+
void sha256_init(SHA256_CTX *ctx)
84+
{
85+
ctx->datalen = 0;
86+
ctx->bitlen = 0;
87+
ctx->state[0] = 0x6a09e667;
88+
ctx->state[1] = 0xbb67ae85;
89+
ctx->state[2] = 0x3c6ef372;
90+
ctx->state[3] = 0xa54ff53a;
91+
ctx->state[4] = 0x510e527f;
92+
ctx->state[5] = 0x9b05688c;
93+
ctx->state[6] = 0x1f83d9ab;
94+
ctx->state[7] = 0x5be0cd19;
95+
}
96+
97+
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
98+
{
99+
WORD i;
100+
101+
for (i = 0; i < len; ++i) {
102+
ctx->data[ctx->datalen] = data[i];
103+
ctx->datalen++;
104+
if (ctx->datalen == 64) {
105+
sha256_transform(ctx, ctx->data);
106+
ctx->bitlen += 512;
107+
ctx->datalen = 0;
108+
}
109+
}
110+
}
111+
112+
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
113+
{
114+
WORD i;
115+
116+
i = ctx->datalen;
117+
118+
// Pad whatever data is left in the buffer.
119+
if (ctx->datalen < 56) {
120+
ctx->data[i++] = 0x80;
121+
while (i < 56)
122+
ctx->data[i++] = 0x00;
123+
} else {
124+
ctx->data[i++] = 0x80;
125+
while (i < 64)
126+
ctx->data[i++] = 0x00;
127+
sha256_transform(ctx, ctx->data);
128+
for (int i = 0; i < 56; i++)
129+
ctx->data[i] = 0;
130+
}
131+
132+
// Append to the padding the total message's length in bits and transform.
133+
ctx->bitlen += ctx->datalen * 8;
134+
ctx->data[63] = ctx->bitlen;
135+
ctx->data[62] = ctx->bitlen >> 8;
136+
ctx->data[61] = ctx->bitlen >> 16;
137+
ctx->data[60] = ctx->bitlen >> 24;
138+
ctx->data[59] = ctx->bitlen >> 32;
139+
ctx->data[58] = ctx->bitlen >> 40;
140+
ctx->data[57] = ctx->bitlen >> 48;
141+
ctx->data[56] = ctx->bitlen >> 56;
142+
sha256_transform(ctx, ctx->data);
143+
144+
// Since this implementation uses little endian byte ordering and SHA uses big endian,
145+
// reverse all the bytes when copying the final state to the output hash.
146+
for (i = 0; i < 4; ++i) {
147+
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
148+
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
149+
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
150+
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
151+
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
152+
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
153+
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
154+
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
155+
}
156+
}

kernel/base/start.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ typedef struct
2323
int64_t map_backup_len;
2424
uint8_t map_backup[MAP_MAX_SIZE];
2525
uint8_t superkey[SUPER_KEY_LEN];
26+
uint8_t root_superkey[ROOT_SUPER_KEY_HASH_LEN];
2627
patch_symbol_t patch_symbol;
2728
} start_preset_t;
2829
#else
@@ -37,7 +38,8 @@ typedef struct
3738
#define start_map_backup_len_offset (start_map_offset_offset + 8)
3839
#define start_map_backup_offset (start_map_backup_len_offset + 8)
3940
#define start_superkey_offset (start_map_backup_offset + MAP_MAX_SIZE)
40-
#define start_patch_symbol_offset (start_superkey_offset + SUPER_KEY_LEN)
41+
#define start_root_superkey_offset (start_superkey_offset + SUPER_KEY_LEN)
42+
#define start_patch_symbol_offset (start_root_superkey_offset + ROOT_SUPER_KEY_HASH_LEN)
4143
#define start_patch_extra_offset_offset (start_patch_symbol_offset + PATCH_SYMBOL_LEN)
4244
#define start_patch_extra_size_offset (start_patch_extra_offset_offset + 8)
4345
#define start_end (start_patch_extra_size_offset + 8)

kernel/include/predata.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@
99
#include <ktypes.h>
1010
#include <preset.h>
1111

12-
int superkey_auth(const char *key);
12+
int auth_superkey(const char *key);
13+
void reset_superkey(const char *key);
14+
void enable_auth_root_key(int skip_hash);
1315
const char *get_superkey();
16+
17+
uint64_t rand_next();
1418
uint64_t get_build_config();
1519
struct patch_symbol *get_preset_patch_sym();
20+
1621
int on_each_extra_item(int (*callback)(const patch_extra_item_t *extra, const char *arg, const void *data, void *udata),
1722
void *udata);
1823

0 commit comments

Comments
 (0)