tss_esapi/attributes/
locality.rs1use crate::{Error, Result, WrapperErrorKind, tss2_esys::TPMA_LOCALITY};
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!(
49 "Cannot retrieve LocalityAttributes as extended when the attributes are not indicated to be extended"
50 );
51 Err(Error::local_error(WrapperErrorKind::InvalidParam))
52 }
53 }
54
55 pub const fn builder() -> LocalityAttributesBuilder {
57 LocalityAttributesBuilder::new()
58 }
59}
60
61impl From<TPMA_LOCALITY> for LocalityAttributes {
62 fn from(tpma_locality: TPMA_LOCALITY) -> Self {
63 LocalityAttributes(tpma_locality)
64 }
65}
66
67impl From<LocalityAttributes> for TPMA_LOCALITY {
68 fn from(locality_attributes: LocalityAttributes) -> Self {
69 locality_attributes.0
70 }
71}
72
73#[derive(Debug, Clone)]
74pub struct LocalityAttributesBuilder {
75 localities: Vec<u8>,
76}
77
78impl LocalityAttributesBuilder {
79 pub const fn new() -> Self {
81 LocalityAttributesBuilder {
82 localities: Vec::new(),
83 }
84 }
85 pub fn with_locality(mut self, locality: u8) -> Self {
87 self.localities.push(locality);
88 self
89 }
90
91 pub fn with_localities(mut self, localities: &[u8]) -> Self {
93 self.localities.extend_from_slice(localities);
94 self
95 }
96
97 pub fn build(self) -> Result<LocalityAttributes> {
99 let mut locality_attributes = LocalityAttributes(0);
100 for locality in self.localities {
101 if locality_attributes.is_extended() {
102 error!(
103 "Locality attribute {new} and locality attribute {prev} cannot be combined because locality attribute {prev} is extended",
104 new = locality,
105 prev = locality_attributes.0
106 );
107 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
108 }
109 match locality {
110 0 => locality_attributes.set_locality_zero(true),
111 1 => locality_attributes.set_locality_one(true),
112 2 => locality_attributes.set_locality_two(true),
113 3 => locality_attributes.set_locality_three(true),
114 4 => locality_attributes.set_locality_four(true),
115 5..=31 => {
116 error!(
117 "Locality attribute {new} is invalid and cannot be combined with other locality attributes",
118 new = locality
119 );
120 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
121 }
122 32..=255 => {
123 if locality_attributes.0 != 0 {
124 error!(
125 "Locality attribute {new} is extended and cannot be combined with locality attribute(s) {old}",
126 new = locality,
127 old = locality_attributes.0
128 );
129 return Err(Error::local_error(WrapperErrorKind::InvalidParam));
130 }
131 locality_attributes.0 = locality;
132 }
133 }
134 }
135 Ok(locality_attributes)
136 }
137}
138
139impl Default for LocalityAttributesBuilder {
140 fn default() -> Self {
141 Self::new()
142 }
143}