Example #1
0
/* 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;
}
Example #2
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;
}
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;
}
Example #4
0
static int vb1_make_keypair()
{
	VbPrivateKey *privkey = 0;
	VbPublicKey *pubkey = 0;
	RSA *rsa_key = 0;
	uint8_t *keyb_data = 0;
	uint32_t keyb_size;
	enum vb2_signature_algorithm sig_alg;
	uint64_t vb1_algorithm;
	FILE *fp;
	int ret = 1;

	fp = fopen(infile, "rb");
	if (!fp) {
		fprintf(stderr, "Unable to open %s\n", infile);
		goto done;
	}

	rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
	fclose(fp);

	if (!rsa_key) {
		fprintf(stderr, "Unable to read RSA key from %s\n", infile);
		goto done;
	}

	sig_alg = vb2_rsa_sig_alg(rsa_key);
	if (sig_alg == VB2_SIG_INVALID) {
		fprintf(stderr, "Unsupported sig algorithm in RSA key\n");
		goto done;
	}

	/* combine the sig_alg with the hash_alg to get the vb1 algorithm */
	vb1_algorithm = (sig_alg - VB2_SIG_RSA1024) * 3
		+ opt_hash_alg - VB2_HASH_SHA1;

	/* Create the private key */
	privkey = (VbPrivateKey *)malloc(sizeof(VbPrivateKey));
	if (!privkey)
		goto done;

	privkey->rsa_private_key = rsa_key;
	privkey->algorithm = vb1_algorithm;

	/* Write it out */
	strcpy(outext, ".vbprivk");
	if (0 != PrivateKeyWrite(outfile, privkey)) {
		fprintf(stderr, "unable to write private key\n");
		goto done;
	}
	fprintf(stderr, "wrote %s\n", outfile);

	/* Create the public key */
	ret = vb_keyb_from_rsa(rsa_key, &keyb_data, &keyb_size);
	if (ret) {
		fprintf(stderr, "couldn't extract the public key\n");
		goto done;
	}

	pubkey = PublicKeyAlloc(keyb_size, vb1_algorithm, opt_version);
	if (!pubkey)
		goto done;
	memcpy(GetPublicKeyData(pubkey), keyb_data, keyb_size);

	/* Write it out */
	strcpy(outext, ".vbpubk");
	if (0 != PublicKeyWrite(outfile, pubkey)) {
		fprintf(stderr, "unable to write public key\n");
		goto done;
	}
	fprintf(stderr, "wrote %s\n", outfile);

	ret = 0;

done:
	free(privkey);
	free(pubkey);
	free(keyb_data);
	RSA_free(rsa_key);
	return ret;
}