diff options
-rw-r--r-- | extra/rma_reset/Makefile | 51 | ||||
-rw-r--r-- | extra/rma_reset/board.h | 11 | ||||
-rw-r--r-- | extra/rma_reset/rma_reset.c | 181 |
3 files changed, 243 insertions, 0 deletions
diff --git a/extra/rma_reset/Makefile b/extra/rma_reset/Makefile new file mode 100644 index 0000000000..4332ce203d --- /dev/null +++ b/extra/rma_reset/Makefile @@ -0,0 +1,51 @@ +# Copyright 2017 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +PROGRAM := rma_reset +SOURCE := $(PROGRAM).c +OBJS := curve25519.o curve25519-generic.o sha256.o base32.o +LIBS := +LFLAGS := +CFLAGS := -std=gnu99 \ + -g3 \ + -O3 \ + -Wall \ + -Werror \ + -Wpointer-arith \ + -Wcast-align \ + -Wcast-qual \ + -Wundef \ + -Wsign-compare \ + -Wredundant-decls \ + -Wmissing-declarations + +# +# Add libusb-1.0 required flags +# +INCLUDE=-I. -I../../ -I../../test -I../../include -I../../chip/host +LIBS += -lcrypto -lssl +CFLAGS += ${INCLUDE} +STANDALONE_FLAGS=${INCLUDE} -ffreestanding -fno-builtin \ + -Ibuiltin/ -D"__keep= " + +$(PROGRAM): $(SOURCE) $(OBJS) Makefile + gcc $(CFLAGS) $(SOURCE) $(LFLAGS) $(LIBS) $(OBJS) -o $@ + +curve25519-generic.o: ../../common/curve25519-generic.c + gcc $(STANDALONE_FLAGS) -c -o curve25519-generic.o \ + ../../common/curve25519-generic.c + +curve25519.o: ../../common/curve25519.c + gcc $(STANDALONE_FLAGS) -c -o curve25519.o ../../common/curve25519.c + +sha256.o: ../../common/sha256.c + gcc $(STANDALONE_FLAGS) -c -o sha256.o ../../common/sha256.c + +base32.o: ../../common/base32.c + gcc $(STANDALONE_FLAGS) -c -o base32.o ../../common/base32.c + +.PHONY: clean + +clean: + rm -rf *.o $(PROGRAM) *~ diff --git a/extra/rma_reset/board.h b/extra/rma_reset/board.h new file mode 100644 index 0000000000..f969ad0c56 --- /dev/null +++ b/extra/rma_reset/board.h @@ -0,0 +1,11 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +#define CONFIG_RNG + +#endif /* __CROS_EC_BOARD_H */ diff --git a/extra/rma_reset/rma_reset.c b/extra/rma_reset/rma_reset.c new file mode 100644 index 0000000000..0c72894f13 --- /dev/null +++ b/extra/rma_reset/rma_reset.c @@ -0,0 +1,181 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#define __packed __attribute__((packed)) +#include "rma_auth.h" +#include "curve25519.h" +#include "sha256.h" +#include "base32.h" + +#define SERVER_ADDRESS "https://www.google.com/chromeos/partner/console/cr50reset/request" + +/* Server public key and key ID */ +static uint8_t server_pri_key[32] = RMA_TEST_SERVER_PRIVATE_KEY; +static uint8_t server_pub_key[32] = RMA_TEST_SERVER_PUBLIC_KEY; +static uint8_t server_key_id = RMA_TEST_SERVER_KEY_ID; +static uint8_t board_id[4] = {'Z', 'Z', 'C', 'R'}; +static uint8_t device_id[8] = {'T', 'H', 'X', 1, 1, 3, 8, 0xfe}; + +static char challenge[RMA_CHALLENGE_BUF_SIZE]; +static char authcode[RMA_AUTHCODE_BUF_SIZE]; + +void panic_assert_fail(const char *fname, int linenum); +void rand_bytes(void *buffer, size_t len); +int safe_memcmp(const void *s1, const void *s2, size_t size); + +void panic_assert_fail(const char *fname, int linenum) +{ + printf("\nASSERTION FAILURE at %s:%d\n", fname, linenum); +} + +int safe_memcmp(const void *s1, const void *s2, size_t size) +{ + const uint8_t *us1 = s1; + const uint8_t *us2 = s2; + int result = 0; + + if (size == 0) + return 0; + + while (size--) + result |= *us1++ ^ *us2++; + + return result != 0; +} + +void rand_bytes(void *buffer, size_t len) +{ + int random_togo = 0; + uint32_t buffer_index = 0; + uint32_t random_value; + uint8_t *buf = (uint8_t *) buffer; + + while (buffer_index < len) { + if (!random_togo) { + random_value = rand(); + random_togo = sizeof(random_value); + } + buf[buffer_index++] = random_value >> + ((random_togo-- - 1) * 8); + } +} + +int rma_create_challenge(void) +{ + uint8_t temp[32]; /* Private key or HMAC */ + uint8_t secret[32]; + struct rma_challenge c; + uint8_t *cptr = (uint8_t *)&c; + + /* Clear the current challenge and authcode, if any */ + memset(challenge, 0, sizeof(challenge)); + memset(authcode, 0, sizeof(authcode)); + + memset(&c, 0, sizeof(c)); + c.version_key_id = RMA_CHALLENGE_VKID_BYTE( + RMA_CHALLENGE_VERSION, server_key_id); + + memcpy(c.board_id, board_id, sizeof(c.board_id)); + memcpy(c.device_id, device_id, sizeof(c.device_id)); + + /* Calculate a new ephemeral key pair */ + X25519_keypair(c.device_pub_key, temp); + + /* Encode the challenge */ + if (base32_encode(challenge, sizeof(challenge), cptr, 8 * sizeof(c), 9)) + return 1; + + /* Calculate the shared secret */ + X25519(secret, temp, server_pub_key); + + /* + * Auth code is a truncated HMAC of the ephemeral public key, BoardID, + * and DeviceID. Those are all in the right order in the challenge + * struct, after the version/key id byte. + */ + hmac_SHA256(temp, secret, sizeof(secret), cptr + 1, sizeof(c) - 1); + if (base32_encode(authcode, sizeof(authcode), temp, + RMA_AUTHCODE_CHARS * 5, 0)) + return 1; + + return 0; +} + +int rma_try_authcode(const char *code) +{ + return safe_memcmp(authcode, code, RMA_AUTHCODE_CHARS); +} + +static void print_params(void) +{ + int i; + + printf("\nBoard Id:\n"); + for (i = 0; i < 4; i++) + printf("%c ", board_id[i]); + + printf("\n\nDevice Id:\n"); + for (i = 0; i < 3; i++) + printf("%c ", device_id[i]); + for (i = 3; i < 8; i++) + printf("%02x ", device_id[i]); + + printf("\n\nServer Key Id:\n"); + printf("%02x", server_key_id); + + printf("\n\nServer Private Key:\n"); + for (i = 0; i < 32; i++) + printf("%02x%c", server_pri_key[i], ((i + 1) % 8) ? ' ':'\n'); + + printf("\nServer Public Key:\n"); + for (i = 0; i < 32; i++) + printf("%02x%c", server_pub_key[i], ((i + 1) % 8) ? ' ':'\n'); + + printf("\nChallenge:\n"); + for (i = 0; i < RMA_CHALLENGE_CHARS; i++) { + printf("%c", challenge[i]); + if (((i + 1) % 5) == 0) + printf(" "); + if (((i + 1) % 40) == 0) + printf("\n"); + } + + printf("\nAuthorization Code:\n"); + for (i = 0; i < RMA_AUTHCODE_BUF_SIZE; i++) + printf("%c", authcode[i]); + + printf("\n\nChallenge String:\n"); + printf("%s?challenge=", SERVER_ADDRESS); + for (i = 0; i < RMA_CHALLENGE_CHARS; i++) + printf("%c", challenge[i]); + printf("&hwid=HWIDTEST2082\n"); + + printf("\n"); +} + +int main(int argc, char **argv) +{ + char code[25]; + int ret; + + rma_create_challenge(); + print_params(); + + do { + printf("Enter Authorization Code: "); + fgets(code, 25, stdin); + ret = rma_try_authcode(code); + if (ret != 0) + printf("\n\nCode is invalid\n\n"); + } while (ret != 0); + + printf("Code Accepted\n"); + + return 0; +} |