tss_esapi/attributes/
locality.rs1use crate::{tss2_esys::TPMA_LOCALITY, Error, Result, WrapperErrorKind};
5use bitfield::bitfield;
6use log::error;
7
8bitfield! {
9 #[derive(Copy, Clone, Eq, PartialEq)]
11 pub struct LocalityAttributes(TPMA_LOCALITY);
12 impl Debug;
13
14 _, set_locality_zero: 0;
15 pub locality_zero, _: 0;
16 _, set_locality_one: 1;
17 pub locality_one, _: 1;
18 _, set_locality_two: 2;
19 pub locality_two, _: 2;
20 _, set_locality_three: 3;
21 pub locality_three, _: 3;
22 _, set_locality_four: 4;
23 pub locality_four, _: 4;
24 _, set_extended: 7, 5;
25 extended, _: 7, 5;
26}
27
28impl LocalityAttributes {
29 pub const LOCALITY_ZERO: LocalityAttributes = LocalityAttributes(1);
30 pub const LOCALITY_ONE: LocalityAttributes = LocalityAttributes(2);
31 pub const LOCALITY_TWO: LocalityAttributes = LocalityAttributes(4);
32 pub const LOCALITY_THREE: LocalityAttributes = LocalityAttributes(8);
33 pub const LOCALITY_FOUR: LocalityAttributes = LocalityAttributes(16);
34 pub fn is_extended(&self) -> bool {
36 self.extended() != 0u8
37 }
38
39 pub fn as_extended(&self) -> Result<u8> {
45 if self.is_extended() {
46 Ok(self.0)
47 } else {
48 error!("Cannot retrieve LocalityAttributes as extended when the attributes are not indicated to be extended");
49 Err(Error::local_error(WrapperErrorKind::InvalidParam))
50 }
51 }
52
53 pub const fn builder() -> LocalityAttributesBuilder {
55 LocalityAttributesBuilder::new()
56 }
57}
58
59impl From<TPMA_LOCALITY> for LocalityAttributes {
60 fn from(tpma_locality: TPMA_LOCALITY) -> Self {
61 LocalityAttributes(tpma_locality)
62 }
63}
64
65impl From<LocalityAttributes> for TPMA_LOCALITY {
66 fn from(locality_attributes: LocalityAttributes) -> Self {
67 locality_attributes.0
68 }
69}
70
71#[derive(Debug, Clone)]
72pub struct LocalityAttributesBuilder {
73 localities: Vec<u8>,
74}
75
76impl LocalityAttributesBuilder {
77 pub const fn new() -> Self {
79 LocalityAttributesBuilder {
80 localities: Vec::new(),
81 }
82 }
83 pub fn with_locality(mut self, locality: u8) -> Self {
85 self.localities.push(locality);
86 self
87 }
88
89 pub fn with_localities(mut self, localities: &[u8]) -> Self {
91 self.localities.extend_from_slice(localities);
92 self
93 }
94
95 pub fn build(self) -> Result<LocalityAttributes> {
97 let mut locality_attributes = LocalityAttributes(0);
98 for locality in self.localities {
99 if locality_attributes.is_extended() {
100 error!("Locality attribute {new} and locality attribute {prev} cannot be combined because locality attribute {prev} is extended", new=locality, prev=locality_attributes.0);
101 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
102 }
103 match locality {
104 0 => locality_attributes.set_locality_zero(true),
105 1 => locality_attributes.set_locality_one(true),
106 2 => locality_attributes.set_locality_two(true),
107 3 => locality_attributes.set_locality_three(true),
108 4 => locality_attributes.set_locality_four(true),
109 5..=31 => {
110 error!(
111 "Locality attribute {new} is invalid and cannot be combined with other locality attributes",
112 new=locality
113 );
114 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
115 }
116 32..=255 => {
117 if locality_attributes.0 != 0 {
118 error!("Locality attribute {new} is extended and cannot be combined with locality attribute(s) {old}", new=locality, old=locality_attributes.0);
119 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
120 }
121 locality_attributes.0 = locality;
122 }
123 }
124 }
125 Ok(locality_attributes)
126 }
127}
128
129impl Default for LocalityAttributesBuilder {
130 fn default() -> Self {
131 Self::new()
132 }
133}