Skip to main content

tss_esapi/structures/tagged/
symmetric.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    interface_types::{
5        algorithm::{HashingAlgorithm, SymmetricAlgorithm, SymmetricMode, SymmetricObject},
6        key_bits::{AesKeyBits, CamelliaKeyBits, Sm4KeyBits},
7    },
8    tss2_esys::{TPMT_SYM_DEF, TPMT_SYM_DEF_OBJECT, TPMU_SYM_KEY_BITS, TPMU_SYM_MODE},
9    Error, Result, WrapperErrorKind,
10};
11use std::convert::{TryFrom, TryInto};
12/// Enum representing the symmetric algorithm definition.
13///
14/// # Details
15/// This corresponds to TPMT_SYM_DEF.
16#[derive(Debug, Clone, Copy, Eq, PartialEq)]
17pub enum SymmetricDefinition {
18    // TODO: Investigate why TDES is not included...
19    Aes {
20        key_bits: AesKeyBits,
21        mode: SymmetricMode,
22    },
23    Sm4 {
24        key_bits: Sm4KeyBits,
25        mode: SymmetricMode,
26    },
27    Camellia {
28        key_bits: CamelliaKeyBits,
29        mode: SymmetricMode,
30    },
31    Xor {
32        hashing_algorithm: HashingAlgorithm,
33    },
34    Null,
35}
36
37impl SymmetricDefinition {
38    /// Constant for the AES 128 bits CFB symmetric definition
39    pub const AES_128_CFB: SymmetricDefinition = SymmetricDefinition::Aes {
40        key_bits: AesKeyBits::Aes128,
41        mode: SymmetricMode::Cfb,
42    };
43
44    /// Constant for the AES 128 bits CFB symmetric definition
45    pub const AES_256_CFB: SymmetricDefinition = SymmetricDefinition::Aes {
46        key_bits: AesKeyBits::Aes256,
47        mode: SymmetricMode::Cfb,
48    };
49}
50
51impl TryFrom<SymmetricDefinition> for TPMT_SYM_DEF {
52    type Error = Error;
53    fn try_from(symmetric_definition: SymmetricDefinition) -> Result<TPMT_SYM_DEF> {
54        match symmetric_definition {
55            SymmetricDefinition::Aes { key_bits, mode } => Ok(TPMT_SYM_DEF {
56                algorithm: SymmetricAlgorithm::Aes.into(),
57                keyBits: TPMU_SYM_KEY_BITS {
58                    aes: key_bits.into(),
59                },
60                mode: TPMU_SYM_MODE { aes: mode.into() },
61            }),
62            SymmetricDefinition::Sm4 { key_bits, mode } => Ok(TPMT_SYM_DEF {
63                algorithm: SymmetricAlgorithm::Sm4.into(),
64                keyBits: TPMU_SYM_KEY_BITS {
65                    sm4: key_bits.into(),
66                },
67                mode: TPMU_SYM_MODE { sm4: mode.into() },
68            }),
69            SymmetricDefinition::Camellia { key_bits, mode } => Ok(TPMT_SYM_DEF {
70                algorithm: SymmetricAlgorithm::Camellia.into(),
71                keyBits: TPMU_SYM_KEY_BITS {
72                    camellia: key_bits.into(),
73                },
74                mode: TPMU_SYM_MODE {
75                    camellia: mode.into(),
76                },
77            }),
78            SymmetricDefinition::Xor { hashing_algorithm } => Ok(TPMT_SYM_DEF {
79                algorithm: SymmetricAlgorithm::Xor.into(),
80                keyBits: TPMU_SYM_KEY_BITS {
81                    exclusiveOr: if hashing_algorithm != HashingAlgorithm::Null {
82                        hashing_algorithm.into()
83                    } else {
84                        return Err(Error::local_error(WrapperErrorKind::InvalidParam));
85                    },
86                },
87                mode: Default::default(),
88            }),
89            SymmetricDefinition::Null => Ok(TPMT_SYM_DEF {
90                algorithm: SymmetricAlgorithm::Null.into(),
91                keyBits: Default::default(),
92                mode: Default::default(),
93            }),
94        }
95    }
96}
97
98impl TryFrom<TPMT_SYM_DEF> for SymmetricDefinition {
99    type Error = Error;
100    fn try_from(tpmt_sym_def: TPMT_SYM_DEF) -> Result<SymmetricDefinition> {
101        match SymmetricAlgorithm::try_from(tpmt_sym_def.algorithm)? {
102            SymmetricAlgorithm::Aes => Ok(SymmetricDefinition::Aes {
103                key_bits: unsafe { tpmt_sym_def.keyBits.aes }.try_into()?,
104                mode: unsafe { tpmt_sym_def.mode.aes }.try_into()?,
105            }),
106            SymmetricAlgorithm::Sm4 => Ok(SymmetricDefinition::Sm4 {
107                key_bits: unsafe { tpmt_sym_def.keyBits.sm4 }.try_into()?,
108                mode: unsafe { tpmt_sym_def.mode.sm4 }.try_into()?,
109            }),
110            SymmetricAlgorithm::Camellia => Ok(SymmetricDefinition::Camellia {
111                key_bits: unsafe { tpmt_sym_def.keyBits.camellia }.try_into()?,
112                mode: unsafe { tpmt_sym_def.mode.camellia }.try_into()?,
113            }),
114            SymmetricAlgorithm::Xor => Ok(SymmetricDefinition::Xor {
115                hashing_algorithm: HashingAlgorithm::try_from(unsafe {
116                    tpmt_sym_def.keyBits.exclusiveOr
117                })
118                .and_then(|ha| {
119                    if ha != HashingAlgorithm::Null {
120                        Ok(ha)
121                    } else {
122                        Err(Error::local_error(WrapperErrorKind::InvalidParam))
123                    }
124                })?,
125            }),
126            SymmetricAlgorithm::Null => Ok(SymmetricDefinition::Null),
127            SymmetricAlgorithm::Tdes => {
128                // TODO: Investigate this...
129                Err(Error::local_error(WrapperErrorKind::WrongValueFromTpm))
130            }
131        }
132    }
133}
134
135/// Enum representing the symmetric definition object.
136///
137/// # Details
138/// This corresponds to TPMT_SYM_DEF_OBJECT
139#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
140pub enum SymmetricDefinitionObject {
141    // TDOD: Investigate why TDES is missing.
142    Aes {
143        key_bits: AesKeyBits,
144        mode: SymmetricMode,
145    },
146    Sm4 {
147        key_bits: Sm4KeyBits,
148        mode: SymmetricMode,
149    },
150    Camellia {
151        key_bits: CamelliaKeyBits,
152        mode: SymmetricMode,
153    },
154    #[default]
155    Null,
156}
157
158impl SymmetricDefinitionObject {
159    /// Constant for the AES 128 bits CFB symmetric definition object
160    pub const AES_128_CFB: SymmetricDefinitionObject = SymmetricDefinitionObject::Aes {
161        key_bits: AesKeyBits::Aes128,
162        mode: SymmetricMode::Cfb,
163    };
164    /// Constant for the AES 256 bits CFB symmetric definition object
165    pub const AES_256_CFB: SymmetricDefinitionObject = SymmetricDefinitionObject::Aes {
166        key_bits: AesKeyBits::Aes256,
167        mode: SymmetricMode::Cfb,
168    };
169    // Constant for the SM4 128 bits CFB symmetric definition object
170    pub const SM4_128_CFB: SymmetricDefinitionObject = SymmetricDefinitionObject::Sm4 {
171        key_bits: Sm4KeyBits::Sm4_128,
172        mode: SymmetricMode::Cfb,
173    };
174    pub(crate) fn is_null(&self) -> bool {
175        matches!(self, Self::Null)
176    }
177}
178
179impl From<SymmetricDefinitionObject> for TPMT_SYM_DEF_OBJECT {
180    fn from(symmetric_definition_object: SymmetricDefinitionObject) -> TPMT_SYM_DEF_OBJECT {
181        match symmetric_definition_object {
182            SymmetricDefinitionObject::Aes { key_bits, mode } => TPMT_SYM_DEF_OBJECT {
183                algorithm: SymmetricAlgorithm::Aes.into(),
184                keyBits: TPMU_SYM_KEY_BITS {
185                    aes: key_bits.into(),
186                },
187                mode: TPMU_SYM_MODE { aes: mode.into() },
188            },
189            SymmetricDefinitionObject::Sm4 { key_bits, mode } => TPMT_SYM_DEF_OBJECT {
190                algorithm: SymmetricAlgorithm::Sm4.into(),
191                keyBits: TPMU_SYM_KEY_BITS {
192                    sm4: key_bits.into(),
193                },
194                mode: TPMU_SYM_MODE { sm4: mode.into() },
195            },
196            SymmetricDefinitionObject::Camellia { key_bits, mode } => TPMT_SYM_DEF_OBJECT {
197                algorithm: SymmetricAlgorithm::Camellia.into(),
198                keyBits: TPMU_SYM_KEY_BITS {
199                    camellia: key_bits.into(),
200                },
201                mode: TPMU_SYM_MODE {
202                    camellia: mode.into(),
203                },
204            },
205            SymmetricDefinitionObject::Null => TPMT_SYM_DEF_OBJECT {
206                algorithm: SymmetricAlgorithm::Null.into(),
207                keyBits: Default::default(),
208                mode: Default::default(),
209            },
210        }
211    }
212}
213
214impl From<SymmetricDefinitionObject> for SymmetricDefinition {
215    fn from(sym_def_obj: SymmetricDefinitionObject) -> Self {
216        match sym_def_obj {
217            SymmetricDefinitionObject::Null => SymmetricDefinition::Null,
218            SymmetricDefinitionObject::Camellia { key_bits, mode } => {
219                SymmetricDefinition::Camellia { key_bits, mode }
220            }
221            SymmetricDefinitionObject::Aes { key_bits, mode } => {
222                SymmetricDefinition::Aes { key_bits, mode }
223            }
224            SymmetricDefinitionObject::Sm4 { key_bits, mode } => {
225                SymmetricDefinition::Sm4 { key_bits, mode }
226            }
227        }
228    }
229}
230
231impl TryFrom<TPMT_SYM_DEF_OBJECT> for SymmetricDefinitionObject {
232    type Error = Error;
233    fn try_from(tpmt_sym_def_object: TPMT_SYM_DEF_OBJECT) -> Result<SymmetricDefinitionObject> {
234        match SymmetricObject::try_from(tpmt_sym_def_object.algorithm)? {
235            SymmetricObject::Aes => Ok(SymmetricDefinitionObject::Aes {
236                key_bits: unsafe { tpmt_sym_def_object.keyBits.aes }.try_into()?,
237                mode: unsafe { tpmt_sym_def_object.mode.aes }.try_into()?,
238            }),
239            SymmetricObject::Sm4 => Ok(SymmetricDefinitionObject::Sm4 {
240                key_bits: unsafe { tpmt_sym_def_object.keyBits.sm4 }.try_into()?,
241                mode: unsafe { tpmt_sym_def_object.mode.sm4 }.try_into()?,
242            }),
243            SymmetricObject::Camellia => Ok(SymmetricDefinitionObject::Camellia {
244                key_bits: unsafe { tpmt_sym_def_object.keyBits.camellia }.try_into()?,
245                mode: unsafe { tpmt_sym_def_object.mode.camellia }.try_into()?,
246            }),
247            SymmetricObject::Null => Ok(SymmetricDefinitionObject::Null),
248            SymmetricObject::Tdes => {
249                // TODO: Investigate this...
250                Err(Error::local_error(WrapperErrorKind::WrongValueFromTpm))
251            }
252        }
253    }
254}