Ejemplo n.º 1
0
TPM_RESULT TPM_ReleaseTransportSigned(TPM_KEY_HANDLE keyHandle,
                                      TPM_NONCE *antiReplay,
                                      TPM_AUTH *auth1, TPM_AUTH *auth2,
                                      TPM_MODIFIER_INDICATOR *locality,
                                      TPM_CURRENT_TICKS *currentTicks,
                                      UINT32 *sigSize, BYTE **sig)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_SESSION_DATA *session;
  BYTE buf[30 + 20];
  info("TPM_ReleaseTransportSigned()");
  /* get key */
  key = tpm_get_key(keyHandle);
  if (key == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */ 
  if (auth2->authHandle != TPM_INVALID_HANDLE
      || key->authDataUsage != TPM_AUTH_NEVER) {
    res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
    if (res != TPM_SUCCESS) return res;
    session = tpm_get_transport(auth2->authHandle);
    if (session == NULL) return TPM_INVALID_AUTHHANDLE;
    res = tpm_verify_auth(auth2, session->transInternal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return (res == TPM_AUTHFAIL) ? TPM_AUTH2FAIL : res;
  } else {
    session = tpm_get_transport(auth1->authHandle);
    if (session == NULL) return TPM_INVALID_AUTHHANDLE;
    res = tpm_verify_auth(auth1, session->transInternal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return res;
  }
  /* invalidate transport session */
  auth1->continueAuthSession = FALSE;
  /* logging must be enabled */
  if (!(session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG))
    return TPM_BAD_MODE;
  *locality = tpmData.stany.flags.localityModifier;
  memcpy(currentTicks, &tpmData.stany.data.currentTicks, sizeof(TPM_CURRENT_TICKS));
  transport_log_out(auth1->digest, &session->transInternal.transDigest);
  /* setup a TPM_SIGN_INFO structure */
  memcpy(&buf[0], (uint8_t*)"\x00\x05TRAN", 6);
  memcpy(&buf[6], antiReplay->nonce, 20);
  memcpy(&buf[26], (uint8_t*)"\x00\x00\x00\x14", 4);
  memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
  /* sign info structure */ 
  if (key->sigScheme == TPM_SS_RSASSAPKCS1v15_SHA1) {
    tpm_sha1_ctx_t ctx;
    debug("TPM_SS_RSASSAPKCS1v15_SHA1");
    tpm_sha1_init(&ctx);
    tpm_sha1_update(&ctx, buf, sizeof(buf));
    tpm_sha1_final(&ctx, buf);
    res = tpm_sign(key, auth1, FALSE, buf, SHA1_DIGEST_LENGTH, sig, sigSize);
  } else if (key->sigScheme == TPM_SS_RSASSAPKCS1v15_INFO) {
    debug("TPM_SS_RSASSAPKCS1v15_INFO");
    res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), sig, sigSize);
  } else {
    debug("unsupported signature scheme: %02x", key->sigScheme);
    res = TPM_INVALID_KEYUSAGE;
  }
  return res;
}
Ejemplo n.º 2
0
/*
 * Sign operation is performed with the private key in the TPM.
 */
static int tpm_key_sign(struct tpm_key *tk,
			struct kernel_pkey_params *params,
			const void *in, void *out)
{
	struct tpm_buf *tb;
	uint32_t keyhandle;
	uint8_t srkauth[SHA1_DIGEST_SIZE];
	uint8_t keyauth[SHA1_DIGEST_SIZE];
	void *asn1_wrapped = NULL;
	uint32_t in_len = params->in_len;
	int r;

	pr_devel("==>%s()\n", __func__);

	if (strcmp(params->encoding, "pkcs1"))
		return -ENOPKG;

	if (params->hash_algo) {
		const struct asn1_template *asn1 =
						lookup_asn1(params->hash_algo);

		if (!asn1)
			return -ENOPKG;

		/* request enough space for the ASN.1 template + input hash */
		asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
		if (!asn1_wrapped)
			return -ENOMEM;

		/* Copy ASN.1 template, then the input */
		memcpy(asn1_wrapped, asn1->data, asn1->size);
		memcpy(asn1_wrapped + asn1->size, in, in_len);

		in = asn1_wrapped;
		in_len += asn1->size;
	}

	if (in_len > tk->key_len / 8 - 11) {
		r = -EOVERFLOW;
		goto error_free_asn1_wrapped;
	}

	r = -ENOMEM;
	tb = kzalloc(sizeof(*tb), GFP_KERNEL);
	if (!tb)
		goto error_free_asn1_wrapped;

	/* TODO: Handle a non-all zero SRK authorization */
	memset(srkauth, 0, sizeof(srkauth));

	r = tpm_loadkey2(tb, SRKHANDLE, srkauth,
			 tk->blob, tk->blob_len, &keyhandle);
	if (r < 0) {
		pr_devel("loadkey2 failed (%d)\n", r);
		goto error_free_tb;
	}

	/* TODO: Handle a non-all zero key authorization */
	memset(keyauth, 0, sizeof(keyauth));

	r = tpm_sign(tb, keyhandle, keyauth, in, in_len, out, params->out_len);
	if (r < 0)
		pr_devel("tpm_sign failed (%d)\n", r);

	if (tpm_flushspecific(tb, keyhandle) < 0)
		pr_devel("flushspecific failed (%d)\n", r);

error_free_tb:
	kzfree(tb);
error_free_asn1_wrapped:
	kfree(asn1_wrapped);
	pr_devel("<==%s() = %d\n", __func__, r);
	return r;
}