tss-esapi-7.4.0/.cargo_vcs_info.json 0000644 00000000147 00000000001 0012756 0 ustar {
"git": {
"sha1": "7c68948b3264c051a16c3a04af505f9d662999bf"
},
"path_in_vcs": "tss-esapi"
} tss-esapi-7.4.0/Cargo.toml 0000644 00000003365 00000000001 0010761 0 ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "tss-esapi"
version = "7.4.0"
authors = ["Parsec Project Contributors"]
description = "Rust-native wrapper around TSS 2.0 Enhanced System API"
documentation = "https://docs.rs/crate/tss-esapi"
readme = "README.md"
keywords = [
"tpm",
"tss",
"esys",
"esapi",
]
categories = [
"api-bindings",
"external-ffi-bindings",
"cryptography",
]
license = "Apache-2.0"
repository = "https://github.com/parallaxsecond/rust-tss-esapi"
[dependencies.bitfield]
version = "0.14.0"
[dependencies.enumflags2]
version = "0.7.1"
[dependencies.hostname-validator]
version = "1.1.0"
[dependencies.log]
version = "0.4.11"
[dependencies.mbox]
version = "0.6.0"
[dependencies.num-derive]
version = "0.4.0"
[dependencies.num-traits]
version = "0.2.12"
[dependencies.oid]
version = "0.2.1"
[dependencies.picky-asn1]
version = "0.8.0"
[dependencies.picky-asn1-x509]
version = "0.12.0"
[dependencies.regex]
version = "1.3.9"
[dependencies.serde]
version = "1.0.115"
features = ["derive"]
[dependencies.tss-esapi-sys]
version = "0.5.0"
[dependencies.zeroize]
version = "1.1.0"
features = ["zeroize_derive"]
[dev-dependencies.env_logger]
version = "0.10.0"
[dev-dependencies.sha2]
version = "0.10.1"
[features]
generate-bindings = ["tss-esapi-sys/generate-bindings"]
tss-esapi-7.4.0/Cargo.toml.orig 0000644 0000000 0000000 00000001743 10461020230 0014440 0 ustar 0000000 0000000 [package]
name = "tss-esapi"
version = "7.4.0"
authors = ["Parsec Project Contributors"]
edition = "2018"
description = "Rust-native wrapper around TSS 2.0 Enhanced System API"
readme = "README.md"
keywords = ["tpm", "tss", "esys", "esapi"]
categories = ["api-bindings", "external-ffi-bindings", "cryptography"]
license = "Apache-2.0"
repository = "https://github.com/parallaxsecond/rust-tss-esapi"
documentation = "https://docs.rs/crate/tss-esapi"
[dependencies]
bitfield = "0.14.0"
serde = { version = "1.0.115", features = ["derive"] }
mbox = "0.6.0"
log = "0.4.11"
enumflags2 = "0.7.1"
num-derive = "0.4.0"
num-traits = "0.2.12"
hostname-validator = "1.1.0"
regex = "1.3.9"
zeroize = { version = "1.1.0", features = ["zeroize_derive"] }
tss-esapi-sys = { path = "../tss-esapi-sys", version = "0.5.0" }
oid = "0.2.1"
picky-asn1 = "0.8.0"
picky-asn1-x509 = "0.12.0"
[dev-dependencies]
env_logger = "0.10.0"
sha2 = "0.10.1"
[features]
generate-bindings = ["tss-esapi-sys/generate-bindings"]
tss-esapi-7.4.0/LICENSE 0000644 0000000 0000000 00000026136 10461020230 0012561 0 ustar 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
tss-esapi-7.4.0/README.md 0000644 0000000 0000000 00000002563 10461020230 0013031 0 ustar 0000000 0000000 # TPM2 Software Stack Rust Wrapper
This is the high-level, Rust idiomatic wrapper crate that exposes an interface
to [TSS](https://github.com/tpm2-software/tpm2-tss).
This crate depends on the [`tss-esapi-sys`](../tss-esapi-sys/) crate for its
FFI interface. By default, pre-generated bindings are used. If you'd like the
bindings to be generated at build time, please enable either the
`generate-bindings` feature - the FFI bindings will then be generated at build
time using the headers identified on the system.
Our end-goal is to achieve a fully Rust-native interface that offers strong safety and security guarantees. Check out our [documentation](https://docs.rs/tss-esapi/*/tss_esapi/#notes-on-code-safety) for an overview of our code safety approach.
## Cross compiling
For more information on cross-compiling the `tss-esapi` crate, please see the README of the `tss-esapi-sys` crate.
*Copyright 2021 Contributors to the Parsec project.*
tss-esapi-7.4.0/build.rs 0000644 0000000 0000000 00000001032 10461020230 0013205 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
fn main() {
if let Ok(tss2_esys_version) = std::env::var("DEP_TSS2_ESYS_VERSION") {
match tss2_esys_version.chars().next().unwrap() {
'2' => println!("cargo:rustc-cfg=tpm2_tss_version=\"2\""),
'3' => println!("cargo:rustc-cfg=tpm2_tss_version=\"3\""),
'4' => println!("cargo:rustc-cfg=tpm2_tss_version=\"4\""),
major => panic!("Unsupported TSS version: {}", major),
}
}
}
tss-esapi-7.4.0/src/abstraction/ak.rs 0000644 0000000 0000000 00000016557 10461020230 0015623 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
abstraction::{cipher::Cipher, IntoKeyCustomization, KeyCustomization},
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
constants::{AlgorithmIdentifier, SessionType},
handles::{AuthHandle, KeyHandle, SessionHandle},
interface_types::{
algorithm::{
AsymmetricAlgorithm, EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm,
RsaSchemeAlgorithm, SignatureSchemeAlgorithm,
},
ecc::EccCurve,
key_bits::RsaKeyBits,
session_handles::PolicySession,
},
structures::{
Auth, CreateKeyResult, EccScheme, KeyDerivationFunctionScheme, Private, Public,
PublicBuilder, PublicEccParametersBuilder, PublicKeyRsa, PublicRsaParametersBuilder,
RsaExponent, RsaScheme, SymmetricDefinitionObject,
},
Context, Error, Result, WrapperErrorKind,
};
use log::error;
use std::convert::{TryFrom, TryInto};
fn create_ak_public(
key_alg: AsymmetricAlgorithm,
hash_alg: HashingAlgorithm,
sign_alg: SignatureSchemeAlgorithm,
key_customization: IKC,
) -> Result {
let key_customization = key_customization.into_key_customization();
let obj_attrs_builder = ObjectAttributesBuilder::new()
.with_restricted(true)
.with_user_with_auth(true)
.with_sign_encrypt(true)
.with_decrypt(false)
.with_fixed_tpm(true)
.with_fixed_parent(true)
.with_sensitive_data_origin(true);
let obj_attrs = if let Some(ref k) = key_customization {
k.attributes(obj_attrs_builder)
} else {
obj_attrs_builder
}
.build()?;
let key_builder = match key_alg {
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Rsa)
.with_name_hashing_algorithm(hash_alg)
.with_object_attributes(obj_attrs)
.with_rsa_parameters(
PublicRsaParametersBuilder::new()
.with_scheme(RsaScheme::create(
RsaSchemeAlgorithm::try_from(AlgorithmIdentifier::from(sign_alg))?,
Some(hash_alg),
)?)
.with_key_bits(RsaKeyBits::Rsa2048)
.with_exponent(RsaExponent::default())
.with_is_signing_key(obj_attrs.sign_encrypt())
.with_is_decryption_key(obj_attrs.decrypt())
.with_restricted(obj_attrs.restricted())
.build()?,
)
.with_rsa_unique_identifier(PublicKeyRsa::default()),
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(hash_alg)
.with_object_attributes(obj_attrs)
.with_ecc_parameters(
PublicEccParametersBuilder::new()
.with_symmetric(SymmetricDefinitionObject::Null)
.with_ecc_scheme(EccScheme::create(
EccSchemeAlgorithm::try_from(AlgorithmIdentifier::from(sign_alg))?,
Some(hash_alg),
Some(0),
)?)
.with_curve(EccCurve::NistP192)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.build()?,
),
AsymmetricAlgorithm::Null => {
// TODO: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
};
let key_builder = if let Some(ref k) = key_customization {
k.template(key_builder)
} else {
key_builder
};
key_builder.build()
}
/// This loads an Attestation Key previously generated under the Endorsement hierarchy
pub fn load_ak(
context: &mut Context,
parent: KeyHandle,
ak_auth_value: Option,
private: Private,
public: Public,
) -> Result {
let policy_auth_session = context
.start_auth_session(
None,
None,
None,
SessionType::Policy,
Cipher::aes_128_cfb().try_into()?,
HashingAlgorithm::Sha256,
)?
.ok_or_else(|| Error::local_error(WrapperErrorKind::WrongValueFromTpm))?;
let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
.with_decrypt(true)
.with_encrypt(true)
.build();
context.tr_sess_set_attributes(
policy_auth_session,
session_attributes,
session_attributes_mask,
)?;
let key_handle = context.execute_with_temporary_object(
SessionHandle::from(policy_auth_session).into(),
|ctx, _| {
let _ = ctx.execute_with_nullauth_session(|ctx| {
ctx.policy_secret(
PolicySession::try_from(policy_auth_session)?,
AuthHandle::Endorsement,
Default::default(),
Default::default(),
Default::default(),
None,
)
})?;
ctx.execute_with_session(Some(policy_auth_session), |ctx| {
ctx.load(parent, private, public)
})
},
)?;
if let Some(ak_auth_value) = ak_auth_value {
context.tr_set_auth(key_handle.into(), ak_auth_value)?;
}
Ok(key_handle)
}
/// This creates an Attestation Key in the Endorsement hierarchy
pub fn create_ak(
context: &mut Context,
parent: KeyHandle,
hash_alg: HashingAlgorithm,
sign_alg: SignatureSchemeAlgorithm,
ak_auth_value: Option,
key_customization: IKC,
) -> Result {
let key_alg = AsymmetricAlgorithm::try_from(sign_alg).map_err(|e| {
// sign_alg is either HMAC or Null.
error!("Could not retrieve asymmetric algorithm for provided signature scheme");
e
})?;
let ak_pub = create_ak_public(key_alg, hash_alg, sign_alg, key_customization)?;
let policy_auth_session = context
.start_auth_session(
None,
None,
None,
SessionType::Policy,
Cipher::aes_128_cfb().try_into()?,
HashingAlgorithm::Sha256,
)?
.ok_or_else(|| Error::local_error(WrapperErrorKind::WrongValueFromTpm))?;
let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
.with_decrypt(true)
.with_encrypt(true)
.build();
context.tr_sess_set_attributes(
policy_auth_session,
session_attributes,
session_attributes_mask,
)?;
context.execute_with_temporary_object(
SessionHandle::from(policy_auth_session).into(),
|ctx, _| {
let _ = ctx.execute_with_nullauth_session(|ctx| {
ctx.policy_secret(
PolicySession::try_from(policy_auth_session)?,
AuthHandle::Endorsement,
Default::default(),
Default::default(),
Default::default(),
None,
)
})?;
ctx.execute_with_session(Some(policy_auth_session), |ctx| {
ctx.create(parent, ak_pub, ak_auth_value, None, None, None)
})
},
)
}
tss-esapi-7.4.0/src/abstraction/cipher.rs 0000644 0000000 0000000 00000020363 10461020230 0016470 0 ustar 0000000 0000000 // Copyright 2019 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::AlgorithmIdentifier,
interface_types::{
algorithm::{HashingAlgorithm, SymmetricAlgorithm, SymmetricMode, SymmetricObject},
key_bits::{AesKeyBits, CamelliaKeyBits, Sm4KeyBits},
},
structures::{SymmetricCipherParameters, SymmetricDefinition, SymmetricDefinitionObject},
Error, Result, WrapperErrorKind,
};
use std::convert::{TryFrom, TryInto};
/// Block cipher identifiers
///
/// Structure useful for handling an abstract representation of ciphers. Ciphers are
/// defined foremost through their symmetric algorithm and, depending on the type of that
/// algorithm, on a set of other values.
#[derive(Copy, Clone, Debug)]
pub struct Cipher {
algorithm: SymmetricAlgorithm,
mode: Option,
key_bits: Option,
hash: Option,
}
impl Cipher {
/// Constructor for AES cipher identifier
///
/// `key_bits` must be one of 128, 192 or 256.
pub fn aes(mode: SymmetricMode, key_bits: u16) -> Result {
match key_bits {
128 | 192 | 256 => (),
_ => return Err(Error::local_error(WrapperErrorKind::InvalidParam)),
}
Ok(Cipher {
algorithm: SymmetricAlgorithm::Aes,
mode: Some(mode),
key_bits: Some(key_bits),
hash: None,
})
}
/// Constructor for Camellia cipher identifier
///
/// `key_bits` must be one of 128, 192 or 256.
pub fn camellia(mode: SymmetricMode, key_bits: u16) -> Result {
match key_bits {
128 | 192 | 256 => (),
_ => return Err(Error::local_error(WrapperErrorKind::InvalidParam)),
}
Ok(Cipher {
algorithm: SymmetricAlgorithm::Camellia,
mode: Some(mode),
key_bits: Some(key_bits),
hash: None,
})
}
/// Constructor for Triple DES cipher identifier
///
/// `key_bits` must be one of 56, 112 or 168.
pub fn tdes(mode: SymmetricMode, key_bits: u16) -> Result {
match key_bits {
56 | 112 | 168 => (),
_ => return Err(Error::local_error(WrapperErrorKind::InvalidParam)),
}
Ok(Cipher {
algorithm: SymmetricAlgorithm::Tdes,
mode: Some(mode),
key_bits: Some(key_bits),
hash: None,
})
}
/// Constructor for SM4 cipher identifier
pub fn sm4(mode: SymmetricMode) -> Self {
Cipher {
algorithm: SymmetricAlgorithm::Sm4,
mode: Some(mode),
key_bits: Some(128),
hash: None,
}
}
/// Constructor for XOR "cipher" identifier
pub fn xor(hash: HashingAlgorithm) -> Self {
Cipher {
algorithm: SymmetricAlgorithm::Xor,
mode: None,
key_bits: None,
hash: Some(hash),
}
}
/// Get general object type for symmetric ciphers.
pub fn object_type() -> AlgorithmIdentifier {
AlgorithmIdentifier::SymCipher
}
/// Get the cipher key length.
pub fn key_bits(self) -> Option {
self.key_bits
}
/// Get the cipher mode.
pub fn mode(self) -> Option {
self.mode
}
/// Get the hash algorithm used with an XOR cipher
pub fn hash(self) -> Option {
self.hash
}
/// Get the symmetrical algorithm for the cipher.
pub fn algorithm(&self) -> SymmetricAlgorithm {
self.algorithm
}
/// Constructor for 128 bit AES in CFB mode.
pub fn aes_128_cfb() -> Self {
Cipher {
algorithm: SymmetricAlgorithm::Aes,
mode: Some(SymmetricMode::Cfb),
key_bits: Some(128),
hash: None,
}
}
/// Constructor for 256 bit AES in CFB mode.
pub fn aes_256_cfb() -> Self {
Cipher {
algorithm: SymmetricAlgorithm::Aes,
mode: Some(SymmetricMode::Cfb),
key_bits: Some(256),
hash: None,
}
}
}
impl TryFrom for SymmetricDefinition {
type Error = Error;
fn try_from(cipher: Cipher) -> Result {
match cipher.algorithm {
SymmetricAlgorithm::Aes => Ok(SymmetricDefinition::Aes {
key_bits: cipher
.key_bits
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(AesKeyBits::try_from)?,
mode: cipher
.mode
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))?,
}),
SymmetricAlgorithm::Sm4 => Ok(SymmetricDefinition::Sm4 {
key_bits: cipher
.key_bits
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(Sm4KeyBits::try_from)?,
mode: cipher
.mode
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))?,
}),
SymmetricAlgorithm::Camellia => Ok(SymmetricDefinition::Camellia {
key_bits: cipher
.key_bits
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(CamelliaKeyBits::try_from)?,
mode: cipher
.mode
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))?,
}),
SymmetricAlgorithm::Xor => Ok(SymmetricDefinition::Xor {
hashing_algorithm: cipher
.hash
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(|ha| {
if ha != HashingAlgorithm::Null {
Ok(ha)
} else {
Err(Error::local_error(WrapperErrorKind::InvalidParam))
}
})?,
}),
SymmetricAlgorithm::Null => Ok(SymmetricDefinition::Null),
SymmetricAlgorithm::Tdes => {
// TODO: Investigate
Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
}
}
}
}
impl TryFrom for SymmetricDefinitionObject {
type Error = Error;
fn try_from(cipher: Cipher) -> Result {
match SymmetricObject::try_from(AlgorithmIdentifier::from(cipher.algorithm))? {
SymmetricObject::Aes => Ok(SymmetricDefinitionObject::Aes {
key_bits: cipher
.key_bits
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(AesKeyBits::try_from)?,
mode: cipher
.mode
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))?,
}),
SymmetricObject::Sm4 => Ok(SymmetricDefinitionObject::Sm4 {
key_bits: cipher
.key_bits
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(Sm4KeyBits::try_from)?,
mode: cipher
.mode
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))?,
}),
SymmetricObject::Camellia => Ok(SymmetricDefinitionObject::Camellia {
key_bits: cipher
.key_bits
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))
.and_then(CamelliaKeyBits::try_from)?,
mode: cipher
.mode
.ok_or_else(|| Error::local_error(WrapperErrorKind::ParamsMissing))?,
}),
SymmetricObject::Null => Ok(SymmetricDefinitionObject::Null),
SymmetricObject::Tdes => {
// TODO investigate
Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
}
}
}
}
impl TryFrom for SymmetricCipherParameters {
type Error = Error;
fn try_from(cipher: Cipher) -> Result {
Ok(SymmetricCipherParameters::new(cipher.try_into()?))
}
}
tss-esapi-7.4.0/src/abstraction/ek.rs 0000644 0000000 0000000 00000014540 10461020230 0015615 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
abstraction::{nv, IntoKeyCustomization, KeyCustomization},
attributes::ObjectAttributesBuilder,
handles::{KeyHandle, NvIndexTpmHandle, TpmHandle},
interface_types::{
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, PublicAlgorithm},
ecc::EccCurve,
key_bits::RsaKeyBits,
resource_handles::{Hierarchy, NvAuth},
},
structures::{
Digest, EccParameter, EccPoint, EccScheme, KeyDerivationFunctionScheme, Public,
PublicBuilder, PublicEccParametersBuilder, PublicKeyRsa, PublicRsaParametersBuilder,
RsaExponent, RsaScheme, SymmetricDefinitionObject,
},
Context, Error, Result, WrapperErrorKind,
};
use std::convert::TryFrom;
// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
// Section 2.2.1.4 (Low Range) for Windows compatibility
const RSA_2048_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00002;
const ECC_P256_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0000a;
/// Get the [`Public`] representing a default Endorsement Key
///
/// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
/// Appendix B.3.3 and B.3.4
pub fn create_ek_public_from_default_template(
alg: AsymmetricAlgorithm,
key_customization: IKC,
) -> Result {
let key_customization = key_customization.into_key_customization();
let obj_attrs_builder = ObjectAttributesBuilder::new()
.with_fixed_tpm(true)
.with_st_clear(false)
.with_fixed_parent(true)
.with_sensitive_data_origin(true)
.with_user_with_auth(false)
.with_admin_with_policy(true)
.with_no_da(false)
.with_encrypted_duplication(false)
.with_restricted(true)
.with_decrypt(true)
.with_sign_encrypt(false);
let obj_attrs = if let Some(ref k) = key_customization {
k.attributes(obj_attrs_builder)
} else {
obj_attrs_builder
}
.build()?;
// TPM2_PolicySecret(TPM_RH_ENDORSEMENT)
// With 32 null-bytes attached, because of the type of with_auth_policy
let authpolicy: [u8; 64] = [
0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8, 0x1a, 0x90, 0xcc, 0x8d, 0x46, 0xa5, 0xd7,
0x24, 0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64, 0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14,
0x69, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let key_builder = match alg {
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Rsa)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(obj_attrs)
.with_auth_policy(Digest::try_from(authpolicy[0..32].to_vec())?)
.with_rsa_parameters(
PublicRsaParametersBuilder::new()
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
.with_scheme(RsaScheme::Null)
.with_key_bits(RsaKeyBits::Rsa2048)
.with_exponent(RsaExponent::default())
.with_is_signing_key(obj_attrs.sign_encrypt())
.with_is_decryption_key(obj_attrs.decrypt())
.with_restricted(obj_attrs.decrypt())
.build()?,
)
.with_rsa_unique_identifier(PublicKeyRsa::new_empty_with_size(RsaKeyBits::Rsa2048)),
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(obj_attrs)
.with_auth_policy(Digest::try_from(authpolicy[0..32].to_vec())?)
.with_ecc_parameters(
PublicEccParametersBuilder::new()
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
.with_ecc_scheme(EccScheme::Null)
.with_curve(EccCurve::NistP256)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.with_is_signing_key(obj_attrs.sign_encrypt())
.with_is_decryption_key(obj_attrs.decrypt())
.with_restricted(obj_attrs.decrypt())
.build()?,
)
.with_ecc_unique_identifier(EccPoint::new(
EccParameter::try_from(vec![0u8; 32])?,
EccParameter::try_from(vec![0u8; 32])?,
)),
AsymmetricAlgorithm::Null => {
// TDOD: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
};
let key_builder = if let Some(ref k) = key_customization {
k.template(key_builder)
} else {
key_builder
};
key_builder.build()
}
/// Create the Endorsement Key object from the specification templates
pub fn create_ek_object(
context: &mut Context,
alg: AsymmetricAlgorithm,
key_customization: IKC,
) -> Result {
let ek_public = create_ek_public_from_default_template(alg, key_customization)?;
Ok(context
.execute_with_nullauth_session(|ctx| {
ctx.create_primary(Hierarchy::Endorsement, ek_public, None, None, None, None)
})?
.key_handle)
}
/// Retrieve the Endorsement Key public certificate from the TPM
pub fn retrieve_ek_pubcert(context: &mut Context, alg: AsymmetricAlgorithm) -> Result> {
let nv_idx = match alg {
AsymmetricAlgorithm::Rsa => RSA_2048_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithm::Ecc => ECC_P256_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithm::Null => {
// TDOD: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
};
let nv_idx = NvIndexTpmHandle::new(nv_idx).unwrap();
let nv_auth_handle = TpmHandle::NvIndex(nv_idx);
let nv_auth_handle = context.execute_without_session(|ctx| {
ctx.tr_from_tpm_public(nv_auth_handle)
.map(|v| NvAuth::NvIndex(v.into()))
})?;
context.execute_with_nullauth_session(|ctx| nv::read_full(ctx, nv_auth_handle, nv_idx))
}
tss-esapi-7.4.0/src/abstraction/mod.rs 0000644 0000000 0000000 00000003013 10461020230 0015766 0 ustar 0000000 0000000 // Copyright 2019 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
pub mod ak;
pub mod cipher;
pub mod ek;
pub mod nv;
pub mod pcr;
pub mod public;
pub mod transient;
use crate::{attributes::ObjectAttributesBuilder, structures::PublicBuilder};
/// KeyCustomizaion allows to adjust how a key is going to be created
pub trait KeyCustomization {
/// Alter the attributes used on key creation
fn attributes(&self, attributes_builder: ObjectAttributesBuilder) -> ObjectAttributesBuilder {
attributes_builder
}
/// Alter the key template used on key creation
fn template(&self, template_builder: PublicBuilder) -> PublicBuilder {
template_builder
}
}
/// IntoKeyCustomization transforms a type into a type that support KeyCustomization
pub trait IntoKeyCustomization {
type T: KeyCustomization;
fn into_key_customization(self) -> Option;
}
impl IntoKeyCustomization for T {
type T = T;
fn into_key_customization(self) -> Option {
Some(self)
}
}
#[derive(Debug, Copy, Clone)]
pub struct DefaultKey;
#[derive(Debug, Copy, Clone)]
pub struct DefaultKeyImpl;
impl KeyCustomization for DefaultKeyImpl {}
impl IntoKeyCustomization for DefaultKey {
type T = DefaultKeyImpl;
fn into_key_customization(self) -> Option {
None
}
}
impl IntoKeyCustomization for Option {
type T = DefaultKeyImpl;
fn into_key_customization(self) -> Option {
None
}
}
tss-esapi-7.4.0/src/abstraction/nv.rs 0000644 0000000 0000000 00000021557 10461020230 0015647 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use std::{
convert::{TryFrom, TryInto},
io::Read,
};
use crate::{
constants::{tss::*, CapabilityType, PropertyTag},
handles::{AuthHandle, NvIndexHandle, NvIndexTpmHandle, TpmHandle},
interface_types::resource_handles::NvAuth,
structures::{CapabilityData, MaxNvBuffer, Name, NvPublic},
Context, Error, Result, WrapperErrorKind,
};
/// Allows reading an NV Index completely, regardless of the max TPM NV buffer size
pub fn read_full(
context: &mut Context,
auth_handle: NvAuth,
nv_index_handle: NvIndexTpmHandle,
) -> Result> {
let mut rw = NvOpenOptions::ExistingIndex {
auth_handle,
nv_index_handle,
}
.open(context)?;
let mut result = Vec::with_capacity(rw.size());
let _ = rw.read_to_end(&mut result).map_err(|e| {
// Try to convert the error back into a tss-esapi::Error if it was one originally
match e.into_inner() {
None => Error::WrapperError(WrapperErrorKind::InvalidParam),
Some(e) => match e.downcast::() {
Ok(e) => *e,
Err(_) => Error::WrapperError(WrapperErrorKind::InvalidParam),
},
}
})?;
Ok(result)
}
/// Returns the NvPublic and Name associated with an NV index TPM handle
///
/// NOTE: This call _may_ close existing ESYS handles to the NV Index.
fn get_nv_index_info(
context: &mut Context,
nv_index_tpm_handle: NvIndexTpmHandle,
) -> Result<(NvPublic, Name)> {
context
.tr_from_tpm_public(nv_index_tpm_handle.into())
.and_then(|mut object_handle| {
context
.nv_read_public(NvIndexHandle::from(object_handle))
.map_err(|e| {
let _ = context.tr_close(&mut object_handle);
e
})
.and_then(|(nv_public, name)| {
context.tr_close(&mut object_handle)?;
Ok((nv_public, name))
})
})
}
/// Lists all the currently defined NV Indexes' names and public components
///
/// NOTE: This call _may_ close existing ESYS handles to the existing NV Indexes.
pub fn list(context: &mut Context) -> Result> {
context.execute_without_session(|ctx| {
ctx.get_capability(
CapabilityType::Handles,
TPM2_NV_INDEX_FIRST,
TPM2_PT_NV_INDEX_MAX,
)
.and_then(|(capability_data, _)| match capability_data {
CapabilityData::Handles(tpm_handles) => Ok(tpm_handles),
_ => Err(Error::local_error(WrapperErrorKind::WrongValueFromTpm)),
})
.and_then(|tpm_handles| {
tpm_handles
.iter()
.map(|&tpm_handle| get_nv_index_info(ctx, NvIndexTpmHandle::try_from(tpm_handle)?))
.collect()
})
})
}
/// Options and flags which can be used to determine how a non-volatile storage index is opened.
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum NvOpenOptions {
/// Define a new NV space with given auth
NewIndex {
nv_public: NvPublic,
auth_handle: NvAuth,
},
/// Open the NV space at the given handle, with the given auth
ExistingIndex {
nv_index_handle: NvIndexTpmHandle,
auth_handle: NvAuth,
},
}
impl NvOpenOptions {
/// Opens a non-volatile storage index using the options specified by `self`
///
/// The non-volatile storage index may be used for reading or writing or both.
pub fn open<'a>(&self, context: &'a mut Context) -> Result> {
let buffer_size = max_nv_buffer_size(context)?;
let (data_size, nv_idx, auth_handle) = match self {
NvOpenOptions::ExistingIndex {
nv_index_handle,
auth_handle,
} => {
let nv_idx = TpmHandle::NvIndex(*nv_index_handle);
let nv_idx = context
.execute_without_session(|ctx| ctx.tr_from_tpm_public(nv_idx))?
.into();
(
context
.execute_without_session(|ctx| ctx.nv_read_public(nv_idx))
.map(|(nvpub, _)| nvpub.data_size())?,
nv_idx,
auth_handle,
)
}
NvOpenOptions::NewIndex {
nv_public,
auth_handle,
} => (
nv_public.data_size(),
context.nv_define_space(
AuthHandle::from(*auth_handle).try_into()?,
None,
nv_public.clone(),
)?,
auth_handle,
),
};
Ok(NvReaderWriter {
context,
auth_handle: *auth_handle,
buffer_size,
nv_idx,
data_size,
offset: 0,
})
}
}
/// Get the maximum buffer size for an NV space.
pub fn max_nv_buffer_size(ctx: &mut Context) -> Result {
Ok(ctx
.get_tpm_property(PropertyTag::NvBufferMax)?
.map(usize::try_from)
.transpose()
.map_err(|_| {
log::error!("Failed to obtain valid maximum NV buffer size");
Error::WrapperError(WrapperErrorKind::InternalError)
})?
.unwrap_or(MaxNvBuffer::MAX_SIZE))
}
/// Non-volatile storage index reader/writer
///
/// Provides methods and trait implementations to interact with a non-volatile storage index that has been opened.
///
/// Use [`NvOpenOptions::open`] to obtain an [`NvReaderWriter`] object.
///
/// NOTE: When the `NvReaderWriter` is dropped, any existing ESYS handles to NV Indexes _may_ be closed.
#[derive(Debug)]
pub struct NvReaderWriter<'a> {
context: &'a mut Context,
auth_handle: NvAuth,
buffer_size: usize,
nv_idx: NvIndexHandle,
data_size: usize,
offset: usize,
}
impl NvReaderWriter<'_> {
/// The size of the data in the non-volatile storage index
pub fn size(&self) -> usize {
self.data_size
}
}
impl Read for NvReaderWriter<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result {
if self.data_size <= self.offset {
return Ok(0);
}
let desired_size = std::cmp::min(buf.len(), self.data_size - self.offset);
let size: u16 = std::cmp::min(self.buffer_size, desired_size) as u16;
let res = self
.context
.nv_read(self.auth_handle, self.nv_idx, size, self.offset as u16)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
buf[0..size as usize].copy_from_slice(&res);
self.offset += size as usize;
Ok(size.into())
}
}
impl std::io::Write for NvReaderWriter<'_> {
fn write(&mut self, buf: &[u8]) -> std::io::Result {
if self.data_size < self.offset {
return Ok(0);
}
let desired_size = std::cmp::min(buf.len(), self.data_size - self.offset);
let size = std::cmp::min(self.buffer_size, desired_size) as u16;
let data = buf[0..size.into()]
.try_into()
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
self.context
.nv_write(self.auth_handle, self.nv_idx, data, self.offset as u16)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
self.offset += size as usize;
Ok(size.into())
}
fn flush(&mut self) -> std::io::Result<()> {
// Data isn't buffered
Ok(())
}
}
impl std::io::Seek for NvReaderWriter<'_> {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result {
let inv_input_err = |_| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"invalid seek to a negative or overflowing position",
)
};
let (base, offset) = match pos {
std::io::SeekFrom::Start(offset) => {
(usize::try_from(offset).map_err(inv_input_err)?, 0)
}
std::io::SeekFrom::End(offset) => (self.data_size, offset),
std::io::SeekFrom::Current(offset) => (self.offset, offset),
};
let new_offset = i64::try_from(base)
.map_err(inv_input_err)?
.checked_add(offset)
.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"invalid seek to a negative or overflowing position",
)
})?;
self.offset = new_offset.try_into().map_err(inv_input_err)?;
self.offset.try_into().map_err(inv_input_err)
}
}
impl Drop for NvReaderWriter<'_> {
fn drop(&mut self) {
let mut obj_handle = self.nv_idx.into();
let _ = self
.context
.execute_without_session(|ctx| ctx.tr_close(&mut obj_handle));
}
}
tss-esapi-7.4.0/src/abstraction/pcr/bank.rs 0000644 0000000 0000000 00000010722 10461020230 0016713 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
structures::{Digest, PcrSlot},
Error, Result, WrapperErrorKind,
};
use log::error;
use std::collections::BTreeMap;
/// Struct for holding PcrSlots and their
/// corresponding values.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct PcrBank {
bank: BTreeMap,
}
impl PcrBank {
/// Function that creates PcrBank from a vector of pcr slots and
/// a vector of pcr digests.
///
/// # Details
/// The order of pcr slots are assumed to match the order of the Digests.
///
/// # Errors
/// - If number of pcr slots does not match the number of pcr digests
/// InconsistentParams error is returned.
///
/// - If the vector of pcr slots contains duplicates then
/// InconsistentParams error is returned.
pub fn create(mut pcr_slots: Vec, mut digests: Vec) -> Result {
if pcr_slots.len() != digests.len() {
error!(
"Number of PcrSlots does not match the number of PCR digests. ({} != {})",
pcr_slots.len(),
digests.len()
);
return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
}
pcr_slots
.drain(..)
.zip(digests.drain(..))
.try_fold(BTreeMap::::new(), |mut data, (pcr_slot, digest)| {
if data.insert(pcr_slot, digest).is_none() {
Ok(data)
} else {
error!("Error trying to insert data into PcrSlot {:?} where data have already been inserted", pcr_slot);
Err(Error::local_error(WrapperErrorKind::InconsistentParams))
}
})
.map(|bank| PcrBank { bank })
}
/// Retrieves reference to a [Digest] associated with the provided [PcrSlot].
///
/// # Details
/// Returns a reference to a [Digest] associated with the provided [PcrSlot]
/// if one exists else returns None.
pub fn get_digest(&self, pcr_slot: PcrSlot) -> Option<&Digest> {
self.bank.get(&pcr_slot)
}
/// Returns true if the [PcrBank] contains a digest
/// for the provided [PcrSlot].
pub fn has_digest(&self, pcr_slot: PcrSlot) -> bool {
self.bank.contains_key(&pcr_slot)
}
/// Number of digests in the [PcrBank]
pub fn len(&self) -> usize {
self.bank.len()
}
/// Returns true if the [PcrBank] is empty
pub fn is_empty(&self) -> bool {
self.bank.is_empty()
}
/// Removees the [Digest] associated with the [PcrSlot] and
/// returns it.
///
/// # Details
/// Removes the [Digest] associated with the provided [PcrSlot]
/// out of the bank and returns it if it exists else returns None.
pub fn remove_digest(&mut self, pcr_slot: PcrSlot) -> Option {
self.bank.remove(&pcr_slot)
}
/// Inserts [Digest] value associated with a [PcrSlot] into the bank.
///
/// # Errors
/// Returns an error if a [Digest] is already associated with the
/// provided [PcrSlot].
pub fn insert_digest(&mut self, pcr_slot: PcrSlot, digest: Digest) -> Result<()> {
self.ensure_non_existing(pcr_slot, "Failed to insert")?;
let _ = self.bank.insert(pcr_slot, digest);
Ok(())
}
/// Attempts to extend the [PcrBank] with `other`.
///
/// # Errors
/// Returns an error if the a value in `other` already
/// exists.
pub fn try_extend(&mut self, other: PcrBank) -> Result<()> {
other
.bank
.keys()
.try_for_each(|&pcr_slot| self.ensure_non_existing(pcr_slot, "Failed to extend"))?;
self.bank.extend(other.bank);
Ok(())
}
/// Returns an error if a [Digest] for [PcrSlot] already exists in the bank
fn ensure_non_existing(&self, pcr_slot: PcrSlot, error_msg: &str) -> Result<()> {
if self.has_digest(pcr_slot) {
error!(
"{}, a digest already for PcrSlot {:?} exists in the bank",
error_msg, pcr_slot
);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
Ok(())
}
}
impl<'a> IntoIterator for &'a PcrBank {
type Item = (&'a PcrSlot, &'a Digest);
type IntoIter = ::std::collections::btree_map::Iter<'a, PcrSlot, Digest>;
fn into_iter(self) -> Self::IntoIter {
self.bank.iter()
}
}
tss-esapi-7.4.0/src/abstraction/pcr/data.rs 0000644 0000000 0000000 00000010626 10461020230 0016714 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
abstraction::pcr::PcrBank,
interface_types::algorithm::HashingAlgorithm,
structures::{Digest, DigestList, PcrSelectionList},
tss2_esys::TPML_DIGEST,
Error, Result, WrapperErrorKind,
};
use log::error;
/// Struct holding pcr banks and their associated
/// hashing algorithm
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PcrData {
data: Vec<(HashingAlgorithm, PcrBank)>,
}
impl PcrData {
/// Creates new empty PcrData
pub const fn new() -> Self {
PcrData { data: Vec::new() }
}
/// Function for creating PcrData from a pcr selection list and pcr digests list.
pub fn create(
pcr_selection_list: &PcrSelectionList,
digest_list: &DigestList,
) -> Result {
Ok(PcrData {
data: Self::create_data(pcr_selection_list, digest_list.value().to_vec())?,
})
}
/// Adds data to the PcrData
pub fn add(
&mut self,
pcr_selection_list: &PcrSelectionList,
digest_list: &DigestList,
) -> Result<()> {
Self::create_data(pcr_selection_list, digest_list.value().to_vec())?
.drain(..)
.try_for_each(|(hashing_algorithm, pcr_bank)| {
if let Some(existing_pcr_bank) = self.pcr_bank_mut(hashing_algorithm) {
existing_pcr_bank.try_extend(pcr_bank)?;
} else {
self.data.push((hashing_algorithm, pcr_bank));
}
Ok(())
})
}
/// Function for turning a pcr selection list and pcr digests values
/// into the format in which data is stored in PcrData.
fn create_data(
pcr_selection_list: &PcrSelectionList,
mut digests: Vec,
) -> Result> {
pcr_selection_list
.get_selections()
.iter()
.map(|pcr_selection| {
let pcr_slots = pcr_selection.selected();
if pcr_slots.len() > digests.len() {
error!("More pcr slots in selection then available digests");
return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
}
let digests_in_bank = digests.drain(..pcr_slots.len()).collect();
Ok((
pcr_selection.hashing_algorithm(),
PcrBank::create(pcr_slots, digests_in_bank)?,
))
})
.collect()
}
/// Function for retrieving the first PCR values associated with hashing_algorithm.
pub fn pcr_bank(&self, hashing_algorithm: HashingAlgorithm) -> Option<&PcrBank> {
self.data
.iter()
.find(|(alg, _)| *alg == hashing_algorithm)
.map(|(_, bank)| bank)
}
/// Function for retrieving the number of banks in the data.
pub fn len(&self) -> usize {
self.data.len()
}
/// Returns true if there are no banks in the data.
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
/// Private method for finding a PCR bank.
fn pcr_bank_mut(&mut self, hashing_algorithm: HashingAlgorithm) -> Option<&mut PcrBank> {
self.data
.iter_mut()
.find(|(alg, _)| *alg == hashing_algorithm)
.map(|(_, bank)| bank)
}
}
impl IntoIterator for PcrData {
type Item = (HashingAlgorithm, PcrBank);
type IntoIter = ::std::vec::IntoIter<(HashingAlgorithm, PcrBank)>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl From for Vec {
fn from(pcr_data: PcrData) -> Self {
pcr_data
.data
.iter()
.flat_map(|(_, pcr_bank)| pcr_bank.into_iter())
.map(|(_, digest)| digest)
.collect::>()
.chunks(DigestList::MAX_SIZE)
.map(|digests| {
let mut tpml_digest: TPML_DIGEST = Default::default();
for (index, digest) in digests.iter().enumerate() {
tpml_digest.count += 1;
tpml_digest.digests[index].size = digest.len() as u16;
tpml_digest.digests[index].buffer[..digest.len()]
.copy_from_slice(digest.value());
}
tpml_digest
})
.collect()
}
}
tss-esapi-7.4.0/src/abstraction/pcr.rs 0000644 0000000 0000000 00000004403 10461020230 0015777 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
mod bank;
mod data;
use crate::{structures::PcrSelectionList, Context, Result};
pub use bank::PcrBank;
pub use data::PcrData;
/// Function that reads all the PCRs in a selection list and returns
/// the result as PCR data.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{Context, TctiNameConf};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// use tss_esapi::{
/// interface_types::algorithm::HashingAlgorithm,
/// structures::{PcrSelectionListBuilder, PcrSlot},
/// };
/// // Create PCR selection list with slots in a bank
/// // that is going to be read.
/// let pcr_selection_list = PcrSelectionListBuilder::new()
/// .with_selection(HashingAlgorithm::Sha256,
/// &[
/// PcrSlot::Slot0,
/// PcrSlot::Slot1,
/// PcrSlot::Slot2,
/// PcrSlot::Slot3,
/// PcrSlot::Slot4,
/// PcrSlot::Slot5,
/// PcrSlot::Slot6,
/// PcrSlot::Slot7,
/// PcrSlot::Slot8,
/// PcrSlot::Slot9,
/// PcrSlot::Slot10,
/// PcrSlot::Slot11,
/// PcrSlot::Slot12,
/// PcrSlot::Slot13,
/// PcrSlot::Slot14,
/// PcrSlot::Slot15,
/// PcrSlot::Slot16,
/// PcrSlot::Slot17,
/// PcrSlot::Slot18,
/// PcrSlot::Slot19,
/// PcrSlot::Slot20,
/// PcrSlot::Slot21,
/// ])
/// .build()
/// .expect("Failed to build PcrSelectionList");
/// let _pcr_data = tss_esapi::abstraction::pcr::read_all(&mut context, pcr_selection_list)
/// .expect("pcr::read_all failed");
/// ```
pub fn read_all(
context: &mut Context,
mut pcr_selection_list: PcrSelectionList,
) -> Result {
let mut pcr_data = PcrData::new();
while !pcr_selection_list.is_empty() {
let (_, pcrs_read, pcr_digests) = context.pcr_read(pcr_selection_list.clone())?;
pcr_data.add(&pcrs_read, &pcr_digests)?;
pcr_selection_list.subtract(&pcrs_read)?;
}
Ok(pcr_data)
}
tss-esapi-7.4.0/src/abstraction/public.rs 0000644 0000000 0000000 00000012275 10461020230 0016477 0 ustar 0000000 0000000 // Copyright 2022 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::interface_types::ecc::EccCurve;
use crate::structures::{Public, RsaExponent};
use crate::{Error, WrapperErrorKind};
use core::convert::TryFrom;
use oid::ObjectIdentifier;
use picky_asn1::bit_string::BitString;
use picky_asn1::wrapper::{IntegerAsn1, OctetStringAsn1};
use picky_asn1_x509::{
AlgorithmIdentifier, EcParameters, EcPoint, PublicKey, RsaPublicKey, SubjectPublicKeyInfo,
};
use serde::{Deserialize, Serialize};
/// Can be converted from [`crate::structures::Public`] when not a fully constructed
/// [`picky_asn1_x509::SubjectPublicKeyInfo`] is required.
///
/// # Details
///
/// Holds either [`picky_asn1_x509::RsaPublicKey`] for [`crate::structures::Public::Rsa`] or
/// [`picky_asn1_x509::EcPoint`] for [`crate::structures::Public::Ecc`].
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum DecodedKey {
RsaPublicKey(RsaPublicKey),
EcPoint(EcPoint),
}
impl TryFrom for DecodedKey {
type Error = Error;
fn try_from(value: Public) -> Result {
public_to_decoded_key(&value)
}
}
impl TryFrom for SubjectPublicKeyInfo {
type Error = Error;
/// Converts [`crate::structures::Public::Rsa`] and [`crate::structures::Public::Ecc`] to [`picky_asn1_x509::SubjectPublicKeyInfo`].
///
/// # Details
/// The result can be used to convert TPM public keys to DER using `picky_asn1_der`.
///
/// # Errors
/// * if other instances of [`crate::structures::Public`] are used `UnsupportedParam` will be returned.
fn try_from(value: Public) -> Result {
let decoded_key = public_to_decoded_key(&value)?;
match (value, decoded_key) {
(Public::Rsa { .. }, DecodedKey::RsaPublicKey(key)) => Ok(SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier::new_rsa_encryption(),
subject_public_key: PublicKey::Rsa(key.into()),
}),
(Public::Ecc { parameters, .. }, DecodedKey::EcPoint(point)) => {
Ok(SubjectPublicKeyInfo {
algorithm: AlgorithmIdentifier::new_elliptic_curve(EcParameters::NamedCurve(
curve_oid(parameters.ecc_curve())?.into(),
)),
subject_public_key: PublicKey::Ec(BitString::with_bytes(point).into()),
})
}
_ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
}
}
}
/// Converts [`crate::structures::Public::Rsa`] and [`crate::structures::Public::Ecc`] to [DecodedKey].
///
/// # Details
/// Does basic key conversion to either RSA or ECC. In RSA conversion the TPM zero exponent is replaced with `65537`.
///
/// # Errors
/// * if other instances of [`crate::structures::Public`] are used `UnsupportedParam` will be returned.
fn public_to_decoded_key(public: &Public) -> Result {
match public {
Public::Rsa {
unique, parameters, ..
} => {
let exponent = match parameters.exponent() {
RsaExponent::ZERO_EXPONENT => 65537,
_ => parameters.exponent().value(),
}
.to_be_bytes();
Ok(DecodedKey::RsaPublicKey(RsaPublicKey {
modulus: IntegerAsn1::from_bytes_be_unsigned(unique.value().to_vec()),
public_exponent: IntegerAsn1::from_bytes_be_signed(exponent.to_vec()),
}))
}
Public::Ecc { unique, .. } => {
let x = unique.x().value().to_vec();
let y = unique.y().value().to_vec();
Ok(DecodedKey::EcPoint(OctetStringAsn1(
elliptic_curve_point_to_octet_string(x, y),
)))
}
_ => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
}
}
// Taken from https://github.com/parallaxsecond/parsec/blob/561235f3cc37bcff3d9a6cb29c84eeae5d55100b/src/providers/tpm/utils.rs#L319
// Points on elliptic curves are represented as defined in section 2.3.3 of https://www.secg.org/sec1-v2.pdf
// The (uncompressed) representation is [ 0x04 || x || y ] where x and y are the coordinates of the point
fn elliptic_curve_point_to_octet_string(mut x: Vec, mut y: Vec) -> Vec {
let mut octet_string = vec![0x04];
octet_string.append(&mut x);
octet_string.append(&mut y);
octet_string
}
// Map TPM supported ECC curves to their respective OIDs
fn curve_oid(ecc_curve: EccCurve) -> Result {
match ecc_curve {
EccCurve::NistP192 => Ok(picky_asn1_x509::oids::secp192r1()),
EccCurve::NistP224 => Ok(picky_asn1_x509::oids::secp256r1()),
EccCurve::NistP256 => Ok(picky_asn1_x509::oids::secp256r1()),
EccCurve::NistP384 => Ok(picky_asn1_x509::oids::secp384r1()),
EccCurve::NistP521 => Ok(picky_asn1_x509::oids::secp521r1()),
// Barreto-Naehrig curves seem to not have any OIDs
EccCurve::BnP256 => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
EccCurve::BnP638 => Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
EccCurve::Sm2P256 => Ok(ObjectIdentifier::try_from("1.2.156.10197.1.301").unwrap()),
}
}
tss-esapi-7.4.0/src/abstraction/transient/key_attestation.rs 0000644 0000000 0000000 00000016434 10461020230 0022440 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use super::{ObjectWrapper, TransientKeyContext};
use crate::{
abstraction::ek,
constants::SessionType,
handles::{AuthHandle, KeyHandle, SessionHandle},
interface_types::{
algorithm::{AsymmetricAlgorithm, HashingAlgorithm},
session_handles::{AuthSession, PolicySession},
},
structures::{EncryptedSecret, IdObject, SymmetricDefinition},
traits::Marshall,
utils::PublicKey,
Result,
};
use std::convert::TryFrom;
#[derive(Debug)]
/// Wrapper for the parameters needed by MakeCredential
///
/// The 3rd party requesting proof that the key is indeed backed
/// by a TPM would perform a MakeCredential and would thus require
/// `name` and `attesting_key_pub` as inputs for that operation.
///
/// `public` is not strictly needed, however it is returned as a
/// convenience block of data. Since the MakeCredential operation
/// bakes into the encrypted credential the identity of the key to
/// be attested via its `name`, the correctness of the `name` must
/// be verifiable by the said 3rd party. `public` bridges this gap:
///
/// * it includes all the public parameters of the attested key
/// * can be hashed (in its marshaled form) with the name hash
/// (found by unmarshaling it) to obtain `name`
pub struct MakeCredParams {
/// TPM name of the object being attested
pub name: Vec,
/// Encoding of the public parameters of the object whose name
/// will be included in the credential computations
pub public: Vec,
/// Public part of the key used to protect the credential
pub attesting_key_pub: PublicKey,
}
impl TransientKeyContext {
/// Get the data required to perform a MakeCredential
///
/// # Parameters
///
/// * `object` - the object whose TPM name will be included in
/// the credential
/// * `key` - the key to be used to encrypt the secret that wraps
/// the credential
///
/// **Note**: If no `key` is given, the default Endorsement Key
/// will be used.
pub fn get_make_cred_params(
&mut self,
object: ObjectWrapper,
key: Option,
) -> Result {
let object_handle = self.load_key(object.params, object.material, None)?;
let (object_public, object_name, _) =
self.context.read_public(object_handle).or_else(|e| {
self.context.flush_context(object_handle.into())?;
Err(e)
})?;
self.context.flush_context(object_handle.into())?;
// Name of objects is derived from their publicArea, i.e. the marshaled TPMT_PUBLIC
let public = object_public.marshall()?;
let attesting_key_pub = match key {
None => get_ek_object_public(&mut self.context)?,
Some(key) => key.material.public,
};
Ok(MakeCredParams {
name: object_name.value().to_vec(),
public,
attesting_key_pub,
})
}
/// Perform an ActivateCredential operation for the given object
///
/// # Parameters
///
/// * `object` - the object whose TPM name is included in the credential
/// * `key` - the key used to encrypt the secret that wraps the credential
/// * `credential_blob` - encrypted credential that will be returned by the
/// TPM
/// * `secret` - encrypted secret that was used to encrypt the credential
///
/// **Note**: if no `key` is given, the default Endorsement Key
/// will be used. You can find more information about the default Endorsement
/// Key in the [ek] module.
pub fn activate_credential(
&mut self,
object: ObjectWrapper,
key: Option,
credential_blob: Vec,
secret: Vec,
) -> Result> {
let credential_blob = IdObject::try_from(credential_blob)?;
let secret = EncryptedSecret::try_from(secret)?;
let object_handle = self.load_key(object.params, object.material, object.auth)?;
let (key_handle, session_2) = match key {
Some(key) => self.prepare_key_activate_cred(key),
None => self.prepare_ek_activate_cred(),
}
.or_else(|e| {
self.context.flush_context(object_handle.into())?;
Err(e)
})?;
let (session_1, _, _) = self.context.sessions();
let credential = self
.context
.execute_with_sessions((session_1, session_2, None), |ctx| {
ctx.activate_credential(object_handle, key_handle, credential_blob, secret)
})
.or_else(|e| {
self.context.flush_context(object_handle.into())?;
self.context.flush_context(key_handle.into())?;
self.context
.flush_context(SessionHandle::from(session_2).into())?;
Err(e)
})?;
self.context.flush_context(object_handle.into())?;
self.context.flush_context(key_handle.into())?;
self.context
.flush_context(SessionHandle::from(session_2).into())?;
Ok(credential.value().to_vec())
}
// No key was given, use the EK. This requires using a Policy session
fn prepare_ek_activate_cred(&mut self) -> Result<(KeyHandle, Option)> {
let session = self.context.start_auth_session(
None,
None,
None,
SessionType::Policy,
SymmetricDefinition::AES_128_CFB,
HashingAlgorithm::Sha256,
)?;
let _ = self.context.policy_secret(
PolicySession::try_from(session.unwrap())
.expect("Failed to convert auth session to policy session"),
AuthHandle::Endorsement,
Default::default(),
Default::default(),
Default::default(),
None,
);
Ok((
ek::create_ek_object(&mut self.context, AsymmetricAlgorithm::Rsa, None).or_else(
|e| {
self.context
.flush_context(SessionHandle::from(session).into())?;
Err(e)
},
)?,
session,
))
}
// Load key and create a HMAC session for it
fn prepare_key_activate_cred(
&mut self,
key: ObjectWrapper,
) -> Result<(KeyHandle, Option)> {
let session = self.context.start_auth_session(
None,
None,
None,
SessionType::Hmac,
SymmetricDefinition::AES_128_CFB,
HashingAlgorithm::Sha256,
)?;
Ok((
self.load_key(key.params, key.material, key.auth)
.or_else(|e| {
self.context
.flush_context(SessionHandle::from(session).into())?;
Err(e)
})?,
session,
))
}
}
fn get_ek_object_public(context: &mut crate::Context) -> Result {
let key_handle = ek::create_ek_object(context, AsymmetricAlgorithm::Rsa, None)?;
let (attesting_key_pub, _, _) = context.read_public(key_handle).or_else(|e| {
context.flush_context(key_handle.into())?;
Err(e)
})?;
context.flush_context(key_handle.into())?;
PublicKey::try_from(attesting_key_pub)
}
tss-esapi-7.4.0/src/abstraction/transient/mod.rs 0000644 0000000 0000000 00000064114 10461020230 0020006 0 ustar 0000000 0000000 // Copyright 2019 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
//! Module for abstracting resource handle management
//!
//! This module presents an abstraction over the TPM functionality exposed through the core
//! `Context` structure. The abstraction works by hiding resource handle management from the
//! client.
use crate::{
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
constants::{tss::*, SessionType, Tss2ResponseCodeKind},
handles::{KeyHandle, SessionHandle},
interface_types::{
algorithm::{HashingAlgorithm, PublicAlgorithm},
ecc::EccCurve,
key_bits::RsaKeyBits,
resource_handles::Hierarchy,
},
structures::{
Auth, CreateKeyResult, Data, Digest, EccPoint, EccScheme, Public, PublicBuilder,
PublicEccParametersBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaExponent,
RsaScheme, Signature, SignatureScheme, SymmetricDefinitionObject, VerifiedTicket,
},
tcti_ldr::TctiNameConf,
tss2_esys::*,
utils::{create_restricted_decryption_rsa_public, PublicKey, TpmsContext},
Context, Error, Result, WrapperErrorKind as ErrorKind,
};
use log::error;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::convert::{AsMut, AsRef, TryFrom, TryInto};
use zeroize::Zeroize;
mod key_attestation;
pub use key_attestation::MakeCredParams;
/// Parameters for the kinds of keys supported by the context
#[derive(Debug, Clone, Copy)]
pub enum KeyParams {
Rsa {
/// Size of key in bits
///
/// Can only be one of: 1024, 2048, 3072 or 4096
size: RsaKeyBits,
/// Asymmetric scheme to be used with the key
scheme: RsaScheme,
/// Public exponent of the key
///
/// If set to 0, it will default to 2^16 - 1.
///
/// (Note that the default value for [`RsaExponent`] is 0)
pub_exponent: RsaExponent,
},
Ecc {
/// Curve that the key will be based on
curve: EccCurve,
/// Asymmetric scheme to be used with the key
scheme: EccScheme,
},
}
/// Structure representing a key created or stored in the TPM
///
/// The `public` field represents the public part of the key in plain text,
/// while `private` is the encrypted version of the private key.
///
/// For information on public key formats, see the documentation of [`PublicKey`].
/// The private part of the key should be treated as an opaque binary blob.
///
/// # Warning
///
/// If the Owner hierarchy is cleared, any key material generated
/// prior to that event will become unusable.
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize)]
pub struct KeyMaterial {
public: PublicKey,
private: Vec,
}
impl KeyMaterial {
/// Get a reference to the public part of the key
pub fn public(&self) -> &PublicKey {
&self.public
}
/// Get a reference to the private part of the key
pub fn private(&self) -> &[u8] {
&self.private
}
}
/// Structure containing all the defining elements of a TPM key
///
/// - `material` identifies the numeric value of the key object
/// - `params` identifies the algorithm to use on the key and other relevant
/// parameters
/// - `auth` identifies the optional authentication value to be used with the
/// key
#[derive(Debug, Clone)]
pub struct ObjectWrapper {
pub material: KeyMaterial,
pub params: KeyParams,
pub auth: Option,
}
/// Structure offering an abstracted programming experience.
///
/// The `TransientKeyContext` makes use of a root key from which the other, client-controlled
/// keys are derived.
///
/// This abstraction makes public key cryptography more accessible, focusing on asymmetric
/// encryption and signatures in particular, by allowing users to offload object and session management.
#[allow(clippy::module_name_repetitions)]
#[derive(Debug)]
pub struct TransientKeyContext {
context: Context,
root_key_handle: KeyHandle,
}
impl TransientKeyContext {
/// Create a new key.
///
/// A key is created as a descendant of the context root key, with the given parameters.
///
/// If successful, the result contains the [KeyMaterial] of the key and a vector of
/// bytes forming the authentication value for said key.
///
/// The following key attributes are always **set**: `fixed_tpm`, `fixed_parent`, `sensitive_data_origin`,
/// `user_with_auth`. The `restricted` attribute is **not set**. See section 8.3 in the Structures
/// spec for a detailed description of these attributes.
///
/// # Constraints
/// * `auth_size` must be at most 32
///
/// # Errors
/// * if the authentication size is larger than 32 a `WrongParamSize` wrapper error is returned
pub fn create_key(
&mut self,
key_params: KeyParams,
auth_size: usize,
) -> Result<(KeyMaterial, Option)> {
if auth_size > 32 {
return Err(Error::local_error(ErrorKind::WrongParamSize));
}
let key_auth = if auth_size > 0 {
self.set_session_attrs()?;
let random_bytes = self.context.get_random(auth_size)?;
Some(Auth::try_from(random_bytes.value().to_vec())?)
} else {
None
};
self.set_session_attrs()?;
let CreateKeyResult {
out_private,
out_public,
..
} = self.context.create(
self.root_key_handle,
TransientKeyContext::get_public_from_params(key_params, None)?,
key_auth.clone(),
None,
None,
None,
)?;
let key_material = KeyMaterial {
public: out_public.try_into()?,
private: out_private.value().to_vec(),
};
Ok((key_material, key_auth))
}
/// Load the public part of a key.
///
/// Returns the appropriate key material after verifying that the key can be loaded.
pub fn load_external_public_key(
&mut self,
public_key: PublicKey,
params: KeyParams,
) -> Result {
let public = TransientKeyContext::get_public_from_params(params, Some(public_key.clone()))?;
self.set_session_attrs()?;
let key_handle = self
.context
.load_external_public(public, Hierarchy::Owner)?;
self.context.flush_context(key_handle.into())?;
Ok(KeyMaterial {
public: public_key,
private: vec![],
})
}
/// Encrypt a message with an existing key.
///
/// Takes the key as a set of parameters (`key_material`, `key_params`, `key_auth`), encrypts the message
/// and returns the ciphertext. A label can also be provided which will be associated with the ciphertext.
///
/// Note: the data passed as `label` MUST end in a `0x00` byte.
pub fn rsa_encrypt(
&mut self,
key_material: KeyMaterial,
key_params: KeyParams,
key_auth: Option,
message: PublicKeyRsa,
label: Option,
) -> Result {
let key_handle = self.load_key(key_params, key_material, key_auth)?;
let decrypt_scheme = if let KeyParams::Rsa { scheme, .. } = key_params {
scheme.try_into()?
} else {
return Err(Error::local_error(ErrorKind::InvalidParam));
};
self.set_session_attrs()?;
let ciphertext = self
.context
.rsa_encrypt(
key_handle,
message,
decrypt_scheme,
label.unwrap_or_default(),
)
.or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
self.context.flush_context(key_handle.into())?;
Ok(ciphertext)
}
/// Decrypt ciphertext with an existing key.
///
/// Takes the key as a set of parameters (`key_material`, `key_params`, `key_auth`), decrypts the ciphertext
/// and returns the plaintext. A label which was associated with the ciphertext can also be provided.
///
/// Note: the data passed as `label` MUST end in a `0x00` byte.
pub fn rsa_decrypt(
&mut self,
key_material: KeyMaterial,
key_params: KeyParams,
key_auth: Option,
ciphertext: PublicKeyRsa,
label: Option,
) -> Result {
let key_handle = self.load_key(key_params, key_material, key_auth)?;
let decrypt_scheme = if let KeyParams::Rsa { scheme, .. } = key_params {
scheme.try_into()?
} else {
return Err(Error::local_error(ErrorKind::InvalidParam));
};
self.set_session_attrs()?;
let plaintext = self
.context
.rsa_decrypt(
key_handle,
ciphertext,
decrypt_scheme,
label.unwrap_or_default(),
)
.or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
self.context.flush_context(key_handle.into())?;
Ok(plaintext)
}
/// Sign a digest with an existing key.
///
/// Takes the key as a set of parameters (`key_material`, `key_params`, `key_auth`), signs and returns the signature.
pub fn sign(
&mut self,
key_material: KeyMaterial,
key_params: KeyParams,
key_auth: Option,
digest: Digest,
) -> Result {
let key_handle = self.load_key(key_params, key_material, key_auth)?;
let validation = TPMT_TK_HASHCHECK {
tag: TPM2_ST_HASHCHECK,
hierarchy: TPM2_RH_NULL,
digest: Default::default(),
};
self.set_session_attrs()?;
let signature = self
.context
.sign(
key_handle,
digest,
SignatureScheme::Null,
validation.try_into()?,
)
.or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
self.context.flush_context(key_handle.into())?;
Ok(signature)
}
/// Verify a signature against a digest.
///
/// Given a digest, a key and a signature, this method returns a `Verified` ticket if the
/// verification was successful.
///
/// # Errors
/// * if the verification fails (i.e. the signature is invalid), a TPM error is returned
pub fn verify_signature(
&mut self,
key_material: KeyMaterial,
key_params: KeyParams,
digest: Digest,
signature: Signature,
) -> Result {
let key_handle = self.load_key(key_params, key_material, None)?;
self.set_session_attrs()?;
let verified = self
.context
.verify_signature(key_handle, digest, signature)
.or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
self.context.flush_context(key_handle.into())?;
Ok(verified)
}
/// Perform a migration from the previous version of the TransientKeyContext.
///
/// The original version of the TransientKeyContext used contexts of keys for
/// persistence. This method allows a key persisted in this way to be migrated
/// to the new format.
///
/// The method determines on its own whether the loaded key was a keypair or
/// just a public key.
pub fn migrate_key_from_ctx(
&mut self,
context: TpmsContext,
auth: Option,
) -> Result {
self.set_session_attrs()?;
let key_handle = self.context.context_load(context).map(KeyHandle::from)?;
if let Some(key_auth_value) = auth.clone() {
self.context
.tr_set_auth(key_handle.into(), key_auth_value)
.or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
}
let (public, _, _) = self.context.read_public(key_handle).or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
let private = self
.context
.object_change_auth(
key_handle.into(),
self.root_key_handle.into(),
auth.unwrap_or_default(),
)
.or_else(|e| {
if let Error::Tss2Error(resp_code) = e {
// If we get `AuthUnavailable` it means the private part of the key has not been
// loaded, and this is thus a public key
if resp_code.kind() == Some(Tss2ResponseCodeKind::AuthUnavailable) {
return Ok(Default::default());
}
}
error!("Getting private part of key failed.");
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
let key_material = KeyMaterial {
public: public.try_into()?,
private: private.value().to_vec(),
};
self.context.flush_context(key_handle.into())?;
Ok(key_material)
}
/// Sets the encrypt and decrypt flags on the main session used by the context.
///
/// # Errors
/// * if `Context::set_session_attr` returns an error, that error is propagated through
fn set_session_attrs(&mut self) -> Result<()> {
if let (Some(session), _, _) = self.context.sessions() {
let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
.with_decrypt(true)
.with_encrypt(true)
.build();
self.context.tr_sess_set_attributes(
session,
session_attributes,
session_attributes_mask,
)?;
}
Ok(())
}
/// Given the parameters for an asymmetric key, return its [Public] structure
///
/// The public part of the key can optionally be inserted in the structure.
///
/// # Errors
/// * if the public key and the parameters don't match, `InconsistentParams` is returned
fn get_public_from_params(params: KeyParams, pub_key: Option) -> Result {
let decrypt_flag = matches!(
params,
KeyParams::Rsa {
scheme: RsaScheme::RsaEs,
..
} | KeyParams::Rsa {
scheme: RsaScheme::Oaep(..),
..
}
);
let object_attributes = ObjectAttributesBuilder::new()
.with_fixed_tpm(true)
.with_fixed_parent(true)
.with_sensitive_data_origin(true)
.with_user_with_auth(true)
.with_decrypt(decrypt_flag)
.with_sign_encrypt(true)
.with_restricted(false)
.build()?;
let mut pub_builder = PublicBuilder::new()
.with_public_algorithm(match params {
KeyParams::Ecc { .. } => PublicAlgorithm::Ecc,
KeyParams::Rsa { .. } => PublicAlgorithm::Rsa,
})
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(object_attributes);
match params {
KeyParams::Rsa {
size,
scheme,
pub_exponent,
} => {
let unique = pub_key
.map(|pub_key| {
if let PublicKey::Rsa(val) = pub_key {
PublicKeyRsa::try_from(val)
} else {
Err(Error::local_error(ErrorKind::InconsistentParams))
}
})
.transpose()?
.unwrap_or_default();
pub_builder = pub_builder
.with_rsa_parameters(
PublicRsaParametersBuilder::new()
.with_scheme(match scheme {
RsaScheme::RsaSsa { .. } | RsaScheme::RsaPss { .. } => scheme,
_ => RsaScheme::Null,
})
.with_key_bits(size)
.with_exponent(pub_exponent)
.with_is_signing_key(true)
.with_is_decryption_key(decrypt_flag)
.with_restricted(false)
.build()?,
)
.with_rsa_unique_identifier(unique);
}
KeyParams::Ecc { scheme, curve } => {
let unique = pub_key
.map(|pub_key| {
if let PublicKey::Ecc { x, y } = pub_key {
Ok(EccPoint::new(x.try_into()?, y.try_into()?))
} else {
Err(Error::local_error(ErrorKind::InconsistentParams))
}
})
.transpose()?
.unwrap_or_default();
pub_builder = pub_builder
.with_ecc_parameters(
PublicEccParametersBuilder::new_unrestricted_signing_key(scheme, curve)
.build()?,
)
.with_ecc_unique_identifier(unique);
}
}
pub_builder.build()
}
/// Load a key into a TPM given its [KeyMaterial]
///
/// If the key has only a public part, it is loaded accordingly in the Owner Hierarchy
fn load_key(
&mut self,
params: KeyParams,
material: KeyMaterial,
auth: Option,
) -> Result {
let public = TransientKeyContext::get_public_from_params(params, Some(material.public))?;
self.set_session_attrs()?;
let key_handle = if material.private.is_empty() {
self.context
.load_external_public(public, Hierarchy::Owner)?
} else {
self.context
.load(self.root_key_handle, material.private.try_into()?, public)
.map(KeyHandle::from)?
};
let key_auth_value = auth.unwrap_or_default();
if !key_auth_value.is_empty() {
self.context
.tr_set_auth(key_handle.into(), key_auth_value)
.or_else(|e| {
self.context.flush_context(key_handle.into())?;
Err(e)
})?;
}
Ok(key_handle)
}
/// Get a builder for the structure
pub fn builder() -> TransientKeyContextBuilder {
TransientKeyContextBuilder::new()
}
}
impl AsRef for TransientKeyContext {
fn as_ref(&self) -> &Context {
&self.context
}
}
impl AsMut for TransientKeyContext {
fn as_mut(&mut self) -> &mut Context {
&mut self.context
}
}
/// Build a new `TransientKeyContext`.
///
/// # Default values
/// * TCTI: Device TCTI
/// * Hierarchy: Owner hierarchy
/// * Root key size: 2048 bits
/// * Root key authentication size: 32 bytes
/// * Hierarchy authentication value: Empty array of bytes
/// * Session encryption cipher: 256 bit AES in CFB mode
/// * Session hash algorithm: SHA256
#[derive(Debug)]
pub struct TransientKeyContextBuilder {
tcti_name_conf: TctiNameConf,
root_key_size: u16, // TODO: replace with root key PUBLIC definition
root_key_auth_size: usize,
root_hierarchy: Hierarchy,
hierarchy_auth: HashMap>,
default_context_cipher: SymmetricDefinitionObject,
session_hash_alg: HashingAlgorithm,
}
impl TransientKeyContextBuilder {
/// Create a new builder.
pub fn new() -> Self {
TransientKeyContextBuilder {
tcti_name_conf: TctiNameConf::Device(Default::default()),
root_hierarchy: Hierarchy::Owner,
root_key_size: 2048,
root_key_auth_size: 32,
hierarchy_auth: HashMap::new(),
default_context_cipher: SymmetricDefinitionObject::AES_256_CFB,
session_hash_alg: HashingAlgorithm::Sha256,
}
}
/// Define the TCTI name configuration to be used by the client.
pub fn with_tcti(mut self, tcti_name_conf: TctiNameConf) -> Self {
self.tcti_name_conf = tcti_name_conf;
self
}
/// Set the auth values for any hierarchies that will be used
pub fn with_hierarchy_auth(mut self, hierarchy: Hierarchy, auth: Vec) -> Self {
let _ = self.hierarchy_auth.insert(hierarchy, auth);
self
}
/// Define which hierarchy will be used for the keys being managed.
pub fn with_root_hierarchy(mut self, hierarchy: Hierarchy) -> Self {
self.root_hierarchy = hierarchy;
self
}
/// Choose length in bits of primary key that will serve as parent to all user keys.
pub fn with_root_key_size(mut self, root_key_size: u16) -> Self {
self.root_key_size = root_key_size;
self
}
/// Choose authentication value length (in bytes) for primary key.
pub fn with_root_key_auth_size(mut self, root_key_auth_size: usize) -> Self {
self.root_key_auth_size = root_key_auth_size;
self
}
/// Define the cipher to be used within this context as a default.
///
/// Currently this default is used for:
/// * securing command parameters using session-based encryption
/// * encrypting all user keys using the primary key
pub fn with_default_context_cipher(
mut self,
default_context_cipher: SymmetricDefinitionObject,
) -> Self {
self.default_context_cipher = default_context_cipher;
self
}
/// Define the cipher to be used by sessions for hashing commands.
pub fn with_session_hash_alg(mut self, session_hash_alg: HashingAlgorithm) -> Self {
self.session_hash_alg = session_hash_alg;
self
}
/// Bootstrap the TransientKeyContext.
///
/// The root key is created as a primary key in the provided hierarchy and thus authentication is
/// needed for said hierarchy. The authentication valuei for the key is generated by the TPM itself,
/// with a configurable length, and never exposed outside the context.
///
/// # Warning
/// It is the responsibility of the client to ensure that the context can be initialized
/// safely, threading-wise by choosing the correct TCTI. See the Warning notice of the Context
/// structure for more information.
///
/// # Constraints
/// * `root_key_size` must be 1024, 2048, 3072 or 4096
/// * `root_key_auth_size` must be at most 32
///
/// # Errors
/// * errors are returned if any method calls return an error: `Context::get_random`,
/// `Context::start_auth_session`, `Context::create_primary`, `Context::flush_context`,
/// `Context::set_handle_auth`
/// * if the root key authentication size is given greater than 32 or if the root key size is
/// not 1024, 2048, 3072 or 4096, a `InvalidParam` wrapper error is returned
pub fn build(mut self) -> Result {
if self.root_key_auth_size > 32 {
return Err(Error::local_error(ErrorKind::WrongParamSize));
}
let root_key_rsa_key_bits = RsaKeyBits::try_from(self.root_key_size)?;
let mut context = Context::new(self.tcti_name_conf)?;
let root_key_auth = if self.root_key_auth_size > 0 {
let random = context.get_random(self.root_key_auth_size)?;
Some(Auth::try_from(random.value().to_vec())?)
} else {
None
};
for (hierarchy, auth) in self.hierarchy_auth.drain() {
let auth_hierarchy = Auth::try_from(auth)?;
context.tr_set_auth(hierarchy.into(), auth_hierarchy)?;
}
let session = context
.start_auth_session(
None,
None,
None,
SessionType::Hmac,
self.default_context_cipher.into(),
self.session_hash_alg,
)
.and_then(|session| {
session.ok_or_else(|| {
error!("Received unexpected NONE handle from the TPM");
Error::local_error(ErrorKind::WrongValueFromTpm)
})
})?;
let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
.with_decrypt(true)
.with_encrypt(true)
.build();
context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)?;
context.set_sessions((Some(session), None, None));
let root_key_handle = context
.create_primary(
self.root_hierarchy,
create_restricted_decryption_rsa_public(
self.default_context_cipher,
root_key_rsa_key_bits,
RsaExponent::ZERO_EXPONENT,
)?,
root_key_auth,
None,
None,
None,
)?
.key_handle;
let new_session_cipher = self.default_context_cipher;
let new_session_hashing_algorithm = self.session_hash_alg;
let new_session = context.execute_without_session(|ctx| {
ctx.start_auth_session(
Some(root_key_handle),
None,
None,
SessionType::Hmac,
new_session_cipher.into(),
new_session_hashing_algorithm,
)
.and_then(|session| {
session.ok_or_else(|| {
error!("Received unexpected NONE handle from the TPM");
Error::local_error(ErrorKind::WrongValueFromTpm)
})
})
})?;
if let (Some(old_session), _, _) = context.sessions() {
context.set_sessions((Some(new_session), None, None));
context.flush_context(SessionHandle::from(old_session).into())?;
}
Ok(TransientKeyContext {
context,
root_key_handle,
})
}
}
impl Default for TransientKeyContextBuilder {
fn default() -> Self {
TransientKeyContextBuilder::new()
}
}
tss-esapi-7.4.0/src/attributes/algorithm.rs 0000644 0000000 0000000 00000001535 10461020230 0017061 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::tss2_esys::TPMA_ALGORITHM;
use bitfield::bitfield;
bitfield! {
/// Bitfield representing the algorithm attributes.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct AlgorithmAttributes(TPMA_ALGORITHM);
impl Debug;
pub asymmetric, _: 0;
pub symmetric, _: 1;
pub hash, _: 2;
pub object, _: 3;
// 7:4 Reserved
pub signing, _: 8;
pub encrypting, _: 9;
pub method, _: 10;
// 31:11 Reserved
}
impl From for AlgorithmAttributes {
fn from(tpma_algorithm: TPMA_ALGORITHM) -> Self {
AlgorithmAttributes(tpma_algorithm)
}
}
impl From for TPMA_ALGORITHM {
fn from(algorithm_attributes: AlgorithmAttributes) -> Self {
algorithm_attributes.0
}
}
tss-esapi-7.4.0/src/attributes/command_code.rs 0000644 0000000 0000000 00000010662 10461020230 0017504 0 ustar 0000000 0000000 // Copyright 2022 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::CommandCode,
tss2_esys::{TPM2_CC, TPMA_CC},
Error, Result, WrapperErrorKind,
};
use bitfield::bitfield;
use log::error;
use std::convert::{TryFrom, TryInto};
bitfield! {
/// Bitfield representing the command code attributes.
///
/// # Details
/// This corresponds to TPMA_CC.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct CommandCodeAttributes(TPMA_CC);
impl Debug;
pub u16, command_index, _: 15, 0;
u16, _, set_command_index: 15, 0;
u8, reserved, set_reserved: 21, 16; // shall be zero
pub nv, _: 22;
_, set_nv: 22;
pub extensive, _: 23;
_, set_extensive: 23;
pub flushed, _: 24;
_, set_flushed: 24;
pub u8, c_handles, _: 27, 25;
u8, _, set_c_handles: 27, 25;
pub r_handle, _: 28;
_, set_r_handle: 28;
pub is_vendor_specific, _: 29;
_, set_vendor_specific: 29;
res, set_res: 31, 30; // shall be zero
}
impl CommandCodeAttributes {
/// Returns a command code attributes builder
pub const fn builder() -> CommandCodeAttributesBuilder {
CommandCodeAttributesBuilder::new()
}
}
impl TryFrom for CommandCodeAttributes {
type Error = Error;
fn try_from(tpma_cc: TPMA_CC) -> Result {
let command_code_attributes = CommandCodeAttributes(tpma_cc);
if command_code_attributes.reserved() != 0 || command_code_attributes.res() != 0 {
error!(
"Command code attributes from the TPM contained a non zero value in a resrved area"
);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
if !command_code_attributes.is_vendor_specific() {
// Non vendor specific command code attributes needs to
// have a command index that corresponds to a command code.
let tpm_command_code: TPM2_CC = command_code_attributes.command_index().into();
let _ = CommandCode::try_from(tpm_command_code)?;
}
Ok(command_code_attributes)
}
}
impl From for TPMA_CC {
fn from(command_code_attributes: CommandCodeAttributes) -> Self {
command_code_attributes.0
}
}
/// A builder for [CommandCodeAttributes]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct CommandCodeAttributesBuilder {
command_code_attributes: CommandCodeAttributes,
}
impl CommandCodeAttributesBuilder {
/// Creates a new command code attributes builder.
pub const fn new() -> Self {
CommandCodeAttributesBuilder {
command_code_attributes: CommandCodeAttributes(0),
}
}
/// Sets the command code to the specified value
/// in the builder.
pub fn with_command_index(mut self, command_index: u16) -> Self {
self.command_code_attributes
.set_command_index(command_index);
self
}
/// Sets the 'nv' bit in the builder.
pub fn with_nv(mut self, set: bool) -> Self {
self.command_code_attributes.set_nv(set);
self
}
/// Sets the 'extensive' bit in the builder.
pub fn with_extensive(mut self, set: bool) -> Self {
self.command_code_attributes.set_extensive(set);
self
}
/// Sets the 'flushed' bit in the builder.
pub fn with_flushed(mut self, set: bool) -> Self {
self.command_code_attributes.set_flushed(set);
self
}
/// Sets the three 'c_handles' bits in the builder.
///
/// # Details
/// All bits besides the three first in the provided
/// argument will be ignored.
pub fn with_c_handles(mut self, value: u8) -> Self {
self.command_code_attributes.set_c_handles(value);
self
}
/// Sets the 'r_handle' bit in the builder.
pub fn with_r_handle(mut self, set: bool) -> Self {
self.command_code_attributes.set_r_handle(set);
self
}
/// Sets the 'V'(i.e. vendor specific) bit in the builder.
pub fn with_vendor_specific(mut self, set: bool) -> Self {
self.command_code_attributes.set_vendor_specific(set);
self
}
/// Builds the command code attributes
///
/// # Errors
/// Returns an error if command index is not
/// a command index associated with a CommandCode
/// specified in the TPM specification.
pub fn build(self) -> Result {
self.command_code_attributes.0.try_into()
}
}
tss-esapi-7.4.0/src/attributes/locality.rs 0000644 0000000 0000000 00000010704 10461020230 0016711 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{tss2_esys::TPMA_LOCALITY, Error, Result, WrapperErrorKind};
use bitfield::bitfield;
use log::error;
bitfield! {
/// Bitfield representing the locality attributes.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct LocalityAttributes(TPMA_LOCALITY);
impl Debug;
_, set_locality_zero: 0;
pub locality_zero, _: 0;
_, set_locality_one: 1;
pub locality_one, _: 1;
_, set_locality_two: 2;
pub locality_two, _: 2;
_, set_locality_three: 3;
pub locality_three, _: 3;
_, set_locality_four: 4;
pub locality_four, _: 4;
_, set_extended: 7, 5;
extended, _: 7, 5;
}
impl LocalityAttributes {
pub const LOCALITY_ZERO: LocalityAttributes = LocalityAttributes(1);
pub const LOCALITY_ONE: LocalityAttributes = LocalityAttributes(2);
pub const LOCALITY_TWO: LocalityAttributes = LocalityAttributes(4);
pub const LOCALITY_THREE: LocalityAttributes = LocalityAttributes(8);
pub const LOCALITY_FOUR: LocalityAttributes = LocalityAttributes(16);
/// Returns true if the attributes are extended
pub fn is_extended(&self) -> bool {
self.extended() != 0u8
}
/// Returns the LocalityAttributes as a number.
///
/// # Errors
/// If the attributes are not extended en InvalidParams error
/// is returned.
pub fn as_extended(&self) -> Result {
if self.is_extended() {
Ok(self.0)
} else {
error!("Cannot retrieve LocalityAttributes as extended when the attributes are not indicated to be extended");
Err(Error::local_error(WrapperErrorKind::InvalidParam))
}
}
/// Returns the builder used to construct LocalAttributes.
pub const fn builder() -> LocalityAttributesBuilder {
LocalityAttributesBuilder::new()
}
}
impl From for LocalityAttributes {
fn from(tpma_locality: TPMA_LOCALITY) -> Self {
LocalityAttributes(tpma_locality)
}
}
impl From for TPMA_LOCALITY {
fn from(locality_attributes: LocalityAttributes) -> Self {
locality_attributes.0
}
}
#[derive(Debug, Clone)]
pub struct LocalityAttributesBuilder {
localities: Vec,
}
impl LocalityAttributesBuilder {
/// Creates a new builder.
pub const fn new() -> Self {
LocalityAttributesBuilder {
localities: Vec::new(),
}
}
/// Adds a locality to the builder
pub fn with_locality(mut self, locality: u8) -> Self {
self.localities.push(locality);
self
}
/// Adds a slice of localities to the builder
pub fn with_localities(mut self, localities: &[u8]) -> Self {
self.localities.extend_from_slice(localities);
self
}
/// Builds the attributes
pub fn build(self) -> Result {
let mut locality_attributes = LocalityAttributes(0);
for locality in self.localities {
if locality_attributes.is_extended() {
error!("Locality attribute {new} and locality attribute {prev} cannot be combined because locality attribute {prev} is extended", new=locality, prev=locality_attributes.0);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
match locality {
0 => locality_attributes.set_locality_zero(true),
1 => locality_attributes.set_locality_one(true),
2 => locality_attributes.set_locality_two(true),
3 => locality_attributes.set_locality_three(true),
4 => locality_attributes.set_locality_four(true),
5..=31 => {
error!(
"Locality attribute {new} is invalid and cannot be combined with other locality attributes",
new=locality
);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
32..=255 => {
if locality_attributes.0 != 0 {
error!("Locality attribute {new} is extended and cannot be combined with locality attribute(s) {old}", new=locality, old=locality_attributes.0);
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
locality_attributes.0 = locality;
}
}
}
Ok(locality_attributes)
}
}
tss-esapi-7.4.0/src/attributes/mod.rs 0000644 0000000 0000000 00000001571 10461020230 0015652 0 ustar 0000000 0000000 //! Module for representation of attributes
/// Representation of the attributes defined in the
/// Attribute structures -> TPMA_OBJECT section of
/// the specification
pub mod object;
/// Representation of the attributes defined in the
/// Attribute structures -> TPMA_OBJECT section of
/// the specification.
pub mod session;
/// Representation of the attributes defined in the
/// NV Storage -> TPMA_NV section of
/// the specification.
pub mod nv_index;
pub mod locality;
pub mod algorithm;
pub mod command_code;
pub use algorithm::AlgorithmAttributes;
pub use command_code::CommandCodeAttributes;
pub use locality::{LocalityAttributes, LocalityAttributesBuilder};
pub use nv_index::{NvIndexAttributes, NvIndexAttributesBuilder};
pub use object::{ObjectAttributes, ObjectAttributesBuilder};
pub use session::{SessionAttributes, SessionAttributesBuilder, SessionAttributesMask};
tss-esapi-7.4.0/src/attributes/nv_index.rs 0000644 0000000 0000000 00000032200 10461020230 0016676 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::NvIndexType,
tss2_esys::{TPM2_NT, TPMA_NV},
Error, Result, WrapperErrorKind,
};
use bitfield::bitfield;
use log::error;
use std::convert::TryFrom;
bitfield! {
/// Bitfield representing the nv index attributes.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct NvIndexAttributes(TPMA_NV);
impl Debug;
// NV Index Attributes
pub pp_write, _: 0;
_, set_pp_write: 0;
pub owner_write, _: 1;
_, set_owner_write: 1;
pub auth_write, _: 2;
_, set_auth_write: 2;
pub policy_write, _: 3;
_, set_policy_write: 3;
TPM2_NT, tss_index_type, _: 7, 4; // private getter
TPM2_NT, from into NvIndexType, _, set_index_type: 7, 4;
// Reserved 9,8
pub policy_delete, _: 10;
_, set_policy_delete: 10;
pub write_locked, _: 11;
_, set_write_locked: 11;
pub write_all, _: 12;
_, set_write_all: 12;
pub write_define, _: 13;
_, set_write_define: 13;
pub write_stclear, _: 14;
_, set_write_stclear: 14;
pub global_lock, _: 15;
_, set_global_lock: 15;
pub pp_read, _: 16;
_, set_pp_read: 16;
pub owner_read, _: 17;
_, set_owner_read: 17;
pub auth_read, _: 18;
_, set_auth_read: 18;
pub policy_read, _: 19;
_, set_policy_read: 19;
// Reserved 24, 20
pub no_da, _: 25;
_, set_no_da: 25;
pub orderly, _: 26;
_, set_orderly: 26;
pub clear_stclear, _: 27;
_, set_clear_stclear: 27;
pub read_locked, _: 28;
_, set_read_locked: 28;
pub written, _: 29;
_, set_written: 29;
pub platform_create, _: 30;
_, set_platform_create: 30;
pub read_stclear, _: 31;
_, set_read_stclear: 31;
}
impl NvIndexAttributes {
/// Returns the `NvIndexType` of the `NvIndexAttributes`
pub fn index_type(&self) -> Result {
NvIndexType::try_from(self.tss_index_type())
}
/// Validates the attributes
///
/// # Details
/// Performs checks on `self` in order to verify
/// that the attributes conforms to the requirements
/// specified in the standard.
///
/// # Errors
/// Returns an error if some attributes are missing
/// or are in conflict with each other.
pub fn validate(&self) -> Result<()> {
// "At least one of TPMA_NV_PPREAD, TPMA_NV_OWNERREAD,
// TPMA_NV_AUTHREAD, or TPMA_NV_POLICYREAD shall be SET."
if !(self.pp_read() | self.owner_read() | self.auth_read() | self.policy_read()) {
error!("Non of the attributes PPREAD, OWERREAD, AUTHREAD, POLICYREAD have been set");
return Err(Error::local_error(WrapperErrorKind::ParamsMissing));
}
// "At least one of TPMA_NV_PPWRITE, TPMA_NV_OWNERWRITE,
// TPMA_NV_AUTHWRITE, or TPMA_NV_POLICYWRITE shall be SET."
if !(self.pp_write() | self.owner_write() | self.auth_write() | self.policy_write()) {
error!(
"Non of the attributes PPWRITE, OWNERWRITE, AUTHWRITE, POLICYWRITE have been set"
);
return Err(Error::local_error(WrapperErrorKind::ParamsMissing));
}
// "If TPM_NT is TPM_NT_PIN_FAIL, TPMA_NV_NO_DA must be SET.
// This removes ambiguity over which Dictionary Attack defense
// protects a TPM_NV_PIN_FAIL's authValue."
if (self.index_type()? == NvIndexType::PinFail) & !self.no_da() {
error!("NvIndexType was PinFail but `no DA` attribute was not set");
return Err(Error::local_error(WrapperErrorKind::ParamsMissing));
}
Ok(())
}
/// Get a builder for the structure
pub const fn builder() -> NvIndexAttributesBuilder {
NvIndexAttributesBuilder::new()
}
}
impl TryFrom for NvIndexAttributes {
type Error = Error;
fn try_from(tss_nv_index_atttributes: TPMA_NV) -> Result {
let nv_index_attributes = NvIndexAttributes(tss_nv_index_atttributes);
nv_index_attributes.validate()?;
Ok(nv_index_attributes)
}
}
impl TryFrom for TPMA_NV {
type Error = Error;
fn try_from(nv_index_atttributes: NvIndexAttributes) -> Result {
nv_index_atttributes.validate()?;
Ok(nv_index_atttributes.0)
}
}
/// A builder NV index attributes
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NvIndexAttributesBuilder {
nv_index_attributes: NvIndexAttributes,
}
impl NvIndexAttributesBuilder {
/// Creates a new nv index builder
pub const fn new() -> Self {
NvIndexAttributesBuilder {
nv_index_attributes: NvIndexAttributes(0),
}
}
/// Creates a new builder from existing `NvIndexAttributes`
pub const fn with_attributes(nv_index_attributes: NvIndexAttributes) -> Self {
NvIndexAttributesBuilder {
nv_index_attributes,
}
}
/// Controls the `pp write` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_pp_write(mut self, set: bool) -> Self {
self.nv_index_attributes.set_pp_write(set);
self
}
/// Controls the `owner write` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_owner_write(mut self, set: bool) -> Self {
self.nv_index_attributes.set_owner_write(set);
self
}
/// Controls the `auth write` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_auth_write(mut self, set: bool) -> Self {
self.nv_index_attributes.set_auth_write(set);
self
}
/// Controls the `policy write` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_policy_write(mut self, set: bool) -> Self {
self.nv_index_attributes.set_policy_write(set);
self
}
/// Controls the `nv index type` attribute
///
/// # Arguments
/// * `nv_index_type` - The nv index type to be used.
pub fn with_nv_index_type(mut self, nv_index_type: NvIndexType) -> Self {
self.nv_index_attributes.set_index_type(nv_index_type);
self
}
/// Controls the `policy delete` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_policy_delete(mut self, set: bool) -> Self {
self.nv_index_attributes.set_policy_delete(set);
self
}
/// Controls the `write locked` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_write_locked(mut self, set: bool) -> Self {
self.nv_index_attributes.set_write_locked(set);
self
}
/// Controls the `write all` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_write_all(mut self, set: bool) -> Self {
self.nv_index_attributes.set_write_all(set);
self
}
/// Controls the `write define` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_write_define(mut self, set: bool) -> Self {
self.nv_index_attributes.set_write_define(set);
self
}
/// Controls the `write stclear` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_write_stclear(mut self, set: bool) -> Self {
self.nv_index_attributes.set_write_stclear(set);
self
}
/// Controls the `global lock` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_global_lock(mut self, set: bool) -> Self {
self.nv_index_attributes.set_global_lock(set);
self
}
/// Controls the `pp read` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_pp_read(mut self, set: bool) -> Self {
self.nv_index_attributes.set_pp_read(set);
self
}
/// Controls the `owner read` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_owner_read(mut self, set: bool) -> Self {
self.nv_index_attributes.set_owner_read(set);
self
}
/// Controls the `auth read` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_auth_read(mut self, set: bool) -> Self {
self.nv_index_attributes.set_auth_read(set);
self
}
/// Controls the `policy read` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_policy_read(mut self, set: bool) -> Self {
self.nv_index_attributes.set_policy_read(set);
self
}
/// Controls the `no DA` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_no_da(mut self, set: bool) -> Self {
self.nv_index_attributes.set_no_da(set);
self
}
/// Controls the `orderly` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_orderly(mut self, set: bool) -> Self {
self.nv_index_attributes.set_orderly(set);
self
}
/// Controls the `clear stclear` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_clear_stclear(mut self, set: bool) -> Self {
self.nv_index_attributes.set_clear_stclear(set);
self
}
/// Controls the `read locked` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_read_locked(mut self, set: bool) -> Self {
self.nv_index_attributes.set_read_locked(set);
self
}
/// Controls the `written` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_written(mut self, set: bool) -> Self {
self.nv_index_attributes.set_written(set);
self
}
/// Controls the `platform create` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_platform_create(mut self, set: bool) -> Self {
self.nv_index_attributes.set_platform_create(set);
self
}
/// Controls the `read stclear` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_read_stclear(mut self, set: bool) -> Self {
self.nv_index_attributes.set_read_stclear(set);
self
}
/// Builds the nv index attributes.
///
/// # Errors
/// Returns an error if some attributes are missing
/// or are in conflict with each other.
pub fn build(self) -> Result {
self.nv_index_attributes.validate()?;
Ok(self.nv_index_attributes)
}
}
impl Default for NvIndexAttributesBuilder {
fn default() -> Self {
NvIndexAttributesBuilder::new()
}
}
tss-esapi-7.4.0/src/attributes/object.rs 0000644 0000000 0000000 00000016425 10461020230 0016345 0 ustar 0000000 0000000 use crate::{tss2_esys::TPMA_OBJECT, Result};
use bitfield::bitfield;
bitfield! {
/// Bitfield representing the object attributes.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct ObjectAttributes(TPMA_OBJECT);
impl Debug;
// Object attribute flags
pub fixed_tpm, _: 1;
_, set_fixed_tpm: 1;
pub st_clear, _: 2;
_, set_st_clear: 2;
pub fixed_parent, _: 4;
_, set_fixed_parent: 4;
pub sensitive_data_origin, _: 5;
_, set_sensitive_data_origin: 5;
pub user_with_auth, _: 6;
_, set_user_with_auth: 6;
pub admin_with_policy, _: 7;
_, set_admin_with_policy: 7;
pub no_da, _: 10;
_, set_no_da: 10;
pub encrypted_duplication, _: 11;
_, set_encrypted_duplication: 11;
pub restricted, _: 16;
_, set_restricted: 16;
pub decrypt, _: 17;
_, set_decrypt: 17;
pub sign_encrypt, _: 18;
_, set_sign_encrypt: 18;
pub x509_sign, _: 19;
_, set_x509_sign: 19;
}
impl ObjectAttributes {
/// Function for creating attributes for a
/// fixed parent key object.
pub fn new_fixed_parent_key() -> Self {
let mut attrs = ObjectAttributes(0);
attrs.set_fixed_tpm(true);
attrs.set_fixed_parent(true);
attrs.set_sensitive_data_origin(true);
attrs.set_user_with_auth(true);
attrs.set_decrypt(true);
attrs.set_restricted(true);
attrs
}
/// Function for creating attributes for
/// a fixed signing key object.
pub fn new_fixed_signing_key() -> Self {
let mut attrs = ObjectAttributes(0);
attrs.set_fixed_tpm(true);
attrs.set_fixed_parent(true);
attrs.set_sensitive_data_origin(true);
attrs.set_user_with_auth(true);
attrs.set_sign_encrypt(true);
attrs
}
/// Get a builder for the structure
pub const fn builder() -> ObjectAttributesBuilder {
ObjectAttributesBuilder::new()
}
}
impl From for TPMA_OBJECT {
fn from(object_attributes: ObjectAttributes) -> Self {
object_attributes.0
}
}
impl From for ObjectAttributes {
fn from(tpma_object: TPMA_OBJECT) -> Self {
ObjectAttributes(tpma_object)
}
}
/// A builder for [ObjectAttributes]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ObjectAttributesBuilder {
object_attributes: ObjectAttributes,
}
impl ObjectAttributesBuilder {
/// Creates an new [ObjectAttributes] builder.
pub const fn new() -> Self {
ObjectAttributesBuilder {
object_attributes: ObjectAttributes(0),
}
}
/// Controls the `fixed tpm` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_fixed_tpm(mut self, set: bool) -> Self {
self.object_attributes.set_fixed_tpm(set);
self
}
/// Controls the `st clear` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_st_clear(mut self, set: bool) -> Self {
self.object_attributes.set_st_clear(set);
self
}
/// Controls the `fixed parent` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_fixed_parent(mut self, set: bool) -> Self {
self.object_attributes.set_fixed_parent(set);
self
}
/// Controls the `sensitive data origin` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_sensitive_data_origin(mut self, set: bool) -> Self {
self.object_attributes.set_sensitive_data_origin(set);
self
}
/// Controls the `user with auth` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_user_with_auth(mut self, set: bool) -> Self {
self.object_attributes.set_user_with_auth(set);
self
}
/// Controls the `admin with policy` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_admin_with_policy(mut self, set: bool) -> Self {
self.object_attributes.set_admin_with_policy(set);
self
}
/// Controls the `no da` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_no_da(mut self, set: bool) -> Self {
self.object_attributes.set_no_da(set);
self
}
/// Controls the `encrypted duplication` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_encrypted_duplication(mut self, set: bool) -> Self {
self.object_attributes.set_encrypted_duplication(set);
self
}
/// Controls the `restricted` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_restricted(mut self, set: bool) -> Self {
self.object_attributes.set_restricted(set);
self
}
/// Controls the `decrypt` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_decrypt(mut self, set: bool) -> Self {
self.object_attributes.set_decrypt(set);
self
}
/// Controls the `sign/encrypt` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_sign_encrypt(mut self, set: bool) -> Self {
self.object_attributes.set_sign_encrypt(set);
self
}
/// Controls the `X509 sign` attribute
///
/// # Arguments
/// * `set` - `true` indicates that the attribute should have the value SET.
/// `false`indicates that the attribute should have the value CLEAR.
pub fn with_x509_sign(mut self, set: bool) -> Self {
self.object_attributes.set_x509_sign(set);
self
}
/// Builds the nv index attributes.
///
/// # Errors
/// Returns an error if some attributes are missing
/// or are in conflict with each other.
pub fn build(self) -> Result {
Ok(self.object_attributes)
}
}
impl Default for ObjectAttributesBuilder {
fn default() -> Self {
ObjectAttributesBuilder::new()
}
}
tss-esapi-7.4.0/src/attributes/session.rs 0000644 0000000 0000000 00000007272 10461020230 0016562 0 ustar 0000000 0000000 use crate::tss2_esys::TPMA_SESSION;
use bitfield::bitfield;
// SESSION ATTRIBUTES
bitfield! {
/// Bitfield representing the session attributes.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct SessionAttributes(TPMA_SESSION);
impl Debug;
_, set_continue_session: 0;
pub continue_session, _: 0;
_, set_audit_exclusive: 1;
pub audit_exclusive, _: 1;
_, set_audit_reset: 2;
pub audit_reset, _: 2;
// Reserved 3,4 (Shall be clear)
_, set_decrypt: 5;
pub decrypt, _: 5;
_, set_encrypt: 6;
pub encrypt, _: 6;
_, set_audit: 7;
pub audit, _: 7;
}
impl SessionAttributes {
/// Get a builder for the structure
pub const fn builder() -> SessionAttributesBuilder {
SessionAttributesBuilder::new()
}
}
impl From for SessionAttributes {
fn from(tss_session_attributes: TPMA_SESSION) -> SessionAttributes {
SessionAttributes(tss_session_attributes)
}
}
impl From for TPMA_SESSION {
fn from(session_attributes: SessionAttributes) -> TPMA_SESSION {
session_attributes.0
}
}
// SESSION ATTRIBUTES MASK
bitfield! {
/// Bitfield representing the session attributes mask.
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct SessionAttributesMask(TPMA_SESSION);
impl Debug;
_, use_continue_session: 0;
_, use_audit_exclusive: 1;
_, use_audit_reset: 2;
// Reserved 3,4 (Shall be clear)
_, use_decrypt: 5;
_, use_encrypt: 6;
_, use_audit: 7;
}
impl SessionAttributesMask {
/// Get a builder for the structure
pub const fn builder() -> SessionAttributesBuilder {
SessionAttributesBuilder::new()
}
}
impl From for SessionAttributesMask {
fn from(tss_session_attributes: TPMA_SESSION) -> SessionAttributesMask {
SessionAttributesMask(tss_session_attributes)
}
}
impl From for TPMA_SESSION {
fn from(session_attributes_mask: SessionAttributesMask) -> TPMA_SESSION {
session_attributes_mask.0
}
}
// SESSION ATTRIBUTES ITEMS BUILDER
/// A builder that is used to create
/// SessionAttributes and a corresponding
/// SessionAttributesMask.
#[derive(Debug, Copy, Clone)]
pub struct SessionAttributesBuilder {
attributes: SessionAttributes,
mask: SessionAttributesMask,
}
impl SessionAttributesBuilder {
pub const fn new() -> SessionAttributesBuilder {
SessionAttributesBuilder {
attributes: SessionAttributes(0),
mask: SessionAttributesMask(0),
}
}
pub fn with_continue_session(mut self, set: bool) -> Self {
self.attributes.set_continue_session(set);
self.mask.use_continue_session(true);
self
}
pub fn with_audit_exclusive(mut self, set: bool) -> Self {
self.attributes.set_audit_exclusive(set);
self.mask.use_audit_exclusive(true);
self
}
pub fn with_audit_reset(mut self, set: bool) -> Self {
self.attributes.set_audit_reset(set);
self.mask.use_audit_reset(true);
self
}
pub fn with_decrypt(mut self, set: bool) -> Self {
self.attributes.set_decrypt(set);
self.mask.use_decrypt(true);
self
}
pub fn with_encrypt(mut self, set: bool) -> Self {
self.attributes.set_encrypt(set);
self.mask.use_encrypt(true);
self
}
pub fn with_audit(mut self, set: bool) -> Self {
self.attributes.set_audit(set);
self.mask.use_audit(true);
self
}
pub fn build(self) -> (SessionAttributes, SessionAttributesMask) {
(self.attributes, self.mask)
}
}
impl Default for SessionAttributesBuilder {
fn default() -> Self {
Self::new()
}
}
tss-esapi-7.4.0/src/constants/algorithm.rs 0000644 0000000 0000000 00000005651 10461020230 0016712 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{
TPM2_ALG_AES, TPM2_ALG_CAMELLIA, TPM2_ALG_CBC, TPM2_ALG_CFB, TPM2_ALG_CMAC, TPM2_ALG_CTR,
TPM2_ALG_ECB, TPM2_ALG_ECC, TPM2_ALG_ECDAA, TPM2_ALG_ECDH, TPM2_ALG_ECDSA, TPM2_ALG_ECMQV,
TPM2_ALG_ECSCHNORR, TPM2_ALG_ERROR, TPM2_ALG_HMAC, TPM2_ALG_KDF1_SP800_108,
TPM2_ALG_KDF1_SP800_56A, TPM2_ALG_KDF2, TPM2_ALG_KEYEDHASH, TPM2_ALG_MGF1, TPM2_ALG_NULL,
TPM2_ALG_OAEP, TPM2_ALG_OFB, TPM2_ALG_RSA, TPM2_ALG_RSAES, TPM2_ALG_RSAPSS,
TPM2_ALG_RSASSA, TPM2_ALG_SHA1, TPM2_ALG_SHA256, TPM2_ALG_SHA384, TPM2_ALG_SHA3_256,
TPM2_ALG_SHA3_384, TPM2_ALG_SHA3_512, TPM2_ALG_SHA512, TPM2_ALG_SM2, TPM2_ALG_SM3_256,
TPM2_ALG_SM4, TPM2_ALG_SYMCIPHER, TPM2_ALG_TDES, TPM2_ALG_XOR,
},
tss2_esys::TPM2_ALG_ID,
Error, Result, WrapperErrorKind,
};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(u16)]
pub enum AlgorithmIdentifier {
Aes = TPM2_ALG_AES,
Camellia = TPM2_ALG_CAMELLIA,
Cbc = TPM2_ALG_CBC,
Cfb = TPM2_ALG_CFB,
Ctr = TPM2_ALG_CTR,
Ecb = TPM2_ALG_ECB,
Ecc = TPM2_ALG_ECC,
EcDaa = TPM2_ALG_ECDAA,
EcDh = TPM2_ALG_ECDH,
EcDsa = TPM2_ALG_ECDSA,
EcMqv = TPM2_ALG_ECMQV,
EcSchnorr = TPM2_ALG_ECSCHNORR,
Error = TPM2_ALG_ERROR,
Hmac = TPM2_ALG_HMAC,
Kdf1Sp800_108 = TPM2_ALG_KDF1_SP800_108,
Kdf1Sp800_56a = TPM2_ALG_KDF1_SP800_56A,
Kdf2 = TPM2_ALG_KDF2,
KeyedHash = TPM2_ALG_KEYEDHASH,
Mgf1 = TPM2_ALG_MGF1,
Null = TPM2_ALG_NULL,
Oaep = TPM2_ALG_OAEP,
Ofb = TPM2_ALG_OFB,
Rsa = TPM2_ALG_RSA,
RsaEs = TPM2_ALG_RSAES,
RsaPss = TPM2_ALG_RSAPSS,
RsaSsa = TPM2_ALG_RSASSA,
Sha1 = TPM2_ALG_SHA1,
Sha256 = TPM2_ALG_SHA256,
Sha384 = TPM2_ALG_SHA384,
Sha3_256 = TPM2_ALG_SHA3_256,
Sha3_384 = TPM2_ALG_SHA3_384,
Sha3_512 = TPM2_ALG_SHA3_512,
Sha512 = TPM2_ALG_SHA512,
Sm2 = TPM2_ALG_SM2,
Sm3_256 = TPM2_ALG_SM3_256,
Sm4 = TPM2_ALG_SM4,
SymCipher = TPM2_ALG_SYMCIPHER,
Tdes = TPM2_ALG_TDES,
Xor = TPM2_ALG_XOR,
Cmac = TPM2_ALG_CMAC,
}
impl TryFrom for AlgorithmIdentifier {
type Error = Error;
fn try_from(tpm_alg_id: TPM2_ALG_ID) -> Result {
AlgorithmIdentifier::from_u16(tpm_alg_id).ok_or_else(|| {
error!(
"Value = {} did not match any algorithm identifier",
tpm_alg_id
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
impl From for TPM2_ALG_ID {
fn from(algorithm: AlgorithmIdentifier) -> TPM2_ALG_ID {
// The values are well defined so this cannot fail.
algorithm.to_u16().unwrap()
}
}
tss-esapi-7.4.0/src/constants/capabilities.rs 0000644 0000000 0000000 00000003307 10461020230 0017351 0 ustar 0000000 0000000 use crate::{Error, Result, WrapperErrorKind};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::{From, TryFrom};
use crate::{
constants::tss::{
TPM2_CAP_ACT, TPM2_CAP_ALGS, TPM2_CAP_AUDIT_COMMANDS, TPM2_CAP_AUTH_POLICIES,
TPM2_CAP_COMMANDS, TPM2_CAP_ECC_CURVES, TPM2_CAP_HANDLES, TPM2_CAP_PCRS,
TPM2_CAP_PCR_PROPERTIES, TPM2_CAP_PP_COMMANDS, TPM2_CAP_TPM_PROPERTIES,
},
tss2_esys::TPM2_CAP,
};
// Enum representing the different TPM Capability Type values.
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum CapabilityType {
Algorithms = TPM2_CAP_ALGS,
Handles = TPM2_CAP_HANDLES,
Command = TPM2_CAP_COMMANDS,
PpCommands = TPM2_CAP_PP_COMMANDS,
AuditCommands = TPM2_CAP_AUDIT_COMMANDS,
AssignedPcr = TPM2_CAP_PCRS,
TpmProperties = TPM2_CAP_TPM_PROPERTIES,
PcrProperties = TPM2_CAP_PCR_PROPERTIES,
EccCurves = TPM2_CAP_ECC_CURVES,
AuthPolicies = TPM2_CAP_AUTH_POLICIES,
Act = TPM2_CAP_ACT,
}
impl From for TPM2_CAP {
fn from(capability_type: CapabilityType) -> TPM2_CAP {
// The values are well defined so this cannot fail.
capability_type.to_u32().unwrap()
}
}
impl TryFrom for CapabilityType {
type Error = Error;
fn try_from(tpm_capability_type: TPM2_CAP) -> Result {
CapabilityType::from_u32(tpm_capability_type).ok_or_else(|| {
error!(
"value = {} did not match any CapabilityType.",
tpm_capability_type
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
tss-esapi-7.4.0/src/constants/command_code/structure.rs 0000644 0000000 0000000 00000037031 10461020230 0021371 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{
TPM2_CC_AC_GetCapability, TPM2_CC_AC_Send, TPM2_CC_ActivateCredential, TPM2_CC_Certify,
TPM2_CC_CertifyCreation, TPM2_CC_ChangeEPS, TPM2_CC_ChangePPS, TPM2_CC_Clear,
TPM2_CC_ClearControl, TPM2_CC_ClockRateAdjust, TPM2_CC_ClockSet, TPM2_CC_Commit,
TPM2_CC_ContextLoad, TPM2_CC_ContextSave, TPM2_CC_Create, TPM2_CC_CreateLoaded,
TPM2_CC_CreatePrimary, TPM2_CC_DictionaryAttackLockReset,
TPM2_CC_DictionaryAttackParameters, TPM2_CC_Duplicate, TPM2_CC_ECC_Parameters,
TPM2_CC_ECDH_KeyGen, TPM2_CC_ECDH_ZGen, TPM2_CC_EC_Ephemeral, TPM2_CC_EncryptDecrypt,
TPM2_CC_EncryptDecrypt2, TPM2_CC_EventSequenceComplete, TPM2_CC_EvictControl,
TPM2_CC_FieldUpgradeData, TPM2_CC_FieldUpgradeStart, TPM2_CC_FirmwareRead,
TPM2_CC_FlushContext, TPM2_CC_GetCapability, TPM2_CC_GetCommandAuditDigest,
TPM2_CC_GetRandom, TPM2_CC_GetSessionAuditDigest, TPM2_CC_GetTestResult, TPM2_CC_GetTime,
TPM2_CC_HMAC_Start, TPM2_CC_Hash, TPM2_CC_HashSequenceStart, TPM2_CC_HierarchyChangeAuth,
TPM2_CC_HierarchyControl, TPM2_CC_Import, TPM2_CC_IncrementalSelfTest, TPM2_CC_Load,
TPM2_CC_LoadExternal, TPM2_CC_MakeCredential, TPM2_CC_NV_Certify, TPM2_CC_NV_ChangeAuth,
TPM2_CC_NV_DefineSpace, TPM2_CC_NV_Extend, TPM2_CC_NV_GlobalWriteLock,
TPM2_CC_NV_Increment, TPM2_CC_NV_Read, TPM2_CC_NV_ReadLock, TPM2_CC_NV_ReadPublic,
TPM2_CC_NV_SetBits, TPM2_CC_NV_UndefineSpace, TPM2_CC_NV_UndefineSpaceSpecial,
TPM2_CC_NV_Write, TPM2_CC_NV_WriteLock, TPM2_CC_ObjectChangeAuth, TPM2_CC_PCR_Allocate,
TPM2_CC_PCR_Event, TPM2_CC_PCR_Extend, TPM2_CC_PCR_Read, TPM2_CC_PCR_Reset,
TPM2_CC_PCR_SetAuthPolicy, TPM2_CC_PCR_SetAuthValue, TPM2_CC_PP_Commands,
TPM2_CC_PolicyAuthValue, TPM2_CC_PolicyAuthorize, TPM2_CC_PolicyAuthorizeNV,
TPM2_CC_PolicyCommandCode, TPM2_CC_PolicyCounterTimer, TPM2_CC_PolicyCpHash,
TPM2_CC_PolicyDuplicationSelect, TPM2_CC_PolicyGetDigest, TPM2_CC_PolicyLocality,
TPM2_CC_PolicyNV, TPM2_CC_PolicyNameHash, TPM2_CC_PolicyNvWritten, TPM2_CC_PolicyOR,
TPM2_CC_PolicyPCR, TPM2_CC_PolicyPassword, TPM2_CC_PolicyPhysicalPresence,
TPM2_CC_PolicyRestart, TPM2_CC_PolicySecret, TPM2_CC_PolicySigned, TPM2_CC_PolicyTemplate,
TPM2_CC_PolicyTicket, TPM2_CC_Policy_AC_SendSelect, TPM2_CC_Quote, TPM2_CC_RSA_Decrypt,
TPM2_CC_RSA_Encrypt, TPM2_CC_ReadClock, TPM2_CC_ReadPublic, TPM2_CC_Rewrap,
TPM2_CC_SelfTest, TPM2_CC_SequenceComplete, TPM2_CC_SequenceUpdate,
TPM2_CC_SetAlgorithmSet, TPM2_CC_SetCommandCodeAuditStatus, TPM2_CC_SetPrimaryPolicy,
TPM2_CC_Shutdown, TPM2_CC_Sign, TPM2_CC_StartAuthSession, TPM2_CC_Startup,
TPM2_CC_StirRandom, TPM2_CC_TestParms, TPM2_CC_Unseal, TPM2_CC_VerifySignature,
TPM2_CC_ZGen_2Phase, TPM2_CC_HMAC,
},
tss2_esys::TPM2_CC,
Error, Result, WrapperErrorKind,
};
use bitfield::bitfield;
use log::error;
use std::convert::TryFrom;
bitfield! {
/// Bitfield representing the command code structure
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct CommandCodeStructure(u32);
impl Debug;
_, set_command_index: 15, 0;
pub command_index, _: 15, 0;
pub reserved, _ : 28, 16; // Shall be zero
_, set_vendor_specific: 29;
pub vendor_specific, _: 29;
pub res, _ : 31, 30; // Shall be zero
}
impl CommandCodeStructure {
pub const NV_UNDEFINE_SPACE_SPECIAL: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_NV_UndefineSpaceSpecial);
pub const EVICT_CONTROL: CommandCodeStructure = CommandCodeStructure(TPM2_CC_EvictControl);
pub const HIERARCHY_CONTROL: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_HierarchyControl);
pub const NV_UNDEFINE_SPACE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_NV_UndefineSpace);
pub const CHANGE_EPS: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ChangeEPS);
pub const CHANGE_PPS: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ChangePPS);
pub const CLEAR: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Clear);
pub const CLEAR_CONTROL: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ClearControl);
pub const CLOCK_SET: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ClockSet);
pub const HIERARCHY_CHANGE_AUTH: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_HierarchyChangeAuth);
pub const NV_DEFINE_SPACE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_DefineSpace);
pub const PCR_ALLOCATE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PCR_Allocate);
pub const PCR_SET_AUTH_POLICY: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PCR_SetAuthPolicy);
pub const PP_COMMANDS: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PP_Commands);
pub const SET_PRIMARY_POLICY: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_SetPrimaryPolicy);
pub const FIELD_UPGRADE_START: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_FieldUpgradeStart);
pub const CLOCK_RATE_ADJUST: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_ClockRateAdjust);
pub const CREATE_PRIMARY: CommandCodeStructure = CommandCodeStructure(TPM2_CC_CreatePrimary);
pub const NV_GLOBAL_WRITE_LOCK: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_NV_GlobalWriteLock);
pub const GET_COMMAND_AUDIT_DIGEST: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_GetCommandAuditDigest);
pub const NV_INCREMENT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_Increment);
pub const NV_SET_BITS: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_SetBits);
pub const NV_EXTEND: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_Extend);
pub const NV_WRITE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_Write);
pub const NV_WRITE_LOCK: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_WriteLock);
pub const DICTIONARY_ATTACK_LOCK_RESET: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_DictionaryAttackLockReset);
pub const DICTIONARY_ATTACK_PARAMETERS: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_DictionaryAttackParameters);
pub const NV_CHANGE_AUTH: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_ChangeAuth);
pub const PCR_EVENT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PCR_Event);
pub const PCR_RESET: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PCR_Reset);
pub const SEQUENCE_COMPLETE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_SequenceComplete);
pub const SET_ALGORITHM_SET: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_SetAlgorithmSet);
pub const SET_COMMAND_CODE_AUDIT_STATUS: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_SetCommandCodeAuditStatus);
pub const FIELD_UPGRADE_DATA: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_FieldUpgradeData);
pub const INCREMENTAL_SELF_TEST: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_IncrementalSelfTest);
pub const SELF_TEST: CommandCodeStructure = CommandCodeStructure(TPM2_CC_SelfTest);
pub const STARTUP: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Startup);
pub const SHUTDOWN: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Shutdown);
pub const STIR_RANDOM: CommandCodeStructure = CommandCodeStructure(TPM2_CC_StirRandom);
pub const ACTIVATE_CREDENTIAL: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_ActivateCredential);
pub const CERTIFY: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Certify);
pub const POLICY_NV: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyNV);
pub const CERTIFY_CREATION: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_CertifyCreation);
pub const DUPLICATE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Duplicate);
pub const GET_TIME: CommandCodeStructure = CommandCodeStructure(TPM2_CC_GetTime);
pub const GET_SESSION_AUDIT_DIGEST: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_GetSessionAuditDigest);
pub const NV_READ: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_Read);
pub const NV_READ_LOCK: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_ReadLock);
pub const OBJECT_CHANGE_AUTH: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_ObjectChangeAuth);
pub const POLICY_SECRET: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicySecret);
pub const REWRAP: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Rewrap);
pub const CREATE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Create);
pub const ECDH_Z_GEN: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ECDH_ZGen);
pub const HMAC: CommandCodeStructure = CommandCodeStructure(TPM2_CC_HMAC);
pub const IMPORT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Import);
pub const LOAD: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Load);
pub const QUOTE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Quote);
pub const RSA_DECRYPT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_RSA_Decrypt);
pub const HMAC_START: CommandCodeStructure = CommandCodeStructure(TPM2_CC_HMAC_Start);
pub const SEQUENCE_UPDATE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_SequenceUpdate);
pub const SIGN: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Sign);
pub const UNSEAL: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Unseal);
pub const POLICY_SIGNED: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicySigned);
pub const CONTEXT_LOAD: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ContextLoad);
pub const CONTEXT_SAVE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ContextSave);
pub const ECDH_KEY_GEN: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ECDH_KeyGen);
pub const ENCRYPT_DECRYPT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_EncryptDecrypt);
pub const FLUSH_CONTEXT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_FlushContext);
pub const LOAD_EXTERNAL: CommandCodeStructure = CommandCodeStructure(TPM2_CC_LoadExternal);
pub const MAKE_CREDENTIAL: CommandCodeStructure = CommandCodeStructure(TPM2_CC_MakeCredential);
pub const NV_READ_PUBLIC: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_ReadPublic);
pub const POLICY_AUTHORIZE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyAuthorize);
pub const POLICY_AUTH_VALUE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyAuthValue);
pub const POLICY_COMMAND_CODE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyCommandCode);
pub const POLICY_COUNTER_TIMER: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyCounterTimer);
pub const POLICY_CP_HASH: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyCpHash);
pub const POLICY_LOCALITY: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyLocality);
pub const POLICY_NAME_HASH: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyNameHash);
pub const POLICY_OR: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyOR);
pub const POLICY_TICKET: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyTicket);
pub const READ_PUBLIC: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ReadPublic);
pub const RSA_ENCRYPT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_RSA_Encrypt);
pub const START_AUTH_SESSION: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_StartAuthSession);
pub const VERIFY_SIGNATURE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_VerifySignature);
pub const ECC_PARAMETERS: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ECC_Parameters);
pub const FIRMWARE_READ: CommandCodeStructure = CommandCodeStructure(TPM2_CC_FirmwareRead);
pub const GET_CAPABILITY: CommandCodeStructure = CommandCodeStructure(TPM2_CC_GetCapability);
pub const GET_RANDOM: CommandCodeStructure = CommandCodeStructure(TPM2_CC_GetRandom);
pub const GET_TEST_RESULT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_GetTestResult);
pub const HASH: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Hash);
pub const PCR_READ: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PCR_Read);
pub const POLICY_PCR: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyPCR);
pub const POLICY_RESTART: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyRestart);
pub const READ_CLOCK: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ReadClock);
pub const PCR_EXTEND: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PCR_Extend);
pub const PCR_SET_AUTH_VALUE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PCR_SetAuthValue);
pub const NV_CERTIFY: CommandCodeStructure = CommandCodeStructure(TPM2_CC_NV_Certify);
pub const EVENT_SEQUENCE_COMPLETE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_EventSequenceComplete);
pub const HASH_SEQUENCE_START: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_HashSequenceStart);
pub const POLICY_PHYSICAL_PRESENCE: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyPhysicalPresence);
pub const POLICY_DUPLICATION_SELECT: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyDuplicationSelect);
pub const POLICY_GET_DIGEST: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyGetDigest);
pub const TEST_PARMS: CommandCodeStructure = CommandCodeStructure(TPM2_CC_TestParms);
pub const COMMIT: CommandCodeStructure = CommandCodeStructure(TPM2_CC_Commit);
pub const POLICY_PASSWORD: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyPassword);
pub const Z_GEN_2_PHASE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_ZGen_2Phase);
pub const EC_EPHEMERAL: CommandCodeStructure = CommandCodeStructure(TPM2_CC_EC_Ephemeral);
pub const POLICY_NV_WRITTEN: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyNvWritten);
pub const POLICY_TEMPLATE: CommandCodeStructure = CommandCodeStructure(TPM2_CC_PolicyTemplate);
pub const CREATE_LOADED: CommandCodeStructure = CommandCodeStructure(TPM2_CC_CreateLoaded);
pub const POLICY_AUTHORIZE_NV: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_PolicyAuthorizeNV);
pub const ENCRYPT_DECRYPT_2: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_EncryptDecrypt2);
pub const AC_GET_CAPABILITY: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_AC_GetCapability);
pub const AC_SEND: CommandCodeStructure = CommandCodeStructure(TPM2_CC_AC_Send);
pub const POLICY_AC_SEND_SELECT: CommandCodeStructure =
CommandCodeStructure(TPM2_CC_Policy_AC_SendSelect);
}
impl TryFrom for CommandCodeStructure {
type Error = Error;
fn try_from(tpm2_cc: TPM2_CC) -> Result {
let command_code_structure = CommandCodeStructure(tpm2_cc);
if command_code_structure.vendor_specific() {
error!("The command code is vendor specific and cannot be parsed");
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
if command_code_structure.reserved() != 0 || command_code_structure.res() != 0 {
error!("Encountered non zero reserved bits");
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
Ok(command_code_structure)
}
}
impl From for TPM2_CC {
fn from(command_code_structure: CommandCodeStructure) -> Self {
command_code_structure.0
}
}
tss-esapi-7.4.0/src/constants/command_code.rs 0000644 0000000 0000000 00000017356 10461020230 0017341 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
mod structure;
use crate::{tss2_esys::TPM2_CC, Error, Result, WrapperErrorKind};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
use structure::CommandCodeStructure;
/// Enum representing the command code constants.
///
/// # Details
/// This corresponds to the TPM2_CC constants.
#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum CommandCode {
NvUndefineSpaceSpecial = CommandCodeStructure::NV_UNDEFINE_SPACE_SPECIAL.0,
EvictControl = CommandCodeStructure::EVICT_CONTROL.0,
HierarchyControl = CommandCodeStructure::HIERARCHY_CONTROL.0,
NvUndefineSpace = CommandCodeStructure::NV_UNDEFINE_SPACE.0,
ChangeEps = CommandCodeStructure::CHANGE_EPS.0,
ChangePps = CommandCodeStructure::CHANGE_PPS.0,
Clear = CommandCodeStructure::CLEAR.0,
ClearControl = CommandCodeStructure::CLEAR_CONTROL.0,
ClockSet = CommandCodeStructure::CLOCK_SET.0,
HierarchyChangeAuth = CommandCodeStructure::HIERARCHY_CHANGE_AUTH.0,
NvDefineSpace = CommandCodeStructure::NV_DEFINE_SPACE.0,
PcrAllocate = CommandCodeStructure::PCR_ALLOCATE.0,
PcrSetAuthPolicy = CommandCodeStructure::PCR_SET_AUTH_POLICY.0,
PpCommands = CommandCodeStructure::PP_COMMANDS.0,
SetPrimaryPolicy = CommandCodeStructure::SET_PRIMARY_POLICY.0,
FieldUpgradeStart = CommandCodeStructure::FIELD_UPGRADE_START.0,
ClockRateAdjust = CommandCodeStructure::CLOCK_RATE_ADJUST.0,
CreatePrimary = CommandCodeStructure::CREATE_PRIMARY.0,
NvGlobalWriteLock = CommandCodeStructure::NV_GLOBAL_WRITE_LOCK.0,
GetCommandAuditDigest = CommandCodeStructure::GET_COMMAND_AUDIT_DIGEST.0,
NvIncrement = CommandCodeStructure::NV_INCREMENT.0,
NvSetBits = CommandCodeStructure::NV_SET_BITS.0,
NvExtend = CommandCodeStructure::NV_EXTEND.0,
NvWrite = CommandCodeStructure::NV_WRITE.0,
NvWriteLock = CommandCodeStructure::NV_WRITE_LOCK.0,
DictionaryAttackLockReset = CommandCodeStructure::DICTIONARY_ATTACK_LOCK_RESET.0,
DictionaryAttackParameters = CommandCodeStructure::DICTIONARY_ATTACK_PARAMETERS.0,
NvChangeAuth = CommandCodeStructure::NV_CHANGE_AUTH.0,
PcrEvent = CommandCodeStructure::PCR_EVENT.0,
PcrReset = CommandCodeStructure::PCR_RESET.0,
SequenceComplete = CommandCodeStructure::SEQUENCE_COMPLETE.0,
SetAlgorithmSet = CommandCodeStructure::SET_ALGORITHM_SET.0,
SetCommandCodeAuditStatus = CommandCodeStructure::SET_COMMAND_CODE_AUDIT_STATUS.0,
FieldUpgradeData = CommandCodeStructure::FIELD_UPGRADE_DATA.0,
IncrementalSelfTest = CommandCodeStructure::INCREMENTAL_SELF_TEST.0,
SelfTest = CommandCodeStructure::SELF_TEST.0,
Startup = CommandCodeStructure::STARTUP.0,
Shutdown = CommandCodeStructure::SHUTDOWN.0,
StirRandom = CommandCodeStructure::STIR_RANDOM.0,
ActivateCredential = CommandCodeStructure::ACTIVATE_CREDENTIAL.0,
Certify = CommandCodeStructure::CERTIFY.0,
PolicyNv = CommandCodeStructure::POLICY_NV.0,
CertifyCreation = CommandCodeStructure::CERTIFY_CREATION.0,
Duplicate = CommandCodeStructure::DUPLICATE.0,
GetTime = CommandCodeStructure::GET_TIME.0,
GetSessionAuditDigest = CommandCodeStructure::GET_SESSION_AUDIT_DIGEST.0,
NvRead = CommandCodeStructure::NV_READ.0,
NvReadLock = CommandCodeStructure::NV_READ_LOCK.0,
ObjectChangeAuth = CommandCodeStructure::OBJECT_CHANGE_AUTH.0,
PolicySecret = CommandCodeStructure::POLICY_SECRET.0,
Rewrap = CommandCodeStructure::REWRAP.0,
Create = CommandCodeStructure::CREATE.0,
EcdhZGen = CommandCodeStructure::ECDH_Z_GEN.0,
Hmac = CommandCodeStructure::HMAC.0,
Import = CommandCodeStructure::IMPORT.0,
Load = CommandCodeStructure::LOAD.0,
Quote = CommandCodeStructure::QUOTE.0,
RsaDecrypt = CommandCodeStructure::RSA_DECRYPT.0,
HmacStart = CommandCodeStructure::HMAC_START.0,
SequenceUpdate = CommandCodeStructure::SEQUENCE_UPDATE.0,
Sign = CommandCodeStructure::SIGN.0,
Unseal = CommandCodeStructure::UNSEAL.0,
PolicySigned = CommandCodeStructure::POLICY_SIGNED.0,
ContextLoad = CommandCodeStructure::CONTEXT_LOAD.0,
ContextSave = CommandCodeStructure::CONTEXT_SAVE.0,
EcdhKeyGen = CommandCodeStructure::ECDH_KEY_GEN.0,
EncryptDecrypt = CommandCodeStructure::ENCRYPT_DECRYPT.0,
FlushContext = CommandCodeStructure::FLUSH_CONTEXT.0,
LoadExternal = CommandCodeStructure::LOAD_EXTERNAL.0,
MakeCredential = CommandCodeStructure::MAKE_CREDENTIAL.0,
NvReadPublic = CommandCodeStructure::NV_READ_PUBLIC.0,
PolicyAuthorize = CommandCodeStructure::POLICY_AUTHORIZE.0,
PolicyAuthValue = CommandCodeStructure::POLICY_AUTH_VALUE.0,
PolicyCommandCode = CommandCodeStructure::POLICY_COMMAND_CODE.0,
PolicyCounterTimer = CommandCodeStructure::POLICY_COUNTER_TIMER.0,
PolicyCpHash = CommandCodeStructure::POLICY_CP_HASH.0,
PolicyLocality = CommandCodeStructure::POLICY_LOCALITY.0,
PolicyNameHash = CommandCodeStructure::POLICY_NAME_HASH.0,
PolicyOr = CommandCodeStructure::POLICY_OR.0,
PolicyTicket = CommandCodeStructure::POLICY_TICKET.0,
ReadPublic = CommandCodeStructure::READ_PUBLIC.0,
RsaEncrypt = CommandCodeStructure::RSA_ENCRYPT.0,
StartAuthSession = CommandCodeStructure::START_AUTH_SESSION.0,
VerifySignature = CommandCodeStructure::VERIFY_SIGNATURE.0,
EccParameters = CommandCodeStructure::ECC_PARAMETERS.0,
FirmwareRead = CommandCodeStructure::FIRMWARE_READ.0,
GetCapability = CommandCodeStructure::GET_CAPABILITY.0,
GetRandom = CommandCodeStructure::GET_RANDOM.0,
GetTestResult = CommandCodeStructure::GET_TEST_RESULT.0,
Hash = CommandCodeStructure::HASH.0,
PcrRead = CommandCodeStructure::PCR_READ.0,
PolicyPcr = CommandCodeStructure::POLICY_PCR.0,
PolicyRestart = CommandCodeStructure::POLICY_RESTART.0,
ReadClock = CommandCodeStructure::READ_CLOCK.0,
PcrExtend = CommandCodeStructure::PCR_EXTEND.0,
PcrSetAuthValue = CommandCodeStructure::PCR_SET_AUTH_VALUE.0,
NvCertify = CommandCodeStructure::NV_CERTIFY.0,
EventSequenceComplete = CommandCodeStructure::EVENT_SEQUENCE_COMPLETE.0,
HashSequenceStart = CommandCodeStructure::HASH_SEQUENCE_START.0,
PolicyPhysicalPresence = CommandCodeStructure::POLICY_PHYSICAL_PRESENCE.0,
PolicyDuplicationSelect = CommandCodeStructure::POLICY_DUPLICATION_SELECT.0,
PolicyGetDigest = CommandCodeStructure::POLICY_GET_DIGEST.0,
TestParms = CommandCodeStructure::TEST_PARMS.0,
Commit = CommandCodeStructure::COMMIT.0,
PolicyPassword = CommandCodeStructure::POLICY_PASSWORD.0,
ZGen2Phase = CommandCodeStructure::Z_GEN_2_PHASE.0,
EcEphemeral = CommandCodeStructure::EC_EPHEMERAL.0,
PolicyNvWritten = CommandCodeStructure::POLICY_NV_WRITTEN.0,
PolicyTemplate = CommandCodeStructure::POLICY_TEMPLATE.0,
CreateLoaded = CommandCodeStructure::CREATE_LOADED.0,
PolicyAuthorizeNv = CommandCodeStructure::POLICY_AUTHORIZE_NV.0,
EncryptDecrypt2 = CommandCodeStructure::ENCRYPT_DECRYPT_2.0,
AcGetCapability = CommandCodeStructure::AC_GET_CAPABILITY.0,
AcSend = CommandCodeStructure::AC_SEND.0,
PolicyAcSendSelect = CommandCodeStructure::POLICY_AC_SEND_SELECT.0,
}
impl TryFrom for CommandCode {
type Error = Error;
fn try_from(tpm2_cc: TPM2_CC) -> Result {
CommandCode::from_u32(CommandCodeStructure::try_from(tpm2_cc)?.0).ok_or_else(|| {
error!("Value = {} did not match any Command Code", tpm2_cc);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
impl From for TPM2_CC {
fn from(command_code: CommandCode) -> Self {
// The values are well defined so this cannot fail.
command_code.to_u32().unwrap()
}
}
tss-esapi-7.4.0/src/constants/ecc.rs 0000644 0000000 0000000 00000003124 10461020230 0015447 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{
TPM2_ECC_BN_P256, TPM2_ECC_BN_P638, TPM2_ECC_NIST_P192, TPM2_ECC_NIST_P224,
TPM2_ECC_NIST_P256, TPM2_ECC_NIST_P384, TPM2_ECC_NIST_P521, TPM2_ECC_SM2_P256,
},
tss2_esys::TPM2_ECC_CURVE,
Error, Result, WrapperErrorKind,
};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
/// Enum that contains the constants for the
/// implemented elliptic curves.
///
/// # Details
/// This corresponds to `TPM2_ECC_CURVE`
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u16)]
pub enum EccCurveIdentifier {
NistP192 = TPM2_ECC_NIST_P192,
NistP224 = TPM2_ECC_NIST_P224,
NistP256 = TPM2_ECC_NIST_P256,
NistP384 = TPM2_ECC_NIST_P384,
NistP521 = TPM2_ECC_NIST_P521,
BnP256 = TPM2_ECC_BN_P256,
BnP638 = TPM2_ECC_BN_P638,
Sm2P256 = TPM2_ECC_SM2_P256,
}
impl From for TPM2_ECC_CURVE {
fn from(curve: EccCurveIdentifier) -> Self {
// The values are well defined so this cannot fail.
curve.to_u16().unwrap()
}
}
impl TryFrom for EccCurveIdentifier {
type Error = Error;
fn try_from(tpm2_ecc_curve: TPM2_ECC_CURVE) -> Result {
EccCurveIdentifier::from_u16(tpm2_ecc_curve).ok_or_else(|| {
error!("Value = {} did not match any ecc curve.", tpm2_ecc_curve);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
tss-esapi-7.4.0/src/constants/mod.rs 0000644 0000000 0000000 00000004340 10461020230 0015475 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
/// This module contains both the constants defined in the TSS specification (tss module)
/// but also the internal representation of the TSS constants.
/// Representation of the constants defined in the
/// Constants -> TPM_ALG_ID section of the specification
mod algorithm;
pub use algorithm::AlgorithmIdentifier;
/// The constants defined in the TSS specification.
#[allow(
non_snake_case,
non_camel_case_types,
non_upper_case_globals,
dead_code,
clippy::all
)]
/// Exposes the constants form the TSS header.
pub mod tss;
/// Representation of the constants defined in the
/// Constants -> TPM_ST section of the specification
pub mod structure_tags;
/// Representation of the constants defined in the
/// Constants -> TPM_PT section of the specification
pub mod property_tag;
/// Representation of the constants defined in the
/// Constants -> TPM_SU section of the specification
pub mod startup_type;
/// Representation of the constants defined in the
/// Constants -> TPM_SE section of the specification
pub mod session_type;
/// Representation of the constants defined in the
/// Constants -> TPM_CAP section of the specification
pub mod capabilities;
/// Representation of the return code TSS2_RC (TPM_RC)
pub mod response_code;
/// Representation of the constants defined in the
/// NV Storage -> TPM_NT section of the specification
pub mod nv_index_type;
/// Representation of the constants defined in
/// Constants -> TPM_ECC_CURVE section of the specification.
pub mod ecc;
/// Representation of the constants defined in
/// Constants -> TPM_CC section of the specification.
pub mod command_code;
/// Representation of the constants defined in
/// Constants -> TPM_PT_PCR section of the specification.
pub mod pcr_property_tag;
pub use capabilities::CapabilityType;
pub use command_code::CommandCode;
pub use ecc::EccCurveIdentifier;
pub use nv_index_type::NvIndexType;
pub use pcr_property_tag::PcrPropertyTag;
pub use property_tag::PropertyTag;
pub use response_code::{ResponseCode, Tss2ResponseCode, Tss2ResponseCodeKind};
pub use session_type::SessionType;
pub use startup_type::StartupType;
pub use structure_tags::StructureTag;
tss-esapi-7.4.0/src/constants/nv_index_type.rs 0000644 0000000 0000000 00000003272 10461020230 0017574 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{
TPM2_NT_BITS, TPM2_NT_COUNTER, TPM2_NT_EXTEND, TPM2_NT_ORDINARY, TPM2_NT_PIN_FAIL,
TPM2_NT_PIN_PASS,
},
tss2_esys::TPM2_NT,
Error, Result, WrapperErrorKind,
};
use log::error;
use std::convert::TryFrom;
/// Enum with values representing the NV index type.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum NvIndexType {
Ordinary,
Counter,
Bits,
Extend,
PinFail,
PinPass,
}
impl From for TPM2_NT {
fn from(nv_index_type: NvIndexType) -> TPM2_NT {
match nv_index_type {
NvIndexType::Ordinary => TPM2_NT_ORDINARY,
NvIndexType::Counter => TPM2_NT_COUNTER,
NvIndexType::Bits => TPM2_NT_BITS,
NvIndexType::Extend => TPM2_NT_EXTEND,
NvIndexType::PinFail => TPM2_NT_PIN_FAIL,
NvIndexType::PinPass => TPM2_NT_PIN_PASS,
}
}
}
impl TryFrom for NvIndexType {
type Error = Error;
fn try_from(tss_nv_index_type: TPM2_NT) -> Result {
match tss_nv_index_type {
TPM2_NT_ORDINARY => Ok(NvIndexType::Ordinary),
TPM2_NT_COUNTER => Ok(NvIndexType::Counter),
TPM2_NT_BITS => Ok(NvIndexType::Bits),
TPM2_NT_EXTEND => Ok(NvIndexType::Extend),
TPM2_NT_PIN_FAIL => Ok(NvIndexType::PinFail),
TPM2_NT_PIN_PASS => Ok(NvIndexType::PinPass),
_ => {
error!("Found invalid value when trying to parse Nv Index Type");
Err(Error::local_error(WrapperErrorKind::InvalidParam))
}
}
}
}
tss-esapi-7.4.0/src/constants/pcr_property_tag.rs 0000644 0000000 0000000 00000003671 10461020230 0020307 0 ustar 0000000 0000000 // Copyright 2022 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{
TPM2_PT_PCR_AUTH, TPM2_PT_PCR_DRTM_RESET, TPM2_PT_PCR_EXTEND_L0, TPM2_PT_PCR_EXTEND_L1,
TPM2_PT_PCR_EXTEND_L2, TPM2_PT_PCR_EXTEND_L3, TPM2_PT_PCR_EXTEND_L4,
TPM2_PT_PCR_NO_INCREMENT, TPM2_PT_PCR_POLICY, TPM2_PT_PCR_RESET_L0, TPM2_PT_PCR_RESET_L1,
TPM2_PT_PCR_RESET_L2, TPM2_PT_PCR_RESET_L3, TPM2_PT_PCR_RESET_L4, TPM2_PT_PCR_SAVE,
},
tss2_esys::TPM2_PT_PCR,
Error, Result, WrapperErrorKind,
};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum PcrPropertyTag {
Save = TPM2_PT_PCR_SAVE,
ExtendL0 = TPM2_PT_PCR_EXTEND_L0,
ResetL0 = TPM2_PT_PCR_RESET_L0,
ExtendL1 = TPM2_PT_PCR_EXTEND_L1,
ResetL1 = TPM2_PT_PCR_RESET_L1,
ExtendL2 = TPM2_PT_PCR_EXTEND_L2,
ResetL2 = TPM2_PT_PCR_RESET_L2,
ExtendL3 = TPM2_PT_PCR_EXTEND_L3,
ResetL3 = TPM2_PT_PCR_RESET_L3,
ExtendL4 = TPM2_PT_PCR_EXTEND_L4,
ResetL4 = TPM2_PT_PCR_RESET_L4,
// Reserved 0x0000000B – 0x00000010
NoIncrement = TPM2_PT_PCR_NO_INCREMENT,
DrtmReset = TPM2_PT_PCR_DRTM_RESET,
Policy = TPM2_PT_PCR_POLICY,
Auth = TPM2_PT_PCR_AUTH,
}
impl From for TPM2_PT_PCR {
fn from(pcr_property_tag: PcrPropertyTag) -> Self {
// The values are well defined so this cannot fail.
pcr_property_tag.to_u32().unwrap()
}
}
impl TryFrom for PcrPropertyTag {
type Error = Error;
fn try_from(tpm_pt_pcr: TPM2_PT_PCR) -> Result {
PcrPropertyTag::from_u32(tpm_pt_pcr).ok_or_else(|| {
error!("value = {} did not match any PcrPropertyTag.", tpm_pt_pcr);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
tss-esapi-7.4.0/src/constants/property_tag.rs 0000644 0000000 0000000 00000007407 10461020230 0017444 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{constants::tss::*, tss2_esys::TPM2_PT, Error, Result, WrapperErrorKind};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
#[derive(FromPrimitive, ToPrimitive, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum PropertyTag {
None = TPM2_PT_NONE,
// Fixed
FamilyIndicator = TPM2_PT_FAMILY_INDICATOR,
Level = TPM2_PT_LEVEL,
Revision = TPM2_PT_REVISION,
DayOfYear = TPM2_PT_DAY_OF_YEAR,
Year = TPM2_PT_YEAR,
Manufacturer = TPM2_PT_MANUFACTURER,
VendorString1 = TPM2_PT_VENDOR_STRING_1,
VendorString2 = TPM2_PT_VENDOR_STRING_2,
VendorString3 = TPM2_PT_VENDOR_STRING_3,
VendorString4 = TPM2_PT_VENDOR_STRING_4,
VendorTPMType = TPM2_PT_VENDOR_TPM_TYPE,
FirmwareVersion1 = TPM2_PT_FIRMWARE_VERSION_1,
FirmwareVersion2 = TPM2_PT_FIRMWARE_VERSION_2,
InputBuffer = TPM2_PT_INPUT_BUFFER,
HrTransientMin = TPM2_PT_HR_TRANSIENT_MIN,
HrPersistentMin = TPM2_PT_HR_PERSISTENT_MIN,
HrLoadedMin = TPM2_PT_HR_LOADED_MIN,
ActiveSessionsMax = TPM2_PT_ACTIVE_SESSIONS_MAX,
PcrCount = TPM2_PT_PCR_COUNT,
PcrSelectMin = TPM2_PT_PCR_SELECT_MIN,
ContextGapMax = TPM2_PT_CONTEXT_GAP_MAX,
NvCountersMax = TPM2_PT_NV_COUNTERS_MAX,
NvIndexMax = TPM2_PT_NV_INDEX_MAX,
Memory = TPM2_PT_MEMORY,
ClockUpdate = TPM2_PT_CLOCK_UPDATE,
ContextHash = TPM2_PT_CONTEXT_HASH,
ContextSym = TPM2_PT_CONTEXT_SYM,
ContextSymSize = TPM2_PT_CONTEXT_SYM_SIZE,
OrderlyCount = TPM2_PT_ORDERLY_COUNT,
MaxCommandSize = TPM2_PT_MAX_COMMAND_SIZE,
MaxResponseSize = TPM2_PT_MAX_RESPONSE_SIZE,
MaxDigest = TPM2_PT_MAX_DIGEST,
MaxObjectContext = TPM2_PT_MAX_OBJECT_CONTEXT,
MaxSessionContext = TPM2_PT_MAX_SESSION_CONTEXT,
PsFamilyIndicator = TPM2_PT_PS_FAMILY_INDICATOR,
PsLevel = TPM2_PT_PS_LEVEL,
PsRevision = TPM2_PT_PS_REVISION,
PsDayOfYear = TPM2_PT_PS_DAY_OF_YEAR,
PsYear = TPM2_PT_PS_YEAR,
SplitMax = TPM2_PT_SPLIT_MAX,
TotalCommands = TPM2_PT_TOTAL_COMMANDS,
LibraryCommands = TPM2_PT_LIBRARY_COMMANDS,
VendorCommands = TPM2_PT_VENDOR_COMMANDS,
NvBufferMax = TPM2_PT_NV_BUFFER_MAX,
Modes = TPM2_PT_MODES,
MaxCapBuffer = TPM2_PT_MAX_CAP_BUFFER,
// Variable
Permanent = TPM2_PT_PERMANENT,
StartupClear = TPM2_PT_STARTUP_CLEAR,
HrNvIndex = TPM2_PT_HR_NV_INDEX,
HrLoaded = TPM2_PT_HR_LOADED,
HrLoadedAvail = TPM2_PT_HR_LOADED_AVAIL,
HrActive = TPM2_PT_HR_ACTIVE,
HrActiveAvail = TPM2_PT_HR_ACTIVE_AVAIL,
HrTransientAvail = TPM2_PT_HR_TRANSIENT_AVAIL,
HrPersistent = TPM2_PT_HR_PERSISTENT,
HrPersistentAvail = TPM2_PT_HR_PERSISTENT_AVAIL,
NvCounters = TPM2_PT_NV_COUNTERS,
NvCountersAvail = TPM2_PT_NV_COUNTERS_AVAIL,
AlgorithmSet = TPM2_PT_ALGORITHM_SET,
LoadedCurves = TPM2_PT_LOADED_CURVES,
LockoutCounter = TPM2_PT_LOCKOUT_COUNTER,
MaxAuthFail = TPM2_PT_MAX_AUTH_FAIL,
LockoutInterval = TPM2_PT_LOCKOUT_INTERVAL,
LockoutRecovery = TPM2_PT_LOCKOUT_RECOVERY,
WriteRecovery = TPM2_PT_NV_WRITE_RECOVERY,
AuditCounter0 = TPM2_PT_AUDIT_COUNTER_0,
AuditCounter1 = TPM2_PT_AUDIT_COUNTER_1,
}
impl From for TPM2_PT {
fn from(property_tag: PropertyTag) -> TPM2_PT {
// The values are well defined so this cannot fail.
property_tag.to_u32().unwrap()
}
}
impl TryFrom for PropertyTag {
type Error = Error;
fn try_from(tpm_pt: TPM2_PT) -> Result {
PropertyTag::from_u32(tpm_pt).ok_or_else(|| {
error!("value = {} did not match any PropertyTag.", tpm_pt);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
tss-esapi-7.4.0/src/constants/response_code.rs 0000644 0000000 0000000 00000065140 10461020230 0017553 0 ustar 0000000 0000000 // Copyright 2019 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
//! Module for error types
//!
//! This module provides the error reporting framework for the crate. Error provenience is marked
//! as a variant of an enum, distinguishing between errors coming from the TSS stack and those
//! generated by this crate.
use crate::tss2_esys::TSS2_RC;
use bitfield::bitfield;
bitfield! {
pub struct ResponseCode(TSS2_RC);
impl Debug;
format_selector, _: 7;
}
bitfield! {
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct FormatZeroResponseCode(TSS2_RC);
impl Debug;
error_number, _: 6, 0;
format_selector, _: 7;
version, _: 8;
tcg_vendor_indicator, _: 10;
severity, _: 11;
}
impl std::fmt::Display for FormatZeroResponseCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Display response code as "Response code value: 0xdeadbeef"
write!(f, "Response code value: {:#x}", self.0)
}
}
impl std::error::Error for FormatZeroResponseCode {}
bitfield! {
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct FormatOneResponseCode(TSS2_RC);
impl Debug;
error_number, _: 5, 0;
parameter, _: 6;
format_selector, _: 7;
number, _: 11, 8;
}
impl std::fmt::Display for FormatOneResponseCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Display response code as "Response code value: 0xdeadbeef"
write!(f, "Response code value: {:#x}", self.0)
}
}
impl std::error::Error for FormatOneResponseCode {}
/// Rust native representation of the TSS2 response codes as defined in the spec.
#[allow(clippy::module_name_repetitions)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Tss2ResponseCode {
Success,
FormatZero(FormatZeroResponseCode),
FormatOne(FormatOneResponseCode),
}
impl Tss2ResponseCode {
/// Generate a `Tss2ResponseCode` from a TSS error
pub(crate) fn from_tss_rc(response_code: TSS2_RC) -> Self {
if response_code == 0 {
Tss2ResponseCode::Success
} else if ResponseCode(response_code).format_selector() {
// The response code is in Format-One.
Tss2ResponseCode::FormatOne(FormatOneResponseCode(response_code))
} else {
// The response code is in Format-Zero.
Tss2ResponseCode::FormatZero(FormatZeroResponseCode(response_code))
}
}
/// Check whether the response code is successful
pub fn is_success(self) -> bool {
self == Tss2ResponseCode::Success
}
fn is_warning(self) -> bool {
match self {
Tss2ResponseCode::Success => false,
Tss2ResponseCode::FormatZero(rc) => rc.severity(),
Tss2ResponseCode::FormatOne(_) => false,
}
}
fn error_number(self) -> u32 {
match self {
Tss2ResponseCode::Success => 0,
Tss2ResponseCode::FormatZero(rc) => rc.error_number(),
Tss2ResponseCode::FormatOne(rc) => rc.error_number(),
}
}
fn get_associated_number_message(self) -> String {
if let Tss2ResponseCode::FormatOne(rc) = self {
if rc.parameter() {
format!("associated with parameter number {}", rc.number())
} else if rc.number() <= 0b0111 {
format!("associated with handle number {}", rc.number())
} else {
format!("associated with session number {}", rc.number() - 8)
}
} else {
String::from("no associated message")
}
}
/// Get the error code as an enum variant.
pub fn kind(self) -> Option {
match self {
Tss2ResponseCode::Success => Some(Tss2ResponseCodeKind::Success),
Tss2ResponseCode::FormatZero(rc) => {
if rc.tcg_vendor_indicator() {
Some(Tss2ResponseCodeKind::TpmVendorSpecific)
} else if self.is_warning() {
// Warnings
match self.error_number() {
0x001 => Some(Tss2ResponseCodeKind::ContextGap),
0x002 => Some(Tss2ResponseCodeKind::ObjectMemory),
0x003 => Some(Tss2ResponseCodeKind::SessionMemory),
0x004 => Some(Tss2ResponseCodeKind::Memory),
0x005 => Some(Tss2ResponseCodeKind::SessionHandles),
0x006 => Some(Tss2ResponseCodeKind::ObjectHandles),
0x007 => Some(Tss2ResponseCodeKind::Locality),
0x008 => Some(Tss2ResponseCodeKind::Yielded),
0x009 => Some(Tss2ResponseCodeKind::Canceled),
0x00A => Some(Tss2ResponseCodeKind::Testing),
0x010 => Some(Tss2ResponseCodeKind::ReferenceH0),
0x011 => Some(Tss2ResponseCodeKind::ReferenceH1),
0x012 => Some(Tss2ResponseCodeKind::ReferenceH2),
0x013 => Some(Tss2ResponseCodeKind::ReferenceH3),
0x014 => Some(Tss2ResponseCodeKind::ReferenceH4),
0x015 => Some(Tss2ResponseCodeKind::ReferenceH5),
0x016 => Some(Tss2ResponseCodeKind::ReferenceH6),
0x018 => Some(Tss2ResponseCodeKind::ReferenceS0),
0x019 => Some(Tss2ResponseCodeKind::ReferenceS1),
0x01A => Some(Tss2ResponseCodeKind::ReferenceS2),
0x01B => Some(Tss2ResponseCodeKind::ReferenceS3),
0x01C => Some(Tss2ResponseCodeKind::ReferenceS4),
0x01D => Some(Tss2ResponseCodeKind::ReferenceS5),
0x01E => Some(Tss2ResponseCodeKind::ReferenceS6),
0x020 => Some(Tss2ResponseCodeKind::NvRate),
0x021 => Some(Tss2ResponseCodeKind::Lockout),
0x022 => Some(Tss2ResponseCodeKind::Retry),
0x023 => Some(Tss2ResponseCodeKind::NvUnavailable),
_ => None,
}
} else {
// Errors
match self.error_number() {
0x000 => Some(Tss2ResponseCodeKind::Initialize),
0x001 => Some(Tss2ResponseCodeKind::Failure),
0x003 => Some(Tss2ResponseCodeKind::Sequence),
0x00B => Some(Tss2ResponseCodeKind::Private),
0x019 => Some(Tss2ResponseCodeKind::Hmac),
0x020 => Some(Tss2ResponseCodeKind::Disabled),
0x021 => Some(Tss2ResponseCodeKind::Exclusive),
0x024 => Some(Tss2ResponseCodeKind::AuthType),
0x025 => Some(Tss2ResponseCodeKind::AuthMissing),
0x026 => Some(Tss2ResponseCodeKind::Policy),
0x027 => Some(Tss2ResponseCodeKind::Pcr),
0x028 => Some(Tss2ResponseCodeKind::PcrChanged),
0x02D => Some(Tss2ResponseCodeKind::Upgrade),
0x02E => Some(Tss2ResponseCodeKind::TooManyContexts),
0x02F => Some(Tss2ResponseCodeKind::AuthUnavailable),
0x030 => Some(Tss2ResponseCodeKind::Reboot),
0x031 => Some(Tss2ResponseCodeKind::Unbalanced),
0x042 => Some(Tss2ResponseCodeKind::CommandSize),
0x043 => Some(Tss2ResponseCodeKind::CommandCode),
0x044 => Some(Tss2ResponseCodeKind::AuthSize),
0x045 => Some(Tss2ResponseCodeKind::AuthContext),
0x046 => Some(Tss2ResponseCodeKind::NvRange),
0x047 => Some(Tss2ResponseCodeKind::NvSize),
0x048 => Some(Tss2ResponseCodeKind::NvLocked),
0x049 => Some(Tss2ResponseCodeKind::NvAuthorization),
0x04A => Some(Tss2ResponseCodeKind::NvUninitialized),
0x04B => Some(Tss2ResponseCodeKind::NvSpace),
0x04C => Some(Tss2ResponseCodeKind::NvDefined),
0x050 => Some(Tss2ResponseCodeKind::BadContext),
0x051 => Some(Tss2ResponseCodeKind::CpHash),
0x052 => Some(Tss2ResponseCodeKind::Parent),
0x053 => Some(Tss2ResponseCodeKind::NeedsTest),
0x054 => Some(Tss2ResponseCodeKind::NoResult),
0x055 => Some(Tss2ResponseCodeKind::Sensitive),
_ => None,
}
}
}
Tss2ResponseCode::FormatOne(_) => match self.error_number() {
0x001 => Some(Tss2ResponseCodeKind::Asymmetric),
0x002 => Some(Tss2ResponseCodeKind::Attributes),
0x003 => Some(Tss2ResponseCodeKind::Hash),
0x004 => Some(Tss2ResponseCodeKind::Value),
0x005 => Some(Tss2ResponseCodeKind::Hierarchy),
0x007 => Some(Tss2ResponseCodeKind::KeySize),
0x008 => Some(Tss2ResponseCodeKind::Mgf),
0x009 => Some(Tss2ResponseCodeKind::Mode),
0x00A => Some(Tss2ResponseCodeKind::Type),
0x00B => Some(Tss2ResponseCodeKind::Handle),
0x00C => Some(Tss2ResponseCodeKind::Kdf),
0x00D => Some(Tss2ResponseCodeKind::Range),
0x00E => Some(Tss2ResponseCodeKind::AuthFail),
0x00F => Some(Tss2ResponseCodeKind::Nonce),
0x010 => Some(Tss2ResponseCodeKind::Pp),
0x012 => Some(Tss2ResponseCodeKind::Scheme),
0x015 => Some(Tss2ResponseCodeKind::Size),
0x016 => Some(Tss2ResponseCodeKind::Symmetric),
0x017 => Some(Tss2ResponseCodeKind::Tag),
0x018 => Some(Tss2ResponseCodeKind::Selector),
0x01A => Some(Tss2ResponseCodeKind::Insufficient),
0x01B => Some(Tss2ResponseCodeKind::Signature),
0x01C => Some(Tss2ResponseCodeKind::Key),
0x01D => Some(Tss2ResponseCodeKind::PolicyFail),
0x01F => Some(Tss2ResponseCodeKind::Integrity),
0x020 => Some(Tss2ResponseCodeKind::Ticket),
0x021 => Some(Tss2ResponseCodeKind::ReservedBits),
0x022 => Some(Tss2ResponseCodeKind::BadAuth),
0x023 => Some(Tss2ResponseCodeKind::Expired),
0x024 => Some(Tss2ResponseCodeKind::PolicyCc),
0x025 => Some(Tss2ResponseCodeKind::Binding),
0x026 => Some(Tss2ResponseCodeKind::Curve),
0x027 => Some(Tss2ResponseCodeKind::EccPoint),
_ => None,
},
}
}
}
/// Rust enum representation of TSS 2 error codes.
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Tss2ResponseCodeKind {
// FormatZero errors
Success,
TpmVendorSpecific,
Initialize,
Failure,
Sequence,
Private,
Hmac,
Disabled,
Exclusive,
AuthType,
AuthMissing,
Policy,
Pcr,
PcrChanged,
Upgrade,
TooManyContexts,
AuthUnavailable,
Reboot,
Unbalanced,
CommandSize,
CommandCode,
AuthSize,
AuthContext,
NvRange,
NvSize,
NvLocked,
NvAuthorization,
NvUninitialized,
NvSpace,
NvDefined,
BadContext,
CpHash,
Parent,
NeedsTest,
NoResult,
Sensitive,
// FormatOne errors
Asymmetric,
Attributes,
Hash,
Value,
Hierarchy,
KeySize,
Mgf,
Mode,
Type,
Handle,
Kdf,
Range,
AuthFail,
Nonce,
Pp,
Scheme,
Size,
Symmetric,
Tag,
Selector,
Insufficient,
Signature,
Key,
PolicyFail,
Integrity,
Ticket,
ReservedBits,
BadAuth,
Expired,
PolicyCc,
Binding,
Curve,
EccPoint,
// Warnings
ContextGap,
ObjectMemory,
SessionMemory,
Memory,
SessionHandles,
ObjectHandles,
Locality,
Yielded,
Canceled,
Testing,
ReferenceH0,
ReferenceH1,
ReferenceH2,
ReferenceH3,
ReferenceH4,
ReferenceH5,
ReferenceH6,
ReferenceS0,
ReferenceS1,
ReferenceS2,
ReferenceS3,
ReferenceS4,
ReferenceS5,
ReferenceS6,
NvRate,
Lockout,
Retry,
NvUnavailable,
}
impl std::fmt::Display for Tss2ResponseCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let kind = self.kind();
if kind.is_none() {
return write!(f, "response code not recognized");
}
match self.kind().unwrap() { // should not panic, given the check above
Tss2ResponseCodeKind::Success => write!(f, "success"),
Tss2ResponseCodeKind::TpmVendorSpecific => write!(f, "vendor specific error: {}", self.error_number()),
// Format Zero
Tss2ResponseCodeKind::Initialize => write!(f, "TPM not initialized by TPM2_Startup or already initialized"),
Tss2ResponseCodeKind::Failure => write!(f, "commands not being accepted because of a TPM failure. NOTE: This may be returned by TPM2_GetTestResult() as the testResultparameter"),
Tss2ResponseCodeKind::Sequence => write!(f, "improper use of a sequence handle"),
Tss2ResponseCodeKind::Private => write!(f, "not currently used"),
Tss2ResponseCodeKind::Hmac => write!(f, "not currently used"),
Tss2ResponseCodeKind::Disabled => write!(f, "the command is disabled"),
Tss2ResponseCodeKind::Exclusive => write!(f, "command failed because audit sequence required exclusivity"),
Tss2ResponseCodeKind::AuthType => write!(f, "authorization handle is not correct for command"),
Tss2ResponseCodeKind::AuthMissing => write!(f, "command requires an authorization session for handle and it is not present"),
Tss2ResponseCodeKind::Policy => write!(f, "policy failure in math operation or an invalid authPolicy value"),
Tss2ResponseCodeKind::Pcr => write!(f, "PCR check fail"),
Tss2ResponseCodeKind::PcrChanged => write!(f, "PCR have changed since checked"),
Tss2ResponseCodeKind::Upgrade => write!(f, "for all commands other than TPM2_FieldUpgradeData(), this code indicates that the TPM is in field upgrade mode; for TPM2_FieldUpgradeData(), this code indicates that the TPM is not in field upgrade mode"),
Tss2ResponseCodeKind::TooManyContexts => write!(f, "context ID counter is at maximum"),
Tss2ResponseCodeKind::AuthUnavailable => write!(f, "authValue or authPolicy is not available for selected entity"),
Tss2ResponseCodeKind::Reboot => write!(f, "a _TPM_Init and Startup(CLEAR) is required before the TPM can resume operation"),
Tss2ResponseCodeKind::Unbalanced => write!(f, "the protection algorithms (hash and symmetric) are not reasonably balanced. The digest size of the hash must be larger than the key size of the symmetric algorithm"),
Tss2ResponseCodeKind::CommandSize => write!(f, "command commandSizevalue is inconsistent with contents of the command buffer; either the size is not the same as the octets loaded by the hardware interface layer or the value is not large enough to hold a command header"),
Tss2ResponseCodeKind::CommandCode => write!(f, "command code not supported"),
Tss2ResponseCodeKind::AuthSize => write!(f, "the value of authorizationSizeis out of range or the number of octets in the Authorization Area is greater than required"),
Tss2ResponseCodeKind::AuthContext => write!(f, "use of an authorization session with a context command or another command that cannot have an authorization session"),
Tss2ResponseCodeKind::NvRange => write!(f, "NV offset+size is out of range"),
Tss2ResponseCodeKind::NvSize => write!(f, "Requested allocation size is larger than allowed"),
Tss2ResponseCodeKind::NvLocked => write!(f, "NV access locked"),
Tss2ResponseCodeKind::NvAuthorization => write!(f, "NV access authorization fails in command actions (this failure does not affect lockout.action)"),
Tss2ResponseCodeKind::NvUninitialized => write!(f, "an NV Index is used before being initialized or the state saved by TPM2_Shutdown(STATE) could not be restored"),
Tss2ResponseCodeKind::NvSpace => write!(f, "insufficient space for NV allocation"),
Tss2ResponseCodeKind::NvDefined => write!(f, "NV Index or persistent object already defined"),
Tss2ResponseCodeKind::BadContext => write!(f, "context in TPM2_ContextLoad() is not valid"),
Tss2ResponseCodeKind::CpHash => write!(f, "cpHash value already set or not correct for use"),
Tss2ResponseCodeKind::Parent => write!(f, "handle for parent is not a valid parent"),
Tss2ResponseCodeKind::NeedsTest => write!(f, "some function needs testing."),
Tss2ResponseCodeKind::NoResult => write!(f, "returned when an internal function cannot process a request due to an unspecified problem. This code is usually related to invalid parameters that are not properly filtered by the input unmarshaling code."),
Tss2ResponseCodeKind::Sensitive => write!(f, "the sensitive area did not unmarshal correctly after decryption – this code is used in lieu of the other unmarshaling errors so that an attacker cannot determine where the unmarshaling error occurred"),
// Warnings
Tss2ResponseCodeKind::ContextGap => write!(f, "gap for context ID is too large"),
Tss2ResponseCodeKind::ObjectMemory => write!(f, "out of memory for object contexts"),
Tss2ResponseCodeKind::SessionMemory => write!(f, "out of memory for session contexts"),
Tss2ResponseCodeKind::Memory => write!(f, "out of shared object/session memory or need space for internal operations"),
Tss2ResponseCodeKind::SessionHandles => write!(f, "out of session handles – a session must be flushed before a new session may be created"),
Tss2ResponseCodeKind::ObjectHandles => write!(f, "out of object handles – the handle space for objects is depleted and a reboot is required. NOTE 1: This cannot occur on the reference implementation. NOTE 2: There is no reason why an implementation would implement a design that would delete handle space. Platform specifications are encouraged to forbid it."),
Tss2ResponseCodeKind::Locality => write!(f, "bad locality"),
Tss2ResponseCodeKind::Yielded => write!(f, "the TPM has suspended operation on the command; forward progress was made and the command may be retried. See TPM 2.0 Part 1, “Multi-tasking.” NOTE: This cannot occur on the reference implementation."),
Tss2ResponseCodeKind::Canceled => write!(f, "the command was canceled"),
Tss2ResponseCodeKind::Testing => write!(f, "TPM is performing self-tests"),
Tss2ResponseCodeKind::ReferenceH0 => write!(f, "the 1st handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceH1 => write!(f, "the 2nd handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceH2 => write!(f, "the 3rd handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceH3 => write!(f, "the 4th handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceH4 => write!(f, "the 5th handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceH5 => write!(f, "the 6th handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceH6 => write!(f, "the 7th handle in the handle area references a transient object or session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS0 => write!(f, "the 1st authorization session handle references a session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS1 => write!(f, "the 2nd authorization session handle references a session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS2 => write!(f, "the 3rd authorization session handle references a session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS3 => write!(f, "the 4th authorization session handle references a session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS4 => write!(f, "the 5th session handle references a session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS5 => write!(f, "the 6th session handle references a session that is not loaded"),
Tss2ResponseCodeKind::ReferenceS6 => write!(f, "the 7th authorization session handle references a session that is not loaded"),
Tss2ResponseCodeKind::NvRate => write!(f, "the TPM is rate-limiting accesses to prevent wearout of NV"),
Tss2ResponseCodeKind::Lockout => write!(f, "authorizations for objects subject to DA protection are not allowed at this time because the TPM is in DA lockout mode"),
Tss2ResponseCodeKind::Retry => write!(f, "the TPM was not able to start the command"),
Tss2ResponseCodeKind::NvUnavailable => write!(f, "the command may require writing of NV and NV is not current accessible"),
// Format-One
Tss2ResponseCodeKind::Asymmetric => write!(f, "asymmetric algorithm not supported or not correct ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Attributes => write!(f, "inconsistent attributes ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Hash => write!(f, "hash algorithm not supported or not appropriate ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Value => write!(f, "value is out of range or is not correct for the context ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Hierarchy => write!(f, "hierarchy is not enabled or is not correct for the use ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::KeySize => write!(f, "key size is not supported ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Mgf => write!(f, "mask generation function not supported ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Mode => write!(f, "mode of operation not supported ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Type => write!(f, "the type of the value is not appropriate for the use ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Handle => write!(f, "the handle is not correct for the use ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Kdf => write!(f, "unsupported key derivation function or function not appropriate for use ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Range => write!(f, "value was out of allowed range. ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::AuthFail => write!(f, "the authorization HMAC check failed and DA counter incremented ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Nonce => write!(f, "invalid nonce size or nonce value mismatch ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Pp => write!(f, "authorization requires assertion of PP ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Scheme => write!(f, "unsupported or incompatible scheme ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Size => write!(f, "structure is the wrong size ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Symmetric => write!(f, "unsupported symmetric algorithm or key size, or not appropriate for instance ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Tag => write!(f, "incorrect structure tag ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Selector => write!(f, "union selector is incorrect ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Insufficient => write!(f, "the TPM was unable to unmarshal a value because there were not enough octets in the input buffer ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Signature => write!(f, "the signature is not valid ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Key => write!(f, "key fields are not compatible with the selected use ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::PolicyFail => write!(f, "a policy check failed ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Integrity => write!(f, "integrity check failed ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Ticket => write!(f, "invalid ticket ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::ReservedBits => write!(f, "reserved bits not set to zero as required ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::BadAuth => write!(f, "authorization failure without DA implications ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Expired => write!(f, "the policy has expired ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::PolicyCc => write!(f, "the command Code in the policy is not the command Code of the command or the command code in a policy command references a command that is not implemented ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Binding => write!(f, "public and sensitive portions of an object are not cryptographically bound ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::Curve => write!(f, "curve not supported ({})", self.get_associated_number_message()),
Tss2ResponseCodeKind::EccPoint => write!(f, "point is not on the required curve ({})", self.get_associated_number_message()),
}
}
}
impl From for Tss2ResponseCode {
fn from(rc: TSS2_RC) -> Self {
Tss2ResponseCode::from_tss_rc(rc)
}
}
impl std::error::Error for Tss2ResponseCode {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Tss2ResponseCode::FormatOne(response_code) => Some(response_code),
Tss2ResponseCode::FormatZero(response_code) => Some(response_code),
Tss2ResponseCode::Success => None,
}
}
}
tss-esapi-7.4.0/src/constants/session_type.rs 0000644 0000000 0000000 00000002306 10461020230 0017442 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{TPM2_SE_HMAC, TPM2_SE_POLICY, TPM2_SE_TRIAL},
tss2_esys::TPM2_SE,
Error, Result, WrapperErrorKind,
};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
/// Enum representing the different TPM session types.
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum SessionType {
Hmac = TPM2_SE_HMAC,
Policy = TPM2_SE_POLICY,
Trial = TPM2_SE_TRIAL,
}
impl From for TPM2_SE {
fn from(session_type: SessionType) -> TPM2_SE {
// The values are well defined so this cannot fail.
session_type.to_u8().unwrap()
}
}
impl TryFrom for SessionType {
type Error = Error;
fn try_from(tpm_session_type: TPM2_SE) -> Result {
SessionType::from_u8(tpm_session_type).ok_or_else(|| {
error!(
"value = {} did not match any SessionType.",
tpm_session_type
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
tss-esapi-7.4.0/src/constants/startup_type.rs 0000644 0000000 0000000 00000002242 10461020230 0017460 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::tss::{TPM2_SU_CLEAR, TPM2_SU_STATE},
tss2_esys::TPM2_SU,
Error, Result, WrapperErrorKind,
};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
/// Enum repsenting the different TPM Startup Type values.
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u16)]
pub enum StartupType {
Clear = TPM2_SU_CLEAR,
State = TPM2_SU_STATE,
}
impl From for TPM2_SU {
fn from(startup_type: StartupType) -> TPM2_SU {
// The values are well defined so this cannot fail.
startup_type.to_u16().unwrap()
}
}
impl TryFrom for StartupType {
type Error = Error;
fn try_from(tpm_startup_type: TPM2_SU) -> Result {
StartupType::from_u16(tpm_startup_type).ok_or_else(|| {
error!(
"value = {} did not match any StartupType.",
tpm_startup_type
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
tss-esapi-7.4.0/src/constants/structure_tags.rs 0000644 0000000 0000000 00000004436 10461020230 0020002 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::constants::tss::{
TPM2_ST_ATTEST_CERTIFY, TPM2_ST_ATTEST_COMMAND_AUDIT, TPM2_ST_ATTEST_CREATION,
TPM2_ST_ATTEST_NV, TPM2_ST_ATTEST_NV_DIGEST, TPM2_ST_ATTEST_QUOTE,
TPM2_ST_ATTEST_SESSION_AUDIT, TPM2_ST_ATTEST_TIME, TPM2_ST_AUTH_SECRET, TPM2_ST_AUTH_SIGNED,
TPM2_ST_CREATION, TPM2_ST_FU_MANIFEST, TPM2_ST_HASHCHECK, TPM2_ST_NO_SESSIONS, TPM2_ST_NULL,
TPM2_ST_RSP_COMMAND, TPM2_ST_SESSIONS, TPM2_ST_VERIFIED,
};
use crate::{tss2_esys::TPM2_ST, Error, Result, WrapperErrorKind};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryFrom;
/// This enum represents the TPM_ST (Structure Tags)
#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(u16)]
pub enum StructureTag {
RspCommand = TPM2_ST_RSP_COMMAND,
Null = TPM2_ST_NULL,
NoSessions = TPM2_ST_NO_SESSIONS,
Sessions = TPM2_ST_SESSIONS,
// Reserved1 = TPM2_ST_RESERVED1,
// Reserved2 = TPM2_ST_RESERVED2,
AttestNv = TPM2_ST_ATTEST_NV,
AttestCommandAudit = TPM2_ST_ATTEST_COMMAND_AUDIT,
AttestSessionAudit = TPM2_ST_ATTEST_SESSION_AUDIT,
AttestCertify = TPM2_ST_ATTEST_CERTIFY,
AttestQuote = TPM2_ST_ATTEST_QUOTE,
AttestTime = TPM2_ST_ATTEST_TIME,
AttestCreation = TPM2_ST_ATTEST_CREATION,
// Reserved3 = TPM2_ST_RESERVED3,
AttestNvDigest = TPM2_ST_ATTEST_NV_DIGEST,
Creation = TPM2_ST_CREATION,
Verified = TPM2_ST_VERIFIED,
AuthSecret = TPM2_ST_AUTH_SECRET,
Hashcheck = TPM2_ST_HASHCHECK,
AuthSigned = TPM2_ST_AUTH_SIGNED,
FuManifest = TPM2_ST_FU_MANIFEST,
}
impl TryFrom for StructureTag {
type Error = Error;
fn try_from(tpm_structure_tag: TPM2_ST) -> Result {
StructureTag::from_u16(tpm_structure_tag).ok_or_else(|| {
error!(
"value = {} did not match any StructureTag.",
tpm_structure_tag
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
impl From for TPM2_ST {
fn from(structure_tag: StructureTag) -> Self {
// The values are well defined so this cannot fail.
structure_tag.to_u16().unwrap()
}
}
tss-esapi-7.4.0/src/constants/tss.rs 0000644 0000000 0000000 00000222437 10461020230 0015540 0 ustar 0000000 0000000 // Copyright 2019 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::tss2_esys::*;
pub const TPM2_ALG_ERROR: TPM2_ALG_ID = 0x0000;
pub const TPM2_ALG_RSA: TPM2_ALG_ID = 0x0001;
pub const TPM2_ALG_TDES: TPM2_ALG_ID = 0x0003;
pub const TPM2_ALG_SHA: TPM2_ALG_ID = 0x0004;
pub const TPM2_ALG_SHA1: TPM2_ALG_ID = 0x0004;
pub const TPM2_ALG_HMAC: TPM2_ALG_ID = 0x0005;
pub const TPM2_ALG_AES: TPM2_ALG_ID = 0x0006;
pub const TPM2_ALG_MGF1: TPM2_ALG_ID = 0x0007;
pub const TPM2_ALG_KEYEDHASH: TPM2_ALG_ID = 0x0008;
pub const TPM2_ALG_XOR: TPM2_ALG_ID = 0x000A;
pub const TPM2_ALG_SHA256: TPM2_ALG_ID = 0x000B;
pub const TPM2_ALG_SHA384: TPM2_ALG_ID = 0x000C;
pub const TPM2_ALG_SHA512: TPM2_ALG_ID = 0x000D;
pub const TPM2_ALG_NULL: TPM2_ALG_ID = 0x0010;
pub const TPM2_ALG_SM3_256: TPM2_ALG_ID = 0x0012;
pub const TPM2_ALG_SM4: TPM2_ALG_ID = 0x0013;
pub const TPM2_ALG_RSASSA: TPM2_ALG_ID = 0x0014;
pub const TPM2_ALG_RSAES: TPM2_ALG_ID = 0x0015;
pub const TPM2_ALG_RSAPSS: TPM2_ALG_ID = 0x0016;
pub const TPM2_ALG_OAEP: TPM2_ALG_ID = 0x0017;
pub const TPM2_ALG_ECDSA: TPM2_ALG_ID = 0x0018;
pub const TPM2_ALG_ECDH: TPM2_ALG_ID = 0x0019;
pub const TPM2_ALG_ECDAA: TPM2_ALG_ID = 0x001A;
pub const TPM2_ALG_SM2: TPM2_ALG_ID = 0x001B;
pub const TPM2_ALG_ECSCHNORR: TPM2_ALG_ID = 0x001C;
pub const TPM2_ALG_ECMQV: TPM2_ALG_ID = 0x001D;
pub const TPM2_ALG_KDF1_SP800_56A: TPM2_ALG_ID = 0x0020;
pub const TPM2_ALG_KDF2: TPM2_ALG_ID = 0x0021;
pub const TPM2_ALG_KDF1_SP800_108: TPM2_ALG_ID = 0x0022;
pub const TPM2_ALG_ECC: TPM2_ALG_ID = 0x0023;
pub const TPM2_ALG_SYMCIPHER: TPM2_ALG_ID = 0x0025;
pub const TPM2_ALG_CAMELLIA: TPM2_ALG_ID = 0x0026;
pub const TPM2_ALG_CMAC: TPM2_ALG_ID = 0x003F;
pub const TPM2_ALG_CTR: TPM2_ALG_ID = 0x0040;
pub const TPM2_ALG_SHA3_256: TPM2_ALG_ID = 0x0027;
pub const TPM2_ALG_SHA3_384: TPM2_ALG_ID = 0x0028;
pub const TPM2_ALG_SHA3_512: TPM2_ALG_ID = 0x0029;
pub const TPM2_ALG_OFB: TPM2_ALG_ID = 0x0041;
pub const TPM2_ALG_CBC: TPM2_ALG_ID = 0x0042;
pub const TPM2_ALG_CFB: TPM2_ALG_ID = 0x0043;
pub const TPM2_ALG_ECB: TPM2_ALG_ID = 0x0044;
pub const TPM2_ALG_FIRST: TPM2_ALG_ID = 0x0001;
pub const TPM2_ALG_LAST: TPM2_ALG_ID = 0x0044;
pub const TPM2_ECC_NONE: TPM2_ECC_CURVE = 0x0000;
pub const TPM2_ECC_NIST_P192: TPM2_ECC_CURVE = 0x0001;
pub const TPM2_ECC_NIST_P224: TPM2_ECC_CURVE = 0x0002;
pub const TPM2_ECC_NIST_P256: TPM2_ECC_CURVE = 0x0003;
pub const TPM2_ECC_NIST_P384: TPM2_ECC_CURVE = 0x0004;
pub const TPM2_ECC_NIST_P521: TPM2_ECC_CURVE = 0x0005;
pub const TPM2_ECC_BN_P256: TPM2_ECC_CURVE = 0x0010;
pub const TPM2_ECC_BN_P638: TPM2_ECC_CURVE = 0x0011;
pub const TPM2_ECC_SM2_P256: TPM2_ECC_CURVE = 0x0020;
pub const TPM2_CC_NV_UndefineSpaceSpecial: TPM2_CC = 0x0000011f;
pub const TPM2_CC_FIRST: TPM2_CC = TPM2_CC_NV_UndefineSpaceSpecial;
pub const TPM2_CC_EvictControl: TPM2_CC = 0x00000120;
pub const TPM2_CC_HierarchyControl: TPM2_CC = 0x00000121;
pub const TPM2_CC_NV_UndefineSpace: TPM2_CC = 0x00000122;
pub const TPM2_CC_ChangeEPS: TPM2_CC = 0x00000124;
pub const TPM2_CC_ChangePPS: TPM2_CC = 0x00000125;
pub const TPM2_CC_Clear: TPM2_CC = 0x00000126;
pub const TPM2_CC_ClearControl: TPM2_CC = 0x00000127;
pub const TPM2_CC_ClockSet: TPM2_CC = 0x00000128;
pub const TPM2_CC_HierarchyChangeAuth: TPM2_CC = 0x00000129;
pub const TPM2_CC_NV_DefineSpace: TPM2_CC = 0x0000012a;
pub const TPM2_CC_PCR_Allocate: TPM2_CC = 0x0000012b;
pub const TPM2_CC_PCR_SetAuthPolicy: TPM2_CC = 0x00000012c;
pub const TPM2_CC_PP_Commands: TPM2_CC = 0x0000012d;
pub const TPM2_CC_SetPrimaryPolicy: TPM2_CC = 0x0000012e;
pub const TPM2_CC_FieldUpgradeStart: TPM2_CC = 0x0000012f;
pub const TPM2_CC_ClockRateAdjust: TPM2_CC = 0x00000130;
pub const TPM2_CC_CreatePrimary: TPM2_CC = 0x00000131;
pub const TPM2_CC_NV_GlobalWriteLock: TPM2_CC = 0x00000132;
pub const TPM2_CC_GetCommandAuditDigest: TPM2_CC = 0x00000133;
pub const TPM2_CC_NV_Increment: TPM2_CC = 0x00000134;
pub const TPM2_CC_NV_SetBits: TPM2_CC = 0x00000135;
pub const TPM2_CC_NV_Extend: TPM2_CC = 0x00000136;
pub const TPM2_CC_NV_Write: TPM2_CC = 0x00000137;
pub const TPM2_CC_NV_WriteLock: TPM2_CC = 0x00000138;
pub const TPM2_CC_DictionaryAttackLockReset: TPM2_CC = 0x00000139;
pub const TPM2_CC_DictionaryAttackParameters: TPM2_CC = 0x0000013a;
pub const TPM2_CC_NV_ChangeAuth: TPM2_CC = 0x0000013b;
pub const TPM2_CC_PCR_Event: TPM2_CC = 0x0000013c;
pub const TPM2_CC_PCR_Reset: TPM2_CC = 0x0000013d;
pub const TPM2_CC_SequenceComplete: TPM2_CC = 0x0000013e;
pub const TPM2_CC_SetAlgorithmSet: TPM2_CC = 0x0000013f;
pub const TPM2_CC_SetCommandCodeAuditStatus: TPM2_CC = 0x00000140;
pub const TPM2_CC_FieldUpgradeData: TPM2_CC = 0x00000141;
pub const TPM2_CC_IncrementalSelfTest: TPM2_CC = 0x00000142;
pub const TPM2_CC_SelfTest: TPM2_CC = 0x00000143;
pub const TPM2_CC_Startup: TPM2_CC = 0x00000144;
pub const TPM2_CC_Shutdown: TPM2_CC = 0x00000145;
pub const TPM2_CC_StirRandom: TPM2_CC = 0x00000146;
pub const TPM2_CC_ActivateCredential: TPM2_CC = 0x00000147;
pub const TPM2_CC_Certify: TPM2_CC = 0x00000148;
pub const TPM2_CC_PolicyNV: TPM2_CC = 0x00000149;
pub const TPM2_CC_CertifyCreation: TPM2_CC = 0x0000014a;
pub const TPM2_CC_Duplicate: TPM2_CC = 0x0000014b;
pub const TPM2_CC_GetTime: TPM2_CC = 0x0000014c;
pub const TPM2_CC_GetSessionAuditDigest: TPM2_CC = 0x0000014d;
pub const TPM2_CC_NV_Read: TPM2_CC = 0x0000014e;
pub const TPM2_CC_NV_ReadLock: TPM2_CC = 0x0000014f;
pub const TPM2_CC_ObjectChangeAuth: TPM2_CC = 0x00000150;
pub const TPM2_CC_PolicySecret: TPM2_CC = 0x00000151;
pub const TPM2_CC_Rewrap: TPM2_CC = 0x00000152;
pub const TPM2_CC_Create: TPM2_CC = 0x00000153;
pub const TPM2_CC_ECDH_ZGen: TPM2_CC = 0x00000154;
pub const TPM2_CC_HMAC: TPM2_CC = 0x00000155;
pub const TPM2_CC_Import: TPM2_CC = 0x00000156;
pub const TPM2_CC_Load: TPM2_CC = 0x00000157;
pub const TPM2_CC_Quote: TPM2_CC = 0x00000158;
pub const TPM2_CC_RSA_Decrypt: TPM2_CC = 0x00000159;
pub const TPM2_CC_HMAC_Start: TPM2_CC = 0x0000015b;
pub const TPM2_CC_SequenceUpdate: TPM2_CC = 0x0000015c;
pub const TPM2_CC_Sign: TPM2_CC = 0x0000015d;
pub const TPM2_CC_Unseal: TPM2_CC = 0x0000015e;
pub const TPM2_CC_PolicySigned: TPM2_CC = 0x00000160;
pub const TPM2_CC_ContextLoad: TPM2_CC = 0x00000161;
pub const TPM2_CC_ContextSave: TPM2_CC = 0x00000162;
pub const TPM2_CC_ECDH_KeyGen: TPM2_CC = 0x00000163;
pub const TPM2_CC_EncryptDecrypt: TPM2_CC = 0x00000164;
pub const TPM2_CC_FlushContext: TPM2_CC = 0x00000165;
pub const TPM2_CC_LoadExternal: TPM2_CC = 0x00000167;
pub const TPM2_CC_MakeCredential: TPM2_CC = 0x00000168;
pub const TPM2_CC_NV_ReadPublic: TPM2_CC = 0x00000169;
pub const TPM2_CC_PolicyAuthorize: TPM2_CC = 0x0000016a;
pub const TPM2_CC_PolicyAuthValue: TPM2_CC = 0x0000016b;
pub const TPM2_CC_PolicyCommandCode: TPM2_CC = 0x0000016c;
pub const TPM2_CC_PolicyCounterTimer: TPM2_CC = 0x0000016d;
pub const TPM2_CC_PolicyCpHash: TPM2_CC = 0x0000016e;
pub const TPM2_CC_PolicyLocality: TPM2_CC = 0x0000016f;
pub const TPM2_CC_PolicyNameHash: TPM2_CC = 0x00000170;
pub const TPM2_CC_PolicyOR: TPM2_CC = 0x00000171;
pub const TPM2_CC_PolicyTicket: TPM2_CC = 0x00000172;
pub const TPM2_CC_ReadPublic: TPM2_CC = 0x00000173;
pub const TPM2_CC_RSA_Encrypt: TPM2_CC = 0x00000174;
pub const TPM2_CC_StartAuthSession: TPM2_CC = 0x00000176;
pub const TPM2_CC_VerifySignature: TPM2_CC = 0x00000177;
pub const TPM2_CC_ECC_Parameters: TPM2_CC = 0x00000178;
pub const TPM2_CC_FirmwareRead: TPM2_CC = 0x00000179;
pub const TPM2_CC_GetCapability: TPM2_CC = 0x0000017a;
pub const TPM2_CC_GetRandom: TPM2_CC = 0x0000017b;
pub const TPM2_CC_GetTestResult: TPM2_CC = 0x0000017c;
pub const TPM2_CC_Hash: TPM2_CC = 0x0000017d;
pub const TPM2_CC_PCR_Read: TPM2_CC = 0x0000017e;
pub const TPM2_CC_PolicyPCR: TPM2_CC = 0x0000017f;
pub const TPM2_CC_PolicyRestart: TPM2_CC = 0x00000180;
pub const TPM2_CC_ReadClock: TPM2_CC = 0x00000181;
pub const TPM2_CC_PCR_Extend: TPM2_CC = 0x00000182;
pub const TPM2_CC_PCR_SetAuthValue: TPM2_CC = 0x00000183;
pub const TPM2_CC_NV_Certify: TPM2_CC = 0x00000184;
pub const TPM2_CC_EventSequenceComplete: TPM2_CC = 0x00000185;
pub const TPM2_CC_HashSequenceStart: TPM2_CC = 0x00000186;
pub const TPM2_CC_PolicyPhysicalPresence: TPM2_CC = 0x00000187;
pub const TPM2_CC_PolicyDuplicationSelect: TPM2_CC = 0x00000188;
pub const TPM2_CC_PolicyGetDigest: TPM2_CC = 0x00000189;
pub const TPM2_CC_TestParms: TPM2_CC = 0x0000018a;
pub const TPM2_CC_Commit: TPM2_CC = 0x0000018b;
pub const TPM2_CC_PolicyPassword: TPM2_CC = 0x0000018c;
pub const TPM2_CC_ZGen_2Phase: TPM2_CC = 0x0000018d;
pub const TPM2_CC_EC_Ephemeral: TPM2_CC = 0x0000018e;
pub const TPM2_CC_PolicyNvWritten: TPM2_CC = 0x0000018f;
pub const TPM2_CC_PolicyTemplate: TPM2_CC = 0x00000190;
pub const TPM2_CC_CreateLoaded: TPM2_CC = 0x00000191;
pub const TPM2_CC_PolicyAuthorizeNV: TPM2_CC = 0x00000192;
pub const TPM2_CC_EncryptDecrypt2: TPM2_CC = 0x00000193;
pub const TPM2_CC_AC_GetCapability: TPM2_CC = 0x00000194;
pub const TPM2_CC_AC_Send: TPM2_CC = 0x00000195;
pub const TPM2_CC_Policy_AC_SendSelect: TPM2_CC = 0x00000196;
pub const TPM2_CC_LAST: TPM2_CC = 0x00000196;
pub const TPM2_CC_Vendor_TCG_Test: TPM2_CC = 0x20000000;
pub const TPM2_SPEC_FAMILY: TPM2_SPEC = 0x322E3000; /* ASCII 2.0 with null terminator */
pub const TPM2_SPEC_LEVEL: TPM2_SPEC = 00; /* the level number for the specification */
pub const TPM2_SPEC_VERSION: TPM2_SPEC = 126; /* the version number of the spec 001.26 * 100 */
pub const TPM2_SPEC_YEAR: TPM2_SPEC = 2015; /* the year of the version */
pub const TPM2_SPEC_DAY_OF_YEAR: TPM2_SPEC = 233; /* the day of the year August 21 2015 */
pub const TPM2_GENERATED_VALUE: TPM2_GENERATED = 0xff544347; /* 0xFF TCG FF 54 43 4716 */
pub const TPM2_RC_SUCCESS: TPM2_RC = 0x000;
pub const TPM2_RC_BAD_TAG: TPM2_RC = 0x01E; /* defined for compatibility with TPM 1.2 */
pub const TPM2_RC_VER1: TPM2_RC = 0x100; /* set for all format 0 response codes */
pub const TPM2_RC_INITIALIZE: TPM2_RC = TPM2_RC_VER1 + 0x000; /* TPM not initialized by TPM2_Startup or already initialized */
pub const TPM2_RC_FAILURE: TPM2_RC = TPM2_RC_VER1 + 0x001; /* commands not being accepted because of a TPM failure. NOTE This may be returned by TPM2_GetTestResult as the testResult parameter. */
pub const TPM2_RC_SEQUENCE: TPM2_RC = TPM2_RC_VER1 + 0x003; /* improper use of a sequence handle */
pub const TPM2_RC_PRIVATE: TPM2_RC = TPM2_RC_VER1 + 0x00B; /* not currently used */
pub const TPM2_RC_HMAC: TPM2_RC = TPM2_RC_VER1 + 0x019; /* not currently used */
pub const TPM2_RC_DISABLED: TPM2_RC = TPM2_RC_VER1 + 0x020; /* the command is disabled */
pub const TPM2_RC_EXCLUSIVE: TPM2_RC = TPM2_RC_VER1 + 0x021; /* command failed because audit sequence required exclusivity */
pub const TPM2_RC_AUTH_TYPE: TPM2_RC = TPM2_RC_VER1 + 0x024; /* authorization handle is not correct for command */
pub const TPM2_RC_AUTH_MISSING: TPM2_RC = TPM2_RC_VER1 + 0x025; /* command requires an authorization session for handle and it is not present. */
pub const TPM2_RC_POLICY: TPM2_RC = TPM2_RC_VER1 + 0x026; /* policy failure in math operation or an invalid authPolicy value */
pub const TPM2_RC_PCR: TPM2_RC = TPM2_RC_VER1 + 0x027; /* PCR check fail */
pub const TPM2_RC_PCR_CHANGED: TPM2_RC = TPM2_RC_VER1 + 0x028; /* PCR have changed since checked. */
pub const TPM2_RC_UPGRADE: TPM2_RC = TPM2_RC_VER1 + 0x02D; /* For all commands, other than TPM2_FieldUpgradeData, this code indicates that the TPM is in field upgrade mode. For TPM2_FieldUpgradeData, this code indicates that the TPM is not in field upgrade mode */
pub const TPM2_RC_TOO_MANY_CONTEXTS: TPM2_RC = TPM2_RC_VER1 + 0x02E; /* context ID counter is at maximum. */
pub const TPM2_RC_AUTH_UNAVAILABLE: TPM2_RC = TPM2_RC_VER1 + 0x02F; /* authValue or authPolicy is not available for selected entity. */
pub const TPM2_RC_REBOOT: TPM2_RC = TPM2_RC_VER1 + 0x030; /* a _TPM_Init and StartupCLEAR is required before the TPM can resume operation. */
pub const TPM2_RC_UNBALANCED: TPM2_RC = TPM2_RC_VER1 + 0x031; /* the protection algorithms hash and symmetric are not reasonably balanced. The digest size of the hash must be larger than the key size of the symmetric algorithm. */
pub const TPM2_RC_COMMAND_SIZE: TPM2_RC = TPM2_RC_VER1 + 0x042; /* command commandSize value is inconsistent with contents of the command buffer. Either the size is not the same as the octets loaded by the hardware interface layer or the value is not large enough to hold a command header */
pub const TPM2_RC_COMMAND_CODE: TPM2_RC = TPM2_RC_VER1 + 0x043; /* command code not supported */
pub const TPM2_RC_AUTHSIZE: TPM2_RC = TPM2_RC_VER1 + 0x044; /* the value of authorizationSize is out of range or the number of octets in the Authorization Area is greater than required */
pub const TPM2_RC_AUTH_CONTEXT: TPM2_RC = TPM2_RC_VER1 + 0x045; /* use of an authorization session with a context command or another command that cannot have an authorization session. */
pub const TPM2_RC_NV_RANGE: TPM2_RC = TPM2_RC_VER1 + 0x046; /* NV offset+size is out of range. */
pub const TPM2_RC_NV_SIZE: TPM2_RC = TPM2_RC_VER1 + 0x047; /* Requested allocation size is larger than allowed. */
pub const TPM2_RC_NV_LOCKED: TPM2_RC = TPM2_RC_VER1 + 0x048; /* NV access locked. */
pub const TPM2_RC_NV_AUTHORIZATION: TPM2_RC = TPM2_RC_VER1 + 0x049; /* NV access authorization fails in command actions this failure does not affect lockout.action */
pub const TPM2_RC_NV_UNINITIALIZED: TPM2_RC = TPM2_RC_VER1 + 0x04A; /* an NV Index is used before being initialized or the state saved by TPM2_ShutdownSTATE could not be restored */
pub const TPM2_RC_NV_SPACE: TPM2_RC = TPM2_RC_VER1 + 0x04B; /* insufficient space for NV allocation */
pub const TPM2_RC_NV_DEFINED: TPM2_RC = TPM2_RC_VER1 + 0x04C; /* NV Index or persistent object already defined */
pub const TPM2_RC_BAD_CONTEXT: TPM2_RC = TPM2_RC_VER1 + 0x050; /* context in TPM2_ContextLoad is not valid */
pub const TPM2_RC_CPHASH: TPM2_RC = TPM2_RC_VER1 + 0x051; /* cpHash value already set or not correct for use */
pub const TPM2_RC_PARENT: TPM2_RC = TPM2_RC_VER1 + 0x052; /* handle for parent is not a valid parent */
pub const TPM2_RC_NEEDS_TEST: TPM2_RC = TPM2_RC_VER1 + 0x053; /* some function needs testing. */
pub const TPM2_RC_NO_RESULT: TPM2_RC = TPM2_RC_VER1 + 0x054; /* returned when an internal function cannot process a request due to an unspecified problem. This code is usually related to invalid parameters that are not properly filtered by the input unmarshaling code. */
pub const TPM2_RC_SENSITIVE: TPM2_RC = TPM2_RC_VER1 + 0x055; /* the sensitive area did not unmarshal correctly after decryption. This code is used in lieu of the other unmarshaling errors so that an attacker cannot determine where the unmarshaling error occurred */
pub const TPM2_RC_MAX_FM0: TPM2_RC = TPM2_RC_VER1 + 0x07F; /* largest version 1 code that is not a warning */
pub const TPM2_RC_FMT1: TPM2_RC = 0x080; /* This bit is SET in all format 1 response codes. The codes in this group may have a value added to them to indicate the handle session or parameter to which they apply. */
pub const TPM2_RC_ASYMMETRIC: TPM2_RC = TPM2_RC_FMT1 + 0x001; /* asymmetric algorithm not supported or not correct */
pub const TPM2_RC_ATTRIBUTES: TPM2_RC = TPM2_RC_FMT1 + 0x002; /* inconsistent attributes */
pub const TPM2_RC_HASH: TPM2_RC = TPM2_RC_FMT1 + 0x003; /* hash algorithm not supported or not appropriate */
pub const TPM2_RC_VALUE: TPM2_RC = TPM2_RC_FMT1 + 0x004; /* value is out of range or is not correct for the context */
pub const TPM2_RC_HIERARCHY: TPM2_RC = TPM2_RC_FMT1 + 0x005; /* hierarchy is not enabled or is not correct for the use */
pub const TPM2_RC_KEY_SIZE: TPM2_RC = TPM2_RC_FMT1 + 0x007; /* key size is not supported */
pub const TPM2_RC_MGF: TPM2_RC = TPM2_RC_FMT1 + 0x008; /* mask generation function not supported */
pub const TPM2_RC_MODE: TPM2_RC = TPM2_RC_FMT1 + 0x009; /* mode of operation not supported */
pub const TPM2_RC_TYPE: TPM2_RC = TPM2_RC_FMT1 + 0x00A; /* the type of the value is not appropriate for the use */
pub const TPM2_RC_HANDLE: TPM2_RC = TPM2_RC_FMT1 + 0x00B; /* the handle is not correct for the use */
pub const TPM2_RC_KDF: TPM2_RC = TPM2_RC_FMT1 + 0x00C; /* unsupported key derivation function or function not appropriate for use */
pub const TPM2_RC_RANGE: TPM2_RC = TPM2_RC_FMT1 + 0x00D; /* value was out of allowed range. */
pub const TPM2_RC_AUTH_FAIL: TPM2_RC = TPM2_RC_FMT1 + 0x00E; /* the authorization HMAC check failed and DA counter incremented */
pub const TPM2_RC_NONCE: TPM2_RC = TPM2_RC_FMT1 + 0x00F; /* invalid nonce size or nonce value mismatch */
pub const TPM2_RC_PP: TPM2_RC = TPM2_RC_FMT1 + 0x010; /* authorization requires assertion of PP */
pub const TPM2_RC_SCHEME: TPM2_RC = TPM2_RC_FMT1 + 0x012; /* unsupported or incompatible scheme */
pub const TPM2_RC_SIZE: TPM2_RC = TPM2_RC_FMT1 + 0x015; /* structure is the wrong size */
pub const TPM2_RC_SYMMETRIC: TPM2_RC = TPM2_RC_FMT1 + 0x016; /* unsupported symmetric algorithm or key size or not appropriate for instance */
pub const TPM2_RC_TAG: TPM2_RC = TPM2_RC_FMT1 + 0x017; /* incorrect structure tag */
pub const TPM2_RC_SELECTOR: TPM2_RC = TPM2_RC_FMT1 + 0x018; /* union selector is incorrect */
pub const TPM2_RC_INSUFFICIENT: TPM2_RC = TPM2_RC_FMT1 + 0x01A; /* the TPM was unable to unmarshal a value because there were not enough octets in the input buffer */
pub const TPM2_RC_SIGNATURE: TPM2_RC = TPM2_RC_FMT1 + 0x01B; /* the signature is not valid */
pub const TPM2_RC_KEY: TPM2_RC = TPM2_RC_FMT1 + 0x01C; /* key fields are not compatible with the selected use */
pub const TPM2_RC_POLICY_FAIL: TPM2_RC = TPM2_RC_FMT1 + 0x01D; /* a policy check failed */
pub const TPM2_RC_INTEGRITY: TPM2_RC = TPM2_RC_FMT1 + 0x01F; /* integrity check failed */
pub const TPM2_RC_TICKET: TPM2_RC = TPM2_RC_FMT1 + 0x020; /* invalid ticket */
pub const TPM2_RC_RESERVED_BITS: TPM2_RC = TPM2_RC_FMT1 + 0x021; /* reserved bits not set to zero as required */
pub const TPM2_RC_BAD_AUTH: TPM2_RC = TPM2_RC_FMT1 + 0x022; /* authorization failure without DA implications */
pub const TPM2_RC_EXPIRED: TPM2_RC = TPM2_RC_FMT1 + 0x023; /* the policy has expired */
pub const TPM2_RC_POLICY_CC: TPM2_RC = TPM2_RC_FMT1 + 0x024; /* the commandCode in the policy is not the commandCode of the command or the command code in a policy command references a command that is not implemented */
pub const TPM2_RC_BINDING: TPM2_RC = TPM2_RC_FMT1 + 0x025; /* public and sensitive portions of an object are not cryptographically bound */
pub const TPM2_RC_CURVE: TPM2_RC = TPM2_RC_FMT1 + 0x026; /* curve not supported */
pub const TPM2_RC_ECC_POINT: TPM2_RC = TPM2_RC_FMT1 + 0x027; /* point is not on the required curve. */
pub const TPM2_RC_WARN: TPM2_RC = 0x900; /* set for warning response codes */
pub const TPM2_RC_CONTEXT_GAP: TPM2_RC = TPM2_RC_WARN + 0x001; /* gap for context ID is too large */
pub const TPM2_RC_OBJECT_MEMORY: TPM2_RC = TPM2_RC_WARN + 0x002; /* out of memory for object contexts */
pub const TPM2_RC_SESSION_MEMORY: TPM2_RC = TPM2_RC_WARN + 0x003; /* out of memory for session contexts */
pub const TPM2_RC_MEMORY: TPM2_RC = TPM2_RC_WARN + 0x004; /* out of shared objectsession memory or need space for internal operations */
pub const TPM2_RC_SESSION_HANDLES: TPM2_RC = TPM2_RC_WARN + 0x005; /* out of session handles a session must be flushed before a new session may be created */
pub const TPM2_RC_OBJECT_HANDLES: TPM2_RC = TPM2_RC_WARN + 0x006; /* out of object handles. The handle space for objects is depleted and a reboot is required. NOTE This cannot occur on the reference implementation. NOTE There is no reason why an implementation would implement a design that would deplete handle space. Platform specifications are encouraged to forbid it. */
pub const TPM2_RC_LOCALITY: TPM2_RC = TPM2_RC_WARN + 0x007; /* bad locality */
pub const TPM2_RC_YIELDED: TPM2_RC = TPM2_RC_WARN + 0x008; /* the TPM has suspended operation on the command forward progress was made and the command may be retried. See TPM 2.0 Part 1 Multitasking. NOTE This cannot occur on the reference implementation. */
pub const TPM2_RC_CANCELED: TPM2_RC = TPM2_RC_WARN + 0x009; /* the command was canceled */
pub const TPM2_RC_TESTING: TPM2_RC = TPM2_RC_WARN + 0x00A; /* TPM is performing selftests */
pub const TPM2_RC_REFERENCE_H0: TPM2_RC = TPM2_RC_WARN + 0x010; /* the 1st handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_H1: TPM2_RC = TPM2_RC_WARN + 0x011; /* the 2nd handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_H2: TPM2_RC = TPM2_RC_WARN + 0x012; /* the 3rd handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_H3: TPM2_RC = TPM2_RC_WARN + 0x013; /* the 4th handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_H4: TPM2_RC = TPM2_RC_WARN + 0x014; /* the 5th handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_H5: TPM2_RC = TPM2_RC_WARN + 0x015; /* the 6th handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_H6: TPM2_RC = TPM2_RC_WARN + 0x016; /* the 7th handle in the handle area references a transient object or session that is not loaded */
pub const TPM2_RC_REFERENCE_S0: TPM2_RC = TPM2_RC_WARN + 0x018; /* the 1st authorization session handle references a session that is not loaded */
pub const TPM2_RC_REFERENCE_S1: TPM2_RC = TPM2_RC_WARN + 0x019; /* the 2nd authorization session handle references a session that is not loaded */
pub const TPM2_RC_REFERENCE_S2: TPM2_RC = TPM2_RC_WARN + 0x01A; /* the 3rd authorization session handle references a session that is not loaded */
pub const TPM2_RC_REFERENCE_S3: TPM2_RC = TPM2_RC_WARN + 0x01B; /* the 4th authorization session handle references a session that is not loaded */
pub const TPM2_RC_REFERENCE_S4: TPM2_RC = TPM2_RC_WARN + 0x01C; /* the 5th session handle references a session that is not loaded */
pub const TPM2_RC_REFERENCE_S5: TPM2_RC = TPM2_RC_WARN + 0x01D; /* the 6th session handle references a session that is not loaded */
pub const TPM2_RC_REFERENCE_S6: TPM2_RC = TPM2_RC_WARN + 0x01E; /* the 7th authorization session handle references a session that is not loaded */
pub const TPM2_RC_NV_RATE: TPM2_RC = TPM2_RC_WARN + 0x020; /* the TPM is rate limiting accesses to prevent wearout of NV */
pub const TPM2_RC_LOCKOUT: TPM2_RC = TPM2_RC_WARN + 0x021; /* authorizations for objects subject to DA protection are not allowed at this time because the TPM is in DA lockout mode */
pub const TPM2_RC_RETRY: TPM2_RC = TPM2_RC_WARN + 0x022; /* the TPM was not able to start the command */
pub const TPM2_RC_NV_UNAVAILABLE: TPM2_RC = TPM2_RC_WARN + 0x023; /* the command may require writing of NV and NV is not current accessible */
pub const TPM2_RC_NOT_USED: TPM2_RC = TPM2_RC_WARN + 0x07F; /* this value is reserved and shall not be returned by the TPM */
pub const TPM2_RC_H: TPM2_RC = 0x000; /* add to a handle related error */
pub const TPM2_RC_P: TPM2_RC = 0x040; /* add to a parameter-related error */
pub const TPM2_RC_S: TPM2_RC = 0x800; /* add to a session-related error */
pub const TPM2_RC_1: TPM2_RC = 0x100; /* add to a parameter handle or session-related error */
pub const TPM2_RC_2: TPM2_RC = 0x200; /* add to a parameter handle or session-related error */
pub const TPM2_RC_3: TPM2_RC = 0x300; /* add to a parameter handle or session-related error */
pub const TPM2_RC_4: TPM2_RC = 0x400; /* add to a parameter handle or session-related error */
pub const TPM2_RC_5: TPM2_RC = 0x500; /* add to a parameter handle or session-related error */
pub const TPM2_RC_6: TPM2_RC = 0x600; /* add to a parameter handle or session-related error */
pub const TPM2_RC_7: TPM2_RC = 0x700; /* add to a parameter handle or session-related error */
pub const TPM2_RC_8: TPM2_RC = 0x800; /* add to a parameter-related error */
pub const TPM2_RC_9: TPM2_RC = 0x900; /* add to a parameter-related error */
pub const TPM2_RC_A: TPM2_RC = 0xA00; /* add to a parameter-related error */
pub const TPM2_RC_B: TPM2_RC = 0xB00; /* add to a parameter-related error */
pub const TPM2_RC_C: TPM2_RC = 0xC00; /* add to a parameter-related error */
pub const TPM2_RC_D: TPM2_RC = 0xD00; /* add to a parameter-related error */
pub const TPM2_RC_E: TPM2_RC = 0xE00; /* add to a parameter-related error */
pub const TPM2_RC_F: TPM2_RC = 0xF00; /* add to a parameter-related error */
pub const TPM2_RC_N_MASK: TPM2_RC = 0xF00; /* number mask */
pub const TPM2_CLOCK_COARSE_SLOWER: TPM2_CLOCK_ADJUST = -3; /* Slow the Clock update rate by one coarse adjustment step. */
pub const TPM2_CLOCK_MEDIUM_SLOWER: TPM2_CLOCK_ADJUST = -2; /* Slow the Clock update rate by one medium adjustment step. */
pub const TPM2_CLOCK_FINE_SLOWER: TPM2_CLOCK_ADJUST = -1; /* Slow the Clock update rate by one fine adjustment step. */
pub const TPM2_CLOCK_NO_CHANGE: TPM2_CLOCK_ADJUST = 0; /* No change to the Clock update rate. */
pub const TPM2_CLOCK_FINE_FASTER: TPM2_CLOCK_ADJUST = 1; /* Speed the Clock update rate by one fine adjustment step. */
pub const TPM2_CLOCK_MEDIUM_FASTER: TPM2_CLOCK_ADJUST = 2; /* Speed the Clock update rate by one medium adjustment step. */
pub const TPM2_CLOCK_COARSE_FASTER: TPM2_CLOCK_ADJUST = 3; /* Speed the Clock update rate by one coarse adjustment step. */
pub const TPM2_EO_EQ: TPM2_EO = 0x0000; /* A B */
pub const TPM2_EO_NEQ: TPM2_EO = 0x0001; /* A B */
pub const TPM2_EO_SIGNED_GT: TPM2_EO = 0x0002; /* A > B signed */
pub const TPM2_EO_UNSIGNED_GT: TPM2_EO = 0x0003; /* A > B unsigned */
pub const TPM2_EO_SIGNED_LT: TPM2_EO = 0x0004; /* A < B signed */
pub const TPM2_EO_UNSIGNED_LT: TPM2_EO = 0x0005; /* A < B unsigned */
pub const TPM2_EO_SIGNED_GE: TPM2_EO = 0x0006; /* A B signed */
pub const TPM2_EO_UNSIGNED_GE: TPM2_EO = 0x0007; /* A B unsigned */
pub const TPM2_EO_SIGNED_LE: TPM2_EO = 0x0008; /* A B signed */
pub const TPM2_EO_UNSIGNED_LE: TPM2_EO = 0x0009; /* A B unsigned */
pub const TPM2_EO_BITSET: TPM2_EO = 0x000A; /* All bits SET in B are SET in A. ABB */
pub const TPM2_EO_BITCLEAR: TPM2_EO = 0x000B; /* All bits SET in B are CLEAR in A. AB0 */
pub const TPM2_ST_RSP_COMMAND: TPM2_ST = 0x00C4; /* Tag value for a response used when there is an error in the tag. This is also the value returned from a TPM 1.2 when an error occurs. This value is used in this specification because an error in the command tag may prevent determination of the family. When this tag is used in the response the response code will be TPM2_RC_BAD_TAG 0 1E16 which has the same numeric value as the TPM 1.2 response code for TPM_BADTAG. NOTE In a previously published version of this specification TPM2_RC_BAD_TAG was incorrectly assigned a value of 0x030 instead of 30 0x01e. Some implementations my return the old value instead of the new value. */
pub const TPM2_ST_NULL: TPM2_ST = 0x8000; /* no structure type specified */
pub const TPM2_ST_NO_SESSIONS: TPM2_ST = 0x8001; /* tag value for a command response for a command defined in this specification indicating that the command response has no attached sessions and no authorizationSizeparameterSize value is present. If the responseCode from the TPM is not TPM2_RC_SUCCESS then the response tag shall have this value. */
pub const TPM2_ST_SESSIONS: TPM2_ST = 0x8002; /* tag value for a command response for a command defined in this specification indicating that the command response has one or more attached sessions and the authorizationSizeparameterSize field is present */
pub const TPM2_ST_RESERVED1: TPM2_ST = 0x8003; /* When used between application software and the TPM resource manager, this tag indicates that the command has no sessions and the handles are using the Name format rather than the 32-bit handle format. NOTE 1 The response to application software will have a tag of TPM2_ST_NO_SESSIONS. Between the TRM and TPM, this tag would occur in a response from a TPM that overlaps the tag parameter of a request with the tag parameter of a response when the response has no associated sessions. NOTE 2 This tag is not used by all TPM or TRM implementations. */
pub const TPM2_ST_RESERVED2: TPM2_ST = 0x8004; /* When used between application software and the TPM resource manager. This tag indicates that the command has sessions and the handles are using the Name format rather than the 32-bit handle format. NOTE 1 If the command completes successfully the response to application software will have a tag of TPM2_ST_SESSIONS. Between the TRM and TPM would occur in a response from a TPM that overlaps the tag parameter of a request with the tag parameter of a response when the response has authorization sessions. NOTE 2 This tag is not used by all TPM or TRM implementations. */
pub const TPM2_ST_ATTEST_NV: TPM2_ST = 0x8014; /* tag for an attestation structure */
pub const TPM2_ST_ATTEST_COMMAND_AUDIT: TPM2_ST = 0x8015; /* tag for an attestation structure */
pub const TPM2_ST_ATTEST_SESSION_AUDIT: TPM2_ST = 0x8016; /* tag for an attestation structure */
pub const TPM2_ST_ATTEST_CERTIFY: TPM2_ST = 0x8017; /* tag for an attestation structure */
pub const TPM2_ST_ATTEST_QUOTE: TPM2_ST = 0x8018; /* tag for an attestation structure */
pub const TPM2_ST_ATTEST_TIME: TPM2_ST = 0x8019; /* tag for an attestation structure */
pub const TPM2_ST_ATTEST_CREATION: TPM2_ST = 0x801A; /* tag for an attestation structure */
pub const TPM2_ST_RESERVED3: TPM2_ST = 0x801B; /* do not use . NOTE This was previously assigned to TPM2_ST_ATTEST_NV. The tag is changed because the structure has changed */
pub const TPM2_ST_ATTEST_NV_DIGEST: TPM2_ST = 0x801c; /* tag for an attestation structure */
pub const TPM2_ST_CREATION: TPM2_ST = 0x8021; /* tag for a ticket type */
pub const TPM2_ST_VERIFIED: TPM2_ST = 0x8022; /* tag for a ticket type */
pub const TPM2_ST_AUTH_SECRET: TPM2_ST = 0x8023; /* tag for a ticket type */
pub const TPM2_ST_HASHCHECK: TPM2_ST = 0x8024; /* tag for a ticket type */
pub const TPM2_ST_AUTH_SIGNED: TPM2_ST = 0x8025; /* tag for a ticket type */
pub const TPM2_ST_FU_MANIFEST: TPM2_ST = 0x8029; /* tag for a structure describing a Field Upgrade Policy */
pub const TPM2_SU_CLEAR: TPM2_SU = 0x0000; /* On TPM2_Shutdown indicates that the TPM should prepare for loss of power and save state required for an orderly startup TPM Reset. On TPM2_Startup indicates that the TPM should perform TPM Reset or TPM Restart */
pub const TPM2_SU_STATE: TPM2_SU = 0x0001; /* On TPM2_Shutdown indicates that the TPM should prepare for loss of power and save state required for an orderly startup. TPM Restart or TPM Resume on TPM2_Startup indicates that the TPM should restore the state saved by TPM2_Shutdown TPM2_SU_STATE */
pub const TPM2_SE_HMAC: TPM2_SE = 0x00;
pub const TPM2_SE_POLICY: TPM2_SE = 0x01;
pub const TPM2_SE_TRIAL: TPM2_SE = 0x03; /* The policy session is being used to compute the policyHash and not for command authorization.This setting modifies some policy commands and prevents session from being used to authorize a command. */
pub const TPM2_CAP_FIRST: TPM2_CAP = 0x00000000;
pub const TPM2_CAP_ALGS: TPM2_CAP = 0x00000000; /* TPM2_ALG_ID1 */
pub const TPM2_CAP_HANDLES: TPM2_CAP = 0x00000001; /* TPM2_HANDLE */
pub const TPM2_CAP_COMMANDS: TPM2_CAP = 0x00000002; /* TPM2_CC */
pub const TPM2_CAP_PP_COMMANDS: TPM2_CAP = 0x00000003; /* TPM2_CC */
pub const TPM2_CAP_AUDIT_COMMANDS: TPM2_CAP = 0x00000004; /* TPM2_CC */
pub const TPM2_CAP_PCRS: TPM2_CAP = 0x00000005; /* reserved */
pub const TPM2_CAP_TPM_PROPERTIES: TPM2_CAP = 0x00000006; /* TPM2_PT */
pub const TPM2_CAP_PCR_PROPERTIES: TPM2_CAP = 0x00000007; /* TPM2_PT_PCR */
pub const TPM2_CAP_ECC_CURVES: TPM2_CAP = 0x00000008; /* TPM2_ECC_CURVE */
pub const TPM2_CAP_AUTH_POLICIES: TPM2_CAP = 0x00000009; /* TPM2_HANDLE */
pub const TPM2_CAP_ACT: TPM2_CAP = 0x0000000A; /* TPM2_HANDLE */
pub const TPM2_CAP_LAST: TPM2_CAP = 0x0000000A;
pub const TPM2_CAP_VENDOR_PROPERTY: TPM2_CAP = 0x00000100; /* manufacturer specific */
pub const TPM2_NT_ORDINARY: TPM2_NT = 0x0; /* Ordinary – contains data that is opaque to the TPM that can only be modified using TPM2_NV_Write(). */
pub const TPM2_NT_COUNTER: TPM2_NT = 0x1; /* Counter – contains an 8-octet value that is to be used as a counter and can only be modified with TPM2_NV_Increment() */
pub const TPM2_NT_BITS: TPM2_NT = 0x2; /* Bit Field – contains an 8-octet value to be used as a bit field and can only be modified with TPM2_NV_SetBits(). */
pub const TPM2_NT_EXTEND: TPM2_NT = 0x4; /* Extend – contains a digest-sized value used like a PCR. The Index can only be modified using TPM2_NV_Extend(). The extend will use the nameAlg of the Index. */
pub const TPM2_NT_PIN_FAIL: TPM2_NT = 0x8; /* PIN Fail - contains pinCount that increments on a PIN authorization failure and a pinLimit. */
pub const TPM2_NT_PIN_PASS: TPM2_NT = 0x9; /* PIN Pass - contains pinCount that increments on a PIN authorization success and a pinLimit. */
pub const TPM2_PT_NONE: TPM2_PT = 0x00000000; /* indicates no property type */
pub const TPM2_PT_GROUP: TPM2_PT = 0x00000100; /* The number of properties in each group. NOTE The first group with any properties is group 1 TPM2_PT_GROUP * 1. Group 0 is reserved. */
pub const TPM2_PT_FIXED: TPM2_PT = TPM2_PT_GROUP * 1; /* the group of fixed properties returned as TPMS_TAGGED_PROPERTY. The values in this group are only changed due to a firmware change in the TPM. */
pub const TPM2_PT_FAMILY_INDICATOR: TPM2_PT = TPM2_PT_FIXED + 0; /* a 4-octet character string containing the TPM Family value TPM2_SPEC_FAMILY */
pub const TPM2_PT_LEVEL: TPM2_PT = TPM2_PT_FIXED + 1; /* the level of the specification. NOTE 1 For this specification the level is zero. NOTE 2 The level is on the title page of the specification. */
pub const TPM2_PT_REVISION: TPM2_PT = TPM2_PT_FIXED + 2; /* the specification Revision times 100. EXAMPLE Revision 01.01 would have a value of 101. NOTE The Revision value is on the title page of the specification. */
pub const TPM2_PT_DAY_OF_YEAR: TPM2_PT = TPM2_PT_FIXED + 3; /* the specification day of year using TCG calendar. EXAMPLE November 15 2010 has a day of year value of 319 00 00 01 3F16. NOTE The specification date is on the title page of the specification. */
pub const TPM2_PT_YEAR: TPM2_PT = TPM2_PT_FIXED + 4; /* the specification year using the CE. EXAMPLE The year 2010 has a value of 00 00 07 DA16. NOTE The specification date is on the title page of the specification. */
pub const TPM2_PT_MANUFACTURER: TPM2_PT = TPM2_PT_FIXED + 5; /* the vendor ID unique to each TPM manufacturer */
pub const TPM2_PT_VENDOR_STRING_1: TPM2_PT = TPM2_PT_FIXED + 6; /* the first four characters of the vendor ID string. NOTE When the vendor string is fewer than 16 octets the additional property values do not have to be present. A vendor string of 4 octets can be represented in one 32-bit value and no null terminating character is required. */
pub const TPM2_PT_VENDOR_STRING_2: TPM2_PT = TPM2_PT_FIXED + 7; /* the second four characters of the vendor ID string */
pub const TPM2_PT_VENDOR_STRING_3: TPM2_PT = TPM2_PT_FIXED + 8; /* the third four characters of the vendor ID string */
pub const TPM2_PT_VENDOR_STRING_4: TPM2_PT = TPM2_PT_FIXED + 9; /* the fourth four characters of the vendor ID string */
pub const TPM2_PT_VENDOR_TPM_TYPE: TPM2_PT = TPM2_PT_FIXED + 10; /* vendor defined value indicating the TPM model */
pub const TPM2_PT_FIRMWARE_VERSION_1: TPM2_PT = TPM2_PT_FIXED + 11; /* the most significant 32 bits of a TPM vendor-specific value indicating the version number of the firmware. See 10.12.2 and 10.12.8. */
pub const TPM2_PT_FIRMWARE_VERSION_2: TPM2_PT = TPM2_PT_FIXED + 12; /* the least significant 32 bits of a TPM vendor-specific value indicating the version number of the firmware. See 10.12.2 and 10.12.8. */
pub const TPM2_PT_INPUT_BUFFER: TPM2_PT = TPM2_PT_FIXED + 13; /* the maximum size of a parameter typically a TPM2B_MAX_BUFFER */
pub const TPM2_PT_HR_TRANSIENT_MIN: TPM2_PT = TPM2_PT_FIXED + 14; /* the minimum number of transient objects that can be held in TPM RAM. NOTE This minimum shall be no less than the minimum value required by the platforms-pecific specification to which the TPM is built. */
pub const TPM2_PT_HR_PERSISTENT_MIN: TPM2_PT = TPM2_PT_FIXED + 15; /* the minimum number of persistent objects that can be held in TPM NV memory. NOTE This minimum shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
pub const TPM2_PT_HR_LOADED_MIN: TPM2_PT = TPM2_PT_FIXED + 16; /* the minimum number of authorization sessions that can be held in TPM RAM . NOTE This minimum shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
pub const TPM2_PT_ACTIVE_SESSIONS_MAX: TPM2_PT = TPM2_PT_FIXED + 17; /* the number of authorization sessions that may be active at a time. A session is active when it has a context associated with its handle. The context may either be in TPM RAM or be context saved. NOTE This value shall be no less than the minimum value required by the platform-specific specification to which the TPM is built. */
pub const TPM2_PT_PCR_COUNT: TPM2_PT = TPM2_PT_FIXED + 18; /* the number of PCR implemented. NOTE This number is determined by the defined attributes not the number of PCR that are populated. */
pub const TPM2_PT_PCR_SELECT_MIN: TPM2_PT = TPM2_PT_FIXED + 19; /* the minimum number of octets in a TPMS_PCR_SELECT.sizeofSelect. NOTE This value is not determined by the number of PCR implemented but by the number of PCR required by the platform-specific specification with which the TPM is compliant or by the implementer if not adhering to a platform-specific specification. */
pub const TPM2_PT_CONTEXT_GAP_MAX: TPM2_PT = TPM2_PT_FIXED + 20; /* the maximum allowed difference unsigned between the contextID values of two saved session contexts. This value shall be 2n1 where n is at least 16. */
pub const TPM2_PT_NV_COUNTERS_MAX: TPM2_PT = TPM2_PT_FIXED + 22; /* the maximum number of NV Indexes that are allowed to have the TPM2_NT_COUNTER attribute. NOTE It is allowed for this value to be larger than the number of NV Indexes that can be defined. This would be indicative of a TPM implementation that did not use different implementation technology for different NV Index types. */
pub const TPM2_PT_NV_INDEX_MAX: TPM2_PT = TPM2_PT_FIXED + 23; /* the maximum size of an NV Index data area */
pub const TPM2_PT_MEMORY: TPM2_PT = TPM2_PT_FIXED + 24; /* a TPMA_MEMORY indicating the memory management method for the TPM */
pub const TPM2_PT_CLOCK_UPDATE: TPM2_PT = TPM2_PT_FIXED + 25; /* interval in milliseconds between updates to the copy of TPMS_CLOCK_INFO.clock in NV */
pub const TPM2_PT_CONTEXT_HASH: TPM2_PT = TPM2_PT_FIXED + 26; /* the algorithm used for the integrity HMAC on saved contexts and for hashing the fuData of TPM2_FirmwareRead */
pub const TPM2_PT_CONTEXT_SYM: TPM2_PT = TPM2_PT_FIXED + 27; /* TPM2_ALG_ID the algorithm used for encryption of saved contexts */
pub const TPM2_PT_CONTEXT_SYM_SIZE: TPM2_PT = TPM2_PT_FIXED + 28; /* TPM2_KEY_BITS the size of the key used for encryption of saved contexts */
pub const TPM2_PT_ORDERLY_COUNT: TPM2_PT = TPM2_PT_FIXED + 29; /* the modulus 1 of the count for NV update of an orderly counter. The returned value is MAX_ORDERLY_COUNT. This will have a value of 2N 1 where 1 N 32. NOTE An orderly counter is an NV Index with an TPM2_NT of TPM_NV_COUNTER and TPMA_NV_ORDERLY SET. NOTE When the low-order bits of a counter equal this value an NV write occurs on the next increment. */
pub const TPM2_PT_MAX_COMMAND_SIZE: TPM2_PT = TPM2_PT_FIXED + 30; /* the maximum value for commandSize in a command */
pub const TPM2_PT_MAX_RESPONSE_SIZE: TPM2_PT = TPM2_PT_FIXED + 31; /* the maximum value for responseSize in a response */
pub const TPM2_PT_MAX_DIGEST: TPM2_PT = TPM2_PT_FIXED + 32; /* the maximum size of a digest that can be produced by the TPM */
pub const TPM2_PT_MAX_OBJECT_CONTEXT: TPM2_PT = TPM2_PT_FIXED + 33; /* the maximum size of an object context that will be returned by TPM2_ContextSave */
pub const TPM2_PT_MAX_SESSION_CONTEXT: TPM2_PT = TPM2_PT_FIXED + 34; /* the maximum size of a session context that will be returned by TPM2_ContextSave */
pub const TPM2_PT_PS_FAMILY_INDICATOR: TPM2_PT = TPM2_PT_FIXED + 35; /* platform-specific family. A TPM2_PS value. See Table 25. NOTE The platform-specific values for the TPM2_PT_PS parameters are in the relevant platform-specific specification. In the reference implementation all of these values are 0. */
pub const TPM2_PT_PS_LEVEL: TPM2_PT = TPM2_PT_FIXED + 36; /* the level of the platform-specific specification */
pub const TPM2_PT_PS_REVISION: TPM2_PT = TPM2_PT_FIXED + 37; /* the specification Revision times 100 for the platform-specific specification */
pub const TPM2_PT_PS_DAY_OF_YEAR: TPM2_PT = TPM2_PT_FIXED + 38; /* the platform-specific specification day of year using TCG calendar */
pub const TPM2_PT_PS_YEAR: TPM2_PT = TPM2_PT_FIXED + 39; /* the platform-specific specification year using the CE */
pub const TPM2_PT_SPLIT_MAX: TPM2_PT = TPM2_PT_FIXED + 40; /* the number of split signing operations supported by the TPM */
pub const TPM2_PT_TOTAL_COMMANDS: TPM2_PT = TPM2_PT_FIXED + 41; /* total number of commands implemented in the TPM */
pub const TPM2_PT_LIBRARY_COMMANDS: TPM2_PT = TPM2_PT_FIXED + 42; /* number of commands from the TPM library that are implemented */
pub const TPM2_PT_VENDOR_COMMANDS: TPM2_PT = TPM2_PT_FIXED + 43; /* number of vendor commands that are implemented */
pub const TPM2_PT_NV_BUFFER_MAX: TPM2_PT = TPM2_PT_FIXED + 44; /* the maximum data size in one NV write command */
pub const TPM2_PT_MODES: TPM2_PT = TPM2_PT_FIXED + 45; /* a TPMA_MODES value indicating that the TPM is designed for these modes. */
pub const TPM2_PT_MAX_CAP_BUFFER: TPM2_PT = TPM2_PT_FIXED + 46; /* the maximum size of a TPMS_CAPABILITY_DATA structure returned in TPM2_GetCapability(). */
pub const TPM2_PT_VAR: TPM2_PT = TPM2_PT_GROUP * 2; /* the group of variable properties returned as TPMS_TAGGED_PROPERTY. The properties in this group change because of a Protected Capability other than a firmware update. The values are not necessarily persistent across all power transitions. */
pub const TPM2_PT_PERMANENT: TPM2_PT = TPM2_PT_VAR + 0; /* TPMA_PERMANENT */
pub const TPM2_PT_STARTUP_CLEAR: TPM2_PT = TPM2_PT_VAR + 1; /* TPMA_STARTUP_CLEAR */
pub const TPM2_PT_HR_NV_INDEX: TPM2_PT = TPM2_PT_VAR + 2; /* the number of NV Indexes currently defined */
pub const TPM2_PT_HR_LOADED: TPM2_PT = TPM2_PT_VAR + 3; /* the number of authorization sessions currently loaded into TPM RAM */
pub const TPM2_PT_HR_LOADED_AVAIL: TPM2_PT = TPM2_PT_VAR + 4; /* the number of additional authorization sessions of any type that could be loaded into TPM RAM. This value is an estimate. If this value is at least 1 then at least one authorization session of any type may be loaded. Any command that changes the RAM memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one authorization session would fit into RAM. */
pub const TPM2_PT_HR_ACTIVE: TPM2_PT = TPM2_PT_VAR + 5; /* the number of active authorization sessions currently being tracked by the TPMThis is the sum of the loaded and saved sessions. */
pub const TPM2_PT_HR_ACTIVE_AVAIL: TPM2_PT = TPM2_PT_VAR + 6; /* the number of additional authorization sessions of any type that could be created. This value is an estimate. If this value is at least 1 then at least one authorization session of any type may be created. Any command that changes the RAM memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one authorization session could be created. */
pub const TPM2_PT_HR_TRANSIENT_AVAIL: TPM2_PT = TPM2_PT_VAR + 7; /* estimate of the number of additional transient objects that could be loaded into TPM RAM. This value is an estimate. If this value is at least 1 then at least one object of any type may be loaded. Any command that changes the memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one transient object would fit into RAM. */
pub const TPM2_PT_HR_PERSISTENT: TPM2_PT = TPM2_PT_VAR + 8; /* the number of persistent objects currently loaded into TPM NV memory */
pub const TPM2_PT_HR_PERSISTENT_AVAIL: TPM2_PT = TPM2_PT_VAR + 9; /* the number of additional persistent objects that could be loaded into NV memory. This value is an estimate. If this value is at least 1 then at least one object of any type may be made persistent. Any command that changes the NV memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one persistent object would fit into NV memory. */
pub const TPM2_PT_NV_COUNTERS: TPM2_PT = TPM2_PT_VAR + 10; /* the number of defined NV Indexes that have NV the TPM2_NT_COUNTER attribute */
pub const TPM2_PT_NV_COUNTERS_AVAIL: TPM2_PT = TPM2_PT_VAR + 11; /* the number of additional NV Indexes that can be defined with their TPM2_NT of TPM_NV_COUNTER and the TPMA_NV_ORDERLY attribute SET. This value is an estimate. If this value is at least 1 then at least one NV Index may be created with a TPM2_NT of TPM_NV_COUNTER and the TPMA_NV_ORDERLY attributes. Any command that changes the NV memory allocation can make this estimate invalid. NOTE A valid implementation may return 1 even if more than one NV counter could be defined. */
pub const TPM2_PT_ALGORITHM_SET: TPM2_PT = TPM2_PT_VAR + 12; /* code that limits the algorithms that may be used with the TPM */
pub const TPM2_PT_LOADED_CURVES: TPM2_PT = TPM2_PT_VAR + 13; /* the number of loaded ECC curves */
pub const TPM2_PT_LOCKOUT_COUNTER: TPM2_PT = TPM2_PT_VAR + 14; /* the current value of the lockout counter failedTries */
pub const TPM2_PT_MAX_AUTH_FAIL: TPM2_PT = TPM2_PT_VAR + 15; /* the number of authorization failures before DA lockout is invoked */
pub const TPM2_PT_LOCKOUT_INTERVAL: TPM2_PT = TPM2_PT_VAR + 16; /* the number of seconds before the value reported by TPM2_PT_LOCKOUT_COUNTER is decremented */
pub const TPM2_PT_LOCKOUT_RECOVERY: TPM2_PT = TPM2_PT_VAR + 17; /* the number of seconds after a lockoutAuth failure before use of lockoutAuth may be attempted again */
pub const TPM2_PT_NV_WRITE_RECOVERY: TPM2_PT = TPM2_PT_VAR + 18; /* number of milliseconds before the TPM will accept another command that will modify NVThis value is an approximation and may go up or down over time. */
pub const TPM2_PT_AUDIT_COUNTER_0: TPM2_PT = TPM2_PT_VAR + 19; /* the high-order 32 bits of the command audit counter */
pub const TPM2_PT_AUDIT_COUNTER_1: TPM2_PT = TPM2_PT_VAR + 20; /* the low-order 32 bits of the command audit counter */
pub const TPM2_PT_TPM2_PCR_FIRST: TPM2_PT_PCR = 0x00000000; /* bottom of the range of TPM2_PT_PCR properties */
pub const TPM2_PT_PCR_SAVE: TPM2_PT_PCR = 0x00000000; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is saved and restored by TPM2_SU_STATE */
pub const TPM2_PT_PCR_EXTEND_L0: TPM2_PT_PCR = 0x00000001; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be extended from locality 0This property is only present if a locality other than 0 is implemented. */
pub const TPM2_PT_PCR_RESET_L0: TPM2_PT_PCR = 0x00000002; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset by TPM2_PCR_Reset from locality 0 */
pub const TPM2_PT_PCR_EXTEND_L1: TPM2_PT_PCR = 0x00000003; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be extended from locality 1 This property is only present if locality 1 is implemented. */
pub const TPM2_PT_PCR_RESET_L1: TPM2_PT_PCR = 0x00000004; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset by TPM2_PCR_Reset from locality 1This property is only present if locality 1 is implemented. */
pub const TPM2_PT_PCR_EXTEND_L2: TPM2_PT_PCR = 0x00000005; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be extended from locality 2 This property is only present if localities 1 and 2 are implemented. */
pub const TPM2_PT_PCR_RESET_L2: TPM2_PT_PCR = 0x00000006; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset by TPM2_PCR_Reset from locality 2This property is only present if localities 1 and 2 are implemented. */
pub const TPM2_PT_PCR_EXTEND_L3: TPM2_PT_PCR = 0x00000007; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be extended from locality 3This property is only present if localities 1 2 and 3 are implemented. */
pub const TPM2_PT_PCR_RESET_L3: TPM2_PT_PCR = 0x00000008; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset by TPM2_PCR_Reset from locality 3This property is only present if localities 1 2 and 3 are implemented. */
pub const TPM2_PT_PCR_EXTEND_L4: TPM2_PT_PCR = 0x00000009; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be extended from locality 4This property is only present if localities 1 2 3 and 4 are implemented. */
pub const TPM2_PT_PCR_RESET_L4: TPM2_PT_PCR = 0x0000000A; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset by TPM2_PCR_Reset from locality 4This property is only present if localities 1 2 3 and 4 are implemented. */
pub const TPM2_PT_PCR_NO_INCREMENT: TPM2_PT_PCR = 0x00000011; /* a SET bit in the TPMS_PCR_SELECT indicates that modifications to this PCR reset or Extend will not increment the pcrUpdateCounter */
pub const TPM2_PT_PCR_DRTM_RESET: TPM2_PT_PCR = 0x00000012; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is reset by a DRTM event. These PCR are reset to 1 on TPM2_Startup and reset to 0 on a _TPM_Hash_End event following a _TPM_Hash_Start event. */
pub const TPM2_PT_PCR_POLICY: TPM2_PT_PCR = 0x00000013; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is controlled by policy. This property is only present if the TPM supports policy control of a PCR. */
pub const TPM2_PT_PCR_AUTH: TPM2_PT_PCR = 0x00000014; /* a SET bit in the TPMS_PCR_SELECT indicates that the PCR is controlled by an authorization value. This property is only present if the TPM supports authorization control of a PCR. */
pub const TPM2_PT_TPM2_PCR_LAST: TPM2_PT_PCR = 0x00000014; /* top of the range of TPM2_PT_PCR properties of the implementation. If the TPM receives a request for a PCR property with a value larger than this the TPM will return a zero length list and set the moreData parameter to NO. NOTE This is an implementation-specific value. The value shown reflects the reference code implementation. */
pub const TPM2_PS_MAIN: TPM2_PS = 0x00000000; /* not platform-specific */
pub const TPM2_PS_PC: TPM2_PS = 0x00000001; /* PC Client */
pub const TPM2_PS_PDA: TPM2_PS = 0x00000002; /* PDA includes all mobile devices that are not specifically cell phones */
pub const TPM2_PS_CELL_PHONE: TPM2_PS = 0x00000003; /* Cell Phone */
pub const TPM2_PS_SERVER: TPM2_PS = 0x00000004; /* Server WG */
pub const TPM2_PS_PERIPHERAL: TPM2_PS = 0x00000005; /* Peripheral WG */
pub const TPM2_PS_TSS: TPM2_PS = 0x00000006; /* TSS WG */
pub const TPM2_PS_STORAGE: TPM2_PS = 0x00000007; /* Storage WG */
pub const TPM2_PS_AUTHENTICATION: TPM2_PS = 0x00000008; /* Authentication WG */
pub const TPM2_PS_EMBEDDED: TPM2_PS = 0x00000009; /* Embedded WG */
pub const TPM2_PS_HARDCOPY: TPM2_PS = 0x0000000A; /* Hardcopy WG */
pub const TPM2_PS_INFRASTRUCTURE: TPM2_PS = 0x0000000B; /* Infrastructure WG */
pub const TPM2_PS_VIRTUALIZATION: TPM2_PS = 0x0000000C; /* Virtualization WG */
pub const TPM2_PS_TNC: TPM2_PS = 0x0000000D; /* Trusted Network Connect WG */
pub const TPM2_PS_MULTI_TENANT: TPM2_PS = 0x0000000E; /* Multi-tenant WG */
pub const TPM2_PS_TC: TPM2_PS = 0x0000000F; /* Technical Committee */
pub const TPM2_HT_PCR: TPM2_HT = 0x00; /* PCR consecutive numbers starting at 0 that reference the PCR registers. A platform-specific specification will set the minimum number of PCR and an implementation may have more. */
pub const TPM2_HT_NV_INDEX: TPM2_HT = 0x01; /* NV Index assigned by the caller */
pub const TPM2_HT_HMAC_SESSION: TPM2_HT = 0x02; /* HMAC Authorization Session assigned by the TPM when the session is created */
pub const TPM2_HT_LOADED_SESSION: TPM2_HT = 0x02; /* Loaded Authorization Session used only in the context of TPM2_GetCapability. This type references both loaded HMAC and loaded policy authorization sessions. */
pub const TPM2_HT_POLICY_SESSION: TPM2_HT = 0x03; /* Policy Authorization Session assigned by the TPM when the session is created */
pub const TPM2_HT_SAVED_SESSION: TPM2_HT = 0x03; /* Saved Authorization Session used only in the context of TPM2_GetCapability. This type references saved authorization session contexts for which the TPM is maintaining tracking information. */
pub const TPM2_HT_PERMANENT: TPM2_HT = 0x40; /* Permanent Values assigned by this specification in */
pub const TPM2_HT_TRANSIENT: TPM2_HT = 0x80; /* Transient Objects assigned by the TPM when an object is loaded into transient object memory or when a persistent object is converted to a transient object */
pub const TPM2_HT_PERSISTENT: TPM2_HT = 0x81; /* Persistent Objects assigned by the TPM when a loaded transient object is made persistent */
pub const TPM2_HT_AC: TPM2_HT = 0x90; /* Attached Component – handle for an Attached Component. */
pub const TPM2_RH_FIRST: TPM2_RH = 0x40000000; /* R */
pub const TPM2_RH_SRK: TPM2_RH = 0x40000000; /* R */
pub const TPM2_RH_OWNER: TPM2_RH = 0x40000001; /* K A P */
pub const TPM2_RH_REVOKE: TPM2_RH = 0x40000002; /* R */
pub const TPM2_RH_TRANSPORT: TPM2_RH = 0x40000003; /* R */
pub const TPM2_RH_OPERATOR: TPM2_RH = 0x40000004; /* R */
pub const TPM2_RH_ADMIN: TPM2_RH = 0x40000005; /* R */
pub const TPM2_RH_EK: TPM2_RH = 0x40000006; /* R */
pub const TPM2_RH_NULL: TPM2_RH = 0x40000007; /* K A P */
pub const TPM2_RH_UNASSIGNED: TPM2_RH = 0x40000008; /* R */
pub const TPM2_RS_PW: TPM2_RH = 0x40000009; /* S */
pub const TPM2_RH_LOCKOUT: TPM2_RH = 0x4000000A; /* A */
pub const TPM2_RH_ENDORSEMENT: TPM2_RH = 0x4000000B; /* K A P */
pub const TPM2_RH_PLATFORM: TPM2_RH = 0x4000000C; /* K A P */
pub const TPM2_RH_PLATFORM_NV: TPM2_RH = 0x4000000D; /* C */
pub const TPM2_RH_AUTH_00: TPM2_RH = 0x40000010; /* A */
pub const TPM2_RH_AUTH_FF: TPM2_RH = 0x4000010F; /* A */
pub const TPM2_RH_ACT_0: TPM2_RH = 0x40000110; /* A P */
pub const TPM2_RH_ACT_F: TPM2_RH = 0x4000011F; /* A P */
pub const TPM2_RH_LAST: TPM2_RH = 0x4000010F; /* R */
pub const TPM2_HR_HANDLE_MASK: TPM2_HC = 0x00FFFFFF; /* to mask off the HR */
pub const TPM2_HR_RANGE_MASK: TPM2_HC = 0xFF000000; /* to mask off the variable part */
pub const TPM2_HR_SHIFT: TPM2_HC = 24;
pub const TPM2_HR_PCR: TPM2_HC = (TPM2_HT_PCR as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_HR_HMAC_SESSION: TPM2_HC = (TPM2_HT_HMAC_SESSION as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_HR_POLICY_SESSION: TPM2_HC = (TPM2_HT_POLICY_SESSION as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_HR_TRANSIENT: TPM2_HC = (TPM2_HT_TRANSIENT as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_HR_PERSISTENT: TPM2_HC = (TPM2_HT_PERSISTENT as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_HR_NV_INDEX: TPM2_HC = (TPM2_HT_NV_INDEX as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_HR_PERMANENT: TPM2_HC = (TPM2_HT_PERMANENT as TPM2_HC) << TPM2_HR_SHIFT;
pub const TPM2_PCR_FIRST: TPM2_HC = TPM2_HR_PCR + 0; /* first PCR */
pub const TPM2_PCR_LAST: TPM2_HC = TPM2_PCR_FIRST + TPM2_MAX_PCRS - 1; /* last PCR */
pub const TPM2_HMAC_SESSION_FIRST: TPM2_HC = TPM2_HR_HMAC_SESSION + 0; /* first HMAC session */
pub const TPM2_HMAC_SESSION_LAST: TPM2_HC = TPM2_HMAC_SESSION_FIRST + 0x00fffffe; /* last HMAC session */
pub const TPM2_LOADED_SESSION_FIRST: TPM2_HC = TPM2_HMAC_SESSION_FIRST; /* used in GetCapability */
pub const TPM2_LOADED_SESSION_LAST: TPM2_HC = TPM2_HMAC_SESSION_LAST; /* used in GetCapability */
pub const TPM2_POLICY_SESSION_FIRST: TPM2_HC = TPM2_HR_POLICY_SESSION + 0; /* first policy session */
pub const TPM2_POLICY_SESSION_LAST: TPM2_HC = TPM2_POLICY_SESSION_FIRST + 0x00fffffe; /* last policy session */
pub const TPM2_TRANSIENT_FIRST: TPM2_HC = TPM2_HR_TRANSIENT + 0; /* first transient object */
pub const TPM2_ACTIVE_SESSION_FIRST: TPM2_HC = TPM2_POLICY_SESSION_FIRST; /* used in GetCapability */
pub const TPM2_ACTIVE_SESSION_LAST: TPM2_HC = TPM2_POLICY_SESSION_LAST; /* used in GetCapability */
pub const TPM2_TRANSIENT_LAST: TPM2_HC = TPM2_TRANSIENT_FIRST + 0x00fffffe; /* last transient object */
pub const TPM2_PERSISTENT_FIRST: TPM2_HC = TPM2_HR_PERSISTENT + 0; /* first persistent object */
pub const TPM2_PERSISTENT_LAST: TPM2_HC = TPM2_PERSISTENT_FIRST + 0x00FFFFFF; /* last persistent object */
pub const TPM2_PLATFORM_PERSISTENT: TPM2_HC = TPM2_PERSISTENT_FIRST + 0x00800000; /* first platform persistent object */
pub const TPM2_NV_INDEX_FIRST: TPM2_HC = TPM2_HR_NV_INDEX + 0; /* first allowed NV Index */
pub const TPM2_NV_INDEX_LAST: TPM2_HC = TPM2_NV_INDEX_FIRST + 0x00FFFFFF; /* last allowed NV Index */
pub const TPM2_PERMANENT_FIRST: TPM2_HC = TPM2_RH_FIRST;
pub const TPM2_PERMANENT_LAST: TPM2_HC = TPM2_RH_LAST;
pub const TPM2_HR_NV_AC: TPM2_HC = ((TPM2_HT_NV_INDEX as TPM2_HC) << TPM2_HR_SHIFT) + 0x00D00000; /* AC aliased NV Index */
pub const TPM2_NV_AC_FIRST: TPM2_HC = TPM2_HR_NV_AC + 0; /* first NV Index aliased to Attached Component */
pub const TPM2_NV_AC_LAST: TPM2_HC = TPM2_HR_NV_AC + 0x0000FFFF; /* last NV Index aliased to Attached Component */
pub const TPM2_HR_AC: TPM2_HC = (TPM2_HT_AC as TPM2_HC) << TPM2_HR_SHIFT; /* AC Handle */
pub const TPM2_AC_FIRST: TPM2_HC = TPM2_HR_AC + 0; /* first Attached Component */
pub const TPM2_AC_LAST: TPM2_HC = TPM2_HR_AC + 0x0000FFFF; /* last Attached Component */
pub const TPMA_ALGORITHM_ASYMMETRIC: TPMA_ALGORITHM = 0x00000001; /* SET 1 an asymmetric algorithm with public and private portions. CLEAR 0 not an asymmetric algorithm */
pub const TPMA_ALGORITHM_SYMMETRIC: TPMA_ALGORITHM = 0x00000002; /* SET 1 a symmetric block cipher. CLEAR 0 not a symmetric block cipher */
pub const TPMA_ALGORITHM_HASH: TPMA_ALGORITHM = 0x00000004; /* SET 1 a hash algorithm. CLEAR 0 not a hash algorithm */
pub const TPMA_ALGORITHM_OBJECT: TPMA_ALGORITHM = 0x00000008; /* SET 1 an algorithm that may be used as an object type. CLEAR 0 an algorithm that is not used as an object type */
pub const TPMA_ALGORITHM_RESERVED1_MASK: TPMA_ALGORITHM = 0x000000F0;
pub const TPMA_ALGORITHM_SIGNING: TPMA_ALGORITHM = 0x00000100; /* SET 1 a signing algorithm. The setting of asymmetric symmetric and hash will indicate the type of signing algorithm. CLEAR 0 not a signing algorithm */
pub const TPMA_ALGORITHM_ENCRYPTING: TPMA_ALGORITHM = 0x00000200; /* SET 1 an encryptiondecryption algorithm. The setting of asymmetric symmetric and hash will indicate the type of encryptiondecryption algorithm. CLEAR 0 not an encryption-decryption algorithm */
pub const TPMA_ALGORITHM_METHOD: TPMA_ALGORITHM = 0x00000400; /* SET 1 a method such as a key derivative function KDF. CLEAR 0 not a method */
pub const TPMA_ALGORITHM_RESERVED2_MASK: TPMA_ALGORITHM = 0xFFFFF800;
pub const TPMA_OBJECT_RESERVED1_MASK: TPMA_OBJECT = 0x00000001; /* shall be zero */
pub const TPMA_OBJECT_FIXEDTPM: TPMA_OBJECT = 0x00000002; /* SET 1 The hierarchy of the object as indicated by its Qualified Name may not change. CLEAR 0 The hierarchy of the object may change as a result of this object or an ancestor key being duplicated for use in another hierarchy. */
pub const TPMA_OBJECT_STCLEAR: TPMA_OBJECT = 0x00000004; /* SET 1 Previously saved contexts of this object may not be loaded after StartupCLEAR. CLEAR 0 Saved contexts of this object may be used after a ShutdownSTATE and subsequent Startup. */
pub const TPMA_OBJECT_RESERVED2_MASK: TPMA_OBJECT = 0x00000008; /* shall be zero */
pub const TPMA_OBJECT_FIXEDPARENT: TPMA_OBJECT = 0x00000010; /* SET 1 The parent of the object may not change. CLEAR 0 The parent of the object may change as the result of a TPM2_Duplicate of the object. */
pub const TPMA_OBJECT_SENSITIVEDATAORIGIN: TPMA_OBJECT = 0x00000020; /* SET 1 Indicates that when the object was created with TPM2_Create or TPM2_CreatePrimary the TPM generated all of the sensitive data other than the authValue. CLEAR 0 A portion of the sensitive data other than the authValue was provided by the caller. */
pub const TPMA_OBJECT_USERWITHAUTH: TPMA_OBJECT = 0x00000040; /* SET 1 Approval of USER role actions with this object may be with an HMAC session or with a password using the authValue of the object or a policy session. CLEAR 0 Approval of USER role actions with this object may only be done with a policy session. */
pub const TPMA_OBJECT_ADMINWITHPOLICY: TPMA_OBJECT = 0x00000080; /* SET 1 Approval of ADMIN role actions with this object may only be done with a policy session. CLEAR 0 Approval of ADMIN role actions with this object may be with an HMAC session or with a password using the authValue of the object or a policy session. */
pub const TPMA_OBJECT_RESERVED3_MASK: TPMA_OBJECT = 0x00000300; /* shall be zero */
pub const TPMA_OBJECT_NODA: TPMA_OBJECT = 0x00000400; /* SET 1 The object is not subject to dictionary attack protections. CLEAR 0 The object is subject to dictionary attack protections. */
pub const TPMA_OBJECT_ENCRYPTEDDUPLICATION: TPMA_OBJECT = 0x00000800; /* SET 1 If the object is duplicated then symmetricAlg shall not be TPM2_ALG_NULL and newParentHandle shall not be TPM2_RH_NULL. CLEAR 0 The object may be duplicated without an inner wrapper on the private portion of the object and the new parent may be TPM2_RH_NULL. */
pub const TPMA_OBJECT_RESERVED4_MASK: TPMA_OBJECT = 0x0000F000; /* shall be zero */
pub const TPMA_OBJECT_RESTRICTED: TPMA_OBJECT = 0x00010000; /* SET 1 Key usage is restricted to manipulate structures of known format the parent of this key shall have restricted SET. CLEAR 0 Key usage is not restricted to use on special formats. */
pub const TPMA_OBJECT_DECRYPT: TPMA_OBJECT = 0x00020000; /* SET 1 The private portion of the key may be used to decrypt. CLEAR 0 The private portion of the key may not be used to decrypt. */
pub const TPMA_OBJECT_SIGN_ENCRYPT: TPMA_OBJECT = 0x00040000; /* SET 1 For a symmetric cipher object the private portion of the key may be used to encrypt. For other objects the private portion of the key may be used to sign. CLEAR 0 The private portion of the key may not be used to sign or encrypt. */
pub const TPMA_OBJECT_RESERVED5_MASK: TPMA_OBJECT = 0xFFF80000; /* shall be zero */
pub const TPMA_SESSION_CONTINUESESSION: TPMA_SESSION = 0x00000001; /* SET 1 In a command this setting indicates that the session is to remain active after successful completion of the command. In a response it indicates that the session is still active. If SET in the command this attribute shall be SET in the response. CLEAR 0 In a command this setting indicates that the TPM should close the session and flush any related context when the command completes successfully. In a response it indicates that the session is closed and the context is no longer active. This attribute has no meaning for a password authorization and the TPM will allow any setting of the attribute in the command and SET the attribute in the response. This attribute will only be CLEAR in one response for a logical session. If the attribute is CLEAR the context associated with the session is no longer in use and the space is available. A session created after another session is ended may have the same handle but logically is not the same session. This attribute has no effect if the command does not complete successfully. */
pub const TPMA_SESSION_AUDITEXCLUSIVE: TPMA_SESSION = 0x00000002; /* SET 1 In a command this setting indicates that the command should only be executed if the session is exclusive at the start of the command. In a response it indicates that the session is exclusive. This setting is only allowed if the audit attribute is SET TPM2_RC_ATTRIBUTES. CLEAR 0 In a command indicates that the session need not be exclusive at the start of the command. In a response indicates that the session is not exclusive. In this revision if audit is CLEAR auditExclusive must be CLEAR in the command and will be CLEAR in the response. In a future revision this bit may have a different meaning if audit is CLEAR. See Exclusive Audit Session clause in TPM 2.0 Part 1. */
pub const TPMA_SESSION_AUDITRESET: TPMA_SESSION = 0x00000004; /* SET 1 In a command this setting indicates that the audit digest of the session should be initialized and the exclusive status of the session SET. This setting is only allowed if the audit attribute is SET TPM2_RC_ATTRIBUTES. CLEAR 0 In a command indicates that the audit digest should not be initialized. This bit is always CLEAR in a response. In this revision if audit is CLEAR auditReset must be clear in the command and will be CLEAR in the response. In a future revision this bit may have a different meaning if audit is CLEAR. */
pub const TPMA_SESSION_RESERVED1_MASK: TPMA_SESSION = 0x00000018; /* shall be CLEAR */
pub const TPMA_SESSION_DECRYPT: TPMA_SESSION = 0x00000020; /* SET 1 In a command this setting indicates that the first parameter in the command is symmetrically encrypted using the parameter encryption scheme described in TPM 2.0 Part 1. The TPM will decrypt the parameter after performing any HMAC computations and before unmarshaling the parameter. In a response the attribute is copied from the request but has no effect on the response. CLEAR 0 Session not used for encryption. For a password authorization this attribute will be CLEAR in both the command and response. This attribute may only be SET in one session per command. This attribute may be SET in a session that is not associated with a command handle. Such a session is provided for purposes of encrypting a parameter and not for authorization. This attribute may be SET in combination with any other session attributes. This attribute may only be SET if the first parameter of the command is a sized buffer TPM2B_. */
pub const TPMA_SESSION_ENCRYPT: TPMA_SESSION = 0x00000040; /* SET 1 In a command this setting indicates that the TPM should use this session to encrypt the first parameter in the response. In a response it indicates that the attribute was set in the command and that the TPM used the session to encrypt the first parameter in the response using the parameter encryption scheme described in TPM 2.0 Part 1. CLEAR 0 Session not used for encryption. For a password authorization this attribute will be CLEAR in both the command and response. This attribute may only be SET in one session per command. This attribute may be SET in a session that is not associated with a command handle. Such a session is provided for purposes of encrypting a parameter and not for authorization. This attribute may only be SET if the first parameter of a response is a sized buffer TPM2B_. */
pub const TPMA_SESSION_AUDIT: TPMA_SESSION = 0x00000080; /* SET 1 In a command or response this setting indicates that the session is for audit and that auditExclusive and auditReset have meaning. This session may also be used for authorization encryption or decryption. The encrypted and encrypt fields may be SET or CLEAR. CLEAR 0 Session is not used for audit. This attribute may only be SET in one session per command or response. If SET in the command then this attribute will be SET in the response. */
pub const TPMA_LOCALITY_TPM2_LOC_ZERO: TPMA_LOCALITY = 0x00000001;
pub const TPMA_LOCALITY_TPM2_LOC_ONE: TPMA_LOCALITY = 0x00000002;
pub const TPMA_LOCALITY_TPM2_LOC_TWO: TPMA_LOCALITY = 0x00000004;
pub const TPMA_LOCALITY_TPM2_LOC_THREE: TPMA_LOCALITY = 0x00000008;
pub const TPMA_LOCALITY_TPM2_LOC_FOUR: TPMA_LOCALITY = 0x00000010;
pub const TPMA_LOCALITY_EXTENDED_MASK: TPMA_LOCALITY = 0x000000E0; /* If any of these bits is set an extended locality is indicated */
pub const TPMA_LOCALITY_EXTENDED_SHIFT: u32 = 5;
pub const TPMA_PERMANENT_OWNERAUTHSET: TPMA_PERMANENT = 0x00000001; /* SET 1 TPM2_HierarchyChangeAuth with ownerAuth has been executed since the last TPM2_Clear. CLEAR 0 ownerAuth has not been changed since TPM2_Clear. */
pub const TPMA_PERMANENT_ENDORSEMENTAUTHSET: TPMA_PERMANENT = 0x00000002; /* SET 1 TPM2_HierarchyChangeAuth with endorsementAuth has been executed since the last TPM2_Clear. CLEAR 0 endorsementAuth has not been changed since TPM2_Clear. */
pub const TPMA_PERMANENT_LOCKOUTAUTHSET: TPMA_PERMANENT = 0x00000004; /* SET 1 TPM2_HierarchyChangeAuth with lockoutAuth has been executed since the last TPM2_Clear. CLEAR 0 lockoutAuth has not been changed since TPM2_Clear. */
pub const TPMA_PERMANENT_RESERVED1_MASK: TPMA_PERMANENT = 0x000000F8;
pub const TPMA_PERMANENT_DISABLECLEAR: TPMA_PERMANENT = 0x00000100; /* SET 1 TPM2_Clear is disabled. CLEAR 0 TPM2_Clear is enabled. NOTE See TPM2_ClearControl in TPM 2.0 Part 3 for details on changing this attribute. */
pub const TPMA_PERMANENT_INLOCKOUT: TPMA_PERMANENT = 0x00000200; /* SET 1 The TPM is in lockout and commands that require authorization with other than Platform Authorization or Lockout Authorization will not succeed. */
pub const TPMA_PERMANENT_TPMGENERATEDEPS: TPMA_PERMANENT = 0x00000400; /* SET 1 The EPS was created by the TPM. CLEAR 0 The EPS was created outside of the TPM using a manufacturer specific process. */
pub const TPMA_PERMANENT_RESERVED2_MASK: TPMA_PERMANENT = 0xFFFFF800;
pub const TPMA_STARTUP_CLEAR_PHENABLE: TPMA_STARTUP_CLEAR = 0x00000001; /* SET 1 The platform hierarchy is enabled and platformAuth or platformPolicy may be used for authorization. CLEAR 0 platformAuth and platformPolicy may not be used for authorizations and objects in the platform hierarchy including persistent objects cannot be used. NOTE See TPM2_HierarchyControl in TPM 2.0 Part 3 for details on changing this attribute. */
pub const TPMA_STARTUP_CLEAR_SHENABLE: TPMA_STARTUP_CLEAR = 0x00000002; /* SET 1 The Storage hierarchy is enabled and ownerAuth or ownerPolicy may be used for authorization. NV indices defined using owner authorization are accessible. CLEAR 0 ownerAuth and ownerPolicy may not be used for authorizations and objects in the Storage hierarchy persistent objects and NV indices defined using owner authorization cannot be used. NOTE See TPM2_HierarchyControl in TPM 2.0 Part 3 for details on changing this attribute. */
pub const TPMA_STARTUP_CLEAR_EHENABLE: TPMA_STARTUP_CLEAR = 0x00000004; /* SET 1 The EPS hierarchy is enabled and Endorsement Authorization may be used to authorize commands. CLEAR 0 Endorsement Authorization may not be used for authorizations and objects in the endorsement hierarchy including persistent objects cannot be used. NOTE See TPM2_HierarchyControl in TPM 2.0 Part 3 for details on changing this attribute. */
pub const TPMA_STARTUP_CLEAR_PHENABLENV: TPMA_STARTUP_CLEAR = 0x00000008; /* SET 1 NV indices that have TPMA_PLATFORM_CREATE SET may be read or written. The platform can create define and undefine indices. CLEAR 0 NV indices that have TPMA_PLATFORM_CREATE SET may not be read or written TPM2_RC_HANDLE. The platform cannot define TPM2_RC_HIERARCHY or undefined TPM2_RC_HANDLE indices. NOTE See TPM2_HierarchyControl in TPM 2.0 Part 3 for details on changing this attribute. NOTE read refers to these commands TPM2_NV_Read TPM2_NV_ReadPublic TPM_NV_Certify TPM2_PolicyNVwrite refers to these commands TPM2_NV_Write TPM2_NV_Increment TPM2_NV_Extend TPM2_NV_SetBitsNOTE The TPM must query the index TPMA_PLATFORM_CREATE attribute to determine whether phEnableNV is applicable. Since the TPM will return TPM2_RC_HANDLE if the index does not exist it also returns this error code if the index is disabled. Otherwise the TPM would leak the existence of an index even when disabled. */
pub const TPMA_STARTUP_CLEAR_RESERVED1_MASK: TPMA_STARTUP_CLEAR = 0x7FFFFFF0; /* shall be zero */
pub const TPMA_STARTUP_CLEAR_ORDERLY: TPMA_STARTUP_CLEAR = 0x80000000; /* SET 1 The TPM received a TPM2_Shutdown and a matching TPM2_Startup. CLEAR 0 TPM2_StartupTPM2_SU_CLEAR was not preceded by a TPM2_Shutdown of any type. NOTE A shutdown is orderly if the TPM receives a TPM2_Shutdown of any type followed by a TPM2_Startup of any type. However the TPM will return an error if TPM2_StartupTPM2_SU_STATE was not preceded by TPM2_State_SaveTPM2_SU_STATE. */
pub const TPMA_MEMORY_SHAREDRAM: TPMA_MEMORY = 0x00000001; /* SET 1 indicates that the RAM memory used for authorization session contexts is shared with the memory used for transient objects. CLEAR 0 indicates that the memory used for authorization sessions is not shared with memory used for transient objects */
pub const TPMA_MEMORY_SHAREDNV: TPMA_MEMORY = 0x00000002; /* SET 1 indicates that the NV memory used for persistent objects is shared with the NV memory used for NV Index values. CLEAR 0 indicates that the persistent objects and NV Index values are allocated from separate sections of NV */
pub const TPMA_MEMORY_OBJECTCOPIEDTORAM: TPMA_MEMORY = 0x00000004; /* SET 1 indicates that the TPM copies persistent objects to a transientobject slot in RAM when the persistent object is referenced in a command. The TRM is required to make sure that an object slot is available. CLEAR 0 indicates that the TPM does not use transientobject slots when persistent objects are referenced */
pub const TPMA_MEMORY_RESERVED1_MASK: TPMA_MEMORY = 0xFFFFFFF8; /* shall be zero */
pub const TPMA_CC_COMMANDINDEX_MASK: TPMA_CC = 0x0000FFFF; /* indicates the command being selected */
pub const TPMA_CC_COMMANDINDEX_SHIFT: u32 = 0;
pub const TPMA_CC_RESERVED1_MASK: TPMA_CC = 0x003F0000; /* shall be zero */
pub const TPMA_CC_NV: TPMA_CC = 0x00400000; /* SET 1 indicates that the command may write to NV. CLEAR 0 indicates that the command does not write to NV */
pub const TPMA_CC_EXTENSIVE: TPMA_CC = 0x00800000; /* SET 1 This command could flush any number of loaded contexts. CLEAR 0 no additional changes other than indicated by the flushed attribute */
pub const TPMA_CC_FLUSHED: TPMA_CC = 0x01000000; /* SET 1 The context associated with any transient handle in the command will be flushed when this command completes. CLEAR 0 No context is flushed as a side effect of this command. */
pub const TPMA_CC_CHANDLES_MASK: TPMA_CC = 0x0E000000; /* indicates the number of the handles in the handle area for this command */
pub const TPMA_CC_CHANDLES_SHIFT: u32 = 25;
pub const TPMA_CC_RHANDLE: TPMA_CC = 0x10000000; /* SET 1 indicates the presence of the handle area in the response */
pub const TPMA_CC_V: TPMA_CC = 0x20000000; /* SET 1 indicates that the command is vendor-specific. CLEAR 0 indicates that the command is defined in a version of this specification */
pub const TPMA_CC_RES_MASK: TPMA_CC = 0xC0000000; /* allocated for software shall be zero */
pub const TPMA_CC_RES_SHIFT: u32 = 30;
tss-esapi-7.4.0/src/constants/types.rs 0000644 0000000 0000000 00000010073 10461020230 0016062 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{Error, Result, WrapperErrorKind};
use log::error;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::{From, TryFrom};
pub mod capability {
use super::*;
use crate::{
constants::tss::{
TPM2_CAP_ALGS, TPM2_CAP_AUDIT_COMMANDS, TPM2_CAP_COMMANDS, TPM2_CAP_ECC_CURVES,
TPM2_CAP_HANDLES, TPM2_CAP_PCRS, TPM2_CAP_PCR_PROPERTIES, TPM2_CAP_PP_COMMANDS,
TPM2_CAP_TPM_PROPERTIES,
},
tss2_esys::TPM2_CAP,
};
// Enum representing the different TPM Capability Type values.
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum CapabilityType {
Algorithms = TPM2_CAP_ALGS,
Handles = TPM2_CAP_HANDLES,
Command = TPM2_CAP_COMMANDS,
PPCommands = TPM2_CAP_PP_COMMANDS,
AuditCommands = TPM2_CAP_AUDIT_COMMANDS,
AssignedPCR = TPM2_CAP_PCRS,
TPMProperties = TPM2_CAP_TPM_PROPERTIES,
PCRProperties = TPM2_CAP_PCR_PROPERTIES,
ECCCurves = TPM2_CAP_ECC_CURVES,
}
impl From for TPM2_CAP {
fn from(capability_type: CapabilityType) -> TPM2_CAP {
// The values are well defined so this cannot fail.
capability_type.to_u32().unwrap()
}
}
impl TryFrom for CapabilityType {
type Error = Error;
fn try_from(tpm_capability_type: TPM2_CAP) -> Result {
CapabilityType::from_u32(tpm_capability_type).ok_or_else(|| {
error!(
"value = {} did not match any CapabilityType.",
tpm_capability_type
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
}
/// Startup module
pub mod startup {
use super::*;
use crate::{
constants::tss::{TPM2_SU_CLEAR, TPM2_SU_STATE},
tss2_esys::TPM2_SU,
};
/// Enum repsenting the different TPM Startup Type values.
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u16)]
pub enum StartupType {
Clear = TPM2_SU_CLEAR,
State = TPM2_SU_STATE,
}
impl From for TPM2_SU {
fn from(startup_type: StartupType) -> TPM2_SU {
// The values are well defined so this cannot fail.
startup_type.to_u16().unwrap()
}
}
impl TryFrom for StartupType {
type Error = Error;
fn try_from(tpm_startup_type: TPM2_SU) -> Result {
StartupType::from_u16(tpm_startup_type).ok_or_else(|| {
error!(
"value = {} did not match any StartupType.",
tpm_startup_type
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
}
/// Session module
pub mod session {
use super::*;
use crate::{
constants::tss::{TPM2_SE_HMAC, TPM2_SE_POLICY, TPM2_SE_TRIAL},
tss2_esys::TPM2_SE,
};
/// Enum representing the different TPM session types.
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum SessionType {
Hmac = TPM2_SE_HMAC,
Policy = TPM2_SE_POLICY,
Trial = TPM2_SE_TRIAL,
}
impl From for TPM2_SE {
fn from(session_type: SessionType) -> TPM2_SE {
// The values are well defined so this cannot fail.
session_type.to_u8().unwrap()
}
}
impl TryFrom for SessionType {
type Error = Error;
fn try_from(tpm_session_type: TPM2_SE) -> Result {
SessionType::from_u8(tpm_session_type).ok_or_else(|| {
error!(
"value = {} did not match any SessionType.",
tpm_session_type
);
Error::local_error(WrapperErrorKind::InvalidParam)
})
}
}
}
tss-esapi-7.4.0/src/context/general_esys_tr.rs 0000644 0000000 0000000 00000006712 10461020230 0017560 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::handle_manager::HandleDropAction,
handles::ObjectHandle,
handles::{handle_conversion::TryIntoNotNone, TpmHandle},
structures::Auth,
structures::Name,
tss2_esys::{Esys_TR_Close, Esys_TR_FromTPMPublic, Esys_TR_GetName, Esys_TR_SetAuth},
Context, Error, Result,
};
use log::error;
use std::convert::TryFrom;
use std::ptr::null_mut;
use zeroize::Zeroize;
impl Context {
/// Set the authentication value for a given object handle in the ESYS context.
pub fn tr_set_auth(&mut self, object_handle: ObjectHandle, auth: Auth) -> Result<()> {
let mut auth_value = auth.into();
let ret = unsafe { Esys_TR_SetAuth(self.mut_context(), object_handle.into(), &auth_value) };
auth_value.buffer.zeroize();
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when setting authentication value: {}", ret);
Err(ret)
}
}
/// Retrieve the name of an object from the object handle
pub fn tr_get_name(&mut self, object_handle: ObjectHandle) -> Result {
let mut name_ptr = null_mut();
let ret =
unsafe { Esys_TR_GetName(self.mut_context(), object_handle.into(), &mut name_ptr) };
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Name::try_from(Context::ffi_data_to_owned(name_ptr))
} else {
error!("Error in getting name: {}", ret);
Err(ret)
}
}
/// Used to construct an esys object from the resources inside the TPM.
pub fn tr_from_tpm_public(&mut self, tpm_handle: TpmHandle) -> Result {
let mut object = ObjectHandle::None.into();
let ret = unsafe {
Esys_TR_FromTPMPublic(
self.mut_context(),
tpm_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut object,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
self.handle_manager.add_handle(
object.into(),
if tpm_handle.may_be_flushed() {
HandleDropAction::Flush
} else {
HandleDropAction::Close
},
)?;
Ok(object.into())
} else {
error!("Error when getting ESYS handle from TPM handle: {}", ret);
Err(ret)
}
}
/// Instructs the ESAPI to release the metadata and resources allocated for a specific ObjectHandle.
///
/// This is useful for cleaning up handles for which the context cannot be flushed.
pub fn tr_close(&mut self, object_handle: &mut ObjectHandle) -> Result<()> {
let mut rsrc_handle = object_handle.try_into_not_none()?;
let ret = unsafe { Esys_TR_Close(self.mut_context(), &mut rsrc_handle) };
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
self.handle_manager.set_as_closed(*object_handle)?;
*object_handle = ObjectHandle::from(rsrc_handle);
Ok(())
} else {
error!("Error when closing an ESYS handle: {}", ret);
Err(ret)
}
}
// Missing function: Esys_TR_Serialize
// Missing function: Esys_TR_Deserialize
}
tss-esapi-7.4.0/src/context/handle_manager.rs 0000644 0000000 0000000 00000011475 10461020230 0017322 0 ustar 0000000 0000000 // Copyright 2020 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{handles::ObjectHandle, tss2_esys::ESYS_TR, Error, Result, WrapperErrorKind};
use log::error;
use std::collections::HashMap;
/// Enum representing the action to be taken
/// when the handle is dropped.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum HandleDropAction {
Close,
Flush,
}
/// The HandleManager is responsible for storing
/// the handles used by Context iand their states.
/// In order to make sure the correct handles get
/// flushed and closed when the Context is dropped.
#[derive(Debug)]
pub struct HandleManager {
open_handles: HashMap,
}
impl HandleManager {
/// Creates a new HandleManager
pub fn new() -> HandleManager {
HandleManager {
open_handles: HashMap::new(),
}
}
/// Adds a handle to the HandleManager
pub fn add_handle(
&mut self,
handle: ObjectHandle,
handle_drop_action: HandleDropAction,
) -> Result<()> {
if handle == ObjectHandle::None || handle == ObjectHandle::Null {
error!("Handle manager does not handle None or Null handles");
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
}
// The TSS might return the same handle, see #383
if let Some(stored_handle_drop_action) = self.open_handles.get(&handle) {
if handle_drop_action != *stored_handle_drop_action {
error!("Handle drop action inconsistency");
return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
}
}
let _ = self.open_handles.insert(handle, handle_drop_action);
Ok(())
}
/// Sets the handle as flushed which removes it from the manager.
///
/// # Errors
/// If the handle was not set to be flushed then this will cause an
/// error but the handle will still be removed from the handler.
pub fn set_as_flushed(&mut self, handle: ObjectHandle) -> Result<()> {
self.open_handles
.remove(&handle)
.ok_or_else(|| {
error!("Handle({}) does not exist", ESYS_TR::from(handle));
Error::local_error(WrapperErrorKind::InvalidHandleState)
})
.and_then(|handle_drop_action| {
if handle_drop_action == HandleDropAction::Flush {
Ok(())
} else {
error!(
"Flushing handle({}) that should not have been flushed.",
ESYS_TR::from(handle)
);
Err(Error::local_error(WrapperErrorKind::InvalidHandleState))
}
})
}
/// Sets the handles as closed which removes it from the handler.
///
/// # Errors
/// If the handle was set to be flushed then this will cause an
/// error but the handle will still be removed from the handler.
pub fn set_as_closed(&mut self, handle: ObjectHandle) -> Result<()> {
self.open_handles
.remove(&handle)
.ok_or_else(|| {
error!("Handle({}) does not exist", ESYS_TR::from(handle));
Error::local_error(WrapperErrorKind::InvalidHandleState)
})
.and_then(|handle_drop_action| {
if handle_drop_action == HandleDropAction::Close {
Ok(())
} else {
error!(
"Closing handle({}) that should have been flushed",
ESYS_TR::from(handle)
);
Err(Error::local_error(WrapperErrorKind::InvalidHandleState))
}
})
}
/// Retrieves all handles that needs to be flushed.
pub fn handles_to_flush(&self) -> Vec {
self.open_handles
.iter()
.filter_map(|(open_handle, &handle_drop_action)| {
if handle_drop_action == HandleDropAction::Flush {
Some(open_handle)
} else {
None
}
})
.cloned()
.collect::>()
}
/// Retrieves all handles that needs to be closed.
pub fn handles_to_close(&self) -> Vec {
self.open_handles
.iter()
.filter_map(|(open_handle, &handle_drop_action)| {
if handle_drop_action == HandleDropAction::Close {
Some(open_handle)
} else {
None
}
})
.cloned()
.collect::>()
}
/// Indicates if the manager has any open handles
pub fn has_open_handles(&self) -> bool {
!self.open_handles.is_empty()
}
}
tss-esapi-7.4.0/src/context/session_administration.rs 0000644 0000000 0000000 00000003307 10461020230 0021160 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
attributes::{SessionAttributes, SessionAttributesMask},
handles::SessionHandle,
interface_types::session_handles::AuthSession,
tss2_esys::{Esys_TRSess_GetAttributes, Esys_TRSess_SetAttributes},
Context, Error, Result,
};
use log::error;
impl Context {
/// Set the given attributes on a given session.
pub fn tr_sess_set_attributes(
&mut self,
session: AuthSession,
attributes: SessionAttributes,
mask: SessionAttributesMask,
) -> Result<()> {
let ret = unsafe {
Esys_TRSess_SetAttributes(
self.mut_context(),
SessionHandle::from(session).into(),
attributes.into(),
mask.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when setting session attributes: {}", ret);
Err(ret)
}
}
/// Get session attribute flags.
pub fn tr_sess_get_attributes(&mut self, session: AuthSession) -> Result {
let mut flags = 0;
let ret = unsafe {
Esys_TRSess_GetAttributes(
self.mut_context(),
SessionHandle::from(session).into(),
&mut flags,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(SessionAttributes(flags))
} else {
error!("Error when getting session attributes: {}", ret);
Err(ret)
}
}
// Missing function: Esys_TRSess_GetNonceTPM
}
tss-esapi-7.4.0/src/context/tpm_commands/asymmetric_primitives.rs 0000644 0000000 0000000 00000031150 10461020230 0023476 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
handles::KeyHandle,
structures::Data,
structures::{EccPoint, PublicKeyRsa, RsaDecryptionScheme},
tss2_esys::{Esys_ECDH_KeyGen, Esys_ECDH_ZGen, Esys_RSA_Decrypt, Esys_RSA_Encrypt},
Context, Error, Result,
};
use log::error;
use std::convert::TryFrom;
use std::ptr::null_mut;
impl Context {
/// Perform an asymmetric RSA encryption.
pub fn rsa_encrypt(
&mut self,
key_handle: KeyHandle,
message: PublicKeyRsa,
in_scheme: RsaDecryptionScheme,
label: Data,
) -> Result {
let mut out_data_ptr = null_mut();
let ret = unsafe {
Esys_RSA_Encrypt(
self.mut_context(),
key_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&message.into(),
&in_scheme.into(),
&label.into(),
&mut out_data_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
PublicKeyRsa::try_from(Context::ffi_data_to_owned(out_data_ptr))
} else {
error!("Error when performing RSA encryption: {}", ret);
Err(ret)
}
}
/// Perform an asymmetric RSA decryption.
pub fn rsa_decrypt(
&mut self,
key_handle: KeyHandle,
cipher_text: PublicKeyRsa,
in_scheme: RsaDecryptionScheme,
label: Data,
) -> Result {
let mut message_ptr = null_mut();
let ret = unsafe {
Esys_RSA_Decrypt(
self.mut_context(),
key_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&cipher_text.into(),
&in_scheme.into(),
&label.into(),
&mut message_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
PublicKeyRsa::try_from(Context::ffi_data_to_owned(message_ptr))
} else {
error!("Error when performing RSA decryption: {}", ret);
Err(ret)
}
}
/// Generate an ephemeral key pair.
///
/// # Arguments
/// * `key_handle`- A [KeyHandle] of ECC key which curve parameters will be used
/// to generate the ephemeral key.
///
/// # Details
/// This command uses the TPM to generate an ephemeral
/// key pair. It uses the private ephemeral key and a loaded
/// public key to compute the shared secret value.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{
/// # Context, TctiNameConf,
/// # attributes::{SessionAttributesBuilder, ObjectAttributesBuilder},
/// # constants::SessionType,
/// # interface_types::{
/// # algorithm::{
/// # HashingAlgorithm, PublicAlgorithm, RsaDecryptAlgorithm,
/// # },
/// # ecc::EccCurve,
/// # resource_handles::Hierarchy,
/// # },
/// # structures::{
/// # Auth, Data, EccScheme, PublicBuilder, PublicEccParametersBuilder, PublicKeyRsa, KeyDerivationFunctionScheme, EccPoint,
/// # RsaDecryptionScheme, HashScheme, SymmetricDefinition,
/// # },
/// # };
/// # use std::{env, str::FromStr, convert::TryFrom};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
/// # )
/// # .expect("Failed to create session")
/// # .expect("Received invalid handle");
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
/// # .expect("Failed to set attributes on session");
/// # context.set_sessions((Some(session), None, None));
/// # let random_digest = context.get_random(16).unwrap();
/// # let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
/// #
/// // Create a key suitable for ECDH key generation
/// let ecc_parms = PublicEccParametersBuilder::new()
/// .with_ecc_scheme(
/// EccScheme::EcDh(HashScheme::new(HashingAlgorithm::Sha256)),
/// )
/// .with_curve(EccCurve::NistP256)
/// .with_is_signing_key(false)
/// .with_is_decryption_key(true)
/// .with_restricted(false)
/// .with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
/// .build()
/// .unwrap();
///
/// let object_attributes = ObjectAttributesBuilder::new()
/// .with_fixed_tpm(true)
/// .with_fixed_parent(true)
/// .with_sensitive_data_origin(true)
/// .with_user_with_auth(true)
/// .with_decrypt(true)
/// .with_sign_encrypt(false)
/// .with_restricted(false)
/// .build()
/// .unwrap();
///
/// let public = PublicBuilder::new()
/// .with_public_algorithm(PublicAlgorithm::Ecc)
/// .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
/// .with_object_attributes(object_attributes)
/// .with_ecc_parameters(ecc_parms)
/// .with_ecc_unique_identifier(EccPoint::default())
/// .build()
/// .unwrap();
///
/// let key_handle = context
/// .create_primary(
/// Hierarchy::Owner,
/// public,
/// Some(key_auth),
/// None,
/// None,
/// None,
/// )
/// .unwrap()
/// .key_handle;
///
/// // Generate ephemeral key pair and a shared secret
/// let (z_point, pub_point) = context.ecdh_key_gen(key_handle).unwrap();
/// ```
pub fn ecdh_key_gen(&mut self, key_handle: KeyHandle) -> Result<(EccPoint, EccPoint)> {
let mut z_point_ptr = null_mut();
let mut pub_point_ptr = null_mut();
let ret = unsafe {
Esys_ECDH_KeyGen(
self.mut_context(),
key_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut z_point_ptr,
&mut pub_point_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let z_point = Context::ffi_data_to_owned(z_point_ptr);
let pub_point = Context::ffi_data_to_owned(pub_point_ptr);
Ok((
EccPoint::try_from(z_point.point)?,
EccPoint::try_from(pub_point.point)?,
))
} else {
error!("Error when generating ECDH keypair: {}", ret);
Err(ret)
}
}
/// Recover Z value from a public point and a private key.
///
/// # Arguments
/// * `key_handle` - A [KeyHandle] of ECC key which curve parameters will be used
/// to generate the ephemeral key.
/// * `in_point` - An [EccPoint] on the curve of the key referenced by `key_handle`
///
/// # Details
/// This command uses the TPM to recover the Z value from a public point and a private key.
/// It will perform the multiplication of the provided `in_point` with the private key and
/// return the coordinates of the resultant point.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{
/// # Context, TctiNameConf,
/// # attributes::{SessionAttributesBuilder, ObjectAttributesBuilder},
/// # constants::SessionType,
/// # interface_types::{
/// # algorithm::{
/// # HashingAlgorithm, PublicAlgorithm, RsaDecryptAlgorithm,
/// # },
/// # ecc::EccCurve,
/// # resource_handles::Hierarchy,
/// # },
/// # structures::{
/// # Auth, Data, EccScheme, PublicBuilder, PublicEccParametersBuilder, PublicKeyRsa, KeyDerivationFunctionScheme, EccPoint,
/// # RsaDecryptionScheme, HashScheme, SymmetricDefinition,
/// # },
/// # };
/// # use std::{env, str::FromStr, convert::TryFrom};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
/// # )
/// # .expect("Failed to create session")
/// # .expect("Received invalid handle");
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
/// # .expect("Failed to set attributes on session");
/// # context.set_sessions((Some(session), None, None));
/// # let random_digest = context.get_random(16).unwrap();
/// # let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
/// #
/// // Create a key suitable for ECDH key generation
/// let ecc_parms = PublicEccParametersBuilder::new()
/// .with_ecc_scheme(
/// EccScheme::EcDh(HashScheme::new(HashingAlgorithm::Sha256)),
/// )
/// .with_curve(EccCurve::NistP256)
/// .with_is_signing_key(false)
/// .with_is_decryption_key(true)
/// .with_restricted(false)
/// .with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
/// .build()
/// .unwrap();
///
/// let object_attributes = ObjectAttributesBuilder::new()
/// .with_fixed_tpm(true)
/// .with_fixed_parent(true)
/// .with_sensitive_data_origin(true)
/// .with_user_with_auth(true)
/// .with_decrypt(true)
/// .with_sign_encrypt(false)
/// .with_restricted(false)
/// .build()
/// .unwrap();
///
/// let public = PublicBuilder::new()
/// .with_public_algorithm(PublicAlgorithm::Ecc)
/// .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
/// .with_object_attributes(object_attributes)
/// .with_ecc_parameters(ecc_parms)
/// .with_ecc_unique_identifier(EccPoint::default())
/// .build()
/// .unwrap();
///
/// let key_handle = context
/// .create_primary(
/// Hierarchy::Owner,
/// public,
/// Some(key_auth),
/// None,
/// None,
/// None,
/// )
/// .unwrap()
/// .key_handle;
///
/// // Generate ephemeral key pair and a shared secret
/// let (z_point, pub_point) = context.ecdh_key_gen(key_handle).unwrap();
/// let z_point_gen = context.ecdh_z_gen(key_handle, pub_point).unwrap();
/// assert_eq!(z_point.x().value(), z_point_gen.x().value());
/// ```
pub fn ecdh_z_gen(&mut self, key_handle: KeyHandle, in_point: EccPoint) -> Result {
let mut out_point_ptr = null_mut();
let ret = unsafe {
Esys_ECDH_ZGen(
self.mut_context(),
key_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&in_point.into(),
&mut out_point_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let out_point = Context::ffi_data_to_owned(out_point_ptr);
EccPoint::try_from(out_point.point)
} else {
error!("Error when performing ECDH ZGen: {}", ret);
Err(ret)
}
}
// Missing function: ECC_Parameters
// Missing function: ZGen_2Phase
}
tss-esapi-7.4.0/src/context/tpm_commands/attached_components.rs 0000644 0000000 0000000 00000000374 10461020230 0023074 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: AC_GetCapability
// Missing function: AC_Send
// Missing function: Policy_AC_SendSelect
}
tss-esapi-7.4.0/src/context/tpm_commands/attestation_commands.rs 0000644 0000000 0000000 00000016676 10461020230 0023306 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
handles::{KeyHandle, ObjectHandle},
structures::{Attest, AttestBuffer, Data, PcrSelectionList, Signature, SignatureScheme},
tss2_esys::{Esys_Certify, Esys_Quote},
Context, Error, Result,
};
use log::error;
use std::convert::TryFrom;
use std::ptr::null_mut;
impl Context {
/// Prove that an object is loaded in the TPM
///
/// # Arguments
/// * `object_handle` - Handle of the object to be certified
/// * `signing_key_handle` - Handle of the key used to sign the attestation buffer
/// * `qualifying_data` - Qualifying data
/// * `signing_scheme` - Signing scheme to use if the scheme for `signing_key_handle` is `Null`.
///
/// The object may be any object that is loaded with [Self::load()] or [Self::create_primary()]. An object that
/// only has its public area loaded may not be certified.
///
/// The `signing_key_handle` must be usable for signing.
///
/// If `signing_key_handle` has the Restricted attribute set to `true` then `signing_scheme` must be
/// [SignatureScheme::Null].
///
/// # Returns
/// The command returns a tuple consisting of:
/// * `attest_data` - TPM-generated attestation data.
/// * `signature` - Signature for the attestation data.
///
/// # Errors
/// * if the qualifying data provided is too long, a `WrongParamSize` wrapper error will be returned
///
/// # Examples
///
/// ```rust
/// # use tss_esapi::{Context, TctiNameConf};
/// # use std::convert::TryFrom;
/// # use tss_esapi::{
/// # abstraction::cipher::Cipher,
/// # handles::KeyHandle,
/// # interface_types::{
/// # algorithm::{HashingAlgorithm, RsaSchemeAlgorithm, SignatureSchemeAlgorithm},
/// # key_bits::RsaKeyBits,
/// # resource_handles::Hierarchy,
/// # },
/// # structures::{
/// # RsaExponent, RsaScheme, SymmetricDefinition,
/// # },
/// # utils::{create_unrestricted_signing_rsa_public, create_restricted_decryption_rsa_public},
/// # };
/// use std::convert::TryInto;
/// use tss_esapi::{
/// structures::{Data, SignatureScheme},
/// interface_types::session_handles::AuthSession,
/// };
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// let qualifying_data = vec![0xff; 16];
/// # let signing_key_pub = create_unrestricted_signing_rsa_public(
/// # RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256))
/// # .expect("Failed to create RSA scheme"),
/// # RsaKeyBits::Rsa2048,
/// # RsaExponent::default(),
/// # )
/// # .expect("Failed to create an unrestricted signing rsa public structure");
/// # let sign_key_handle = context
/// # .execute_with_nullauth_session(|ctx| {
/// # ctx.create_primary(Hierarchy::Owner, signing_key_pub, None, None, None, None)
/// # })
/// # .unwrap()
/// # .key_handle;
/// # let decryption_key_pub = create_restricted_decryption_rsa_public(
/// # Cipher::aes_256_cfb()
/// # .try_into()
/// # .expect("Failed to create symmetric object"),
/// # RsaKeyBits::Rsa2048,
/// # RsaExponent::default(),
/// # )
/// # .expect("Failed to create a restricted decryption rsa public structure");
/// # let obj_key_handle = context
/// # .execute_with_nullauth_session(|ctx| {
/// # ctx.create_primary(
/// # Hierarchy::Owner,
/// # decryption_key_pub,
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # })
/// # .unwrap()
/// # .key_handle;
/// let (attest, signature) = context
/// .execute_with_sessions(
/// (
/// Some(AuthSession::Password),
/// Some(AuthSession::Password),
/// None,
/// ),
/// |ctx| {
/// ctx.certify(
/// obj_key_handle.into(),
/// sign_key_handle,
/// Data::try_from(qualifying_data).unwrap(),
/// SignatureScheme::Null,
/// )
/// },
/// )
/// .expect("Failed to certify object handle");
/// ```
pub fn certify(
&mut self,
object_handle: ObjectHandle,
signing_key_handle: KeyHandle,
qualifying_data: Data,
signing_scheme: SignatureScheme,
) -> Result<(Attest, Signature)> {
let mut certify_info_ptr = null_mut();
let mut signature_ptr = null_mut();
let ret = unsafe {
Esys_Certify(
self.mut_context(),
object_handle.into(),
signing_key_handle.into(),
self.required_session_1()?,
self.required_session_2()?,
self.optional_session_3(),
&qualifying_data.into(),
&signing_scheme.into(),
&mut certify_info_ptr,
&mut signature_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let certify_info = Context::ffi_data_to_owned(certify_info_ptr);
let signature = Context::ffi_data_to_owned(signature_ptr);
Ok((
Attest::try_from(AttestBuffer::try_from(certify_info)?)?,
Signature::try_from(signature)?,
))
} else {
error!("Error in certifying: {}", ret);
Err(ret)
}
}
// Missing function: CertifyCreation
/// Generate a quote on the selected PCRs
///
/// # Errors
/// * if the qualifying data provided is too long, a `WrongParamSize` wrapper error will be returned
pub fn quote(
&mut self,
signing_key_handle: KeyHandle,
qualifying_data: Data,
signing_scheme: SignatureScheme,
pcr_selection_list: PcrSelectionList,
) -> Result<(Attest, Signature)> {
let mut quoted_ptr = null_mut();
let mut signature_ptr = null_mut();
let ret = unsafe {
Esys_Quote(
self.mut_context(),
signing_key_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&qualifying_data.into(),
&signing_scheme.into(),
&pcr_selection_list.into(),
&mut quoted_ptr,
&mut signature_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let quoted = Context::ffi_data_to_owned(quoted_ptr);
let signature = Context::ffi_data_to_owned(signature_ptr);
Ok((
Attest::try_from(AttestBuffer::try_from(quoted)?)?,
Signature::try_from(signature)?,
))
} else {
error!("Error in quoting PCR: {}", ret);
Err(ret)
}
}
// Missing function: GetSessionAuditDigest
// Missing function: GestCommandAuditDigest
// Missing function: GetTime
// Missing function: CertifyX509
}
tss-esapi-7.4.0/src/context/tpm_commands/authenticated_countdown_timer.rs 0000644 0000000 0000000 00000000253 10461020230 0025170 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: ACT_SetTimeout
}
tss-esapi-7.4.0/src/context/tpm_commands/capability_commands.rs 0000644 0000000 0000000 00000006527 10461020230 0023062 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::CapabilityType,
interface_types::YesNo,
structures::{CapabilityData, PublicParameters},
tss2_esys::{Esys_GetCapability, Esys_TestParms},
Context, Error, Result,
};
use log::{error, warn};
use std::convert::TryFrom;
use std::ptr::null_mut;
impl Context {
/// Get current capability information about the TPM.
///
/// # Warning
/// - If [CapabilityType::AuthPolicies] is used but the version of the
/// tpm2-tss library used does not have the 'authPolicies' field
/// in the TPMU_CAPABILITIES defined then the call using this method
/// will fail.
///
/// - If [CapabilityType::Act] is used but the the version of the
/// tpm2-tss library used does not have the 'actData' field in the
/// TPMU_CAPABILITIES defined then the call using this method will fail.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{Context, TctiNameConf};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// use tss_esapi::constants::CapabilityType;
///
/// let (_capabilities, _more) = context
/// .get_capability(CapabilityType::Algorithms, 0, 80)
/// .expect("Failed to call get_capability");
/// ```
pub fn get_capability(
&mut self,
capability: CapabilityType,
property: u32,
property_count: u32,
) -> Result<(CapabilityData, bool)> {
let mut capability_data_ptr = null_mut();
let mut more_data = YesNo::No.into();
let ret = unsafe {
Esys_GetCapability(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
capability.into(),
property,
property_count,
&mut more_data,
&mut capability_data_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
CapabilityData::try_from(Context::ffi_data_to_owned(capability_data_ptr))?,
YesNo::try_from(more_data)?.into(),
))
} else {
error!("Error when getting capabilities: {}", ret);
Err(ret)
}
}
/// Test if the given parameters are supported by the TPM.
///
/// # Errors
/// * if any of the public parameters is not compatible with the TPM,
/// an `Err` containing the specific unmarshalling error will be returned.
pub fn test_parms(&mut self, public_parmeters: PublicParameters) -> Result<()> {
let ret = unsafe {
Esys_TestParms(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&public_parmeters.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
warn!("Parameters under test could not be unmarshalled: {}", ret);
Err(ret)
}
}
}
tss-esapi-7.4.0/src/context/tpm_commands/clocks_and_timers.rs 0000644 0000000 0000000 00000000361 10461020230 0022531 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: ReadClock
// Missing function: ClockSet
// Missing function: ClockRateAdjust
}
tss-esapi-7.4.0/src/context/tpm_commands/command_audit.rs 0000644 0000000 0000000 00000000266 10461020230 0021656 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: SetCommandCodeAuditStatus
}
tss-esapi-7.4.0/src/context/tpm_commands/context_management.rs 0000644 0000000 0000000 00000047707 10461020230 0022745 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::handle_manager::HandleDropAction,
handles::{handle_conversion::TryIntoNotNone, AuthHandle, ObjectHandle, PersistentTpmHandle},
interface_types::{dynamic_handles::Persistent, resource_handles::Provision},
tss2_esys::{Esys_ContextLoad, Esys_ContextSave, Esys_EvictControl, Esys_FlushContext},
utils::TpmsContext,
Context, Error, Result,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
impl Context {
/// Save the context of an object from the TPM and return it.
///
/// # Errors
/// * if conversion from `TPMS_CONTEXT` to `TpmsContext` fails, a `WrongParamSize` error will
/// be returned
pub fn context_save(&mut self, handle: ObjectHandle) -> Result {
let mut context_ptr = null_mut();
let ret = unsafe { Esys_ContextSave(self.mut_context(), handle.into(), &mut context_ptr) };
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
TpmsContext::try_from(Context::ffi_data_to_owned(context_ptr))
} else {
error!("Error in saving context: {}", ret);
Err(ret)
}
}
/// Load a previously saved context into the TPM and return the object handle.
///
/// # Errors
/// * if conversion from `TpmsContext` to the native `TPMS_CONTEXT` fails, a `WrongParamSize`
/// error will be returned
pub fn context_load(&mut self, context: TpmsContext) -> Result {
let mut loaded_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_ContextLoad(self.mut_context(), &context.try_into()?, &mut loaded_handle)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
self.handle_manager
.add_handle(loaded_handle.into(), HandleDropAction::Flush)?;
Ok(loaded_handle.into())
} else {
error!("Error in loading context: {}", ret);
Err(ret)
}
}
/// Flush the context of an object from the TPM.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{
/// # Context, tcti_ldr::TctiNameConf, structures::Auth,
/// # constants::{
/// # tss::{TPMA_SESSION_DECRYPT, TPMA_SESSION_ENCRYPT},
/// # SessionType,
/// # },
/// # interface_types::{
/// # resource_handles::Hierarchy,
/// # algorithm::{HashingAlgorithm, RsaSchemeAlgorithm},
/// # key_bits::RsaKeyBits,
/// # },
/// # utils::create_unrestricted_signing_rsa_public,
/// # attributes::SessionAttributesBuilder,
/// # structures::{SymmetricDefinition, RsaExponent, RsaScheme},
/// # };
/// # use std::convert::TryFrom;
/// # use std::str::FromStr;
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
///
/// // Create session for a key
/// let session = context
/// .start_auth_session(
/// None,
/// None,
/// None,
/// SessionType::Hmac,
/// SymmetricDefinition::AES_256_CFB,
/// HashingAlgorithm::Sha256,
/// )
/// .expect("Failed to create session")
/// .expect("Received invalid handle");
/// let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// .with_decrypt(true)
/// .with_encrypt(true)
/// .build();
/// context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
/// .expect("Failed to set attributes on session");
///
/// // Create public area for a rsa key
/// let public_area = create_unrestricted_signing_rsa_public(
/// RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256))
/// .expect("Failed to create RSA scheme"),
/// RsaKeyBits::Rsa2048,
/// RsaExponent::default(),
/// )
/// .expect("Failed to create rsa public area");
///
/// // Execute context methods using the session
/// context.execute_with_session(Some(session), |ctx| {
/// let random_digest = ctx.get_random(16)
/// .expect("Call to get_random failed");
/// let key_auth = Auth::try_from(random_digest.value().to_vec())
/// .expect("Failed to create Auth");
/// let key_handle = ctx
/// .create_primary(
/// Hierarchy::Owner,
/// public_area,
/// Some(key_auth),
/// None,
/// None,
/// None,
/// )
/// .expect("Failed to create primary key")
/// .key_handle;
///
/// // Flush the context of the key.
/// ctx.flush_context(key_handle.into()).expect("Call to flush_context failed");
/// assert!(ctx.read_public(key_handle).is_err());
/// })
/// ```
pub fn flush_context(&mut self, handle: ObjectHandle) -> Result<()> {
let ret = unsafe { Esys_FlushContext(self.mut_context(), handle.try_into_not_none()?) };
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
self.handle_manager.set_as_flushed(handle)?;
Ok(())
} else {
error!("Error in flushing context: {}", ret);
Err(ret)
}
}
/// Evicts persistent objects or allows certain transient objects
/// to be made persistent.
///
/// # Details
/// In order to be able to perform this action an authorization
/// session is required.
///
/// # Arguments
/// * `auth` - An a handle used for authorization that is limited to the ones
/// specified in [Provision].
/// * `object_handle` - The handle of a loaded object.
/// * `persistent` - If the `object_handle` is transient object then this
/// then this will become the persistent handle of that
/// object. If the `object_handle` refers to a persistent
/// object then this shall be the persistent handle of that
/// object.
///
/// # Returns
/// If the input `object_handle` was transient object then it will be made
/// persistent and the returned [ObjectHandle] will refer to the persistent
/// object.
///
/// If the input `object_handle` refers to a persistent object the returned
/// value will be ObjectHandle::None and the input `object_handle` will not
/// be valid after this call is made.
///
/// # Example
///
/// Make transient object persistent:
/// ```rust
/// # use tss_esapi::{
/// # Context, tcti_ldr::TctiNameConf, Result,
/// # constants::{
/// # SessionType, CapabilityType,
/// # tss::TPM2_PERSISTENT_FIRST,
/// # },
/// # handles::PcrHandle,
/// # structures::{Digest, CapabilityData, Auth, RsaExponent, SymmetricDefinitionObject},
/// # interface_types::{
/// # resource_handles::Hierarchy,
/// # key_bits::RsaKeyBits,
/// # },
/// # handles::{ObjectHandle, TpmHandle, PersistentTpmHandle},
/// # utils::create_restricted_decryption_rsa_public,
/// # tss2_esys::TPM2_HANDLE,
/// # };
/// # use std::{env, str::FromStr, convert::TryFrom};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// # // Create persistent TPM handle with
/// # let persistent_tpm_handle =
/// # PersistentTpmHandle::new(u32::from_be_bytes([0x81, 0x00, 0x00, 0x01]))
/// # .expect("Failed to create Persistent TPM handle");
/// # // -----> REMOVE ANY PREVIOUS HANDLES <---------------
/// # let mut property = TPM2_PERSISTENT_FIRST;
/// # while let Ok((capability_data, more_data_available)) =
/// # context.get_capability(CapabilityType::Handles, property, 1)
/// # {
/// # if let CapabilityData::Handles(persistent_handles) = capability_data {
/// # if let Some(&retrieved_persistent_handle) = persistent_handles.first() {
/// # if retrieved_persistent_handle == persistent_tpm_handle.into() {
/// # let handle = context
/// # .tr_from_tpm_public(TpmHandle::Persistent(persistent_tpm_handle))
/// # .expect("Failed to retrieve handle from TPM");
/// # context.execute_with_session(Some(tss_esapi::interface_types::session_handles::AuthSession::Password), |ctx| {
/// # ctx
/// # .evict_control(
/// # tss_esapi::interface_types::resource_handles::Provision::Owner,
/// # handle,
/// # tss_esapi::interface_types::dynamic_handles::Persistent::Persistent(persistent_tpm_handle),
/// # )
/// # .expect("Failed to evict persitent handle")
/// # });
/// # break;
/// # }
/// # if more_data_available {
/// # property = TPM2_HANDLE::from(retrieved_persistent_handle) + 1;
/// # }
/// # }
/// # }
/// # if !more_data_available {
/// # break;
/// # }
/// # }
/// # let transient_object_handle = context.execute_with_session(Some(tss_esapi::interface_types::session_handles::AuthSession::Password), |ctx| {
/// # // Create primary key handle
/// # let auth_value_primary = Auth::try_from(vec![1, 2, 3, 4, 5])
/// # .expect("Failed to crate auth value for primary key");
/// # ctx
/// # .create_primary(
/// # Hierarchy::Owner,
/// # create_restricted_decryption_rsa_public(
/// # SymmetricDefinitionObject::AES_256_CFB,
/// # RsaKeyBits::Rsa2048,
/// # RsaExponent::default(),
/// # ).expect("Failed to Public structure for key"),
/// # Some(auth_value_primary),
/// # None,
/// # None,
/// # None,
/// # )
/// # .map(|v| ObjectHandle::from(v.key_handle))
/// # .expect("Failed to create primary key")
/// # });
/// use tss_esapi::{
/// interface_types::{
/// resource_handles::Provision,
/// dynamic_handles::Persistent,
/// session_handles::AuthSession,
/// },
/// };
/// // Create interface type Persistent by using the persistent tpm handle.
/// let persistent = Persistent::Persistent(persistent_tpm_handle);
/// // Make transient_object_handle persistent.
/// // An authorization session is required!
/// let mut persistent_object_handle = context.execute_with_session(Some(AuthSession::Password), |ctx| {
/// ctx
/// .evict_control(Provision::Owner, transient_object_handle.into(), persistent)
/// .expect("Failed to make the transient_object_handle handle persistent")
/// });
/// # assert_ne!(persistent_object_handle, ObjectHandle::Null);
/// # assert_ne!(persistent_object_handle, ObjectHandle::None);
/// # // Flush out the transient_object_handle
/// # context
/// # .flush_context(ObjectHandle::from(transient_object_handle))
/// # .expect("Failed to flush context");
/// # // Close the persistent_handle returned by evict_control
/// # context
/// # .tr_close(&mut persistent_object_handle)
/// # .expect("Failed to close persistent handle");
/// # // Retrieve the handle from the tpm again.
/// # let retireved_persistent_handle = context.execute_without_session(|ctx| {
/// # ctx.tr_from_tpm_public(TpmHandle::Persistent(persistent_tpm_handle))
/// # .expect("Failed to load the persistent handle")
/// # });
/// # // Evict the persitent handle from the tpm
/// # let _ = context.execute_with_session(Some(AuthSession::Password), |ctx| {
/// # ctx
/// # .evict_control(Provision::Owner, retireved_persistent_handle, persistent)
/// # .expect("Failed to evict persistent handle")
/// # });
/// # assert_ne!(retireved_persistent_handle, ObjectHandle::None);
/// ```
///
/// Make persistent object transient
/// ```rust
/// # use tss_esapi::{
/// # Context, tcti_ldr::TctiNameConf, Result,
/// # constants::{
/// # SessionType, CapabilityType,
/// # tss::TPM2_PERSISTENT_FIRST,
/// # },
/// # handles::PcrHandle,
/// # structures::{Digest, CapabilityData, Auth, RsaExponent, SymmetricDefinitionObject},
/// # interface_types::{
/// # resource_handles::Hierarchy,
/// # key_bits::RsaKeyBits,
/// # },
/// # handles::{ObjectHandle, TpmHandle, PersistentTpmHandle},
/// # utils::create_restricted_decryption_rsa_public,
/// # tss2_esys::TPM2_HANDLE,
/// # };
/// # use std::{env, str::FromStr, convert::TryFrom};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// # // Create persistent TPM handle with
/// # let persistent_tpm_handle =
/// # PersistentTpmHandle::new(u32::from_be_bytes([0x81, 0x00, 0x00, 0x01]))
/// # .expect("Failed to create Persistent TPM handle");
/// # // -----> REMOVE ANY PREVIOUS HANDLES <---------------
/// # let mut property = TPM2_PERSISTENT_FIRST;
/// # while let Ok((capability_data, more_data_available)) =
/// # context.get_capability(CapabilityType::Handles, property, 1)
/// # {
/// # if let CapabilityData::Handles(persistent_handles) = capability_data {
/// # if let Some(&retrieved_persistent_handle) = persistent_handles.first() {
/// # if retrieved_persistent_handle == persistent_tpm_handle.into() {
/// # let handle = context
/// # .tr_from_tpm_public(TpmHandle::Persistent(persistent_tpm_handle))
/// # .expect("Failed to retrieve handle from TPM");
/// # context.execute_with_session(Some(tss_esapi::interface_types::session_handles::AuthSession::Password), |ctx| {
/// # ctx
/// # .evict_control(
/// # tss_esapi::interface_types::resource_handles::Provision::Owner,
/// # handle,
/// # tss_esapi::interface_types::dynamic_handles::Persistent::Persistent(persistent_tpm_handle),
/// # )
/// # .expect("Failed to evict persitent handle")
/// # });
/// # break;
/// # }
/// # if more_data_available {
/// # property = TPM2_HANDLE::from(retrieved_persistent_handle) + 1;
/// # }
/// # }
/// # }
/// # if !more_data_available {
/// # break;
/// # }
/// # }
/// # let transient_object_handle = context.execute_with_session(Some(tss_esapi::interface_types::session_handles::AuthSession::Password), |ctx| {
/// # // Create primary key handle
/// # let auth_value_primary = Auth::try_from(vec![1, 2, 3, 4, 5])
/// # .expect("Failed to crate auth value for primary key");
/// # ctx
/// # .create_primary(
/// # Hierarchy::Owner,
/// # create_restricted_decryption_rsa_public(
/// # SymmetricDefinitionObject::AES_256_CFB,
/// # RsaKeyBits::Rsa2048,
/// # RsaExponent::default(),
/// # ).expect("Failed to Public structure for key"),
/// # Some(auth_value_primary),
/// # None,
/// # None,
/// # None,
/// # )
/// # .map(|v| ObjectHandle::from(v.key_handle))
/// # .expect("Failed to create primary key")
/// # });
/// use tss_esapi::{
/// interface_types::{
/// resource_handles::Provision,
/// dynamic_handles::Persistent,
/// session_handles::AuthSession,
/// },
/// };
/// // Create interface type Persistent by using the persistent tpm handle.
/// let persistent = Persistent::Persistent(persistent_tpm_handle);
/// # // Evict control to make transient_object_handle persistent.
/// # // An authorization session is required!
/// # let mut persistent_object_handle = context.execute_with_session(Some(AuthSession::Password), |ctx| {
/// # ctx
/// # .evict_control(Provision::Owner, transient_object_handle.into(), persistent)
/// # .expect("Failed to make the transient_object_handle handle persistent")
/// # });
/// # assert_ne!(persistent_object_handle, ObjectHandle::Null);
/// # assert_ne!(persistent_object_handle, ObjectHandle::None);
/// # // Flush out the transient_object_handle
/// # context
/// # .flush_context(ObjectHandle::from(transient_object_handle))
/// # .expect("Failed to flush context");
/// # // Close the persistent_handle returned by evict_control
/// # context
/// # .tr_close(&mut persistent_object_handle)
/// # .expect("Failed to close persistent handle");
/// # // Retrieve the handle from the tpm again.
/// # let retrieved_persistent_handle = context.execute_without_session(|ctx| {
/// # ctx.tr_from_tpm_public(TpmHandle::Persistent(persistent_tpm_handle))
/// # .expect("Failed to load the persistent handle")
/// # });
/// // Evict the persitent handle from the tpm
/// // An authorization session is required!
/// let _ = context.execute_with_session(Some(AuthSession::Password), |ctx| {
/// ctx
/// .evict_control(Provision::Owner, retrieved_persistent_handle, persistent)
/// .expect("Failed to evict persistent handle")
/// });
/// # assert_ne!(retrieved_persistent_handle, ObjectHandle::None);
/// ```
pub fn evict_control(
&mut self,
auth: Provision,
object_handle: ObjectHandle,
persistent: Persistent,
) -> Result {
let mut new_object_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_EvictControl(
self.mut_context(),
AuthHandle::from(auth).into(),
object_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
PersistentTpmHandle::from(persistent).into(),
&mut new_object_handle,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let new_object_handle = ObjectHandle::from(new_object_handle);
// If you look at the specification and see that it says ESYS_TR_NULL
// then that is an error in the spec. ESYS_TR_NULL was renamed to
// ESYS_TR NONE.
if new_object_handle.is_none() {
self.handle_manager.set_as_closed(object_handle)?;
} else {
self.handle_manager
.add_handle(new_object_handle, HandleDropAction::Close)?;
}
Ok(new_object_handle)
} else {
error!("Error in evict control: {}", ret);
Err(ret)
}
}
}
tss-esapi-7.4.0/src/context/tpm_commands/dictionary_attack_functions.rs 0000644 0000000 0000000 00000000352 10461020230 0024632 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: DictionaryAttackLockReset
// Missing function: DictionaryAttackParameters
}
tss-esapi-7.4.0/src/context/tpm_commands/duplication_commands.rs 0000644 0000000 0000000 00000063474 10461020230 0023260 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
use crate::{
handles::ObjectHandle,
structures::{Data, EncryptedSecret, Private, Public, SymmetricDefinitionObject},
tss2_esys::{Esys_Duplicate, Esys_Import},
Error, Result,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
impl Context {
/// Duplicate a loaded object so that it may be used in a different hierarchy.
///
/// # Details
/// This command duplicates a loaded object so that it may be used in a different hierarchy.
/// The new parent key for the duplicate may be on the same or different TPM or the Null hierarchy.
/// Only the public area of `new_parent_handle` is required to be loaded.
///
/// # Arguments
/// * `object_to_duplicate` - An [ObjectHandle] of the object that will be duplicated.
/// * `new_parent_handle` - An [ObjectHandle] of the new parent.
/// * `encryption_key_in` - An optional encryption key. If this parameter is `None`
/// then a [default value][Default::default] is used.
/// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
///
/// The `object_to_duplicate` need to be have Fixed TPM and Fixed Parent attributes set to `false`.
///
/// # Returns
/// The command returns a tuple consisting of:
/// * `encryption_key_out` - TPM generated, symmetric encryption key for the inner wrapper if
/// `symmetric_alg` is not `Null`.
/// * `duplicate` - Private area that may be encrypted.
/// * `out_sym_seed` - Seed protected by the asymmetric algorithms of new parent.
///
/// # Example
///
/// ```rust
/// # use std::convert::{TryFrom, TryInto};
/// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
/// # use tss_esapi::constants::{CommandCode, SessionType};
/// # use tss_esapi::handles::ObjectHandle;
/// # use tss_esapi::interface_types::{
/// # algorithm::{HashingAlgorithm, PublicAlgorithm},
/// # key_bits::RsaKeyBits,
/// # resource_handles::Hierarchy,
/// # session_handles::PolicySession,
/// # };
/// # use tss_esapi::structures::SymmetricDefinition;
/// # use tss_esapi::structures::{
/// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
/// # RsaExponent,
/// # };
/// use tss_esapi::structures::SymmetricDefinitionObject;
/// # use tss_esapi::abstraction::cipher::Cipher;
/// # use tss_esapi::{Context, TctiNameConf};
/// #
/// # let mut context = // ...
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let trial_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Trial,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
/// # SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context
/// # .tr_sess_set_attributes(
/// # trial_session,
/// # policy_auth_session_attributes,
/// # policy_auth_session_attributes_mask,
/// # )
/// # .expect("tr_sess_set_attributes call failed");
/// #
/// # let policy_session = PolicySession::try_from(trial_session)
/// # .expect("Failed to convert auth session into policy session");
/// #
/// # context
/// # .policy_auth_value(policy_session)
/// # .expect("Policy auth value");
/// #
/// # context
/// # .policy_command_code(policy_session, CommandCode::Duplicate)
/// # .expect("Policy command code");
/// #
/// # /// Digest of the policy that allows duplication
/// # let digest = context
/// # .policy_get_digest(policy_session)
/// # .expect("Could retrieve digest");
/// #
/// # drop(context);
/// # let mut context = // ...
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// #
/// # context.tr_sess_set_attributes(
/// # session,
/// # session_attributes,
/// # session_attributes_mask,
/// # ).unwrap();
/// #
/// # context.set_sessions((Some(session), None, None));
/// #
/// # // Attributes of parent objects. The `restricted` attribute need
/// # // to be `true` so that parents can act as storage keys.
/// # let parent_object_attributes = ObjectAttributesBuilder::new()
/// # .with_fixed_tpm(true)
/// # .with_fixed_parent(true)
/// # .with_sensitive_data_origin(true)
/// # .with_user_with_auth(true)
/// # .with_decrypt(true)
/// # .with_sign_encrypt(false)
/// # .with_restricted(true)
/// # .build()
/// # .unwrap();
/// #
/// # let parent_public = PublicBuilder::new()
/// # .with_public_algorithm(PublicAlgorithm::Rsa)
/// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
/// # .with_object_attributes(parent_object_attributes)
/// # .with_rsa_parameters(
/// # PublicRsaParametersBuilder::new_restricted_decryption_key(
/// # Cipher::aes_256_cfb().try_into().unwrap(),
/// # RsaKeyBits::Rsa2048,
/// # RsaExponent::default(),
/// # )
/// # .build()
/// # .unwrap(),
/// # )
/// # .with_rsa_unique_identifier(PublicKeyRsa::default())
/// # .build()
/// # .unwrap();
/// #
/// # let parent_of_object_to_duplicate_handle = context
/// # .create_primary(
/// # Hierarchy::Owner,
/// # parent_public.clone(),
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # .unwrap()
/// # .key_handle;
/// #
/// # // Fixed TPM and Fixed Parent should be "false" for an object
/// # // to be eligible for duplication
/// # let object_attributes = ObjectAttributesBuilder::new()
/// # .with_fixed_tpm(false)
/// # .with_fixed_parent(false)
/// # .with_sensitive_data_origin(true)
/// # .with_user_with_auth(true)
/// # .with_decrypt(true)
/// # .with_sign_encrypt(true)
/// # .with_restricted(false)
/// # .build()
/// # .expect("Attributes to be valid");
/// #
/// # let public_child = PublicBuilder::new()
/// # .with_public_algorithm(PublicAlgorithm::Rsa)
/// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
/// # .with_object_attributes(object_attributes)
/// # .with_auth_policy(digest)
/// # .with_rsa_parameters(
/// # PublicRsaParametersBuilder::new()
/// # .with_scheme(RsaScheme::Null)
/// # .with_key_bits(RsaKeyBits::Rsa2048)
/// # .with_is_signing_key(true)
/// # .with_is_decryption_key(true)
/// # .with_restricted(false)
/// # .build()
/// # .expect("Params to be valid"),
/// # )
/// # .with_rsa_unique_identifier(PublicKeyRsa::default())
/// # .build()
/// # .expect("public to be valid");
/// #
/// # let result = context
/// # .create(
/// # parent_of_object_to_duplicate_handle,
/// # public_child,
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # .unwrap();
/// #
/// # let object_to_duplicate_handle: ObjectHandle = context
/// # .load(
/// # parent_of_object_to_duplicate_handle,
/// # result.out_private.clone(),
/// # result.out_public,
/// # )
/// # .unwrap()
/// # .into();
/// #
/// # let new_parent_handle: ObjectHandle = context
/// # .create_primary(
/// # Hierarchy::Owner,
/// # parent_public,
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # .unwrap()
/// # .key_handle
/// # .into();
/// #
/// # context.set_sessions((None, None, None));
/// #
/// # // Create a Policy session with the same exact attributes
/// # // as the trial session so that the session digest stays
/// # // the same.
/// # let policy_auth_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Policy,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
/// # SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context
/// # .tr_sess_set_attributes(
/// # policy_auth_session,
/// # policy_auth_session_attributes,
/// # policy_auth_session_attributes_mask,
/// # )
/// # .expect("tr_sess_set_attributes call failed");
/// #
/// # let policy_session = PolicySession::try_from(policy_auth_session)
/// # .expect("Failed to convert auth session into policy session");
/// #
/// # context
/// # .policy_auth_value(policy_session)
/// # .expect("Policy auth value");
/// #
/// # context
/// # .policy_command_code(policy_session, CommandCode::Duplicate)
/// # .unwrap();
/// #
/// # context.set_sessions((Some(policy_auth_session), None, None));
///
/// let (encryption_key_out, duplicate, out_sym_seed) = context
/// .duplicate(
/// object_to_duplicate_handle,
/// new_parent_handle,
/// None,
/// SymmetricDefinitionObject::Null,
/// )
/// .unwrap();
/// # eprintln!("D: {:?}, P: {:?}, S: {:?}", encryption_key_out, duplicate, out_sym_seed);
/// ```
pub fn duplicate(
&mut self,
object_to_duplicate: ObjectHandle,
new_parent_handle: ObjectHandle,
encryption_key_in: Option,
symmetric_alg: SymmetricDefinitionObject,
) -> Result<(Data, Private, EncryptedSecret)> {
let mut encryption_key_out_ptr = null_mut();
let mut duplicate_ptr = null_mut();
let mut out_sym_seed_ptr = null_mut();
let ret = unsafe {
Esys_Duplicate(
self.mut_context(),
object_to_duplicate.into(),
new_parent_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&encryption_key_in.unwrap_or_default().into(),
&symmetric_alg.into(),
&mut encryption_key_out_ptr,
&mut duplicate_ptr,
&mut out_sym_seed_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
Data::try_from(Context::ffi_data_to_owned(encryption_key_out_ptr))?,
Private::try_from(Context::ffi_data_to_owned(duplicate_ptr))?,
EncryptedSecret::try_from(Context::ffi_data_to_owned(out_sym_seed_ptr))?,
))
} else {
error!("Error when performing duplication: {}", ret);
Err(ret)
}
}
// Missing function: Rewrap
/// Import attaches imported object to a new parent.
///
/// # Details
/// This command allows an object to be encrypted using the symmetric
/// encryption values of a Storage Key. After encryption, the
/// object may be loaded and used in the new hierarchy. The
/// imported object (duplicate) may be singly encrypted, multiply
/// encrypted, or unencrypted.
///
/// # Arguments
/// * `parent_handle` - An [ObjectHandle] of the new parent for the object.
/// * `encryption_key` - An optional symmetric encryption key used as the inner wrapper.
/// If `encryption_key` is `None` then a [default value][Default::default] is used.
/// * `public` - A [Public] of the imported object.
/// * `duplicate` - A symmetrically encrypted duplicated object.
/// * `encrypted_secret` - The seed for the symmetric key and HMAC key.
/// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
///
/// The `public` is needed to check the integrity value for `duplicate`.
///
/// # Returns
/// The command returns the sensitive area encrypted with the symmetric key of `parent_handle`.
///
/// # Example
///
/// ```rust
/// # use std::convert::{TryFrom, TryInto};
/// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
/// # use tss_esapi::constants::{CommandCode, SessionType};
/// # use tss_esapi::handles::ObjectHandle;
/// # use tss_esapi::interface_types::{
/// # algorithm::{HashingAlgorithm, PublicAlgorithm},
/// # key_bits::RsaKeyBits,
/// # resource_handles::Hierarchy,
/// # session_handles::PolicySession,
/// # };
/// # use tss_esapi::structures::SymmetricDefinition;
/// # use tss_esapi::structures::{
/// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
/// # RsaExponent,
/// # };
/// use tss_esapi::structures::SymmetricDefinitionObject;
/// # use tss_esapi::abstraction::cipher::Cipher;
/// # use tss_esapi::{Context, TctiNameConf};
/// #
/// # let mut context = // ...
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let trial_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Trial,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
/// # SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context
/// # .tr_sess_set_attributes(
/// # trial_session,
/// # policy_auth_session_attributes,
/// # policy_auth_session_attributes_mask,
/// # )
/// # .expect("tr_sess_set_attributes call failed");
/// #
/// # let policy_session = PolicySession::try_from(trial_session)
/// # .expect("Failed to convert auth session into policy session");
/// #
/// # context
/// # .policy_auth_value(policy_session)
/// # .expect("Policy auth value");
/// #
/// # context
/// # .policy_command_code(policy_session, CommandCode::Duplicate)
/// # .expect("Policy command code");
/// #
/// # /// Digest of the policy that allows duplication
/// # let digest = context
/// # .policy_get_digest(policy_session)
/// # .expect("Could retrieve digest");
/// #
/// # drop(context);
/// # let mut context = // ...
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// #
/// # context.tr_sess_set_attributes(
/// # session,
/// # session_attributes,
/// # session_attributes_mask,
/// # ).unwrap();
/// #
/// # context.set_sessions((Some(session), None, None));
/// #
/// # // Attributes of parent objects. The `restricted` attribute need
/// # // to be `true` so that parents can act as storage keys.
/// # let parent_object_attributes = ObjectAttributesBuilder::new()
/// # .with_fixed_tpm(true)
/// # .with_fixed_parent(true)
/// # .with_sensitive_data_origin(true)
/// # .with_user_with_auth(true)
/// # .with_decrypt(true)
/// # .with_sign_encrypt(false)
/// # .with_restricted(true)
/// # .build()
/// # .unwrap();
/// #
/// # let parent_public = PublicBuilder::new()
/// # .with_public_algorithm(PublicAlgorithm::Rsa)
/// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
/// # .with_object_attributes(parent_object_attributes)
/// # .with_rsa_parameters(
/// # PublicRsaParametersBuilder::new_restricted_decryption_key(
/// # Cipher::aes_256_cfb().try_into().unwrap(),
/// # RsaKeyBits::Rsa2048,
/// # RsaExponent::default(),
/// # )
/// # .build()
/// # .unwrap(),
/// # )
/// # .with_rsa_unique_identifier(PublicKeyRsa::default())
/// # .build()
/// # .unwrap();
/// #
/// # let parent_of_object_to_duplicate_handle = context
/// # .create_primary(
/// # Hierarchy::Owner,
/// # parent_public.clone(),
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # .unwrap()
/// # .key_handle;
/// #
/// # // Fixed TPM and Fixed Parent should be "false" for an object
/// # // to be eligible for duplication
/// # let object_attributes = ObjectAttributesBuilder::new()
/// # .with_fixed_tpm(false)
/// # .with_fixed_parent(false)
/// # .with_sensitive_data_origin(true)
/// # .with_user_with_auth(true)
/// # .with_decrypt(true)
/// # .with_sign_encrypt(true)
/// # .with_restricted(false)
/// # .build()
/// # .expect("Attributes to be valid");
/// #
/// # let public_child = PublicBuilder::new()
/// # .with_public_algorithm(PublicAlgorithm::Rsa)
/// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
/// # .with_object_attributes(object_attributes)
/// # .with_auth_policy(digest)
/// # .with_rsa_parameters(
/// # PublicRsaParametersBuilder::new()
/// # .with_scheme(RsaScheme::Null)
/// # .with_key_bits(RsaKeyBits::Rsa2048)
/// # .with_is_signing_key(true)
/// # .with_is_decryption_key(true)
/// # .with_restricted(false)
/// # .build()
/// # .expect("Params to be valid"),
/// # )
/// # .with_rsa_unique_identifier(PublicKeyRsa::default())
/// # .build()
/// # .expect("public to be valid");
/// #
/// # let result = context
/// # .create(
/// # parent_of_object_to_duplicate_handle,
/// # public_child,
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # .unwrap();
/// #
/// # let object_to_duplicate_handle: ObjectHandle = context
/// # .load(
/// # parent_of_object_to_duplicate_handle,
/// # result.out_private.clone(),
/// # result.out_public,
/// # )
/// # .unwrap()
/// # .into();
/// #
/// # let new_parent_handle: ObjectHandle = context
/// # .create_primary(
/// # Hierarchy::Owner,
/// # parent_public,
/// # None,
/// # None,
/// # None,
/// # None,
/// # )
/// # .unwrap()
/// # .key_handle
/// # .into();
/// #
/// # context.set_sessions((None, None, None));
/// #
/// # // Create a Policy session with the same exact attributes
/// # // as the trial session so that the session digest stays
/// # // the same.
/// # let policy_auth_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Policy,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
/// # SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context
/// # .tr_sess_set_attributes(
/// # policy_auth_session,
/// # policy_auth_session_attributes,
/// # policy_auth_session_attributes_mask,
/// # )
/// # .expect("tr_sess_set_attributes call failed");
/// #
/// # let policy_session = PolicySession::try_from(policy_auth_session)
/// # .expect("Failed to convert auth session into policy session");
/// #
/// # context
/// # .policy_auth_value(policy_session)
/// # .expect("Policy auth value");
/// #
/// # context
/// # .policy_command_code(policy_session, CommandCode::Duplicate)
/// # .unwrap();
/// #
/// # context.set_sessions((Some(policy_auth_session), None, None));
/// #
/// # let (encryption_key_out, duplicate, out_sym_seed) = context
/// # .duplicate(
/// # object_to_duplicate_handle,
/// # new_parent_handle,
/// # None,
/// # SymmetricDefinitionObject::Null,
/// # )
/// # .unwrap();
/// # eprintln!("D: {:?}, P: {:?}, S: {:?}", encryption_key_out, duplicate, out_sym_seed);
/// # let public = context.read_public(object_to_duplicate_handle.into()).unwrap().0;
/// #
/// # let session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .unwrap();
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context.tr_sess_set_attributes(
/// # session.unwrap(),
/// # session_attributes,
/// # session_attributes_mask,
/// # )
/// # .unwrap();
/// # context.set_sessions((session, None, None));
///
/// // `encryption_key_out`, `duplicate` and `out_sym_seed` are generated
/// // by `duplicate` function
/// let private = context.import(
/// new_parent_handle,
/// Some(encryption_key_out),
/// public,
/// duplicate,
/// out_sym_seed,
/// SymmetricDefinitionObject::Null,
/// ).unwrap();
/// #
/// # eprintln!("P: {:?}", private);
/// ```
pub fn import(
&mut self,
parent_handle: ObjectHandle,
encryption_key: Option,
public: Public,
duplicate: Private,
encrypted_secret: EncryptedSecret,
symmetric_alg: SymmetricDefinitionObject,
) -> Result {
let mut out_private_ptr = null_mut();
let ret = unsafe {
Esys_Import(
self.mut_context(),
parent_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&encryption_key.unwrap_or_default().into(),
&public.try_into()?,
&duplicate.into(),
&encrypted_secret.into(),
&symmetric_alg.into(),
&mut out_private_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Private::try_from(Context::ffi_data_to_owned(out_private_ptr))
} else {
error!("Error when performing import: {}", ret);
Err(ret)
}
}
}
tss-esapi-7.4.0/src/context/tpm_commands/enhanced_authorization_ea_commands.rs 0000644 0000000 0000000 00000052636 10461020230 0026135 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
attributes::LocalityAttributes,
constants::CommandCode,
handles::{AuthHandle, ObjectHandle, SessionHandle},
interface_types::{session_handles::PolicySession, YesNo},
structures::{
AuthTicket, Digest, DigestList, Name, Nonce, PcrSelectionList, Signature, Timeout,
VerifiedTicket,
},
tss2_esys::{
Esys_PolicyAuthValue, Esys_PolicyAuthorize, Esys_PolicyCommandCode, Esys_PolicyCpHash,
Esys_PolicyDuplicationSelect, Esys_PolicyGetDigest, Esys_PolicyLocality,
Esys_PolicyNameHash, Esys_PolicyNvWritten, Esys_PolicyOR, Esys_PolicyPCR,
Esys_PolicyPassword, Esys_PolicyPhysicalPresence, Esys_PolicySecret, Esys_PolicySigned,
Esys_PolicyTemplate,
},
Context, Error, Result, WrapperErrorKind as ErrorKind,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
use std::time::Duration;
impl Context {
/// Cause the policy to include a signed authorization
#[allow(clippy::too_many_arguments)]
pub fn policy_signed(
&mut self,
policy_session: PolicySession,
auth_object: ObjectHandle,
nonce_tpm: Nonce,
cp_hash_a: Digest,
policy_ref: Nonce,
expiration: Option,
signature: Signature,
) -> Result<(Timeout, AuthTicket)> {
let mut out_timeout_ptr = null_mut();
let mut out_policy_ticket_ptr = null_mut();
let ret = unsafe {
Esys_PolicySigned(
self.mut_context(),
auth_object.into(),
SessionHandle::from(policy_session).into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&nonce_tpm.into(),
&cp_hash_a.into(),
&policy_ref.into(),
i32::try_from(expiration.map_or(0, |v| v.as_secs())).map_err(|e| {
error!("Unable to convert duration to i32: {}", e);
Error::local_error(ErrorKind::InvalidParam)
})?,
&signature.try_into()?,
&mut out_timeout_ptr,
&mut out_policy_ticket_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
Timeout::try_from(Context::ffi_data_to_owned(out_timeout_ptr))?,
AuthTicket::try_from(Context::ffi_data_to_owned(out_policy_ticket_ptr))?,
))
} else {
error!("Error when sending policy signed: {}", ret);
Err(ret)
}
}
/// Cause the policy to require a secret in authValue
pub fn policy_secret(
&mut self,
policy_session: PolicySession,
auth_handle: AuthHandle,
nonce_tpm: Nonce,
cp_hash_a: Digest,
policy_ref: Nonce,
expiration: Option,
) -> Result<(Timeout, AuthTicket)> {
let mut out_timeout_ptr = null_mut();
let mut out_policy_ticket_ptr = null_mut();
let ret = unsafe {
Esys_PolicySecret(
self.mut_context(),
auth_handle.into(),
SessionHandle::from(policy_session).into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&nonce_tpm.into(),
&cp_hash_a.into(),
&policy_ref.into(),
i32::try_from(expiration.map_or(0, |v| v.as_secs())).map_err(|e| {
error!("Unable to convert duration to i32: {}", e);
Error::local_error(ErrorKind::InvalidParam)
})?,
&mut out_timeout_ptr,
&mut out_policy_ticket_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
Timeout::try_from(Context::ffi_data_to_owned(out_timeout_ptr))?,
AuthTicket::try_from(Context::ffi_data_to_owned(out_policy_ticket_ptr))?,
))
} else {
error!("Error when sending policy secret: {}", ret);
Err(ret)
}
}
// Missing function: PolicyTicket
/// Cause conditional gating of a policy based on an OR'd condition.
///
/// The TPM will ensure that the current policy digest equals at least
/// one of the digests.
/// If this is the case, the policyDigest of the policy session is replaced
/// by the value of the different hashes.
///
/// # Constraints
/// * `digest_list` must be at least 2 and at most 8 elements long
///
/// # Errors
/// * if the hash list provided is too short or too long, a `WrongParamSize` wrapper error will be returned
pub fn policy_or(
&mut self,
policy_session: PolicySession,
digest_list: DigestList,
) -> Result<()> {
if digest_list.len() < 2 {
error!(
"The digest list only contains {} digests, it must contain at least 2",
digest_list.len()
);
return Err(Error::local_error(ErrorKind::WrongParamSize));
}
let ret = unsafe {
Esys_PolicyOR(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&digest_list.try_into()?,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy OR: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on PCR.
///
/// # Details
/// The TPM will use the hash algorithm of the policy_session
/// to calculate a digest from the values of the pcr slots
/// specified in the pcr_selections.
/// This is then compared to pcr_policy_digest if they match then
/// the policyDigest of the policy session is extended.
///
/// # Errors
/// * if the pcr policy digest provided is too long, a `WrongParamSize` wrapper error will be returned
pub fn policy_pcr(
&mut self,
policy_session: PolicySession,
pcr_policy_digest: Digest,
pcr_selection_list: PcrSelectionList,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyPCR(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&pcr_policy_digest.into(),
&pcr_selection_list.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy PCR: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on locality.
///
/// The TPM will ensure that the current policy can only complete in the specified
/// locality (extended) or any of the specified localities (non-extended).
pub fn policy_locality(
&mut self,
policy_session: PolicySession,
locality: LocalityAttributes,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyLocality(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
locality.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy locality: {}", ret);
Err(ret)
}
}
// Missing function: PolicyNV
// Missing function: PolicyCounterTimer
/// Cause conditional gating of a policy based on command code of authorized command.
///
/// The TPM will ensure that the current policy can only be used to complete the command
/// indicated by code.
pub fn policy_command_code(
&mut self,
policy_session: PolicySession,
code: CommandCode,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyCommandCode(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
code.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy command code: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on physical presence.
///
/// The TPM will ensure that the current policy can only complete when physical
/// presence is asserted. The way this is done is implementation-specific.
pub fn policy_physical_presence(&mut self, policy_session: PolicySession) -> Result<()> {
let ret = unsafe {
Esys_PolicyPhysicalPresence(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy physical presence: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on command parameters.
///
/// The TPM will ensure that the current policy can only be used to authorize
/// a command where the parameters are hashed into cp_hash_a.
pub fn policy_cp_hash(
&mut self,
policy_session: PolicySession,
cp_hash_a: Digest,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyCpHash(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&cp_hash_a.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy command parameters: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on name hash.
///
/// The TPM will ensure that the current policy can only be used to authorize
/// a command acting on an object whose name hashes to name_hash.
pub fn policy_name_hash(
&mut self,
policy_session: PolicySession,
name_hash: Digest,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyNameHash(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&name_hash.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy name hash: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on duplication parent's name.
///
/// # Arguments
/// * `policy_session` - The [policy session][PolicySession] being extended.
/// * `object_name` - The [name][Name] of the object being duplicated.
/// * `new_parent_name` - The [name][Name] of the new parent.
/// * `include_object` - Flag indicating if `object_name` will be included in policy
/// calculation.
///
/// # Details
/// Set `include_object` only when this command is used in conjunction with
/// [`policy_authorize`][Context::policy_authorize].
///
/// # Example
///
/// ```rust
/// # use std::convert::{TryFrom, TryInto};
/// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
/// # use tss_esapi::constants::{CommandCode, SessionType};
/// # use tss_esapi::handles::ObjectHandle;
/// # use tss_esapi::interface_types::{
/// # algorithm::{HashingAlgorithm, PublicAlgorithm},
/// # key_bits::RsaKeyBits,
/// # resource_handles::Hierarchy,
/// # session_handles::PolicySession,
/// # };
/// # use tss_esapi::structures::SymmetricDefinition;
/// # use tss_esapi::structures::{
/// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
/// # RsaExponent, Name,
/// # };
/// # use tss_esapi::structures::SymmetricDefinitionObject;
/// # use tss_esapi::abstraction::cipher::Cipher;
/// # use tss_esapi::{Context, TctiNameConf};
/// #
/// # let mut context = // ...
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// #
/// # let trial_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Trial,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Start auth session failed")
/// # .expect("Start auth session returned a NONE handle");
/// #
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
/// # SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context
/// # .tr_sess_set_attributes(
/// # trial_session,
/// # policy_auth_session_attributes,
/// # policy_auth_session_attributes_mask,
/// # )
/// # .expect("tr_sess_set_attributes call failed");
/// #
/// # let policy_session = PolicySession::try_from(trial_session)
/// # .expect("Failed to convert auth session into policy session");
/// #
/// # let object_name: Name = Vec::::new().try_into().unwrap();
/// # let parent_name = object_name.clone();
/// #
/// context
/// .policy_duplication_select(policy_session, object_name, parent_name, false)
/// .expect("Policy command code");
/// #
/// # /// Digest of the policy that allows duplication
/// # let digest = context
/// # .policy_get_digest(policy_session)
/// # .expect("Could retrieve digest");
/// ```
pub fn policy_duplication_select(
&mut self,
policy_session: PolicySession,
object_name: Name,
new_parent_name: Name,
include_object: bool,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyDuplicationSelect(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&object_name.into(),
&new_parent_name.into(),
u8::from(include_object),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy duplication select: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on an authorized policy
///
/// The TPM will ensure that the current policy digest is correctly signed
/// by the ticket in check_ticket and that check_ticket is signed by the key
/// named in key_sign.
/// If this is the case, the policyDigest of the policy session is replaced
/// by the value of the key_sign and policy_ref values.
pub fn policy_authorize(
&mut self,
policy_session: PolicySession,
approved_policy: Digest,
policy_ref: Nonce,
key_sign: &Name,
check_ticket: VerifiedTicket,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyAuthorize(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&approved_policy.into(),
&policy_ref.into(),
key_sign.as_ref(),
&check_ticket.try_into()?,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy authorize: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on authValue.
///
/// The TPM will ensure that the current policy requires the user to know the authValue
/// used when creating the object.
pub fn policy_auth_value(&mut self, policy_session: PolicySession) -> Result<()> {
let ret = unsafe {
Esys_PolicyAuthValue(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy auth value: {}", ret);
Err(ret)
}
}
/// Cause conditional gating of a policy based on password.
///
/// The TPM will ensure that the current policy requires the user to know the password
/// used when creating the object.
pub fn policy_password(&mut self, policy_session: PolicySession) -> Result<()> {
let ret = unsafe {
Esys_PolicyPassword(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy password: {}", ret);
Err(ret)
}
}
/// Function for retrieving the current policy digest for
/// the session.
pub fn policy_get_digest(&mut self, policy_session: PolicySession) -> Result {
let mut policy_digest_ptr = null_mut();
let ret = unsafe {
Esys_PolicyGetDigest(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut policy_digest_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Digest::try_from(Context::ffi_data_to_owned(policy_digest_ptr))
} else {
error!(
"Error failed to perform policy get digest operation: {}.",
ret
);
Err(ret)
}
}
/// Cause conditional gating of a policy based on NV written state.
///
/// The TPM will ensure that the NV index that is used has a specific written state.
pub fn policy_nv_written(
&mut self,
policy_session: PolicySession,
written_set: bool,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyNvWritten(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
YesNo::from(written_set).into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when computing policy NV written state: {}", ret);
Err(ret)
}
}
/// Bind policy to a specific creation template.
///
/// # Arguments
/// * `policy_session` - The [policy session][PolicySession] being extended.
/// * `template_hash` - The [digest][Digest] to be added to the policy.
pub fn policy_template(
&mut self,
policy_session: PolicySession,
template_hash: Digest,
) -> Result<()> {
let ret = unsafe {
Esys_PolicyTemplate(
self.mut_context(),
SessionHandle::from(policy_session).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&template_hash.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!(
"Failed to bind template to a specific creation template: {}",
ret
);
Err(ret)
}
}
// Missing function: PolicyAuthorizeNV
}
tss-esapi-7.4.0/src/context/tpm_commands/ephemeral_ec_keys.rs 0000644 0000000 0000000 00000000311 10461020230 0022505 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: Commit
// Missing function: EC_Ephemeral
}
tss-esapi-7.4.0/src/context/tpm_commands/field_upgrade.rs 0000644 0000000 0000000 00000000376 10461020230 0021646 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: FieldUpgradeStart
// Missing function: FieldUpgradeData
// Missing function: FirmwareRead
}
tss-esapi-7.4.0/src/context/tpm_commands/hash_hmac_event_sequences.rs 0000644 0000000 0000000 00000000566 10461020230 0024244 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: HMAC_Start
// Missing function: MAC_Start
// Missing function: HashSequenceStart
// Missing function: SequenceUpdate
// Missing function: SequenceComplete
// Missing function: EventSequenceComplete
}
tss-esapi-7.4.0/src/context/tpm_commands/hierarchy_commands.rs 0000644 0000000 0000000 00000014024 10461020230 0022706 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::handle_manager::HandleDropAction,
handles::{AuthHandle, KeyHandle, ObjectHandle},
interface_types::{resource_handles::Hierarchy, YesNo},
structures::{
Auth, CreatePrimaryKeyResult, CreationData, CreationTicket, Data, Digest, PcrSelectionList,
Public, SensitiveData,
},
tss2_esys::{
Esys_Clear, Esys_ClearControl, Esys_CreatePrimary, Esys_HierarchyChangeAuth,
TPM2B_SENSITIVE_CREATE, TPMS_SENSITIVE_CREATE,
},
Context, Error, Result,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
impl Context {
/// Create a primary key and return the handle.
///
/// The authentication value, initial data, outside info and creation PCRs are passed as slices
/// which are then converted by the method into TSS native structures.
///
/// # Errors
/// * if either of the slices is larger than the maximum size of the native objects, a
/// `WrongParamSize` wrapper error is returned
// TODO: Fix when compacting the arguments into a struct
#[allow(clippy::too_many_arguments)]
pub fn create_primary(
&mut self,
primary_handle: Hierarchy,
public: Public,
auth_value: Option,
initial_data: Option,
outside_info: Option,
creation_pcrs: Option,
) -> Result {
let sensitive_create = TPM2B_SENSITIVE_CREATE {
size: std::mem::size_of::()
.try_into()
.unwrap(),
sensitive: TPMS_SENSITIVE_CREATE {
userAuth: auth_value.unwrap_or_default().into(),
data: initial_data.unwrap_or_default().into(),
},
};
let creation_pcrs = PcrSelectionList::list_from_option(creation_pcrs);
let mut out_public_ptr = null_mut();
let mut creation_data_ptr = null_mut();
let mut creation_hash_ptr = null_mut();
let mut creation_ticket_ptr = null_mut();
let mut object_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_CreatePrimary(
self.mut_context(),
ObjectHandle::from(primary_handle).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&sensitive_create,
&public.try_into()?,
&outside_info.unwrap_or_default().into(),
&creation_pcrs.into(),
&mut object_handle,
&mut out_public_ptr,
&mut creation_data_ptr,
&mut creation_hash_ptr,
&mut creation_ticket_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let out_public_owned = Context::ffi_data_to_owned(out_public_ptr);
let creation_data_owned = Context::ffi_data_to_owned(creation_data_ptr);
let creation_hash_owned = Context::ffi_data_to_owned(creation_hash_ptr);
let creation_ticket_owned = Context::ffi_data_to_owned(creation_ticket_ptr);
let primary_key_handle = KeyHandle::from(object_handle);
self.handle_manager
.add_handle(primary_key_handle.into(), HandleDropAction::Flush)?;
Ok(CreatePrimaryKeyResult {
key_handle: primary_key_handle,
out_public: Public::try_from(out_public_owned)?,
creation_data: CreationData::try_from(creation_data_owned)?,
creation_hash: Digest::try_from(creation_hash_owned)?,
creation_ticket: CreationTicket::try_from(creation_ticket_owned)?,
})
} else {
error!("Error in creating primary key: {}", ret);
Err(ret)
}
}
// Missing function: HierarchyControl
// Missing function: SetPrimaryPolicy
// Missing function: ChangePPS
// Missing function: ChangeEPS
/// Clear all TPM context associated with a specific Owner
pub fn clear(&mut self, auth_handle: AuthHandle) -> Result<()> {
let ret = unsafe {
Esys_Clear(
self.mut_context(),
auth_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error in clearing TPM hierarchy: {}", ret);
Err(ret)
}
}
/// Disable or enable the TPM2_CLEAR command
pub fn clear_control(&mut self, auth_handle: AuthHandle, disable: bool) -> Result<()> {
let ret = unsafe {
Esys_ClearControl(
self.mut_context(),
auth_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
YesNo::from(disable).into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error in controlling clear command: {}", ret);
Err(ret)
}
}
/// Change authorization for a hierarchy root
pub fn hierarchy_change_auth(&mut self, auth_handle: AuthHandle, new_auth: Auth) -> Result<()> {
let ret = unsafe {
Esys_HierarchyChangeAuth(
self.mut_context(),
auth_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&new_auth.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error changing hierarchy auth: {}", ret);
Err(ret)
}
}
}
tss-esapi-7.4.0/src/context/tpm_commands/integrity_collection_pcr.rs 0000644 0000000 0000000 00000023022 10461020230 0024142 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
handles::PcrHandle,
structures::{DigestList, DigestValues, PcrSelectionList},
tss2_esys::{Esys_PCR_Extend, Esys_PCR_Read, Esys_PCR_Reset},
Context, Error, Result,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
impl Context {
/// Extends a PCR with the specified digests.
///
/// # Arguments
/// * `pcr_handle`- A [PcrHandle] to the PCR slot that is to be extended.
/// * `digests` - The [DigestValues] with which the slot shall be extended.
///
/// # Details
/// This method is used to cause an update to the indicated PCR. The digests param
/// contains the digests for specific algorithms that are to be used.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{
/// # Context, TctiNameConf,
/// # constants::SessionType,
/// # attributes::SessionAttributesBuilder,
/// # handles::PcrHandle,
/// # structures::{Digest, SymmetricDefinition},
/// # };
/// # use std::{env, str::FromStr};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// # // Create session for a pcr
/// # let pcr_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
/// # )
/// # .expect("Failed to create session")
/// # .expect("Received invalid handle");
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
/// # .expect("Failed to set attributes on session");
/// #
/// # let digest_sha1 = Digest::try_from(vec![
/// # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
/// # ])
/// # .expect("Failed to create sha1 Digest from data");
/// #
/// # let digest_sha256 = Digest::try_from(vec![
/// # 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
/// # 24, 25, 26, 27, 28, 29, 30, 31, 32,
/// # ]).expect("Failed to create Sha256 Digest from data");
/// use std::convert::TryFrom;
/// use tss_esapi::{
/// structures::{DigestValues},
/// interface_types::algorithm::HashingAlgorithm,
/// };
/// // Extend both sha256 and sha1
/// let mut vals = DigestValues::new();
/// vals.set(
/// HashingAlgorithm::Sha1,
/// digest_sha1,
/// );
/// vals.set(
/// HashingAlgorithm::Sha256,
/// digest_sha256,
/// );
/// // Use pcr_session for authorization when extending
/// // PCR 16 with the values for the banks specified in
/// // vals.
/// context.execute_with_session(Some(pcr_session), |ctx| {
/// ctx.pcr_extend(PcrHandle::Pcr16, vals).expect("Call to pcr_extend failed");
/// });
/// ```
pub fn pcr_extend(&mut self, pcr_handle: PcrHandle, digests: DigestValues) -> Result<()> {
let ret = unsafe {
Esys_PCR_Extend(
self.mut_context(),
pcr_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&digests.try_into()?,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when extending PCR: {}", ret);
Err(ret)
}
}
// Missing function: PCR_Event
/// Reads the values of a PCR.
///
/// # Arguments
/// * `pcr_selection_list` - A [PcrSelectionList] that contains pcr slots in
/// different banks that is going to be read.
///
/// # Details
/// The provided [PcrSelectionList] contains the pcr slots in the different
/// banks that is going to be read. It is possible to select more pcr slots
/// then what will fit in the returned result so the method returns a [PcrSelectionList]
/// that indicates what values were read. The values that were read are returned
/// in a [DigestList].
///
/// # Errors
/// * Several different errors can occur if conversion of return
/// data fails.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{Context, TctiNameConf};
/// # use std::{env, str::FromStr};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// use tss_esapi::{
/// interface_types::algorithm::HashingAlgorithm,
/// structures::{PcrSelectionListBuilder, PcrSlot},
/// };
/// // Create PCR selection list with slots in a bank
/// // that is going to be read.
/// let pcr_selection_list = PcrSelectionListBuilder::new()
/// .with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot0, PcrSlot::Slot1])
/// .build()
/// .expect("Failed to build PcrSelectionList");
///
/// let (update_counter, read_pcr_list, digest_list) = context.pcr_read(pcr_selection_list)
/// .expect("Call to pcr_read failed");
/// ```
pub fn pcr_read(
&mut self,
pcr_selection_list: PcrSelectionList,
) -> Result<(u32, PcrSelectionList, DigestList)> {
let mut pcr_update_counter: u32 = 0;
let mut pcr_selection_out_ptr = null_mut();
let mut pcr_values_ptr = null_mut();
let ret = unsafe {
Esys_PCR_Read(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&pcr_selection_list.into(),
&mut pcr_update_counter,
&mut pcr_selection_out_ptr,
&mut pcr_values_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
pcr_update_counter,
PcrSelectionList::try_from(Context::ffi_data_to_owned(pcr_selection_out_ptr))?,
DigestList::try_from(Context::ffi_data_to_owned(pcr_values_ptr))?,
))
} else {
error!("Error when reading PCR: {}", ret);
Err(ret)
}
}
// Missing function: PCR_Allocate
// Missing function: PCR_SetAuthPolicy
// Missing function: PCR_SetAuthValue
/// Resets the value in a PCR.
///
/// # Arguments
/// * `pcr_handle` - A [PcrHandle] to the PCR slot that is to be reset.
///
/// # Details
/// If the attributes of the PCR indicates that it is allowed
/// to reset them and the proper authorization is provided then
/// this method can be used to set the the specified PCR in all
/// banks to 0.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{
/// # Context, TctiNameConf,
/// # constants::SessionType,
/// # attributes::SessionAttributesBuilder,
/// # structures::SymmetricDefinition,
/// # interface_types::algorithm::HashingAlgorithm,
/// # };
/// # use std::{env, str::FromStr};
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// # // Create session for a pcr
/// # let pcr_session = context
/// # .start_auth_session(
/// # None,
/// # None,
/// # None,
/// # SessionType::Hmac,
/// # SymmetricDefinition::AES_256_CFB,
/// # HashingAlgorithm::Sha256,
/// # )
/// # .expect("Failed to create session")
/// # .expect("Received invalid handle");
/// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
/// # .with_decrypt(true)
/// # .with_encrypt(true)
/// # .build();
/// # context.tr_sess_set_attributes(pcr_session, session_attributes, session_attributes_mask)
/// # .expect("Failed to set attributes on session");
///
/// use tss_esapi::{
/// handles::PcrHandle
/// };
/// context.execute_with_session(Some(pcr_session), |ctx| {
/// ctx.pcr_reset(PcrHandle::Pcr16).expect("Call to pcr_reset failed");
/// });
/// ```
pub fn pcr_reset(&mut self, pcr_handle: PcrHandle) -> Result<()> {
let ret = unsafe {
Esys_PCR_Reset(
self.mut_context(),
pcr_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when resetting PCR: {}", ret);
Err(ret)
}
}
// Missing function: _TPM_Hash_Start
// Missing function: _TPM_Hash_Data
// Missing function: _TPM_Hash_End
}
tss-esapi-7.4.0/src/context/tpm_commands/miscellaneous_management_functions.rs 0000644 0000000 0000000 00000000321 10461020230 0026171 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::Context;
impl Context {
// Missing function: PP_Commands
// Missing function: SetAlgorithmSet
}
tss-esapi-7.4.0/src/context/tpm_commands/mod.rs 0000644 0000000 0000000 00000001406 10461020230 0017626 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
mod asymmetric_primitives;
mod attached_components;
mod attestation_commands;
mod authenticated_countdown_timer;
mod capability_commands;
mod clocks_and_timers;
mod command_audit;
mod context_management;
mod dictionary_attack_functions;
mod duplication_commands;
mod enhanced_authorization_ea_commands;
mod ephemeral_ec_keys;
mod field_upgrade;
mod hash_hmac_event_sequences;
mod hierarchy_commands;
mod integrity_collection_pcr;
mod miscellaneous_management_functions;
mod non_volatile_storage;
mod object_commands;
mod random_number_generator;
mod session_commands;
mod signing_and_signature_verification;
mod startup;
mod symmetric_primitives;
mod testing;
mod vendor_specific;
tss-esapi-7.4.0/src/context/tpm_commands/non_volatile_storage.rs 0000644 0000000 0000000 00000016223 10461020230 0023267 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::handle_manager::HandleDropAction,
handles::{AuthHandle, NvIndexHandle, ObjectHandle},
interface_types::resource_handles::{NvAuth, Provision},
structures::{Auth, MaxNvBuffer, Name, NvPublic},
tss2_esys::{
Esys_NV_DefineSpace, Esys_NV_Increment, Esys_NV_Read, Esys_NV_ReadPublic,
Esys_NV_UndefineSpace, Esys_NV_Write,
},
Context, Error, Result,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
impl Context {
/// Allocates an index in the non volatile storage.
///
/// # Details
/// This method will instruct the TPM to reserve space for an NV index
/// with the attributes defined in the provided parameters.
///
/// # Arguments
/// * `nv_auth` - The [Provision] used for authorization.
/// * `auth` - The authorization value.
/// * `public_info` - The public parameters of the NV area.
pub fn nv_define_space(
&mut self,
nv_auth: Provision,
auth: Option,
public_info: NvPublic,
) -> Result {
let mut nv_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_NV_DefineSpace(
self.mut_context(),
AuthHandle::from(nv_auth).into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&auth.unwrap_or_default().into(),
&public_info.try_into()?,
&mut nv_handle,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
self.handle_manager
.add_handle(nv_handle.into(), HandleDropAction::Close)?;
Ok(NvIndexHandle::from(nv_handle))
} else {
error!("Error when defining NV space: {}", ret);
Err(ret)
}
}
/// Deletes an index in the non volatile storage.
///
/// # Details
/// The method will instruct the TPM to remove a
/// nv index.
///
/// # Arguments
/// * `nv_auth` - The [Provision] used for authorization.
/// * `nv_index_handle`- The [NvIndexHandle] associated with
/// the nv area that is to be removed.
pub fn nv_undefine_space(
&mut self,
nv_auth: Provision,
nv_index_handle: NvIndexHandle,
) -> Result<()> {
let ret = unsafe {
Esys_NV_UndefineSpace(
self.mut_context(),
AuthHandle::from(nv_auth).into(),
nv_index_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
self.handle_manager.set_as_closed(nv_index_handle.into())?;
Ok(())
} else {
error!("Error when undefining NV space: {}", ret);
Err(ret)
}
}
// Missing function: UndefineSpaceSpecial
/// Reads the public part of an nv index.
///
/// # Details
/// This method is used to read the public
/// area and name of a nv index.
pub fn nv_read_public(&mut self, nv_index_handle: NvIndexHandle) -> Result<(NvPublic, Name)> {
let mut nv_public_ptr = null_mut();
let mut nv_name_ptr = null_mut();
let ret = unsafe {
Esys_NV_ReadPublic(
self.mut_context(),
nv_index_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut nv_public_ptr,
&mut nv_name_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
NvPublic::try_from(Context::ffi_data_to_owned(nv_public_ptr))?,
Name::try_from(Context::ffi_data_to_owned(nv_name_ptr))?,
))
} else {
error!("Error when reading NV public: {}", ret);
Err(ret)
}
}
/// Writes data to an nv index.
///
/// # Details
/// This method is used to write a value to
/// the nv memory in the TPM.
pub fn nv_write(
&mut self,
auth_handle: NvAuth,
nv_index_handle: NvIndexHandle,
data: MaxNvBuffer,
offset: u16,
) -> Result<()> {
let ret = unsafe {
Esys_NV_Write(
self.mut_context(),
AuthHandle::from(auth_handle).into(),
nv_index_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&data.into(),
offset,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when writing NV: {}", ret);
Err(ret)
}
}
/// Increment monotonic counter index
///
/// # Details
/// This method is used to increment monotonic counter
/// in the TPM.
pub fn nv_increment(
&mut self,
auth_handle: NvAuth,
nv_index_handle: NvIndexHandle,
) -> Result<()> {
let ret = unsafe {
Esys_NV_Increment(
self.mut_context(),
AuthHandle::from(auth_handle).into(),
nv_index_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error when incrementing NV: {}", ret);
Err(ret)
}
}
// Missing function: NV_Extend
// Missing function: NV_SetBits
// Missing function: NV_WriteLock
// Missing function: NV_GlobalWriteLock
/// Reads data from the nv index.
///
/// # Details
/// This method is used to read a value from an area in
/// NV memory of the TPM.
pub fn nv_read(
&mut self,
auth_handle: NvAuth,
nv_index_handle: NvIndexHandle,
size: u16,
offset: u16,
) -> Result {
let mut data_ptr = null_mut();
let ret = unsafe {
Esys_NV_Read(
self.mut_context(),
AuthHandle::from(auth_handle).into(),
nv_index_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
size,
offset,
&mut data_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
MaxNvBuffer::try_from(Context::ffi_data_to_owned(data_ptr))
} else {
error!("Error when reading NV: {}", ret);
Err(ret)
}
}
// Missing function: NV_ReadLock
// Missing function: NV_ChangeAuth
// Missing function: NV_Certify
}
tss-esapi-7.4.0/src/context/tpm_commands/object_commands.rs 0000644 0000000 0000000 00000032167 10461020230 0022206 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
context::handle_manager::HandleDropAction,
handles::{KeyHandle, ObjectHandle, TpmHandle},
interface_types::resource_handles::Hierarchy,
structures::{
Auth, CreateKeyResult, CreationData, CreationTicket, Data, Digest, EncryptedSecret,
IdObject, Name, PcrSelectionList, Private, Public, Sensitive, SensitiveData,
},
tss2_esys::{
Esys_ActivateCredential, Esys_Create, Esys_Load, Esys_LoadExternal, Esys_MakeCredential,
Esys_ObjectChangeAuth, Esys_ReadPublic, Esys_Unseal, TPM2B_SENSITIVE_CREATE,
TPMS_SENSITIVE_CREATE,
},
Context, Error, Result,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::{null, null_mut};
impl Context {
/// Create a key and return the handle.
///
/// The authentication value, initial data, outside info and creation PCRs are passed as slices
/// which are then converted by the method into TSS native structures.
///
/// # Parameters
/// * `parent_handle` - The [KeyHandle] of the parent for the new object that is being created.
/// * `public` - The public part of the object that is being created.
/// * `auth_value` - The value used to be used for authorize usage of the object.
/// * `sensitive_data` - The data that is to be sealed, a key or derivation values.
/// * `outside_info` - Data that will be included in the creation data for this
/// object to provide permanent, verifiable linkage between
/// the object that is being created and some object owner data.
/// * `creation_pcrs`- PCRs that will be used in creation data.
///
/// # Errors
/// * if either of the slices is larger than the maximum size of the native objects, a
/// `WrongParamSize` wrapper error is returned
// TODO: Fix when compacting the arguments into a struct
#[allow(clippy::too_many_arguments)]
pub fn create(
&mut self,
parent_handle: KeyHandle,
public: Public,
auth_value: Option,
sensitive_data: Option,
outside_info: Option,
creation_pcrs: Option,
) -> Result {
let sensitive_create = TPM2B_SENSITIVE_CREATE {
size: std::mem::size_of::()
.try_into()
.unwrap(), // will not fail on targets of at least 16 bits
sensitive: TPMS_SENSITIVE_CREATE {
userAuth: auth_value.unwrap_or_default().into(),
data: sensitive_data.unwrap_or_default().into(),
},
};
let creation_pcrs = PcrSelectionList::list_from_option(creation_pcrs);
let mut out_public_ptr = null_mut();
let mut out_private_ptr = null_mut();
let mut creation_data_ptr = null_mut();
let mut creation_hash_ptr = null_mut();
let mut creation_ticket_ptr = null_mut();
let ret = unsafe {
Esys_Create(
self.mut_context(),
parent_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&sensitive_create,
&public.try_into()?,
&outside_info.unwrap_or_default().into(),
&creation_pcrs.into(),
&mut out_private_ptr,
&mut out_public_ptr,
&mut creation_data_ptr,
&mut creation_hash_ptr,
&mut creation_ticket_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let out_private_owned = Context::ffi_data_to_owned(out_private_ptr);
let out_public_owned = Context::ffi_data_to_owned(out_public_ptr);
let creation_data_owned = Context::ffi_data_to_owned(creation_data_ptr);
let creation_hash_owned = Context::ffi_data_to_owned(creation_hash_ptr);
let creation_ticket_owned = Context::ffi_data_to_owned(creation_ticket_ptr);
Ok(CreateKeyResult {
out_private: Private::try_from(out_private_owned)?,
out_public: Public::try_from(out_public_owned)?,
creation_data: CreationData::try_from(creation_data_owned)?,
creation_hash: Digest::try_from(creation_hash_owned)?,
creation_ticket: CreationTicket::try_from(creation_ticket_owned)?,
})
} else {
error!("Error in creating derived key: {}", ret);
Err(ret)
}
}
/// Load a previously generated key back into the TPM and return its new handle.
pub fn load(
&mut self,
parent_handle: KeyHandle,
private: Private,
public: Public,
) -> Result {
let mut object_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_Load(
self.mut_context(),
parent_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&private.into(),
&public.try_into()?,
&mut object_handle,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let key_handle = KeyHandle::from(object_handle);
self.handle_manager
.add_handle(key_handle.into(), HandleDropAction::Flush)?;
Ok(key_handle)
} else {
error!("Error in loading: {}", ret);
Err(ret)
}
}
/// Load an external key into the TPM and return its new handle.
pub fn load_external(
&mut self,
private: Sensitive,
public: Public,
hierarchy: Hierarchy,
) -> Result {
let mut object_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_LoadExternal(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&private.try_into()?,
&public.try_into()?,
if cfg!(tpm2_tss_version = "2") {
TpmHandle::from(hierarchy).into()
} else {
ObjectHandle::from(hierarchy).into()
},
&mut object_handle,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let key_handle = KeyHandle::from(object_handle);
self.handle_manager
.add_handle(key_handle.into(), HandleDropAction::Flush)?;
Ok(key_handle)
} else {
error!("Error in loading external object: {}", ret);
Err(ret)
}
}
/// Load the public part of an external key and return its new handle.
pub fn load_external_public(
&mut self,
public: Public,
hierarchy: Hierarchy,
) -> Result {
let mut object_handle = ObjectHandle::None.into();
let ret = unsafe {
Esys_LoadExternal(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
null(),
&public.try_into()?,
if cfg!(tpm2_tss_version = "2") {
TpmHandle::from(hierarchy).into()
} else {
ObjectHandle::from(hierarchy).into()
},
&mut object_handle,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
let key_handle = KeyHandle::from(object_handle);
self.handle_manager
.add_handle(key_handle.into(), HandleDropAction::Flush)?;
Ok(key_handle)
} else {
error!("Error in loading external public object: {}", ret);
Err(ret)
}
}
/// Read the public part of a key currently in the TPM and return it.
pub fn read_public(&mut self, key_handle: KeyHandle) -> Result<(Public, Name, Name)> {
let mut out_public_ptr = null_mut();
let mut name_ptr = null_mut();
let mut qualified_name_ptr = null_mut();
let ret = unsafe {
Esys_ReadPublic(
self.mut_context(),
key_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut out_public_ptr,
&mut name_ptr,
&mut qualified_name_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
Public::try_from(Context::ffi_data_to_owned(out_public_ptr))?,
Name::try_from(Context::ffi_data_to_owned(name_ptr))?,
Name::try_from(Context::ffi_data_to_owned(qualified_name_ptr))?,
))
} else {
error!("Error in reading public part of object: {}", ret);
Err(ret)
}
}
/// Activates a credential in a way that ensures parameters are validated.
pub fn activate_credential(
&mut self,
activate_handle: KeyHandle,
key_handle: KeyHandle,
credential_blob: IdObject,
secret: EncryptedSecret,
) -> Result {
let mut cert_info_ptr = null_mut();
let ret = unsafe {
Esys_ActivateCredential(
self.mut_context(),
activate_handle.into(),
key_handle.into(),
self.required_session_1()?,
self.required_session_2()?,
self.optional_session_3(),
&credential_blob.into(),
&secret.into(),
&mut cert_info_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Digest::try_from(Context::ffi_data_to_owned(cert_info_ptr))
} else {
error!("Error when activating credential: {}", ret);
Err(ret)
}
}
/// Perform actions to create a [IdObject] containing an activation credential.
///
/// This does not use any TPM secrets, and is really just a convenience function.
pub fn make_credential(
&mut self,
key_handle: KeyHandle,
credential: Digest,
object_name: Name,
) -> Result<(IdObject, EncryptedSecret)> {
let mut credential_blob_ptr = null_mut();
let mut secret_ptr = null_mut();
let ret = unsafe {
Esys_MakeCredential(
self.mut_context(),
key_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&credential.into(),
object_name.as_ref(),
&mut credential_blob_ptr,
&mut secret_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok((
IdObject::try_from(Context::ffi_data_to_owned(credential_blob_ptr))?,
EncryptedSecret::try_from(Context::ffi_data_to_owned(secret_ptr))?,
))
} else {
error!("Error when making credential: {}", ret);
Err(ret)
}
}
/// Unseal and return data from a Sealed Data Object
pub fn unseal(&mut self, item_handle: ObjectHandle) -> Result {
let mut out_data_ptr = null_mut();
let ret = unsafe {
Esys_Unseal(
self.mut_context(),
item_handle.into(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&mut out_data_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
SensitiveData::try_from(Context::ffi_data_to_owned(out_data_ptr))
} else {
error!("Error in unsealing: {}", ret);
Err(ret)
}
}
/// Change authorization for a TPM-resident object.
pub fn object_change_auth(
&mut self,
object_handle: ObjectHandle,
parent_handle: ObjectHandle,
new_auth: Auth,
) -> Result {
let mut out_private_ptr = null_mut();
let ret = unsafe {
Esys_ObjectChangeAuth(
self.mut_context(),
object_handle.into(),
parent_handle.into(),
self.required_session_1()?,
self.optional_session_2(),
self.optional_session_3(),
&new_auth.into(),
&mut out_private_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Private::try_from(Context::ffi_data_to_owned(out_private_ptr))
} else {
error!("Error changing object auth: {}", ret);
Err(ret)
}
}
// Missing function: CreateLoaded
}
tss-esapi-7.4.0/src/context/tpm_commands/random_number_generator.rs 0000644 0000000 0000000 00000003643 10461020230 0023752 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
structures::{Digest, SensitiveData},
tss2_esys::{Esys_GetRandom, Esys_StirRandom},
Context, Error, Result, WrapperErrorKind as ErrorKind,
};
use log::error;
use std::convert::{TryFrom, TryInto};
use std::ptr::null_mut;
impl Context {
/// Get a number of random bytes from the TPM and return them.
///
/// # Errors
/// * if converting `num_bytes` to `u16` fails, a `WrongParamSize` will be returned
pub fn get_random(&mut self, num_bytes: usize) -> Result {
let mut random_bytes_ptr = null_mut();
let ret = unsafe {
Esys_GetRandom(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
num_bytes
.try_into()
.map_err(|_| Error::local_error(ErrorKind::WrongParamSize))?,
&mut random_bytes_ptr,
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Digest::try_from(Context::ffi_data_to_owned(random_bytes_ptr))
} else {
error!("Error in getting random bytes: {}", ret);
Err(ret)
}
}
/// Add additional information into the TPM RNG state
pub fn stir_random(&mut self, in_data: SensitiveData) -> Result<()> {
let ret = unsafe {
Esys_StirRandom(
self.mut_context(),
self.optional_session_1(),
self.optional_session_2(),
self.optional_session_3(),
&in_data.into(),
)
};
let ret = Error::from_tss_rc(ret);
if ret.is_success() {
Ok(())
} else {
error!("Error stirring random: {}", ret);
Err(ret)
}
}
}
tss-esapi-7.4.0/src/context/tpm_commands/session_commands.rs 0000644 0000000 0000000 00000007600 10461020230 0022415 0 ustar 0000000 0000000 // Copyright 2021 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
use crate::{
constants::SessionType,
context::handle_manager::HandleDropAction,
handles::{KeyHandle, ObjectHandle, SessionHandle},
interface_types::{
algorithm::HashingAlgorithm,
session_handles::{AuthSession, PolicySession},
},
structures::{Nonce, SymmetricDefinition},
tss2_esys::{Esys_PolicyRestart, Esys_StartAuthSession},
Context, Error, Result,
};
use log::error;
use std::{convert::TryInto, ptr::null};
impl Context {
/// Start new authentication session and return the Session object
/// associated with the session.
///
/// If the returned session handle from ESYS api is ESYS_TR_NONE then
/// the value of the option in the result will be None.
///
/// # Example
///
/// ```rust
/// # use tss_esapi::{Context, Tcti,
/// # constants::SessionType,
/// # interface_types::algorithm::HashingAlgorithm,
/// # structures::SymmetricDefinition,
/// # };
/// # // Create context
/// # let mut context =
/// # Context::new(
/// # Tcti::from_environment_variable().expect("Failed to get TCTI"),
/// # ).expect("Failed to create Context");
/// // Create auth session without key_handle, bind_handle
/// // and Nonce
/// let session = context
/// .start_auth_session(
/// None,
/// None,
/// None,
/// SessionType::Hmac,
/// SymmetricDefinition::AES_256_CFB,
/// HashingAlgorithm::Sha256,
/// )
/// .expect("Failed to create session")
/// .expect("Received invalid handle");
/// ```
#[allow(clippy::too_many_arguments)]
pub fn start_auth_session(
&mut self,
tpm_key: Option,
bind: Option,
nonce: Option,
session_type: SessionType,
symmetric: SymmetricDefinition,
auth_hash: HashingAlgorithm,
) -> Result