iBoot/lib/effaceable/iboot/effaceable_cmd.c

187 lines
5.2 KiB
C

/*
* Copyright (c) 2010-11 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
// =============================================================================
#include <AppleEffaceableStorageFormat.h>
#include <AppleEffaceableStorageKeys.h>
#include <lib/effaceable.h>
#include <debug.h>
#include <sys/menu.h>
#include <drivers/sha1.h>
// =============================================================================
static int do_effaceable(int argc, struct cmd_arg *args);
static void printUsage(int argc, struct cmd_arg *args);
static void effaceable_hexdump(const void * buf, uint32_t count);
static int lockerList(void);
#if DEBUG_BUILD
static int consumeNonce(void);
#endif
// =============================================================================
static int
do_effaceable(int argc, struct cmd_arg *args)
{
int err;
if (1 >= argc) {
printUsage(argc, args);
err = 0;
} else if (0 == strcmp("lockers", args[1].str)) {
err = lockerList();
#if DEBUG_BUILD
} else if (0 == strcmp("nonce", args[1].str)) {
err = consumeNonce();
#endif
} else {
printUsage(argc, args);
printf("unrecognized subcommand\n");
err = -1;
}
return err;
}
// =============================================================================
static void
printUsage(int argc, struct cmd_arg *args)
{
printf("USAGE: %s <subcmd>\n\n", ((0 < argc) ? args[0].str : "?"));
printf(" Where <subcmd> is one of following\n\n");
printf(" lockers - list lockers and contents\n");
#if DEBUG_BUILD
printf(" nonce - consume nonce; then, report its SHA1 hash and value\n");
#endif
printf(" ...(more to come)...\n\n");
}
// =============================================================================
static void
effaceable_hexdump(const void * buf, uint32_t count)
{
uint32_t i, j;
for (i = 0; i < count; i += 16) {
printf("0x%08x:", ((uint32_t) buf) + i);
for (j = 0; (j < 16) && ((i + j) < count); j++) {
printf(" %02.2x", ((uint8_t*)buf)[i+j]);
}
printf("\n");
}
}
// =============================================================================
#define UNTAG(x) \
\
(uint8_t)(((x) >> 24) & 0xff), \
(uint8_t)(((x) >> 16) & 0xff), \
(uint8_t)(((x) >> 8) & 0xff), \
(uint8_t)((x) & 0xff)
// =============================================================================
static int
lockerList(void)
{
uint8_t *buf, *cursor;
uint32_t size;
AppleEffaceableStorageLockerHeader *header;
size = effaceable_get_capacity();
if (0 == size) {
printf("ERROR: unable to get capacity\n");
return -1;
}
buf = malloc(size);
if (!effaceable_get_bytes(buf, 0, size)) {
printf("ERROR: unable to read\n");
return -1;
}
cursor = buf;
for (;;) {
header = (AppleEffaceableStorageLockerHeader *)cursor;
if (header->magic != kAppleEffaceableStorageLockerMagic) {
printf("WARNING: unexpected magic 0x%04x at %u, expected 0x%04x\n",
header->magic, cursor - buf, kAppleEffaceableStorageLockerMagic);
break;
}
if (header->type_id == kAppleEffaceableStorageLockerSentinel) {
printf("<END>\n");
break;
}
printf("0x%08x/0x%04x %c%c%c%c %s\n",
header->type_id,
header->data_size,
UNTAG(header->type_id & ~kAppleEffaceableStorageLockerProtected),
(header->type_id & kAppleEffaceableStorageLockerProtected) ? "(protected)" : "");
cursor += sizeof(*header);
if (header->data_size > 0) {
if ((cursor + header->data_size) > (buf + size)) {
printf("WARNING: data overflows buffer\n");
break;
}
effaceable_hexdump(cursor, header->data_size);
cursor += header->data_size;
}
if ((cursor + sizeof(*header)) > (buf + size)) {
printf("WARNING: header overflows buffer\n");
break;
}
}
return 0;
}
// =============================================================================
// XXX correct hard-coding of SHA1 buffer size
#define SHA1_HASH_SIZE 20
static int
consumeNonce(void)
{
uint64_t nonce;
uint8_t hash[SHA1_HASH_SIZE];
int idx;
if (!effaceable_consume_nonce(&nonce)) {
printf("ERROR: unable to consume nonce\n");
return -1;
}
sha1_calculate(&nonce, sizeof(nonce), hash);
for (idx = 0; idx < SHA1_HASH_SIZE; idx++) {
printf("%s%02X", (idx ? " " : ""), hash[idx]);
}
printf(" (0x%016llX)\n", nonce);
return 0;
}
// =============================================================================
MENU_COMMAND_DEBUG(effaceable, do_effaceable, "effaceable storage utilities", NULL);
// =============================================================================