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, PartialEq, Eq, Default)]
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
165    /// Constant for the AES 256 bits CFB symmetric definition object
166    pub const AES_256_CFB: SymmetricDefinitionObject = SymmetricDefinitionObject::Aes {
167        key_bits: AesKeyBits::Aes256,
168        mode: SymmetricMode::Cfb,
169    };
170
171    // Constant for the SM4 128 bits CFB symmetric definition object
172    pub const SM4_128_CFB: SymmetricDefinitionObject = SymmetricDefinitionObject::Sm4 {
173        key_bits: Sm4KeyBits::Sm4_128,
174        mode: SymmetricMode::Cfb,
175    };
176
177    pub(crate) fn is_null(&self) -> bool {
178        matches!(self, Self::Null)
179    }
180}
181
182impl From<SymmetricDefinitionObject> for TPMT_SYM_DEF_OBJECT {
183    fn from(symmetric_definition_object: SymmetricDefinitionObject) -> TPMT_SYM_DEF_OBJECT {
184        match symmetric_definition_object {
185            SymmetricDefinitionObject::Aes { key_bits, mode } => TPMT_SYM_DEF_OBJECT {
186                algorithm: SymmetricAlgorithm::Aes.into(),
187                keyBits: TPMU_SYM_KEY_BITS {
188                    aes: key_bits.into(),
189                },
190                mode: TPMU_SYM_MODE { aes: mode.into() },
191            },
192            SymmetricDefinitionObject::Sm4 { key_bits, mode } => TPMT_SYM_DEF_OBJECT {
193                algorithm: SymmetricAlgorithm::Sm4.into(),
194                keyBits: TPMU_SYM_KEY_BITS {
195                    sm4: key_bits.into(),
196                },
197                mode: TPMU_SYM_MODE { sm4: mode.into() },
198            },
199            SymmetricDefinitionObject::Camellia { key_bits, mode } => TPMT_SYM_DEF_OBJECT {
200                algorithm: SymmetricAlgorithm::Camellia.into(),
201                keyBits: TPMU_SYM_KEY_BITS {
202                    camellia: key_bits.into(),
203                },
204                mode: TPMU_SYM_MODE {
205                    camellia: mode.into(),
206                },
207            },
208            SymmetricDefinitionObject::Null => TPMT_SYM_DEF_OBJECT {
209                algorithm: SymmetricAlgorithm::Null.into(),
210                keyBits: Default::default(),
211                mode: Default::default(),
212            },
213        }
214    }
215}
216
217impl From<SymmetricDefinitionObject> for SymmetricDefinition {
218    fn from(sym_def_obj: SymmetricDefinitionObject) -> Self {
219        match sym_def_obj {
220            SymmetricDefinitionObject::Null => SymmetricDefinition::Null,
221            SymmetricDefinitionObject::Camellia { key_bits, mode } => {
222                SymmetricDefinition::Camellia { key_bits, mode }
223            }
224            SymmetricDefinitionObject::Aes { key_bits, mode } => {
225                SymmetricDefinition::Aes { key_bits, mode }
226            }
227            SymmetricDefinitionObject::Sm4 { key_bits, mode } => {
228                SymmetricDefinition::Sm4 { key_bits, mode }
229            }
230        }
231    }
232}
233
234impl TryFrom<TPMT_SYM_DEF_OBJECT> for SymmetricDefinitionObject {
235    type Error = Error;
236    fn try_from(tpmt_sym_def_object: TPMT_SYM_DEF_OBJECT) -> Result<SymmetricDefinitionObject> {
237        match SymmetricObject::try_from(tpmt_sym_def_object.algorithm)? {
238            SymmetricObject::Aes => Ok(SymmetricDefinitionObject::Aes {
239                key_bits: unsafe { tpmt_sym_def_object.keyBits.aes }.try_into()?,
240                mode: unsafe { tpmt_sym_def_object.mode.aes }.try_into()?,
241            }),
242            SymmetricObject::Sm4 => Ok(SymmetricDefinitionObject::Sm4 {
243                key_bits: unsafe { tpmt_sym_def_object.keyBits.sm4 }.try_into()?,
244                mode: unsafe { tpmt_sym_def_object.mode.sm4 }.try_into()?,
245            }),
246            SymmetricObject::Camellia => Ok(SymmetricDefinitionObject::Camellia {
247                key_bits: unsafe { tpmt_sym_def_object.keyBits.camellia }.try_into()?,
248                mode: unsafe { tpmt_sym_def_object.mode.camellia }.try_into()?,
249            }),
250            SymmetricObject::Null => Ok(SymmetricDefinitionObject::Null),
251            SymmetricObject::Tdes => {
252                // TODO: Investigate this...
253                Err(Error::local_error(WrapperErrorKind::WrongValueFromTpm))
254            }
255        }
256    }
257}