diff --git a/Makefile b/Makefile index 8bb2667..83deb9a 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,9 @@ CC ?= gcc SHELL ?= /bin/sh KVSFLIST := \ src/KVS/main.c \ - src/KVS/ui.c \ - src/KVS/kernver-utils.c + src/KVS/tpm.c \ + src/KVS/rmasmoke.c \ + src/KVS/ui.c CFLAGS := \ -Iinclude \ diff --git a/include/arg_checks.h b/include/arg_checks.h index 555ee08..1e22c5e 100644 --- a/include/arg_checks.h +++ b/include/arg_checks.h @@ -19,4 +19,14 @@ bool fbool(const char *arg) } return false; +} + +char *fequals(const char *arg) +{ + for (int i = 0; i < gargc; i++) { + if (!memcmp(gargv[i], arg, strlen(arg) - 1)) + return gargv[i] + strlen(arg) + 1; + } + + return ""; } \ No newline at end of file diff --git a/include/ui.h b/include/ui.h new file mode 100644 index 0000000..97d6f9b --- /dev/null +++ b/include/ui.h @@ -0,0 +1,7 @@ +#ifndef KVS2_UI_H +#define KVS2_UI_H + +void ui_flash(char* flashtype); +void ui_header(char* fwver, char* kernver, char* tpmver, char* fwmp, char* gscver, char* gsctype); + +#endif \ No newline at end of file diff --git a/src/KVS/kernver-utils.c b/include/ver0.h similarity index 100% rename from src/KVS/kernver-utils.c rename to include/ver0.h diff --git a/src/KVS/tpm-payload.c b/include/ver1.h similarity index 100% rename from src/KVS/tpm-payload.c rename to include/ver1.h diff --git a/src/KVG/main.c b/src/KVG/main.c index a77ecfd..1d15405 100644 --- a/src/KVG/main.c +++ b/src/KVG/main.c @@ -9,19 +9,36 @@ #include "arg_checks.h" #include "hex_utils.h" +uint32_t kvarg; // basically almost all of this code was pieced together // using vboot_reference code, credits to Google // for writing most of this code in a sense :3 +#define VB2_SHA256_DIGEST_SIZE 32 + struct vb2_secdata_kernel_v0 { uint8_t struct_version; uint32_t uid; - uint32_t kernel_versions; + uint32_t kernver; uint8_t reserved[3]; uint8_t crc8; } __attribute__((packed)); +struct vb2_secdata_kernel_v1 { + uint8_t struct_version; /* 1.0 (or 0x10 in v0 format) */ + uint8_t struct_size; + uint8_t crc8; + uint8_t flags; + uint32_t kernver; + uint8_t ec_hash[VB2_SHA256_DIGEST_SIZE]; +}; + + +struct vb2_secdata_kernel_v0 secdata0; +struct vb2_secdata_kernel_v1 secdata1; + + struct vb2_context { void *secdata_kernel; }; @@ -44,17 +61,37 @@ uint8_t vb2_crc8(const void *vptr, uint32_t size) return (uint8_t)(crc >> 8); } +#define MAJOR_VER(x) (((x) & 0xf0) >> 4) +#define MINOR_VER(x) ((x) & 0x0f) + +static inline int is_v0(struct vb2_context *ctx) +{ + struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel; + return MAJOR_VER(sec->struct_version) == 0; +} + static uint8_t secdata_kernel_crc(struct vb2_context *ctx) { - size_t offset, size; - offset = 0; - size = offsetof(struct vb2_secdata_kernel_v0, crc8); - return vb2_crc8(ctx->secdata_kernel + offset, size); + size_t offset, size; + + if (is_v0(ctx)) { + offset = 0; + size = offsetof(struct vb2_secdata_kernel_v0, crc8); + } else { + struct vb2_secdata_kernel_v1 *sec + = (void *)ctx->secdata_kernel; + offset = offsetof(struct vb2_secdata_kernel_v1, flags); + size = sec->struct_size - offset; + } + + return vb2_crc8(ctx->secdata_kernel + offset, size); } + int main(int argc, char *argv[]) { gargc = argc; gargv = argv; + char *version = fequals("--ver"); // if --help or no args are passsed // print the usage and an example command @@ -63,38 +100,69 @@ int main(int argc, char *argv[]) { printf("e.g: %s 0x00010001 --raw\n", argv[0]); printf("-=-=-=-=-=-=-\n"); printf("--raw - prints the output as raw hex bytes\n"); + printf("--ver=<0/1> - specifies the kernver struct version to use, oldui boards use ver0 while newui boards use ver1\n"); printf("--help - shows this message :3\n"); printf("-=-=-=-=-=-=-\n"); printf("KVG was created by kxtzownsu\n"); + printf("Credits go to Hannah for making the arg parsing system\n"); exit(0); } - struct vb2_secdata_kernel_v0 secdata; - - secdata.struct_version = 0x02; - secdata.uid = 0x4752574c; - secdata.reserved[0] = 0x00; - secdata.reserved[1] = 0x00; - secdata.reserved[2] = 0x00; - // make sure the user sends us a correct hex value, // we dont want to just blindly trust that its correct if (is_valid_hex(argv[1])) { - uint32_t kvarg = convert_to_uint32(argv[1]); - secdata.kernel_versions = kvarg; + kvarg = convert_to_uint32(argv[1]); } else { printf("The entered kernver: %s, wasn't detected as valid hexadecimal, please try again.\n", argv[1]); exit(1); } - struct vb2_context ctx; - ctx.secdata_kernel = (void *)&secdata; - - secdata.crc8 = secdata_kernel_crc(&ctx); - if (fbool("--raw")) { - fwrite(&secdata, sizeof(secdata), 1, stdout); - } else { - print_hex((uint8_t *)&secdata, sizeof(struct vb2_secdata_kernel_v0)); + if (strcmp(version, "0") != 0 && strcmp(version, "1") != 0) { + printf("The entered struct version: %s, wasn't a valid option (see --help). Please try again.\n", version); + exit(1); } + + if (!strcmp(version, "0")){ + secdata0.struct_version = 0x02; + secdata0.uid = 0x4752574c; + secdata0.reserved[0] = 0x00; + secdata0.reserved[1] = 0x00; + secdata0.reserved[2] = 0x00; + secdata0.kernver = kvarg; + + struct vb2_context ctx; + ctx.secdata_kernel = (void *)&secdata0; + + secdata0.crc8 = secdata_kernel_crc(&ctx); + } + + if (!strcmp(version, "1")) { + secdata1.struct_version = 0x10; + secdata1.struct_size = sizeof(struct vb2_secdata_kernel_v1); + secdata1.flags = 0x0; + secdata1.kernver = kvarg; + + struct vb2_context ctx; + ctx.secdata_kernel = (void *)&secdata1; + secdata1.crc8 = secdata_kernel_crc(&ctx); + } + + // god i hate this nesting, TODO: find a better way to detect if we're specifying ver0 or ver1 + if (fbool("--raw")) { + if (!strcmp(version, "0")) { + fwrite(&secdata0, sizeof(secdata0), 1, stdout); + } + if (!strcmp(version, "1")) { + fwrite(&secdata1, sizeof(secdata1), 1, stdout); + } + } else { + if (!strcmp(version, "0")) { + print_hex((uint8_t *)&secdata0, sizeof(struct vb2_secdata_kernel_v0)); + } + if (!strcmp(version, "1")) { + print_hex((uint8_t *)&secdata1, sizeof(struct vb2_secdata_kernel_v1)); + } + } + return 0; -} \ No newline at end of file +} diff --git a/src/KVS/main.c b/src/KVS/main.c index e69de29..a73bd2f 100644 --- a/src/KVS/main.c +++ b/src/KVS/main.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include "ui.h" + +int main(int argc, char **argv) { + // example values for testing + char* fwver = "Google_Grunt.11031.149.0"; + char* kernver = "0x00010001"; + char* tpmver = "2.0"; + char* fwmp = "0x1"; + char* gscver = "0.5.229"; + char* gsctype = "Cr50"; + + // only allow 2 characters (option & newline) + char choice[2]; + + ui_header(fwver, kernver, tpmver, fwmp, gscver, gsctype); + printf("1) Flash new kernver via /dev/tpm0 (REQ. UNENROLLED)\n"); + printf("2) Flash new kernver via RMASmoke (REQ. CR50 VER 0.5.229 OR LOWER)\n"); + printf("3) Make kernver index unwritable\n"); + printf("4) Shell\n"); + printf("5) Reboot\n"); + printf("> "); + fgets(choice, sizeof(choice), stdin); + if (choice[strlen(choice) - 1] == '\n') { + choice[strlen(choice) - 1] = '\0'; + } + printf("You entered: %s\n", choice); + + if (strcmp(choice, "1") == 0) { + ui_flash("tpm0"); + } + + return 0; +} diff --git a/src/KVS/rmasmoke.c b/src/KVS/rmasmoke.c new file mode 100644 index 0000000..e69de29 diff --git a/src/KVS/tpm.c b/src/KVS/tpm.c new file mode 100644 index 0000000..e69de29 diff --git a/src/KVS/ui.c b/src/KVS/ui.c index e69de29..b65f8fa 100644 --- a/src/KVS/ui.c +++ b/src/KVS/ui.c @@ -0,0 +1,22 @@ +#include + +void ui_flash(char* flashtype) { + printf("wip\n"); +} + +void ui_header(char* fwver, char* kernver, char* tpmver, char* fwmp, char* gscver, char* gsctype){ + printf("KVS: Kernel Version Switcher (codename Maglev, bid: 2.0.0))\n"); + printf("FW Version: %s\n", fwver); + printf("Kernel Version: %s\n", kernver); + printf("TPM: %s\n", tpmver); + printf("FWMP: %s\n", fwmp); + printf("GSC RW Version: %s\n", gscver); + printf("GSC Type: %s\n", gsctype); + printf("-=-=-=-=-=-=-=-=-=-=-=-=-\n"); +} + +void ui_credits(){ + printf("kxtzownsu - Writing KVS 1 and 2\n"); + printf("Hannah/ZegLol - Helping with /dev/tpm0 flashing, rewriting RMASmoke.\n"); + printf("Writable - Writing the RMASmoke vulnerability\n"); +} \ No newline at end of file