3
3
use crate :: Context ;
4
4
use crate :: {
5
5
handles:: ObjectHandle ,
6
- structures:: { Data , EncryptedSecret , Private , SymmetricDefinitionObject } ,
6
+ structures:: { Data , EncryptedSecret , Private , Public , SymmetricDefinitionObject } ,
7
7
tss2_esys:: * ,
8
8
Error , Result ,
9
9
} ;
@@ -23,7 +23,8 @@ impl Context {
23
23
/// # Arguments
24
24
/// * `object_to_duplicate` - An [ObjectHandle] of the object that will be duplicated.
25
25
/// * `new_parent_handle` - An [ObjectHandle] of the new parent.
26
- /// * `encryption_key_in` - An optional encryption key.
26
+ /// * `encryption_key_in` - An optional encryption key. If this parameter is `None`
27
+ /// then a [default value][Default::default] is used.
27
28
/// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
28
29
///
29
30
/// The `object_to_duplicate` need to be have Fixed TPM and Fixed Parent attributes set to `false`.
@@ -35,6 +36,8 @@ impl Context {
35
36
/// * `duplicate` - Private area that may be encrypted.
36
37
/// * `out_sym_seed` - Seed protected by the asymmetric algorithms of new parent.
37
38
///
39
+ /// # Example
40
+ ///
38
41
/// ```rust
39
42
/// # use std::convert::{TryFrom, TryInto};
40
43
/// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
@@ -331,5 +334,357 @@ impl Context {
331
334
}
332
335
333
336
// Missing function: Rewrap
334
- // Missing function: Import
337
+
338
+ /// Import attaches imported object to a new parent.
339
+ ///
340
+ /// # Details
341
+ /// This command allows an object to be encrypted using the symmetric
342
+ /// encryption values of a Storage Key. After encryption, the
343
+ /// object may be loaded and used in the new hierarchy. The
344
+ /// imported object (duplicate) may be singly encrypted, multiply
345
+ /// encrypted, or unencrypted.
346
+ ///
347
+ /// # Arguments
348
+ /// * `parent_handle` - An [ObjectHandle] of the new parent for the object.
349
+ /// * `encryption_key` - An optional symmetric encryption key used as the inner wrapper.
350
+ /// If `encryption_key` is `None` then a [default value][Default::default] is used.
351
+ /// * `public` - A [Public] of the imported object.
352
+ /// * `duplicate` - A symmetrically encrypted duplicated object.
353
+ /// * `encrypted_secret` - The seed for the symmetric key and HMAC key.
354
+ /// * `symmetric_alg` - Symmetric algorithm to be used for the inner wrapper.
355
+ ///
356
+ /// The `public` is needed to check the integrity value for `duplicate`.
357
+ ///
358
+ /// # Returns
359
+ /// The command returns the sensitive area encrypted with the symmetric key of `parent_handle`.
360
+ ///
361
+ /// # Example
362
+ ///
363
+ /// ```rust
364
+ /// # use std::convert::{TryFrom, TryInto};
365
+ /// # use tss_esapi::attributes::{ObjectAttributesBuilder, SessionAttributesBuilder};
366
+ /// # use tss_esapi::constants::{tss::TPM2_CC_Duplicate, SessionType};
367
+ /// # use tss_esapi::handles::ObjectHandle;
368
+ /// # use tss_esapi::interface_types::{
369
+ /// # algorithm::{HashingAlgorithm, PublicAlgorithm},
370
+ /// # key_bits::RsaKeyBits,
371
+ /// # resource_handles::Hierarchy,
372
+ /// # session_handles::PolicySession,
373
+ /// # };
374
+ /// # use tss_esapi::structures::SymmetricDefinition;
375
+ /// # use tss_esapi::structures::{
376
+ /// # PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme,
377
+ /// # RsaExponent,
378
+ /// # };
379
+ /// use tss_esapi::structures::SymmetricDefinitionObject;
380
+ /// # use tss_esapi::abstraction::cipher::Cipher;
381
+ /// # use tss_esapi::{Context, TctiNameConf};
382
+ /// #
383
+ /// # let mut context = // ...
384
+ /// # Context::new(
385
+ /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
386
+ /// # ).expect("Failed to create Context");
387
+ /// #
388
+ /// # let trial_session = context
389
+ /// # .start_auth_session(
390
+ /// # None,
391
+ /// # None,
392
+ /// # None,
393
+ /// # SessionType::Trial,
394
+ /// # SymmetricDefinition::AES_256_CFB,
395
+ /// # HashingAlgorithm::Sha256,
396
+ /// # )
397
+ /// # .expect("Start auth session failed")
398
+ /// # .expect("Start auth session returned a NONE handle");
399
+ /// #
400
+ /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
401
+ /// # SessionAttributesBuilder::new()
402
+ /// # .with_decrypt(true)
403
+ /// # .with_encrypt(true)
404
+ /// # .build();
405
+ /// # context
406
+ /// # .tr_sess_set_attributes(
407
+ /// # trial_session,
408
+ /// # policy_auth_session_attributes,
409
+ /// # policy_auth_session_attributes_mask,
410
+ /// # )
411
+ /// # .expect("tr_sess_set_attributes call failed");
412
+ /// #
413
+ /// # let policy_session = PolicySession::try_from(trial_session)
414
+ /// # .expect("Failed to convert auth session into policy session");
415
+ /// #
416
+ /// # context
417
+ /// # .policy_auth_value(policy_session)
418
+ /// # .expect("Policy auth value");
419
+ /// #
420
+ /// # context
421
+ /// # .policy_command_code(policy_session, TPM2_CC_Duplicate)
422
+ /// # .expect("Policy command code");
423
+ /// #
424
+ /// # /// Digest of the policy that allows duplication
425
+ /// # let digest = context
426
+ /// # .policy_get_digest(policy_session)
427
+ /// # .expect("Could retrieve digest");
428
+ /// #
429
+ /// # drop(context);
430
+ /// # let mut context = // ...
431
+ /// # Context::new(
432
+ /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
433
+ /// # ).expect("Failed to create Context");
434
+ /// #
435
+ /// # let session = context
436
+ /// # .start_auth_session(
437
+ /// # None,
438
+ /// # None,
439
+ /// # None,
440
+ /// # SessionType::Hmac,
441
+ /// # SymmetricDefinition::AES_256_CFB,
442
+ /// # HashingAlgorithm::Sha256,
443
+ /// # )
444
+ /// # .expect("Start auth session failed")
445
+ /// # .expect("Start auth session returned a NONE handle");
446
+ /// #
447
+ /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
448
+ /// # .with_decrypt(true)
449
+ /// # .with_encrypt(true)
450
+ /// # .build();
451
+ /// #
452
+ /// # context.tr_sess_set_attributes(
453
+ /// # session,
454
+ /// # session_attributes,
455
+ /// # session_attributes_mask,
456
+ /// # ).unwrap();
457
+ /// #
458
+ /// # context.set_sessions((Some(session), None, None));
459
+ /// #
460
+ /// # // Attributes of parent objects. The `restricted` attribute need
461
+ /// # // to be `true` so that parents can act as storage keys.
462
+ /// # let parent_object_attributes = ObjectAttributesBuilder::new()
463
+ /// # .with_fixed_tpm(true)
464
+ /// # .with_fixed_parent(true)
465
+ /// # .with_sensitive_data_origin(true)
466
+ /// # .with_user_with_auth(true)
467
+ /// # .with_decrypt(true)
468
+ /// # .with_sign_encrypt(false)
469
+ /// # .with_restricted(true)
470
+ /// # .build()
471
+ /// # .unwrap();
472
+ /// #
473
+ /// # let parent_public = PublicBuilder::new()
474
+ /// # .with_public_algorithm(PublicAlgorithm::Rsa)
475
+ /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
476
+ /// # .with_object_attributes(parent_object_attributes)
477
+ /// # .with_rsa_parameters(
478
+ /// # PublicRsaParametersBuilder::new_restricted_decryption_key(
479
+ /// # Cipher::aes_256_cfb().try_into().unwrap(),
480
+ /// # RsaKeyBits::Rsa2048,
481
+ /// # RsaExponent::default(),
482
+ /// # )
483
+ /// # .build()
484
+ /// # .unwrap(),
485
+ /// # )
486
+ /// # .with_rsa_unique_identifier(&PublicKeyRsa::default())
487
+ /// # .build()
488
+ /// # .unwrap();
489
+ /// #
490
+ /// # let parent_of_object_to_duplicate_handle = context
491
+ /// # .create_primary(
492
+ /// # Hierarchy::Owner,
493
+ /// # &parent_public,
494
+ /// # None,
495
+ /// # None,
496
+ /// # None,
497
+ /// # None,
498
+ /// # )
499
+ /// # .unwrap()
500
+ /// # .key_handle;
501
+ /// #
502
+ /// # // Fixed TPM and Fixed Parent should be "false" for an object
503
+ /// # // to be elligible for duplication
504
+ /// # let object_attributes = ObjectAttributesBuilder::new()
505
+ /// # .with_fixed_tpm(false)
506
+ /// # .with_fixed_parent(false)
507
+ /// # .with_sensitive_data_origin(true)
508
+ /// # .with_user_with_auth(true)
509
+ /// # .with_decrypt(true)
510
+ /// # .with_sign_encrypt(true)
511
+ /// # .with_restricted(false)
512
+ /// # .build()
513
+ /// # .expect("Attributes to be valid");
514
+ /// #
515
+ /// # let public_child = PublicBuilder::new()
516
+ /// # .with_public_algorithm(PublicAlgorithm::Rsa)
517
+ /// # .with_name_hashing_algorithm(HashingAlgorithm::Sha256)
518
+ /// # .with_object_attributes(object_attributes)
519
+ /// # .with_auth_policy(&digest)
520
+ /// # .with_rsa_parameters(
521
+ /// # PublicRsaParametersBuilder::new()
522
+ /// # .with_scheme(RsaScheme::Null)
523
+ /// # .with_key_bits(RsaKeyBits::Rsa2048)
524
+ /// # .with_is_signing_key(true)
525
+ /// # .with_is_decryption_key(true)
526
+ /// # .with_restricted(false)
527
+ /// # .build()
528
+ /// # .expect("Params to be valid"),
529
+ /// # )
530
+ /// # .with_rsa_unique_identifier(&PublicKeyRsa::default())
531
+ /// # .build()
532
+ /// # .expect("public to be valid");
533
+ /// #
534
+ /// # let result = context
535
+ /// # .create(
536
+ /// # parent_of_object_to_duplicate_handle,
537
+ /// # &public_child,
538
+ /// # None,
539
+ /// # None,
540
+ /// # None,
541
+ /// # None,
542
+ /// # )
543
+ /// # .unwrap();
544
+ /// #
545
+ /// # let object_to_duplicate_handle: ObjectHandle = context
546
+ /// # .load(
547
+ /// # parent_of_object_to_duplicate_handle,
548
+ /// # result.out_private.clone(),
549
+ /// # &result.out_public,
550
+ /// # )
551
+ /// # .unwrap()
552
+ /// # .into();
553
+ /// #
554
+ /// # let new_parent_handle: ObjectHandle = context
555
+ /// # .create_primary(
556
+ /// # Hierarchy::Owner,
557
+ /// # &parent_public,
558
+ /// # None,
559
+ /// # None,
560
+ /// # None,
561
+ /// # None,
562
+ /// # )
563
+ /// # .unwrap()
564
+ /// # .key_handle
565
+ /// # .into();
566
+ /// #
567
+ /// # context.set_sessions((None, None, None));
568
+ /// #
569
+ /// # // Create a Policy session with the same exact attributes
570
+ /// # // as the trial session so that the session digest stays
571
+ /// # // the same.
572
+ /// # let policy_auth_session = context
573
+ /// # .start_auth_session(
574
+ /// # None,
575
+ /// # None,
576
+ /// # None,
577
+ /// # SessionType::Policy,
578
+ /// # SymmetricDefinition::AES_256_CFB,
579
+ /// # HashingAlgorithm::Sha256,
580
+ /// # )
581
+ /// # .expect("Start auth session failed")
582
+ /// # .expect("Start auth session returned a NONE handle");
583
+ /// #
584
+ /// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
585
+ /// # SessionAttributesBuilder::new()
586
+ /// # .with_decrypt(true)
587
+ /// # .with_encrypt(true)
588
+ /// # .build();
589
+ /// # context
590
+ /// # .tr_sess_set_attributes(
591
+ /// # policy_auth_session,
592
+ /// # policy_auth_session_attributes,
593
+ /// # policy_auth_session_attributes_mask,
594
+ /// # )
595
+ /// # .expect("tr_sess_set_attributes call failed");
596
+ /// #
597
+ /// # let policy_session = PolicySession::try_from(policy_auth_session)
598
+ /// # .expect("Failed to convert auth session into policy session");
599
+ /// #
600
+ /// # context
601
+ /// # .policy_auth_value(policy_session)
602
+ /// # .expect("Policy auth value");
603
+ /// #
604
+ /// # context
605
+ /// # .policy_command_code(policy_session, TPM2_CC_Duplicate)
606
+ /// # .unwrap();
607
+ /// #
608
+ /// # context.set_sessions((Some(policy_auth_session), None, None));
609
+ /// #
610
+ /// # let (encryption_key_out, duplicate, out_sym_seed) = context
611
+ /// # .duplicate(
612
+ /// # object_to_duplicate_handle,
613
+ /// # new_parent_handle,
614
+ /// # None,
615
+ /// # SymmetricDefinitionObject::Null,
616
+ /// # )
617
+ /// # .unwrap();
618
+ /// # eprintln!("D: {:?}, P: {:?}, S: {:?}", encryption_key_out, duplicate, out_sym_seed);
619
+ /// # let public = context.read_public(object_to_duplicate_handle.into()).unwrap().0;
620
+ /// #
621
+ /// # let session = context
622
+ /// # .start_auth_session(
623
+ /// # None,
624
+ /// # None,
625
+ /// # None,
626
+ /// # SessionType::Hmac,
627
+ /// # SymmetricDefinition::AES_256_CFB,
628
+ /// # HashingAlgorithm::Sha256,
629
+ /// # )
630
+ /// # .unwrap();
631
+ /// # let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
632
+ /// # .with_decrypt(true)
633
+ /// # .with_encrypt(true)
634
+ /// # .build();
635
+ /// # context.tr_sess_set_attributes(
636
+ /// # session.unwrap(),
637
+ /// # session_attributes,
638
+ /// # session_attributes_mask,
639
+ /// # )
640
+ /// # .unwrap();
641
+ /// # context.set_sessions((session, None, None));
642
+ ///
643
+ /// // `encryption_key_out`, `duplicate` and `out_sym_seed` are generated
644
+ /// // by `duplicate` function
645
+ /// let private = context.import(
646
+ /// new_parent_handle,
647
+ /// Some(encryption_key_out),
648
+ /// public,
649
+ /// duplicate,
650
+ /// out_sym_seed,
651
+ /// SymmetricDefinitionObject::Null,
652
+ /// ).unwrap();
653
+ /// #
654
+ /// # eprintln!("P: {:?}", private);
655
+ /// ```
656
+ pub fn import (
657
+ & mut self ,
658
+ parent_handle : ObjectHandle ,
659
+ encryption_key : Option < Data > ,
660
+ public : Public ,
661
+ duplicate : Private ,
662
+ encrypted_secret : EncryptedSecret ,
663
+ symmetric_alg : SymmetricDefinitionObject ,
664
+ ) -> Result < Private > {
665
+ let mut out_private = null_mut ( ) ;
666
+ let ret = unsafe {
667
+ Esys_Import (
668
+ self . mut_context ( ) ,
669
+ parent_handle. into ( ) ,
670
+ self . required_session_1 ( ) ?,
671
+ self . optional_session_2 ( ) ,
672
+ self . optional_session_3 ( ) ,
673
+ & encryption_key. unwrap_or_default ( ) . into ( ) ,
674
+ & public. into ( ) ,
675
+ & duplicate. into ( ) ,
676
+ & encrypted_secret. into ( ) ,
677
+ & symmetric_alg. into ( ) ,
678
+ & mut out_private,
679
+ )
680
+ } ;
681
+ let ret = Error :: from_tss_rc ( ret) ;
682
+
683
+ if ret. is_success ( ) {
684
+ Ok ( unsafe { Private :: try_from ( * out_private) ? } )
685
+ } else {
686
+ error ! ( "Error when performing import: {}" , ret) ;
687
+ Err ( ret)
688
+ }
689
+ }
335
690
}
0 commit comments