parallaxsecond / rust-tss-esapi

TSS 2.0 Enhanced System API (ESAPI) Rust wrapper
https://docs.rs/tss-esapi/
Apache License 2.0
85 stars 51 forks source link

error in key_handle in rsa_encrypt using tss-esapi #399

Closed Ravindra1618 closed 1 year ago

Ravindra1618 commented 1 year ago
fn main() {
    // Initialize TSS context and connect to TPM

    let device_conf: DeviceConfig = DeviceConfig::default();

    let mut context: Context = Context::new(TctiNameConf::Device(device_conf)).unwrap();

    // Create a primary key

    let key_handle = context
        .create_primary(
            Hierarchy::Owner,
            PublicBuilder::new()
                .with_public_algorithm(PublicAlgorithm::Rsa)
                .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
                .with_object_attributes(
                    ObjectAttributesBuilder::new()
                        .with_sign_encrypt(true)
                        .with_sensitive_data_origin(true)
                        .with_user_with_auth(true)
                        .build()
                        .unwrap(),
                )
                .build()
                .unwrap(),
            None,
            None,
            None,
            None,
        )
        .unwrap()
        .key_handle
        .into();

    // Message to be encrypted

    let message = b"Hello, world!".to_vec();

    let plaintext = PublicKeyRsa::try_from(message).unwrap();

    // Encryption scheme

    let scheme =
        RsaDecryptionScheme::create(RsaDecryptAlgorithm::Oaep, Some(HashingAlgorithm::Sha256))
            .unwrap();

    // Encrypt the message using the key handle and encryption scheme

    let ciphertext = context
        .rsa_encrypt(key_handle, plaintext, scheme, Data::default())
        .unwrap();

    println!("{:?}", ciphertext);
}

The error which i am facing here is

thread 'main' panicked at 'called Result::unwrap() on an Err value: WrapperError(ParamsMissing)'

any changes in code for that error regarding key_handle

Superhepper commented 1 year ago

One thing I would do if I were you is to move the building of the Public struct before call to the create_primary. Because I suspect that you lack some parameters in the PublicBuilder, because I cannot see any calls to with_rsa_parameters and with_rsa_unique_identifier.

Ravindra1618 commented 1 year ago

Yes i tried that i am getting error

WARNING:esys:src/tss2-esys/api/Esys_RSA_Encrypt.c:302:Esys_RSA_Encrypt_Finish() Received TPM Error

ERROR:esys:src/tss2-esys/api/Esys_RSA_Encrypt.c:103:Esys_RSA_Encrypt() Esys Finish ErrorCode (0x000002d2)

this is my code

fn main() {

let device_conf: DeviceConfig = DeviceConfig::default();

let mut context: Context = Context::new(TctiNameConf::Device(device_conf)).unwrap();

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();

let rsa_parms = PublicRsaParametersBuilder::new()

.with_symmetric(SymmetricDefinitionObject::default())    

.with_scheme(RsaScheme::RsaEs)

.with_key_bits(RsaKeyBits::Rsa1024)

.with_exponent(RsaExponent::default())

.with_is_signing_key(false)

.with_is_decryption_key(true)

.with_restricted(false)

.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::Rsa)

.with_name_hashing_algorithm(HashingAlgorithm::Sha256)

.with_object_attributes(object_attributes)

.with_rsa_parameters(rsa_parms)

.with_rsa_unique_identifier(PublicKeyRsa::default())

.build()

.unwrap();

let key_handle = context

               .create_primary(

                   Hierarchy::Owner,

                   public,

                   Some(key_auth),

                   None,

                   None,

                   None,

               )

               .unwrap()

               .key_handle;

let message = b"Hello, world!".to_vec();

let plaintext = PublicKeyRsa::try_from(message).unwrap();

let scheme = RsaDecryptionScheme::create(

    RsaDecryptAlgorithm::Oaep,

    Some(HashingAlgorithm::Sha256),

).unwrap();

