diff --git a/extra/rma_reset/rma_reset.c b/extra/rma_reset/rma_reset.c index efbb1b8850..30a2e652cb 100644 --- a/extra/rma_reset/rma_reset.c +++ b/extra/rma_reset/rma_reset.c @@ -47,9 +47,10 @@ static char challenge[RMA_CHALLENGE_BUF_SIZE]; static char authcode[RMA_AUTHCODE_BUF_SIZE]; static char *progname; -static char *short_opts = "k:b:d:a:w:th"; +static char *short_opts = "c:k:b:d:a:w:th"; static const struct option long_opts[] = { /* name hasarg *flag val */ + {"challenge", 1, NULL, 'c'}, {"key_id", 1, NULL, 'k'}, {"board_id", 1, NULL, 'b'}, {"device_id", 1, NULL, 'd'}, @@ -101,6 +102,51 @@ void rand_bytes(void *buffer, size_t len) } } +static int rma_server_side(const char *generated_challenge) +{ + int key_id, version; + uint8_t secret[32]; + uint8_t hmac[32]; + struct rma_challenge c; + uint8_t *cptr = (uint8_t *)&c; + + /* Convert the challenge back into binary */ + if (base32_decode(cptr, 8 * sizeof(c), generated_challenge, 9) != + 8 * sizeof(c)) { + printf("Error decoding challenge\n"); + return -1; + } + + version = RMA_CHALLENGE_GET_VERSION(c.version_key_id); + key_id = RMA_CHALLENGE_GET_KEY_ID(c.version_key_id); + printf("Challenge: %s\n", generated_challenge); + printf("Version: %d\n", version); + printf("Server KeyID: %d\n", key_id); + + if (version != RMA_CHALLENGE_VERSION) + printf("Unsupported challenge version %d\n", version); + + if (key_id != RMA_TEST_SERVER_KEY_ID) + printf("Unsupported KeyID %d\n", key_id); + + /* Calculate the shared secret */ + X25519(secret, server_pri_key, c.device_pub_key); + + /* + * Auth code is a truncated HMAC of the ephemeral public key, BoardID, + * and DeviceID. + */ + hmac_SHA256(hmac, secret, sizeof(secret), cptr + 1, sizeof(c) - 1); + if (base32_encode(authcode, RMA_AUTHCODE_BUF_SIZE, + hmac, RMA_AUTHCODE_CHARS * 5, 0)) { + printf("Error encoding auth code\n"); + return -1; + } + printf("Authcode: %s\n", authcode); + + return 0; +}; + int rma_create_challenge(void) { uint8_t temp[32]; /* Private key or HMAC */ @@ -205,11 +251,17 @@ static void print_params(void) static void usage(void) { printf("\nUsage: %s --key_id --board_id --device_id " - "--hw_id | --auth_code \n" + "--hw_id | --auth_code | " + "--challenge \n" "\n" - "This generates a challenge response and " - "sends authoriztion code to reset device.\n" + "This is used to generate the cr50 or server responses for rma " + "open.\n" + "The cr50 side can be used to generate a challenge response " + "and sends authoriztion code to reset device.\n" + "The server side can generate an authcode from cr50's " + "rma challenge.\n" "\n" + " -c,--challenge The challenge generated by cr50\n" " -k,--key_id Index of the server private key\n" " -b,--board_id BoardID type field\n" " -d,--device_id Device-unique identifier\n" @@ -339,6 +391,8 @@ int main(int argc, char **argv) case 't': t_flag = 1; break; + case 'c': + return rma_server_side(optarg); case 'k': if (set_server_key_id(optarg)) { printf("Malformed key id\n"); @@ -414,8 +468,9 @@ int main(int argc, char **argv) } else { if (!t_flag) { /* Use default values */ if (!k_flag || !b_flag || !d_flag || !w_flag) { - printf("Flags -k, -b, -d, and -w are " - "mandiatory\n"); + printf("server-side: Flag -c is mandatory\n"); + printf("cr50-side: Flags -k, -b, -d, and -w " + "are mandatory\n"); return 1; } }