char *FindKernelConfig(const char *infile, uint64_t kernel_body_load_address)
{
  uint8_t* blob;
  size_t blob_size;
  uint8_t *config = NULL;
  char *newstr = NULL;

  blob = MMapFile(infile, &blob_size);
  if (!blob) {
    VbExError("Error reading input file\n");
    return 0;
  }

  config = GetKernelConfig(blob, blob_size, kernel_body_load_address);
  if (!config) {
    VbExError("Error parsing input file\n");
    munmap(blob, blob_size);
    return 0;
  }

  newstr = strndup((char *)config, CROS_CONFIG_SIZE);
  if (!newstr)
    VbExError("Can't allocate new string\n");

  munmap(blob, blob_size);

  return newstr;
}
Beispiel #2
0
VbPrivateKey* PrivateKeyRead(const char* filename) {
  VbPrivateKey *key;
  uint64_t filelen = 0;
  uint8_t *buffer;
  const unsigned char *start;

  buffer = ReadFile(filename, &filelen);
  if (!buffer) {
    VbExError("unable to read from file %s\n", filename);
    return 0;
  }

  key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey));
  if (!key) {
    VbExError("Unable to allocate VbPrivateKey\n");
    free(buffer);
    return 0;
  }

  key->algorithm = *(typeof(key->algorithm) *)buffer;
  start = buffer + sizeof(key->algorithm);

  key->rsa_private_key = d2i_RSAPrivateKey(0, &start,
                                           filelen - sizeof(key->algorithm));

  if (!key->rsa_private_key) {
    VbExError("Unable to parse RSA private key\n");
    free(buffer);
    free(key);
    return 0;
  }

  free(buffer);
  return key;
}
static void* MMapFile(const char* filename, size_t *size) {
  FILE* f;
  uint8_t* buf;
  long file_size = 0;

  f = fopen(filename, "rb");
  if (!f) {
    VBDEBUG(("Unable to open file %s\n", filename));
    return NULL;
  }

  fseek(f, 0, SEEK_END);
  file_size = ftell(f);
  rewind(f);

  if (file_size <= 0) {
    fclose(f);
    return NULL;
  }
  *size = (size_t) file_size;

  /* Uses a host primitive as this is not meant for firmware use. */
  buf = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fileno(f), 0);
  if (buf == MAP_FAILED) {
    VbExError("Failed to mmap the file %s\n", filename);
    fclose(f);
    return NULL;
  }

  fclose(f);
  return buf;
}
/* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */
static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
                uint64_t version) {
  VbPublicKey* pubkey;
  VbPrivateKey* privkey;

  if (!infile || !outfile) {
    fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
    return 1;
  }

  if ((pubkey = PublicKeyReadKeyb(infile, algorithm, version))) {
    if (0 != PublicKeyWrite(outfile, pubkey)) {
      fprintf(stderr, "vbutil_key: Error writing key.\n");
      return 1;
    }
    free(pubkey);
    return 0;
  }

  if ((privkey = PrivateKeyReadPem(infile, algorithm))) {
    if (0 != PrivateKeyWrite(outfile, privkey)) {
      fprintf(stderr, "vbutil_key: Error writing key.\n");
      return 1;
    }
    free(privkey);
    return 0;
  }

  VbExError("Unable to parse either .keyb or .pem from %s\n", infile);
  return 1;
}
Beispiel #5
0
void *VbExMalloc(size_t size)
{
	void *ptr = cros_memalign_cache(size);
	if (!ptr) {
		VbExError("Internal malloc error.");
	}
	return ptr;
}
Beispiel #6
0
VbError_t VbExBeep(uint32_t msec, uint32_t frequency)
{
#if defined(CONFIG_SYS_COREBOOT)
	if (frequency)
		enable_beep(frequency);
	else
		disable_beep();

	if (msec > 0) {
		VbExSleepMs(msec);
		disable_beep();
	}

	return VBERROR_SUCCESS;
#elif defined CONFIG_SOUND
	int ret;

	VBDEBUG("About to beep for %d ms at %d Hz.\n", msec, frequency);
	if (!msec || !frequency) {
		if (msec)
			VbExSleepMs(msec);
		return VBERROR_NO_BACKGROUND_SOUND;
	}

	ret = sound_init(gd->fdt_blob);
	if (ret) {
		VbExError("Failed to initialize sound.\n");
		return VBERROR_NO_SOUND;
	}

	ret = sound_play(msec, frequency);
	if (ret) {
		VbExError("Failed to play beep.\n");
		return VBERROR_NO_SOUND;
	}

	return VBERROR_SUCCESS;
#else
	/* TODO Implement it later. */
	VbExSleepMs(msec);
	VBDEBUG("Beep!\n");
	return VBERROR_NO_SOUND;
#endif
}
static uint8_t* GetKernelConfig(uint8_t* blob, size_t blob_size,
                                uint64_t kernel_body_load_address) {

  VbKeyBlockHeader* key_block;
  VbKernelPreambleHeader* preamble;
  uint32_t now = 0;
  uint32_t offset = 0;

  /* Skip the key block */
  key_block = (VbKeyBlockHeader*)blob;
  now += key_block->key_block_size;
  if (now + blob > blob + blob_size) {
    VbExError("key_block_size advances past the end of the blob\n");
    return NULL;
  }

  /* Open up the preamble */
  preamble = (VbKernelPreambleHeader*)(blob + now);
  now += preamble->preamble_size;
  if (now + blob > blob + blob_size) {
    VbExError("preamble_size advances past the end of the blob\n");
    return NULL;
  }

  /* Read body_load_address from preamble if no kernel_body_load_address */
  if (kernel_body_load_address == USE_PREAMBLE_LOAD_ADDR)
    kernel_body_load_address = preamble->body_load_address;

  /* The x86 kernels have a pointer to the kernel commandline in the zeropage
   * table, but that's irrelevant for ARM. Both types keep the config blob in
   * the same place, so just go find it. */
  offset = preamble->bootloader_address -
    (kernel_body_load_address + CROS_PARAMS_SIZE +
     CROS_CONFIG_SIZE) + now;
  if (offset > blob_size) {
    VbExError("params are outside of the memory blob: %x\n", offset);
    return NULL;
  }
  return blob + offset;
}
Beispiel #8
0
/* Write a private key to a file in .vbprivk format. */
int PrivateKeyWrite(const char* filename, const VbPrivateKey* key) {
  uint8_t *outbuf = 0;
  int buflen;
  FILE *f;

  buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf);
  if (buflen <= 0) {
    VbExError("Unable to write private key buffer\n");
    return 1;
  }

  f = fopen(filename, "wb");
  if (!f) {
    VbExError("Unable to open file %s\n", filename);
    free(outbuf);
    return 1;
  }

  if (1 != fwrite(&key->algorithm, sizeof(key->algorithm), 1, f)) {
    VbExError("Unable to write to file %s\n", filename);
    fclose(f);
    free(outbuf);
    unlink(filename);  /* Delete any partial file */
  }

  if (1 != fwrite(outbuf, buflen, 1, f)) {
    VbExError("Unable to write to file %s\n", filename);
    fclose(f);
    unlink(filename);  /* Delete any partial file */
    free(outbuf);
  }

  fclose(f);
  free(outbuf);
  return 0;
}
/* Unpack a .vbpubk or .vbprivk */
static int Unpack(const char *infile, const char *outfile) {
  VbPublicKey* pubkey;
  VbPrivateKey* privkey;

  if (!infile) {
    fprintf(stderr, "Need file to unpack\n");
    return 1;
  }

  if ((pubkey = PublicKeyRead(infile))) {
    printf("Public Key file:   %s\n", infile);
    printf("Algorithm:         %" PRIu64 " %s\n", pubkey->algorithm,
           (pubkey->algorithm < kNumAlgorithms ?
            algo_strings[pubkey->algorithm] : "(invalid)"));
    printf("Key Version:       %" PRIu64 "\n", pubkey->key_version);
    printf("Key sha1sum:       ");
    PrintPubKeySha1Sum(pubkey);
    printf("\n");
    if (outfile) {
      if (0 != PublicKeyWrite(outfile, pubkey)) {
        fprintf(stderr, "vbutil_key: Error writing key copy.\n");
        free(pubkey);
        return 1;
      }
    }
    free(pubkey);
    return 0;
  }

  if ((privkey = PrivateKeyRead(infile))) {
    printf("Private Key file:  %s\n", infile);
    printf("Algorithm:         %" PRIu64 " %s\n", privkey->algorithm,
           (privkey->algorithm < kNumAlgorithms ?
            algo_strings[privkey->algorithm] : "(invalid)"));
    if (outfile) {
      if (0 != PrivateKeyWrite(outfile, privkey)) {
        fprintf(stderr, "vbutil_key: Error writing key copy.\n");
        free(privkey);
        return 1;
      }
    }
    free(privkey);
    return 0;
  }

  VbExError("Unable to parse either .vbpubk or vbprivk from %s\n", infile);
  return 1;
}
int main(int argc, char** argv) {
  uint8_t disable, deactivated;

  TlclLibInit();
  TPM_CHECK(TlclStartupIfNeeded());
  TPM_CHECK(TlclSelfTestFull());
  TPM_CHECK(TlclAssertPhysicalPresence());
  TPM_CHECK(TlclGetFlags(&disable, &deactivated, NULL));
  printf("disable is %d, deactivated is %d\n", disable, deactivated);
  TPM_CHECK(TlclSetEnable());
  TPM_CHECK(TlclSetDeactivated(0));
  TPM_CHECK(TlclGetFlags(&disable, &deactivated, NULL));
  printf("disable is %d, deactivated is %d\n", disable, deactivated);
  if (disable == 1 || deactivated == 1) {
    VbExError("failed to enable or activate");
  }
  printf("TEST SUCCEEDED\n");
  return 0;
}
static void setup_arch_unused_memory(memory_wipe_t *wipe,
	crossystem_data_t *cdata, VbCommonParams *cparams)
{
	struct fdt_memory config, ramoops, lp0;

	if (cros_fdtdec_memory(gd->fdt_blob, "/memory", &config))
		VbExError("FDT decode memory section error\n");

	memory_wipe_add(wipe, config.start, config.end);

#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
	/* Exclude the TLB */
	memory_wipe_sub(wipe, gd->tlb_addr, gd->tlb_addr + gd->tlb_size);
#endif

	/* Excludes kcrashmem if in FDT */
	if (cros_fdtdec_memory(gd->fdt_blob, "/ramoops", &ramoops))
		VBDEBUG("RAMOOPS not contained within FDT\n");
	else
		memory_wipe_sub(wipe, ramoops.start, ramoops.end);

	/* Excludes the LP0 vector; only applicable to tegra platforms */
	if (cros_fdtdec_memory(gd->fdt_blob, "/lp0", &lp0))
		VBDEBUG("LP0 not contained within FDT\n");
	else
		memory_wipe_sub(wipe, lp0.start, lp0.end);

#ifdef CONFIG_LCD
	{
		/* Excludes the frame buffer. */
		int fb_size = lcd_fb_size();

		memory_wipe_sub(wipe,
				(uintptr_t)gd->fb_base,
				(uintptr_t)gd->fb_base + fb_size);
	}
#endif
}
Beispiel #12
0
void *VbExMalloc(size_t size)
{
	void *ptr;

	if (heap_current == NULL) {
		heap_current = &_heap[0];
		heap_size = &_eheap[0] - &_heap[0];
		VbExDebug("vboot heap: %p 0x%08x bytes\n",
		           heap_current, heap_size);
	}

	if (heap_size < size) {
		VbExError("vboot heap request cannot be fulfilled. "
		           "0x%08x available, 0x%08x requested\n",
		           heap_size, size);
	}

	ptr = heap_current;
	heap_size -= size;
	heap_current += size;

	return ptr;
}
/* Create a firmware .vblock */
static int Vblock(const char* outfile, const char* keyblock_file,
                  const char* signprivate, uint64_t version,
                  const char* fv_file, const char* kernelkey_file,
                  uint32_t preamble_flags) {

  VbPrivateKey* signing_key;
  VbPublicKey* kernel_subkey;
  VbSignature* body_sig;
  VbFirmwarePreambleHeader* preamble;
  VbKeyBlockHeader* key_block;
  uint64_t key_block_size;
  uint8_t* fv_data;
  uint64_t fv_size;
  FILE* f;
  uint64_t i;

  if (!outfile) {
    VbExError("Must specify output filename\n");
    return 1;
  }
  if (!keyblock_file || !signprivate || !kernelkey_file) {
    VbExError("Must specify all keys\n");
    return 1;
  }
  if (!fv_file) {
    VbExError("Must specify firmware volume\n");
    return 1;
  }

  /* Read the key block and keys */
  key_block = (VbKeyBlockHeader*)ReadFile(keyblock_file, &key_block_size);
  if (!key_block) {
    VbExError("Error reading key block.\n");
    return 1;
  }

  signing_key = PrivateKeyRead(signprivate);
  if (!signing_key) {
    VbExError("Error reading signing key.\n");
    return 1;
  }

  kernel_subkey = PublicKeyRead(kernelkey_file);
  if (!kernel_subkey) {
    VbExError("Error reading kernel subkey.\n");
    return 1;
  }

  /* Read and sign the firmware volume */
  fv_data = ReadFile(fv_file, &fv_size);
  if (!fv_data)
    return 1;
  if (!fv_size) {
    VbExError("Empty firmware volume file\n");
    return 1;
  }
  body_sig = CalculateSignature(fv_data, fv_size, signing_key);
  if (!body_sig) {
    VbExError("Error calculating body signature\n");
    return 1;
  }
  free(fv_data);

  /* Create preamble */
  preamble = CreateFirmwarePreamble(version,
                                    kernel_subkey,
                                    body_sig,
                                    signing_key,
                                    preamble_flags);
  if (!preamble) {
    VbExError("Error creating preamble.\n");
    return 1;
  }

  /* Write the output file */
  f = fopen(outfile, "wb");
  if (!f) {
    VbExError("Can't open output file %s\n", outfile);
    return 1;
  }
  i = ((1 != fwrite(key_block, key_block_size, 1, f)) ||
       (1 != fwrite(preamble, preamble->preamble_size, 1, f)));
  fclose(f);
  if (i) {
    VbExError("Can't write output file %s\n", outfile);
    unlink(outfile);
    return 1;
  }

  /* Success */
  return 0;
}
static int Verify(const char* infile, const char* signpubkey,
                  const char* fv_file, const char* kernelkey_file) {

  VbKeyBlockHeader* key_block;
  VbFirmwarePreambleHeader* preamble;
  VbPublicKey* data_key;
  VbPublicKey* sign_key;
  VbPublicKey* kernel_subkey;
  RSAPublicKey* rsa;
  uint8_t* blob;
  uint64_t blob_size;
  uint8_t* fv_data;
  uint64_t fv_size;
  uint64_t now = 0;
  uint32_t flags;

  if (!infile || !signpubkey || !fv_file) {
    VbExError("Must specify filename, signpubkey, and fv\n");
    return 1;
  }

  /* Read public signing key */
  sign_key = PublicKeyRead(signpubkey);
  if (!sign_key) {
    VbExError("Error reading signpubkey.\n");
    return 1;
  }

  /* Read blob */
  blob = ReadFile(infile, &blob_size);
  if (!blob) {
    VbExError("Error reading input file\n");
    return 1;
  }

  /* Read firmware volume */
  fv_data = ReadFile(fv_file, &fv_size);
  if (!fv_data) {
    VbExError("Error reading firmware volume\n");
    return 1;
  }

  /* Verify key block */
  key_block = (VbKeyBlockHeader*)blob;
  if (0 != KeyBlockVerify(key_block, blob_size, sign_key, 0)) {
    VbExError("Error verifying key block.\n");
    return 1;
  }
  free(sign_key);
  now += key_block->key_block_size;

  printf("Key block:\n");
  data_key = &key_block->data_key;
  printf("  Size:                %" PRIu64 "\n", key_block->key_block_size);
  printf("  Flags:               %" PRIu64 " (ignored)\n",
         key_block->key_block_flags);
  printf("  Data key algorithm:  %" PRIu64 " %s\n", data_key->algorithm,
         (data_key->algorithm < kNumAlgorithms ?
          algo_strings[data_key->algorithm] : "(invalid)"));
  printf("  Data key version:    %" PRIu64 "\n", data_key->key_version);
  printf("  Data key sha1sum:    ");
  PrintPubKeySha1Sum(data_key);
  printf("\n");

  rsa = PublicKeyToRSA(&key_block->data_key);
  if (!rsa) {
    VbExError("Error parsing data key.\n");
    return 1;
  }

  /* Verify preamble */
  preamble = (VbFirmwarePreambleHeader*)(blob + now);
  if (0 != VerifyFirmwarePreamble(preamble, blob_size - now, rsa)) {
    VbExError("Error verifying preamble.\n");
    return 1;
  }
  now += preamble->preamble_size;

  flags = VbGetFirmwarePreambleFlags(preamble);
  printf("Preamble:\n");
  printf("  Size:                  %" PRIu64 "\n", preamble->preamble_size);
  printf("  Header version:        %" PRIu32 ".%" PRIu32"\n",
         preamble->header_version_major, preamble->header_version_minor);
  printf("  Firmware version:      %" PRIu64 "\n", preamble->firmware_version);
  kernel_subkey = &preamble->kernel_subkey;
  printf("  Kernel key algorithm:  %" PRIu64 " %s\n",
         kernel_subkey->algorithm,
         (kernel_subkey->algorithm < kNumAlgorithms ?
          algo_strings[kernel_subkey->algorithm] : "(invalid)"));
  printf("  Kernel key version:    %" PRIu64 "\n",
         kernel_subkey->key_version);
  printf("  Kernel key sha1sum:    ");
  PrintPubKeySha1Sum(kernel_subkey);
  printf("\n");
  printf("  Firmware body size:    %" PRIu64 "\n",
         preamble->body_signature.data_size);
  printf("  Preamble flags:        %" PRIu32 "\n", flags);

  /* TODO: verify body size same as signature size */

  /* Verify body */
  if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
    printf("Preamble requests USE_RO_NORMAL; skipping body verification.\n");
  } else {
    if (0 != VerifyData(fv_data, fv_size, &preamble->body_signature, rsa)) {
      VbExError("Error verifying firmware body.\n");
      return 1;
    }
    printf("Body verification succeeded.\n");
  }

  if (kernelkey_file) {
    if (0 != PublicKeyWrite(kernelkey_file, kernel_subkey)) {
      fprintf(stderr,
              "vbutil_firmware: unable to write kernel subkey\n");
      return 1;
    }
  }

  return 0;
}
Beispiel #15
0
int main(int argc, char* argv[]) {

  char *infile = NULL;
  char *outfile = NULL;
  int mode = 0;
  int parse_error = 0;
  uint64_t version = 1;
  uint64_t algorithm = kNumAlgorithms;
  char* e;
  int i;

  char *progname = strrchr(argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[0];

  while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
    switch (i) {
      case '?':
        /* Unhandled option */
        VbExError("Unknown option\n");
        parse_error = 1;
        break;

      case OPT_INKEY:
        infile = optarg;
        break;

      case OPT_KEY_VERSION:
        version = strtoul(optarg, &e, 0);
        if (!*optarg || (e && *e)) {
          VbExError("Invalid --version\n");
          parse_error = 1;
        }
        break;

      case OPT_ALGORITHM:
        algorithm = strtoul(optarg, &e, 0);
        if (!*optarg || (e && *e)) {
          VbExError("Invalid --algorithm\n");
          parse_error = 1;
        }
        break;

      case OPT_MODE_PACK:
        mode = i;
        outfile = optarg;
        break;

      case OPT_MODE_UNPACK:
        mode = i;
        infile = optarg;
        break;

      case OPT_COPYTO:
        outfile = optarg;
        break;
    }
  }

  if (parse_error)
    return PrintHelp(progname);

  switch(mode) {
    case OPT_MODE_PACK:
      return Pack(infile, outfile, algorithm, version);
    case OPT_MODE_UNPACK:
      return Unpack(infile, outfile);
    default:
      printf("Must specify a mode.\n");
      return PrintHelp(progname);
  }
}