let ciphertext = context.rsa_encrypt(key_handle, plaintext, scheme, Data::default()); }

please suggest any changes in code regarding this error

Superhepper commented 1 year ago

The problem seems to be that you uses RsaScheme::RsaEs for the primary key. I am not sure exactly why that should be a problem but one have to dig into the specification to find out. If you would use RsaScheme::Null it should probably work.

The error from the crate also (though not so clearly I admit) points out that it is a problem with parameter 2. Now this is where it gets really confusing because the error message actually refers to parameter 2 of the underlaying C-API. So that would be the key handle.

Superhepper commented 1 year ago

But it is a little bit odd because the specification says:

scheme.scheme shall be: for an unrestricted signing key, either TPM_ALG_RSAPSS TPM_ALG_RSASSA or TPM_ALG_NULLfor a restricted signing key, either TPM_ALG_RSAPSS or TPM_ALG_RSASSAfor an unrestricted decryption key, TPM_ALG_RSAES, TPM_ALG_OAEP, or TPM_ALG_NULL unless the object also has the sign attribute for a restricted decryption key, TPM_ALG_NULLNOTE When both sign and decrypt are SET, restricted shall be CLEAR and scheme shall be TPM_ALG_NULL.

So a decryption key with RsaEs should work. But this is not a problem with the tss-esapi crate but rather that the correct parameters for the primary object are not correct.

Ravindra1618 commented 1 year ago

Its working fine , Thank You @Superhepper.

Superhepper commented 1 year ago

I found the real problem in the specification for commands:

This command performs RSA encryption using the indicated padding scheme according to IETF RFC

  1. If the scheme of keyHandle is TPM_ALG_NULL, then the caller may use inScheme to specify the padding scheme. If scheme of keyHandle is not TPM_ALG_NULL, then inScheme shall either be TPM_ALG_NULL or be the same as scheme (TPM_RC_SCHEME).

You used RsaEs when creating the primary key. And then you used Oaep when doing the encryption and that is not allowed.

Ravindra1618 commented 1 year ago

Hi I am facing error while doing sign part in Transientkeycontext Any suggestions for this error should be helpful

use std::fs; use tss_esapi::Context; use tss_esapi::abstraction::transient::KeyMaterial; use tss_esapi::abstraction::transient::TransientKeyContextBuilder; use tss_esapi::constants::SessionType; use tss_esapi::interface_types::algorithm::HashingAlgorithm; use tss_esapi::interface_types::algorithm::RsaSchemeAlgorithm; use tss_esapi::interface_types::key_bits::RsaKeyBits; use tss_esapi::interface_types::resource_handles::Hierarchy; use tss_esapi::structures::Digest; use tss_esapi::structures::RsaExponent; use tss_esapi::structures::RsaScheme; use tss_esapi::structures::SymmetricDefinition; use tss_esapi::tcti_ldr::TctiNameConf; use tss_esapi::tcti_ldr::DeviceConfig;

fn main() { let device_conf: DeviceConfig = DeviceConfig::default(); let create_ctx = TransientKeyContextBuilder::new() .with_tcti(TctiNameConf::Device(device_conf)) .build() .unwrap();

let mut ctx = create_ctx; let key_params = tss_esapi::abstraction::transient::KeyParams::Rsa { size: RsaKeyBits::Rsa3072, scheme: RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256)) .expect("Failed to create RSA scheme"), pub_exponent: RsaExponent::default(), }; let (key, auth) = ctx.create_key(key_params,32).unwrap(); let val = vec![2,3,4,56,7,77,8,8]; let digest : Digest = Digest::try_from(val).unwrap(); let digest1 = ctx.sign(key,key_params,auth,digest);

}

The error is ERROR:esys:src/tss2-esys/api/Esys_Sign.c:105:Esys_Sign() Esys Finish ErrorCode (0x000001d5)