1use crate::{
4 Error, Result, WrapperErrorKind,
5 interface_types::algorithm::{
6 EccSchemeAlgorithm, HashingAlgorithm, KeyDerivationFunction, KeyedHashSchemeAlgorithm,
7 RsaDecryptAlgorithm, RsaSchemeAlgorithm, SignatureSchemeAlgorithm,
8 },
9 structures::schemes::{EcDaaScheme, HashScheme, HmacScheme, XorScheme},
10 tss2_esys::{
11 TPMT_ECC_SCHEME, TPMT_KDF_SCHEME, TPMT_KEYEDHASH_SCHEME, TPMT_RSA_DECRYPT, TPMT_RSA_SCHEME,
12 TPMT_SIG_SCHEME, TPMU_ASYM_SCHEME, TPMU_KDF_SCHEME, TPMU_SCHEME_KEYEDHASH, TPMU_SIG_SCHEME,
13 },
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!(
120 "A hashing algorithm shall not be provided when creating RSA scheme of type RSA ES"
121 );
122 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
123 }
124 Ok(RsaScheme::RsaEs)
125 }
126 RsaSchemeAlgorithm::RsaPss => Ok(RsaScheme::RsaPss(HashScheme::new(
127 hashing_algorithm.ok_or_else(|| {
128 error!(
129 "Hashing algorithm is required when creating RSA scheme of type RSA PSS"
130 );
131 Error::local_error(WrapperErrorKind::ParamsMissing)
132 })?,
133 ))),
134 RsaSchemeAlgorithm::Oaep => Ok(RsaScheme::Oaep(HashScheme::new(
135 hashing_algorithm.ok_or_else(|| {
136 error!("Hashing algorithm is required when creating RSA scheme of type OAEP");
137 Error::local_error(WrapperErrorKind::ParamsMissing)
138 })?,
139 ))),
140 RsaSchemeAlgorithm::Null => {
141 if hashing_algorithm.is_some() {
142 error!(
143 "A hashing algorithm shall not be provided when creating RSA scheme of type Null"
144 );
145 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
146 }
147 Ok(RsaScheme::Null)
148 }
149 }
150 }
151
152 pub fn algorithm(&self) -> RsaSchemeAlgorithm {
154 match self {
155 RsaScheme::RsaSsa(_) => RsaSchemeAlgorithm::RsaSsa,
156 RsaScheme::RsaEs => RsaSchemeAlgorithm::RsaEs,
157 RsaScheme::RsaPss(_) => RsaSchemeAlgorithm::RsaPss,
158 RsaScheme::Oaep(_) => RsaSchemeAlgorithm::Oaep,
159 RsaScheme::Null => RsaSchemeAlgorithm::Null,
160 }
161 }
162}
163
164impl From<RsaScheme> for TPMT_RSA_SCHEME {
165 fn from(rsa_scheme: RsaScheme) -> Self {
166 match rsa_scheme {
167 RsaScheme::RsaSsa(hash_scheme) => TPMT_RSA_SCHEME {
168 scheme: rsa_scheme.algorithm().into(),
169 details: TPMU_ASYM_SCHEME {
170 rsassa: hash_scheme.into(),
171 },
172 },
173 RsaScheme::RsaEs => TPMT_RSA_SCHEME {
174 scheme: rsa_scheme.algorithm().into(),
175 details: TPMU_ASYM_SCHEME {
176 rsaes: Default::default(),
177 },
178 },
179 RsaScheme::RsaPss(hash_scheme) => TPMT_RSA_SCHEME {
180 scheme: rsa_scheme.algorithm().into(),
181 details: TPMU_ASYM_SCHEME {
182 rsapss: hash_scheme.into(),
183 },
184 },
185 RsaScheme::Oaep(hash_scheme) => TPMT_RSA_SCHEME {
186 scheme: rsa_scheme.algorithm().into(),
187 details: TPMU_ASYM_SCHEME {
188 oaep: hash_scheme.into(),
189 },
190 },
191 RsaScheme::Null => TPMT_RSA_SCHEME {
192 scheme: rsa_scheme.algorithm().into(),
193 details: Default::default(),
194 },
195 }
196 }
197}
198
199impl TryFrom<TPMT_RSA_SCHEME> for RsaScheme {
200 type Error = Error;
201
202 fn try_from(tpmt_rsa_scheme: TPMT_RSA_SCHEME) -> Result<Self> {
203 match RsaSchemeAlgorithm::try_from(tpmt_rsa_scheme.scheme)? {
204 RsaSchemeAlgorithm::RsaSsa => Ok(RsaScheme::RsaSsa(
205 unsafe { tpmt_rsa_scheme.details.rsassa }.try_into()?,
206 )),
207 RsaSchemeAlgorithm::RsaEs => Ok(RsaScheme::RsaEs),
208 RsaSchemeAlgorithm::RsaPss => Ok(RsaScheme::RsaPss(
209 unsafe { tpmt_rsa_scheme.details.rsapss }.try_into()?,
210 )),
211 RsaSchemeAlgorithm::Oaep => Ok(RsaScheme::Oaep(
212 unsafe { tpmt_rsa_scheme.details.oaep }.try_into()?,
213 )),
214 RsaSchemeAlgorithm::Null => Ok(RsaScheme::Null),
215 }
216 }
217}
218
219#[derive(Clone, Copy, Debug, PartialEq, Eq)]
226pub enum EccScheme {
227 EcDsa(HashScheme),
228 EcDh(HashScheme),
229 EcDaa(EcDaaScheme),
230 Sm2(HashScheme),
231 EcSchnorr(HashScheme),
232 EcMqv(HashScheme),
233 Null,
234}
235
236impl EccScheme {
237 pub fn create(
253 ecc_scheme_algorithm: EccSchemeAlgorithm,
254 hashing_algorithm: Option<HashingAlgorithm>,
255 count: Option<u16>,
256 ) -> Result<Self> {
257 match ecc_scheme_algorithm {
258 EccSchemeAlgorithm::EcDsa => {
259 if count.is_some() {
260 error!(
261 "`count` should not be provided when creating ECC scheme of type EC DSA."
262 );
263 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
264 }
265
266 hashing_algorithm
267 .ok_or_else(|| {
268 error!(
269 "Hashing algorithm is required when creating ECC scheme of type EC DSA."
270 );
271 Error::local_error(WrapperErrorKind::ParamsMissing)
272 })
273 .map(|v| EccScheme::EcDsa(HashScheme::new(v)))
274 }
275 EccSchemeAlgorithm::EcDh => {
276 if count.is_some() {
277 error!(
278 "`count` should not be provided when creating ECC scheme of type EC DH."
279 );
280 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
281 }
282
283 hashing_algorithm
284 .ok_or_else(|| {
285 error!(
286 "Hashing algorithm is required when creating ECC scheme of type EC DH."
287 );
288 Error::local_error(WrapperErrorKind::ParamsMissing)
289 })
290 .map(|v| EccScheme::EcDh(HashScheme::new(v)))
291 }
292 EccSchemeAlgorithm::EcDaa => Ok(EccScheme::EcDaa(EcDaaScheme::new(
293 hashing_algorithm.ok_or_else(|| {
294 error!(
295 "Hashing algorithm is required when creating ECC scheme of type EC DAA."
296 );
297 Error::local_error(WrapperErrorKind::ParamsMissing)
298 })?,
299 count.ok_or_else(|| {
300 error!("Count is required when creating ECC scheme of type EC DAA.");
301 Error::local_error(WrapperErrorKind::ParamsMissing)
302 })?,
303 ))),
304 EccSchemeAlgorithm::Sm2 => {
305 if count.is_some() {
306 error!("`count` should not be provided when creating ECC scheme of type SM2.");
307 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
308 }
309
310 hashing_algorithm
311 .ok_or_else(|| {
312 error!(
313 "Hashing algorithm is required when creating ECC scheme of type SM2."
314 );
315 Error::local_error(WrapperErrorKind::ParamsMissing)
316 })
317 .map(|v| EccScheme::Sm2(HashScheme::new(v)))
318 }
319 EccSchemeAlgorithm::EcSchnorr => {
320 if count.is_some() {
321 error!(
322 "`count` should not be provided when creating ECC scheme of type EC SCHNORR."
323 );
324 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
325 }
326
327 hashing_algorithm
328 .ok_or_else(|| {
329 error!(
330 "Hashing algorithm is required when creating ECC scheme of type EC SCHNORR."
331 );
332 Error::local_error(WrapperErrorKind::ParamsMissing)
333 })
334 .map(|v| EccScheme::EcSchnorr(HashScheme::new(v)))
335 }
336 EccSchemeAlgorithm::EcMqv => {
337 if count.is_some() {
338 error!(
339 "`count` should not be provided when creating ECC scheme of type EC MQV."
340 );
341 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
342 }
343
344 hashing_algorithm
345 .ok_or_else(|| {
346 error!(
347 "Hashing algorithm is required when creating ECC scheme of type EC MQV."
348 );
349 Error::local_error(WrapperErrorKind::ParamsMissing)
350 })
351 .map(|v| EccScheme::EcMqv(HashScheme::new(v)))
352 }
353 EccSchemeAlgorithm::Null => {
354 if count.is_some() {
355 error!("`count` should not be provided when creating ECC scheme of type Null.");
356 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
357 }
358 if hashing_algorithm.is_some() {
359 error!(
360 "A hashing algorithm shall not be provided when creating ECC scheme of type Null."
361 );
362 return Err(Error::local_error(WrapperErrorKind::InconsistentParams));
363 }
364 Ok(EccScheme::Null)
365 }
366 }
367 }
368
369 pub fn algorithm(&self) -> EccSchemeAlgorithm {
370 match self {
371 EccScheme::EcDsa(_) => EccSchemeAlgorithm::EcDsa,
372 EccScheme::EcDh(_) => EccSchemeAlgorithm::EcDh,
373 EccScheme::EcDaa(_) => EccSchemeAlgorithm::EcDaa,
374 EccScheme::Sm2(_) => EccSchemeAlgorithm::Sm2,
375 EccScheme::EcSchnorr(_) => EccSchemeAlgorithm::EcSchnorr,
376 EccScheme::EcMqv(_) => EccSchemeAlgorithm::EcMqv,
377 EccScheme::Null => EccSchemeAlgorithm::Null,
378 }
379 }
380}
381
382impl From<EccScheme> for TPMT_ECC_SCHEME {
383 fn from(ecc_scheme: EccScheme) -> Self {
384 match ecc_scheme {
385 EccScheme::EcDsa(hash_scheme) => TPMT_ECC_SCHEME {
386 scheme: ecc_scheme.algorithm().into(),
387 details: TPMU_ASYM_SCHEME {
388 ecdsa: hash_scheme.into(),
389 },
390 },
391 EccScheme::EcDh(hash_scheme) => TPMT_ECC_SCHEME {
392 scheme: ecc_scheme.algorithm().into(),
393 details: TPMU_ASYM_SCHEME {
394 ecdh: hash_scheme.into(),
395 },
396 },
397 EccScheme::EcDaa(ec_daa_scheme) => TPMT_ECC_SCHEME {
398 scheme: ecc_scheme.algorithm().into(),
399 details: TPMU_ASYM_SCHEME {
400 ecdaa: ec_daa_scheme.into(),
401 },
402 },
403
404 EccScheme::Sm2(hash_scheme) => TPMT_ECC_SCHEME {
405 scheme: ecc_scheme.algorithm().into(),
406 details: TPMU_ASYM_SCHEME {
407 sm2: hash_scheme.into(),
408 },
409 },
410 EccScheme::EcSchnorr(hash_scheme) => TPMT_ECC_SCHEME {
411 scheme: ecc_scheme.algorithm().into(),
412 details: TPMU_ASYM_SCHEME {
413 ecschnorr: hash_scheme.into(),
414 },
415 },
416 EccScheme::EcMqv(hash_scheme) => TPMT_ECC_SCHEME {
417 scheme: ecc_scheme.algorithm().into(),
418 details: TPMU_ASYM_SCHEME {
419 ecmqv: hash_scheme.into(),
420 },
421 },
422 EccScheme::Null => TPMT_ECC_SCHEME {
423 scheme: ecc_scheme.algorithm().into(),
424 details: Default::default(),
425 },
426 }
427 }
428}
429
430impl TryFrom<TPMT_ECC_SCHEME> for EccScheme {
431 type Error = Error;
432
433 fn try_from(tpmt_ecc_scheme: TPMT_ECC_SCHEME) -> Result<Self> {
434 match EccSchemeAlgorithm::try_from(tpmt_ecc_scheme.scheme)? {
435 EccSchemeAlgorithm::EcDsa => Ok(EccScheme::EcDsa(
436 unsafe { tpmt_ecc_scheme.details.ecdsa }.try_into()?,
437 )),
438 EccSchemeAlgorithm::EcDh => Ok(EccScheme::EcDh(
439 unsafe { tpmt_ecc_scheme.details.ecdh }.try_into()?,
440 )),
441 EccSchemeAlgorithm::EcDaa => Ok(EccScheme::EcDaa(
442 unsafe { tpmt_ecc_scheme.details.ecdaa }.try_into()?,
443 )),
444 EccSchemeAlgorithm::Sm2 => Ok(EccScheme::Sm2(
445 unsafe { tpmt_ecc_scheme.details.sm2 }.try_into()?,
446 )),
447 EccSchemeAlgorithm::EcSchnorr => Ok(EccScheme::EcSchnorr(
448 unsafe { tpmt_ecc_scheme.details.ecschnorr }.try_into()?,
449 )),
450 EccSchemeAlgorithm::EcMqv => Ok(EccScheme::EcMqv(
451 unsafe { tpmt_ecc_scheme.details.ecmqv }.try_into()?,
452 )),
453 EccSchemeAlgorithm::Null => Ok(EccScheme::Null),
454 }
455 }
456}
457
458#[derive(Clone, Copy, Debug, PartialEq, Eq)]
463pub enum KeyDerivationFunctionScheme {
464 Kdf1Sp800_56a(HashScheme),
465 Kdf2(HashScheme),
466 Kdf1Sp800_108(HashScheme),
467 Mgf1(HashScheme),
468 Null,
469}
470
471impl From<KeyDerivationFunctionScheme> for TPMT_KDF_SCHEME {
472 fn from(key_derivation_function_scheme: KeyDerivationFunctionScheme) -> Self {
473 match key_derivation_function_scheme {
474 KeyDerivationFunctionScheme::Kdf1Sp800_56a(hash_scheme) => TPMT_KDF_SCHEME {
475 scheme: KeyDerivationFunction::Kdf1Sp800_56a.into(),
476 details: TPMU_KDF_SCHEME {
477 kdf1_sp800_56a: hash_scheme.into(),
478 },
479 },
480 KeyDerivationFunctionScheme::Kdf2(hash_scheme) => TPMT_KDF_SCHEME {
481 scheme: KeyDerivationFunction::Kdf2.into(),
482 details: TPMU_KDF_SCHEME {
483 kdf2: hash_scheme.into(),
484 },
485 },
486 KeyDerivationFunctionScheme::Kdf1Sp800_108(hash_scheme) => TPMT_KDF_SCHEME {
487 scheme: KeyDerivationFunction::Kdf1Sp800_108.into(),
488 details: TPMU_KDF_SCHEME {
489 kdf1_sp800_108: hash_scheme.into(),
490 },
491 },
492 KeyDerivationFunctionScheme::Mgf1(hash_scheme) => TPMT_KDF_SCHEME {
493 scheme: KeyDerivationFunction::Mgf1.into(),
494 details: TPMU_KDF_SCHEME {
495 mgf1: hash_scheme.into(),
496 },
497 },
498 KeyDerivationFunctionScheme::Null => TPMT_KDF_SCHEME {
499 scheme: KeyDerivationFunction::Null.into(),
500 details: Default::default(),
501 },
502 }
503 }
504}
505
506impl TryFrom<TPMT_KDF_SCHEME> for KeyDerivationFunctionScheme {
507 type Error = Error;
508
509 fn try_from(tpmt_kdf_scheme: TPMT_KDF_SCHEME) -> Result<Self> {
510 match KeyDerivationFunction::try_from(tpmt_kdf_scheme.scheme)? {
511 KeyDerivationFunction::Kdf1Sp800_56a => Ok(KeyDerivationFunctionScheme::Kdf1Sp800_56a(
512 unsafe { tpmt_kdf_scheme.details.kdf1_sp800_56a }.try_into()?,
513 )),
514 KeyDerivationFunction::Kdf2 => Ok(KeyDerivationFunctionScheme::Kdf2(
515 unsafe { tpmt_kdf_scheme.details.kdf2 }.try_into()?,
516 )),
517 KeyDerivationFunction::Kdf1Sp800_108 => Ok(KeyDerivationFunctionScheme::Kdf1Sp800_108(
518 unsafe { tpmt_kdf_scheme.details.kdf1_sp800_108 }.try_into()?,
519 )),
520 KeyDerivationFunction::Mgf1 => Ok(KeyDerivationFunctionScheme::Mgf1(
521 unsafe { tpmt_kdf_scheme.details.mgf1 }.try_into()?,
522 )),
523 KeyDerivationFunction::Null => Ok(KeyDerivationFunctionScheme::Null),
524 }
525 }
526}
527
528#[derive(Clone, Copy, Debug, PartialEq, Eq)]
533pub enum RsaDecryptionScheme {
534 RsaEs,
535 Oaep(HashScheme),
536 Null,
537}
538
539impl RsaDecryptionScheme {
540 pub fn create(
550 rsa_decrypt_algorithm: RsaDecryptAlgorithm,
551 hashing_algorithm: Option<HashingAlgorithm>,
552 ) -> Result<RsaDecryptionScheme> {
553 match rsa_decrypt_algorithm {
554 RsaDecryptAlgorithm::RsaEs => {
555 if hashing_algorithm.is_none() {
556 Ok(RsaDecryptionScheme::RsaEs)
557 } else {
558 error!("A hashing algorithm shall not be provided when creating RSA decryption scheme of type RSA ES");
559 Err(Error::local_error(WrapperErrorKind::InconsistentParams))
560 }
561 },
562 RsaDecryptAlgorithm::Oaep => Ok(RsaDecryptionScheme::Oaep(HashScheme::new(
563 hashing_algorithm.ok_or_else(|| {
564 error!("Hashing algorithm is required when creating RSA decrypt scheme of type OEAP");
565 Error::local_error(WrapperErrorKind::ParamsMissing)
566 })?,
567 ))),
568 RsaDecryptAlgorithm::Null => {
569 if hashing_algorithm.is_none() {
570 Ok(RsaDecryptionScheme::Null)
571 } else {
572 error!("A hashing algorithm shall not be provided when creating RSA decryption scheme of type Null");
573 Err(Error::local_error(WrapperErrorKind::InconsistentParams))
574 }
575 }
576 }
577 }
578
579 pub fn algorithm(&self) -> RsaDecryptAlgorithm {
581 match self {
582 RsaDecryptionScheme::RsaEs => RsaDecryptAlgorithm::RsaEs,
583 RsaDecryptionScheme::Oaep(_) => RsaDecryptAlgorithm::Oaep,
584 RsaDecryptionScheme::Null => RsaDecryptAlgorithm::Null,
585 }
586 }
587}
588
589impl From<RsaDecryptionScheme> for TPMT_RSA_DECRYPT {
590 fn from(rsa_decryption_scheme: RsaDecryptionScheme) -> Self {
591 match rsa_decryption_scheme {
592 RsaDecryptionScheme::RsaEs => TPMT_RSA_DECRYPT {
593 scheme: rsa_decryption_scheme.algorithm().into(),
594 details: TPMU_ASYM_SCHEME {
595 rsaes: Default::default(),
596 },
597 },
598 RsaDecryptionScheme::Oaep(hash_scheme) => TPMT_RSA_DECRYPT {
599 scheme: rsa_decryption_scheme.algorithm().into(),
600 details: TPMU_ASYM_SCHEME {
601 oaep: hash_scheme.into(),
602 },
603 },
604 RsaDecryptionScheme::Null => TPMT_RSA_DECRYPT {
605 scheme: rsa_decryption_scheme.algorithm().into(),
606 details: Default::default(),
607 },
608 }
609 }
610}
611
612impl TryFrom<TPMT_RSA_DECRYPT> for RsaDecryptionScheme {
613 type Error = Error;
614
615 fn try_from(tpmt_rsa_decrypt: TPMT_RSA_DECRYPT) -> Result<Self> {
616 match RsaDecryptAlgorithm::try_from(tpmt_rsa_decrypt.scheme)? {
617 RsaDecryptAlgorithm::RsaEs => Ok(RsaDecryptionScheme::RsaEs),
618 RsaDecryptAlgorithm::Oaep => Ok(RsaDecryptionScheme::Oaep(
619 unsafe { tpmt_rsa_decrypt.details.oaep }.try_into()?,
620 )),
621 RsaDecryptAlgorithm::Null => Ok(RsaDecryptionScheme::Null),
622 }
623 }
624}
625
626impl TryFrom<RsaScheme> for RsaDecryptionScheme {
627 type Error = Error;
628
629 fn try_from(rsa_scheme: RsaScheme) -> Result<Self> {
630 match rsa_scheme {
631 RsaScheme::RsaEs => Ok(RsaDecryptionScheme::RsaEs),
632 RsaScheme::Oaep(hash_scheme) => Ok(RsaDecryptionScheme::Oaep(hash_scheme)),
633 RsaScheme::Null => Ok(RsaDecryptionScheme::Null),
634 _ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
635 }
636 }
637}
638
639#[derive(Clone, Copy, Debug, Eq, PartialEq)]
644pub enum SignatureScheme {
645 RsaSsa { scheme: HashScheme },
646 RsaPss { scheme: HashScheme },
647 EcDsa { scheme: HashScheme },
648 Sm2 { scheme: HashScheme },
649 EcSchnorr { scheme: HashScheme },
650 EcDaa { scheme: EcDaaScheme },
651 Hmac { scheme: HmacScheme },
652 Null,
653}
654
655impl SignatureScheme {
656 pub fn signing_scheme(&self) -> Result<HashingAlgorithm> {
666 match self {
667 SignatureScheme::RsaSsa { scheme }
668 | SignatureScheme::RsaPss { scheme }
669 | SignatureScheme::EcDsa { scheme }
670 | SignatureScheme::Sm2 { scheme }
671 | SignatureScheme::EcSchnorr { scheme } => Ok(scheme.hashing_algorithm()),
672 SignatureScheme::EcDaa { scheme } => Ok(scheme.hashing_algorithm()),
673 SignatureScheme::Hmac { scheme } => Ok(scheme.hashing_algorithm()),
674 _ => {
675 error!("Cannot access digest for a non signing scheme");
676 Err(Error::local_error(WrapperErrorKind::InvalidParam))
677 }
678 }
679 }
680
681 pub fn set_signing_scheme(&mut self, hashing_algorithm: HashingAlgorithm) -> Result<()> {
691 match self {
692 SignatureScheme::RsaSsa { scheme }
693 | SignatureScheme::RsaPss { scheme }
694 | SignatureScheme::EcDsa { scheme }
695 | SignatureScheme::Sm2 { scheme }
696 | SignatureScheme::EcSchnorr { scheme } => {
697 *scheme = HashScheme::new(hashing_algorithm);
698 Ok(())
699 }
700 SignatureScheme::EcDaa { scheme } => {
701 *scheme = EcDaaScheme::new(hashing_algorithm, scheme.count());
702 Ok(())
703 }
704 SignatureScheme::Hmac { scheme } => {
705 *scheme = HmacScheme::new(hashing_algorithm);
706 Ok(())
707 }
708 _ => {
709 error!("Cannot access digest for a non signing scheme");
710 Err(Error::local_error(WrapperErrorKind::InvalidParam))
711 }
712 }
713 }
714}
715
716impl From<SignatureScheme> for TPMT_SIG_SCHEME {
717 fn from(native: SignatureScheme) -> TPMT_SIG_SCHEME {
718 match native {
719 SignatureScheme::EcDaa { scheme } => TPMT_SIG_SCHEME {
720 scheme: SignatureSchemeAlgorithm::EcDaa.into(),
721 details: TPMU_SIG_SCHEME {
722 ecdaa: scheme.into(),
723 },
724 },
725 SignatureScheme::EcDsa { scheme } => TPMT_SIG_SCHEME {
726 scheme: SignatureSchemeAlgorithm::EcDsa.into(),
727 details: TPMU_SIG_SCHEME {
728 ecdsa: scheme.into(),
729 },
730 },
731 SignatureScheme::EcSchnorr { scheme } => TPMT_SIG_SCHEME {
732 scheme: SignatureSchemeAlgorithm::EcSchnorr.into(),
733 details: TPMU_SIG_SCHEME {
734 ecschnorr: scheme.into(),
735 },
736 },
737 SignatureScheme::Hmac { scheme } => TPMT_SIG_SCHEME {
738 scheme: SignatureSchemeAlgorithm::Hmac.into(),
739 details: TPMU_SIG_SCHEME {
740 hmac: scheme.into(),
741 },
742 },
743 SignatureScheme::Null => TPMT_SIG_SCHEME {
744 scheme: SignatureSchemeAlgorithm::Null.into(),
745 details: Default::default(),
746 },
747 SignatureScheme::RsaPss { scheme } => TPMT_SIG_SCHEME {
748 scheme: SignatureSchemeAlgorithm::RsaPss.into(),
749 details: TPMU_SIG_SCHEME {
750 rsapss: scheme.into(),
751 },
752 },
753 SignatureScheme::RsaSsa { scheme } => TPMT_SIG_SCHEME {
754 scheme: SignatureSchemeAlgorithm::RsaSsa.into(),
755 details: TPMU_SIG_SCHEME {
756 rsassa: scheme.into(),
757 },
758 },
759 SignatureScheme::Sm2 { scheme } => TPMT_SIG_SCHEME {
760 scheme: SignatureSchemeAlgorithm::Sm2.into(),
761 details: TPMU_SIG_SCHEME { sm2: scheme.into() },
762 },
763 }
764 }
765}
766
767impl TryFrom<TPMT_SIG_SCHEME> for SignatureScheme {
768 type Error = Error;
769
770 fn try_from(tss: TPMT_SIG_SCHEME) -> Result<Self> {
771 match SignatureSchemeAlgorithm::try_from(tss.scheme)? {
772 SignatureSchemeAlgorithm::EcDaa => Ok(SignatureScheme::EcDaa {
773 scheme: unsafe { tss.details.ecdaa }.try_into()?,
774 }),
775 SignatureSchemeAlgorithm::EcDsa => Ok(SignatureScheme::EcDsa {
776 scheme: unsafe { tss.details.ecdsa }.try_into()?,
777 }),
778 SignatureSchemeAlgorithm::EcSchnorr => Ok(SignatureScheme::EcSchnorr {
779 scheme: unsafe { tss.details.ecschnorr }.try_into()?,
780 }),
781 SignatureSchemeAlgorithm::Hmac => Ok(SignatureScheme::Hmac {
782 scheme: unsafe { tss.details.hmac }.try_into()?,
783 }),
784 SignatureSchemeAlgorithm::Null => Ok(SignatureScheme::Null),
785 SignatureSchemeAlgorithm::RsaPss => Ok(SignatureScheme::RsaPss {
786 scheme: unsafe { tss.details.rsapss }.try_into()?,
787 }),
788 SignatureSchemeAlgorithm::RsaSsa => Ok(SignatureScheme::RsaSsa {
789 scheme: unsafe { tss.details.rsassa }.try_into()?,
790 }),
791 SignatureSchemeAlgorithm::Sm2 => Ok(SignatureScheme::Sm2 {
792 scheme: unsafe { tss.details.sm2 }.try_into()?,
793 }),
794 }
795 }
796}