1use crate::{
4 interface_types::algorithm::{
5 EccSchemeAlgorithm, HashingAlgorithm, KeyDerivationFunction, KeyedHashSchemeAlgorithm,
6 RsaDecryptAlgorithm, RsaSchemeAlgorithm, SignatureSchemeAlgorithm,
7 },
8 structures::schemes::{EcDaaScheme, HashScheme, HmacScheme, XorScheme},
9 tss2_esys::{
10 TPMT_ECC_SCHEME, TPMT_KDF_SCHEME, TPMT_KEYEDHASH_SCHEME, TPMT_RSA_DECRYPT, TPMT_RSA_SCHEME,
11 TPMT_SIG_SCHEME, TPMU_ASYM_SCHEME, TPMU_KDF_SCHEME, TPMU_SCHEME_KEYEDHASH, TPMU_SIG_SCHEME,
12 },
13 Error, Result, WrapperErrorKind,
14};
15use log::error;
16use std::convert::{TryFrom, TryInto};
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum KeyedHashScheme {
24 Xor { xor_scheme: XorScheme },
25 Hmac { hmac_scheme: HmacScheme },
26 Null,
27}
28
29impl KeyedHashScheme {
30 pub const HMAC_SHA_256: KeyedHashScheme = KeyedHashScheme::Hmac {
31 hmac_scheme: HmacScheme::new(HashingAlgorithm::Sha256),
32 };
33}
34
35impl From<KeyedHashScheme> for TPMT_KEYEDHASH_SCHEME {
36 fn from(keyed_hash_scheme: KeyedHashScheme) -> Self {
37 match keyed_hash_scheme {
38 KeyedHashScheme::Xor { xor_scheme } => TPMT_KEYEDHASH_SCHEME {
39 scheme: KeyedHashSchemeAlgorithm::Xor.into(),
40 details: TPMU_SCHEME_KEYEDHASH {
41 exclusiveOr: xor_scheme.into(),
42 },
43 },
44 KeyedHashScheme::Hmac { hmac_scheme } => TPMT_KEYEDHASH_SCHEME {
45 scheme: KeyedHashSchemeAlgorithm::Hmac.into(),
46 details: TPMU_SCHEME_KEYEDHASH {
47 hmac: hmac_scheme.into(),
48 },
49 },
50 KeyedHashScheme::Null => TPMT_KEYEDHASH_SCHEME {
51 scheme: KeyedHashSchemeAlgorithm::Null.into(),
52 details: Default::default(),
53 },
54 }
55 }
56}
57
58impl TryFrom<TPMT_KEYEDHASH_SCHEME> for KeyedHashScheme {
59 type Error = Error;
60 fn try_from(tpmt_keyedhash_scheme: TPMT_KEYEDHASH_SCHEME) -> Result<KeyedHashScheme> {
61 match KeyedHashSchemeAlgorithm::try_from(tpmt_keyedhash_scheme.scheme)? {
62 KeyedHashSchemeAlgorithm::Xor => Ok(KeyedHashScheme::Xor {
63 xor_scheme: unsafe { tpmt_keyedhash_scheme.details.exclusiveOr }.try_into()?,
64 }),
65 KeyedHashSchemeAlgorithm::Hmac => Ok(KeyedHashScheme::Hmac {
66 hmac_scheme: unsafe { tpmt_keyedhash_scheme.details.hmac }.try_into()?,
67 }),
68 KeyedHashSchemeAlgorithm::Null => Ok(KeyedHashScheme::Null),
69 }
70 }
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub enum RsaScheme {
81 RsaSsa(HashScheme),
82 RsaEs,
83 RsaPss(HashScheme),
84 Oaep(HashScheme),
85 Null,
86}
87
88impl RsaScheme {
89 pub fn create(
105 rsa_scheme_algorithm: RsaSchemeAlgorithm,
106 hashing_algorithm: Option<HashingAlgorithm>,
107 ) -> Result<RsaScheme> {
108 match rsa_scheme_algorithm {
109 RsaSchemeAlgorithm::RsaSsa => Ok(RsaScheme::RsaSsa(HashScheme::new(
110 hashing_algorithm.ok_or_else(|| {
111 error!(
112 "Hashing algorithm is required when creating RSA scheme of type RSA SSA"
113 );
114 Error::local_error(WrapperErrorKind::ParamsMissing)
115 })?,
116 ))),
117 RsaSchemeAlgorithm::RsaEs => {
118 if hashing_algorithm.is_some() {
119 error!("A hashing algorithm shall not be provided when creating RSA scheme of type RSA ES");
120 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
121 }
122 Ok(RsaScheme::RsaEs)
123 }
124 RsaSchemeAlgorithm::RsaPss => Ok(RsaScheme::RsaPss(HashScheme::new(
125 hashing_algorithm.ok_or_else(|| {
126 error!(
127 "Hashing algorithm is required when creating RSA scheme of type RSA PSS"
128 );
129 Error::local_error(WrapperErrorKind::ParamsMissing)
130 })?,
131 ))),
132 RsaSchemeAlgorithm::Oaep => Ok(RsaScheme::Oaep(HashScheme::new(
133 hashing_algorithm.ok_or_else(|| {
134 error!("Hashing algorithm is required when creating RSA scheme of type OAEP");
135 Error::local_error(WrapperErrorKind::ParamsMissing)
136 })?,
137 ))),
138 RsaSchemeAlgorithm::Null => {
139 if hashing_algorithm.is_some() {
140 error!("A hashing algorithm shall not be provided when creating RSA scheme of type Null");
141 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
142 }
143 Ok(RsaScheme::Null)
144 }
145 }
146 }
147
148 pub fn algorithm(&self) -> RsaSchemeAlgorithm {
150 match self {
151 RsaScheme::RsaSsa(_) => RsaSchemeAlgorithm::RsaSsa,
152 RsaScheme::RsaEs => RsaSchemeAlgorithm::RsaEs,
153 RsaScheme::RsaPss(_) => RsaSchemeAlgorithm::RsaPss,
154 RsaScheme::Oaep(_) => RsaSchemeAlgorithm::Oaep,
155 RsaScheme::Null => RsaSchemeAlgorithm::Null,
156 }
157 }
158}
159
160impl From<RsaScheme> for TPMT_RSA_SCHEME {
161 fn from(rsa_scheme: RsaScheme) -> Self {
162 match rsa_scheme {
163 RsaScheme::RsaSsa(hash_scheme) => TPMT_RSA_SCHEME {
164 scheme: rsa_scheme.algorithm().into(),
165 details: TPMU_ASYM_SCHEME {
166 rsassa: hash_scheme.into(),
167 },
168 },
169 RsaScheme::RsaEs => TPMT_RSA_SCHEME {
170 scheme: rsa_scheme.algorithm().into(),
171 details: TPMU_ASYM_SCHEME {
172 rsaes: Default::default(),
173 },
174 },
175 RsaScheme::RsaPss(hash_scheme) => TPMT_RSA_SCHEME {
176 scheme: rsa_scheme.algorithm().into(),
177 details: TPMU_ASYM_SCHEME {
178 rsapss: hash_scheme.into(),
179 },
180 },
181 RsaScheme::Oaep(hash_scheme) => TPMT_RSA_SCHEME {
182 scheme: rsa_scheme.algorithm().into(),
183 details: TPMU_ASYM_SCHEME {
184 oaep: hash_scheme.into(),
185 },
186 },
187 RsaScheme::Null => TPMT_RSA_SCHEME {
188 scheme: rsa_scheme.algorithm().into(),
189 details: Default::default(),
190 },
191 }
192 }
193}
194
195impl TryFrom<TPMT_RSA_SCHEME> for RsaScheme {
196 type Error = Error;
197
198 fn try_from(tpmt_rsa_scheme: TPMT_RSA_SCHEME) -> Result<Self> {
199 match RsaSchemeAlgorithm::try_from(tpmt_rsa_scheme.scheme)? {
200 RsaSchemeAlgorithm::RsaSsa => Ok(RsaScheme::RsaSsa(
201 unsafe { tpmt_rsa_scheme.details.rsassa }.try_into()?,
202 )),
203 RsaSchemeAlgorithm::RsaEs => Ok(RsaScheme::RsaEs),
204 RsaSchemeAlgorithm::RsaPss => Ok(RsaScheme::RsaPss(
205 unsafe { tpmt_rsa_scheme.details.rsapss }.try_into()?,
206 )),
207 RsaSchemeAlgorithm::Oaep => Ok(RsaScheme::Oaep(
208 unsafe { tpmt_rsa_scheme.details.oaep }.try_into()?,
209 )),
210 RsaSchemeAlgorithm::Null => Ok(RsaScheme::Null),
211 }
212 }
213}
214
215#[derive(Clone, Copy, Debug, PartialEq, Eq)]
222pub enum EccScheme {
223 EcDsa(HashScheme),
224 EcDh(HashScheme),
225 EcDaa(EcDaaScheme),
226 Sm2(HashScheme),
227 EcSchnorr(HashScheme),
228 EcMqv(HashScheme),
229 Null,
230}
231
232impl EccScheme {
233 pub fn create(
249 ecc_scheme_algorithm: EccSchemeAlgorithm,
250 hashing_algorithm: Option<HashingAlgorithm>,
251 count: Option<u16>,
252 ) -> Result<Self> {
253 match ecc_scheme_algorithm {
254 EccSchemeAlgorithm::EcDsa => {
255 if count.is_some() {
256 error!(
257 "`count` should not be provided when creating ECC scheme of type EC DSA."
258 );
259 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
260 }
261
262 hashing_algorithm
263 .ok_or_else(|| {
264 error!(
265 "Hashing algorithm is required when creating ECC scheme of type EC DSA."
266 );
267 Error::local_error(WrapperErrorKind::ParamsMissing)
268 })
269 .map(|v| EccScheme::EcDsa(HashScheme::new(v)))
270 }
271 EccSchemeAlgorithm::EcDh => {
272 if count.is_some() {
273 error!(
274 "`count` should not be provided when creating ECC scheme of type EC DH."
275 );
276 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
277 }
278
279 hashing_algorithm
280 .ok_or_else(|| {
281 error!(
282 "Hashing algorithm is required when creating ECC scheme of type EC DH."
283 );
284 Error::local_error(WrapperErrorKind::ParamsMissing)
285 })
286 .map(|v| EccScheme::EcDh(HashScheme::new(v)))
287 }
288 EccSchemeAlgorithm::EcDaa => Ok(EccScheme::EcDaa(EcDaaScheme::new(
289 hashing_algorithm.ok_or_else(|| {
290 error!(
291 "Hashing algorithm is required when creating ECC scheme of type EC DAA."
292 );
293 Error::local_error(WrapperErrorKind::ParamsMissing)
294 })?,
295 count.ok_or_else(|| {
296 error!("Count is required when creating ECC scheme of type EC DAA.");
297 Error::local_error(WrapperErrorKind::ParamsMissing)
298 })?,
299 ))),
300 EccSchemeAlgorithm::Sm2 => {
301 if count.is_some() {
302 error!("`count` should not be provided when creating ECC scheme of type SM2.");
303 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
304 }
305
306 hashing_algorithm
307 .ok_or_else(|| {
308 error!(
309 "Hashing algorithm is required when creating ECC scheme of type SM2."
310 );
311 Error::local_error(WrapperErrorKind::ParamsMissing)
312 })
313 .map(|v| EccScheme::Sm2(HashScheme::new(v)))
314 }
315 EccSchemeAlgorithm::EcSchnorr => {
316 if count.is_some() {
317 error!("`count` should not be provided when creating ECC scheme of type EC SCHNORR.");
318 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
319 }
320
321 hashing_algorithm
322 .ok_or_else(|| {
323 error!(
324 "Hashing algorithm is required when creating ECC scheme of type EC SCHNORR."
325 );
326 Error::local_error(WrapperErrorKind::ParamsMissing)
327 })
328 .map(|v| EccScheme::EcSchnorr(HashScheme::new(v)))
329 }
330 EccSchemeAlgorithm::EcMqv => {
331 if count.is_some() {
332 error!(
333 "`count` should not be provided when creating ECC scheme of type EC MQV."
334 );
335 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
336 }
337
338 hashing_algorithm
339 .ok_or_else(|| {
340 error!(
341 "Hashing algorithm is required when creating ECC scheme of type EC MQV."
342 );
343 Error::local_error(WrapperErrorKind::ParamsMissing)
344 })
345 .map(|v| EccScheme::EcMqv(HashScheme::new(v)))
346 }
347 EccSchemeAlgorithm::Null => {
348 if count.is_some() {
349 error!("`count` should not be provided when creating ECC scheme of type Null.");
350 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
351 }
352 if hashing_algorithm.is_some() {
353 error!("A hashing algorithm shall not be provided when creating ECC scheme of type Null.");
354 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
355 }
356 Ok(EccScheme::Null)
357 }
358 }
359 }
360
361 pub fn algorithm(&self) -> EccSchemeAlgorithm {
362 match self {
363 EccScheme::EcDsa(_) => EccSchemeAlgorithm::EcDsa,
364 EccScheme::EcDh(_) => EccSchemeAlgorithm::EcDh,
365 EccScheme::EcDaa(_) => EccSchemeAlgorithm::EcDaa,
366 EccScheme::Sm2(_) => EccSchemeAlgorithm::Sm2,
367 EccScheme::EcSchnorr(_) => EccSchemeAlgorithm::EcSchnorr,
368 EccScheme::EcMqv(_) => EccSchemeAlgorithm::EcMqv,
369 EccScheme::Null => EccSchemeAlgorithm::Null,
370 }
371 }
372}
373
374impl From<EccScheme> for TPMT_ECC_SCHEME {
375 fn from(ecc_scheme: EccScheme) -> Self {
376 match ecc_scheme {
377 EccScheme::EcDsa(hash_scheme) => TPMT_ECC_SCHEME {
378 scheme: ecc_scheme.algorithm().into(),
379 details: TPMU_ASYM_SCHEME {
380 ecdsa: hash_scheme.into(),
381 },
382 },
383 EccScheme::EcDh(hash_scheme) => TPMT_ECC_SCHEME {
384 scheme: ecc_scheme.algorithm().into(),
385 details: TPMU_ASYM_SCHEME {
386 ecdh: hash_scheme.into(),
387 },
388 },
389 EccScheme::EcDaa(ec_daa_scheme) => TPMT_ECC_SCHEME {
390 scheme: ecc_scheme.algorithm().into(),
391 details: TPMU_ASYM_SCHEME {
392 ecdaa: ec_daa_scheme.into(),
393 },
394 },
395
396 EccScheme::Sm2(hash_scheme) => TPMT_ECC_SCHEME {
397 scheme: ecc_scheme.algorithm().into(),
398 details: TPMU_ASYM_SCHEME {
399 sm2: hash_scheme.into(),
400 },
401 },
402 EccScheme::EcSchnorr(hash_scheme) => TPMT_ECC_SCHEME {
403 scheme: ecc_scheme.algorithm().into(),
404 details: TPMU_ASYM_SCHEME {
405 ecschnorr: hash_scheme.into(),
406 },
407 },
408 EccScheme::EcMqv(hash_scheme) => TPMT_ECC_SCHEME {
409 scheme: ecc_scheme.algorithm().into(),
410 details: TPMU_ASYM_SCHEME {
411 ecmqv: hash_scheme.into(),
412 },
413 },
414 EccScheme::Null => TPMT_ECC_SCHEME {
415 scheme: ecc_scheme.algorithm().into(),
416 details: Default::default(),
417 },
418 }
419 }
420}
421
422impl TryFrom<TPMT_ECC_SCHEME> for EccScheme {
423 type Error = Error;
424
425 fn try_from(tpmt_ecc_scheme: TPMT_ECC_SCHEME) -> Result<Self> {
426 match EccSchemeAlgorithm::try_from(tpmt_ecc_scheme.scheme)? {
427 EccSchemeAlgorithm::EcDsa => Ok(EccScheme::EcDsa(
428 unsafe { tpmt_ecc_scheme.details.ecdsa }.try_into()?,
429 )),
430 EccSchemeAlgorithm::EcDh => Ok(EccScheme::EcDh(
431 unsafe { tpmt_ecc_scheme.details.ecdh }.try_into()?,
432 )),
433 EccSchemeAlgorithm::EcDaa => Ok(EccScheme::EcDaa(
434 unsafe { tpmt_ecc_scheme.details.ecdaa }.try_into()?,
435 )),
436 EccSchemeAlgorithm::Sm2 => Ok(EccScheme::Sm2(
437 unsafe { tpmt_ecc_scheme.details.sm2 }.try_into()?,
438 )),
439 EccSchemeAlgorithm::EcSchnorr => Ok(EccScheme::EcSchnorr(
440 unsafe { tpmt_ecc_scheme.details.ecschnorr }.try_into()?,
441 )),
442 EccSchemeAlgorithm::EcMqv => Ok(EccScheme::EcMqv(
443 unsafe { tpmt_ecc_scheme.details.ecmqv }.try_into()?,
444 )),
445 EccSchemeAlgorithm::Null => Ok(EccScheme::Null),
446 }
447 }
448}
449
450#[derive(Clone, Copy, Debug, PartialEq, Eq)]
455pub enum KeyDerivationFunctionScheme {
456 Kdf1Sp800_56a(HashScheme),
457 Kdf2(HashScheme),
458 Kdf1Sp800_108(HashScheme),
459 Mgf1(HashScheme),
460 Null,
461}
462
463impl From<KeyDerivationFunctionScheme> for TPMT_KDF_SCHEME {
464 fn from(key_derivation_function_scheme: KeyDerivationFunctionScheme) -> Self {
465 match key_derivation_function_scheme {
466 KeyDerivationFunctionScheme::Kdf1Sp800_56a(hash_scheme) => TPMT_KDF_SCHEME {
467 scheme: KeyDerivationFunction::Kdf1Sp800_56a.into(),
468 details: TPMU_KDF_SCHEME {
469 kdf1_sp800_56a: hash_scheme.into(),
470 },
471 },
472 KeyDerivationFunctionScheme::Kdf2(hash_scheme) => TPMT_KDF_SCHEME {
473 scheme: KeyDerivationFunction::Kdf2.into(),
474 details: TPMU_KDF_SCHEME {
475 kdf2: hash_scheme.into(),
476 },
477 },
478 KeyDerivationFunctionScheme::Kdf1Sp800_108(hash_scheme) => TPMT_KDF_SCHEME {
479 scheme: KeyDerivationFunction::Kdf1Sp800_108.into(),
480 details: TPMU_KDF_SCHEME {
481 kdf1_sp800_108: hash_scheme.into(),
482 },
483 },
484 KeyDerivationFunctionScheme::Mgf1(hash_scheme) => TPMT_KDF_SCHEME {
485 scheme: KeyDerivationFunction::Mgf1.into(),
486 details: TPMU_KDF_SCHEME {
487 mgf1: hash_scheme.into(),
488 },
489 },
490 KeyDerivationFunctionScheme::Null => TPMT_KDF_SCHEME {
491 scheme: KeyDerivationFunction::Null.into(),
492 details: Default::default(),
493 },
494 }
495 }
496}
497
498impl TryFrom<TPMT_KDF_SCHEME> for KeyDerivationFunctionScheme {
499 type Error = Error;
500
501 fn try_from(tpmt_kdf_scheme: TPMT_KDF_SCHEME) -> Result<Self> {
502 match KeyDerivationFunction::try_from(tpmt_kdf_scheme.scheme)? {
503 KeyDerivationFunction::Kdf1Sp800_56a => Ok(KeyDerivationFunctionScheme::Kdf1Sp800_56a(
504 unsafe { tpmt_kdf_scheme.details.kdf1_sp800_56a }.try_into()?,
505 )),
506 KeyDerivationFunction::Kdf2 => Ok(KeyDerivationFunctionScheme::Kdf2(
507 unsafe { tpmt_kdf_scheme.details.kdf2 }.try_into()?,
508 )),
509 KeyDerivationFunction::Kdf1Sp800_108 => Ok(KeyDerivationFunctionScheme::Kdf1Sp800_108(
510 unsafe { tpmt_kdf_scheme.details.kdf1_sp800_108 }.try_into()?,
511 )),
512 KeyDerivationFunction::Mgf1 => Ok(KeyDerivationFunctionScheme::Mgf1(
513 unsafe { tpmt_kdf_scheme.details.mgf1 }.try_into()?,
514 )),
515 KeyDerivationFunction::Null => Ok(KeyDerivationFunctionScheme::Null),
516 }
517 }
518}
519
520#[derive(Clone, Copy, Debug, PartialEq, Eq)]
525pub enum RsaDecryptionScheme {
526 RsaEs,
527 Oaep(HashScheme),
528 Null,
529}
530
531impl RsaDecryptionScheme {
532 pub fn create(
542 rsa_decrypt_algorithm: RsaDecryptAlgorithm,
543 hashing_algorithm: Option<HashingAlgorithm>,
544 ) -> Result<RsaDecryptionScheme> {
545 match rsa_decrypt_algorithm {
546 RsaDecryptAlgorithm::RsaEs => {
547 if hashing_algorithm.is_none() {
548 Ok(RsaDecryptionScheme::RsaEs)
549 } else {
550 error!("A hashing algorithm shall not be provided when creating RSA decryption scheme of type RSA ES");
551 Err(Error::local_error(WrapperErrorKind::InconsistentParams))
552 }
553 },
554 RsaDecryptAlgorithm::Oaep => Ok(RsaDecryptionScheme::Oaep(HashScheme::new(
555 hashing_algorithm.ok_or_else(|| {
556 error!("Hashing algorithm is required when creating RSA decrypt scheme of type OEAP");
557 Error::local_error(WrapperErrorKind::ParamsMissing)
558 })?,
559 ))),
560 RsaDecryptAlgorithm::Null => {
561 if hashing_algorithm.is_none() {
562 Ok(RsaDecryptionScheme::Null)
563 } else {
564 error!("A hashing algorithm shall not be provided when creating RSA decryption scheme of type Null");
565 Err(Error::local_error(WrapperErrorKind::InconsistentParams))
566 }
567 }
568 }
569 }
570
571 pub fn algorithm(&self) -> RsaDecryptAlgorithm {
573 match self {
574 RsaDecryptionScheme::RsaEs => RsaDecryptAlgorithm::RsaEs,
575 RsaDecryptionScheme::Oaep(_) => RsaDecryptAlgorithm::Oaep,
576 RsaDecryptionScheme::Null => RsaDecryptAlgorithm::Null,
577 }
578 }
579}
580
581impl From<RsaDecryptionScheme> for TPMT_RSA_DECRYPT {
582 fn from(rsa_decryption_scheme: RsaDecryptionScheme) -> Self {
583 match rsa_decryption_scheme {
584 RsaDecryptionScheme::RsaEs => TPMT_RSA_DECRYPT {
585 scheme: rsa_decryption_scheme.algorithm().into(),
586 details: TPMU_ASYM_SCHEME {
587 rsaes: Default::default(),
588 },
589 },
590 RsaDecryptionScheme::Oaep(hash_scheme) => TPMT_RSA_DECRYPT {
591 scheme: rsa_decryption_scheme.algorithm().into(),
592 details: TPMU_ASYM_SCHEME {
593 oaep: hash_scheme.into(),
594 },
595 },
596 RsaDecryptionScheme::Null => TPMT_RSA_DECRYPT {
597 scheme: rsa_decryption_scheme.algorithm().into(),
598 details: Default::default(),
599 },
600 }
601 }
602}
603
604impl TryFrom<TPMT_RSA_DECRYPT> for RsaDecryptionScheme {
605 type Error = Error;
606
607 fn try_from(tpmt_rsa_decrypt: TPMT_RSA_DECRYPT) -> Result<Self> {
608 match RsaDecryptAlgorithm::try_from(tpmt_rsa_decrypt.scheme)? {
609 RsaDecryptAlgorithm::RsaEs => Ok(RsaDecryptionScheme::RsaEs),
610 RsaDecryptAlgorithm::Oaep => Ok(RsaDecryptionScheme::Oaep(
611 unsafe { tpmt_rsa_decrypt.details.oaep }.try_into()?,
612 )),
613 RsaDecryptAlgorithm::Null => Ok(RsaDecryptionScheme::Null),
614 }
615 }
616}
617
618impl TryFrom<RsaScheme> for RsaDecryptionScheme {
619 type Error = Error;
620
621 fn try_from(rsa_scheme: RsaScheme) -> Result<Self> {
622 match rsa_scheme {
623 RsaScheme::RsaEs => Ok(RsaDecryptionScheme::RsaEs),
624 RsaScheme::Oaep(hash_scheme) => Ok(RsaDecryptionScheme::Oaep(hash_scheme)),
625 RsaScheme::Null => Ok(RsaDecryptionScheme::Null),
626 _ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
627 }
628 }
629}
630
631#[derive(Clone, Copy, Debug, Eq, PartialEq)]
636pub enum SignatureScheme {
637 RsaSsa { scheme: HashScheme },
638 RsaPss { scheme: HashScheme },
639 EcDsa { scheme: HashScheme },
640 Sm2 { scheme: HashScheme },
641 EcSchnorr { scheme: HashScheme },
642 EcDaa { scheme: EcDaaScheme },
643 Hmac { scheme: HmacScheme },
644 Null,
645}
646
647impl SignatureScheme {
648 pub fn signing_scheme(&self) -> Result<HashingAlgorithm> {
658 match self {
659 SignatureScheme::RsaSsa { scheme }
660 | SignatureScheme::RsaPss { scheme }
661 | SignatureScheme::EcDsa { scheme }
662 | SignatureScheme::Sm2 { scheme }
663 | SignatureScheme::EcSchnorr { scheme } => Ok(scheme.hashing_algorithm()),
664 SignatureScheme::EcDaa { scheme } => Ok(scheme.hashing_algorithm()),
665 SignatureScheme::Hmac { scheme } => Ok(scheme.hashing_algorithm()),
666 _ => {
667 error!("Cannot access digest for a non signing scheme");
668 Err(Error::local_error(WrapperErrorKind::InvalidParam))
669 }
670 }
671 }
672
673 pub fn set_signing_scheme(&mut self, hashing_algorithm: HashingAlgorithm) -> Result<()> {
683 match self {
684 SignatureScheme::RsaSsa { scheme }
685 | SignatureScheme::RsaPss { scheme }
686 | SignatureScheme::EcDsa { scheme }
687 | SignatureScheme::Sm2 { scheme }
688 | SignatureScheme::EcSchnorr { scheme } => {
689 *scheme = HashScheme::new(hashing_algorithm);
690 Ok(())
691 }
692 SignatureScheme::EcDaa { scheme } => {
693 *scheme = EcDaaScheme::new(hashing_algorithm, scheme.count());
694 Ok(())
695 }
696 SignatureScheme::Hmac { scheme } => {
697 *scheme = HmacScheme::new(hashing_algorithm);
698 Ok(())
699 }
700 _ => {
701 error!("Cannot access digest for a non signing scheme");
702 Err(Error::local_error(WrapperErrorKind::InvalidParam))
703 }
704 }
705 }
706}
707
708impl From<SignatureScheme> for TPMT_SIG_SCHEME {
709 fn from(native: SignatureScheme) -> TPMT_SIG_SCHEME {
710 match native {
711 SignatureScheme::EcDaa { scheme } => TPMT_SIG_SCHEME {
712 scheme: SignatureSchemeAlgorithm::EcDaa.into(),
713 details: TPMU_SIG_SCHEME {
714 ecdaa: scheme.into(),
715 },
716 },
717 SignatureScheme::EcDsa { scheme } => TPMT_SIG_SCHEME {
718 scheme: SignatureSchemeAlgorithm::EcDsa.into(),
719 details: TPMU_SIG_SCHEME {
720 ecdsa: scheme.into(),
721 },
722 },
723 SignatureScheme::EcSchnorr { scheme } => TPMT_SIG_SCHEME {
724 scheme: SignatureSchemeAlgorithm::EcSchnorr.into(),
725 details: TPMU_SIG_SCHEME {
726 ecschnorr: scheme.into(),
727 },
728 },
729 SignatureScheme::Hmac { scheme } => TPMT_SIG_SCHEME {
730 scheme: SignatureSchemeAlgorithm::Hmac.into(),
731 details: TPMU_SIG_SCHEME {
732 hmac: scheme.into(),
733 },
734 },
735 SignatureScheme::Null => TPMT_SIG_SCHEME {
736 scheme: SignatureSchemeAlgorithm::Null.into(),
737 details: Default::default(),
738 },
739 SignatureScheme::RsaPss { scheme } => TPMT_SIG_SCHEME {
740 scheme: SignatureSchemeAlgorithm::RsaPss.into(),
741 details: TPMU_SIG_SCHEME {
742 rsapss: scheme.into(),
743 },
744 },
745 SignatureScheme::RsaSsa { scheme } => TPMT_SIG_SCHEME {
746 scheme: SignatureSchemeAlgorithm::RsaSsa.into(),
747 details: TPMU_SIG_SCHEME {
748 rsassa: scheme.into(),
749 },
750 },
751 SignatureScheme::Sm2 { scheme } => TPMT_SIG_SCHEME {
752 scheme: SignatureSchemeAlgorithm::Sm2.into(),
753 details: TPMU_SIG_SCHEME { sm2: scheme.into() },
754 },
755 }
756 }
757}
758
759impl TryFrom<TPMT_SIG_SCHEME> for SignatureScheme {
760 type Error = Error;
761
762 fn try_from(tss: TPMT_SIG_SCHEME) -> Result<Self> {
763 match SignatureSchemeAlgorithm::try_from(tss.scheme)? {
764 SignatureSchemeAlgorithm::EcDaa => Ok(SignatureScheme::EcDaa {
765 scheme: unsafe { tss.details.ecdaa }.try_into()?,
766 }),
767 SignatureSchemeAlgorithm::EcDsa => Ok(SignatureScheme::EcDsa {
768 scheme: unsafe { tss.details.ecdsa }.try_into()?,
769 }),
770 SignatureSchemeAlgorithm::EcSchnorr => Ok(SignatureScheme::EcSchnorr {
771 scheme: unsafe { tss.details.ecschnorr }.try_into()?,
772 }),
773 SignatureSchemeAlgorithm::Hmac => Ok(SignatureScheme::Hmac {
774 scheme: unsafe { tss.details.hmac }.try_into()?,
775 }),
776 SignatureSchemeAlgorithm::Null => Ok(SignatureScheme::Null),
777 SignatureSchemeAlgorithm::RsaPss => Ok(SignatureScheme::RsaPss {
778 scheme: unsafe { tss.details.rsapss }.try_into()?,
779 }),
780 SignatureSchemeAlgorithm::RsaSsa => Ok(SignatureScheme::RsaSsa {
781 scheme: unsafe { tss.details.rsassa }.try_into()?,
782 }),
783 SignatureSchemeAlgorithm::Sm2 => Ok(SignatureScheme::Sm2 {
784 scheme: unsafe { tss.details.sm2 }.try_into()?,
785 }),
786 }
787 }
788}