summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extra/rma_reset/Makefile51
-rw-r--r--extra/rma_reset/board.h11
-rw-r--r--extra/rma_reset/rma_reset.c181
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;
+}