parsec_interface/operations/
psa_sign_hash.rs1use super::psa_key_attributes::Attributes;
8use crate::operations::psa_algorithm::AsymmetricSignature;
9use crate::requests::ResponseStatus;
10
11#[derive(Debug)]
13pub struct Operation {
14 pub key_name: String,
16 pub alg: AsymmetricSignature,
19 pub hash: zeroize::Zeroizing<Vec<u8>>,
21}
22
23#[derive(Debug)]
25pub struct Result {
26 pub signature: zeroize::Zeroizing<Vec<u8>>,
29}
30
31impl Operation {
32 pub fn validate(&self, key_attributes: Attributes) -> crate::requests::Result<()> {
40 key_attributes.can_sign_hash()?;
41 key_attributes.permits_alg(self.alg.into())?;
42 key_attributes.compatible_with_alg(self.alg.into())?;
43 if !self.alg.is_hash_len_permitted(self.hash.len()) {
44 return Err(ResponseStatus::PsaErrorInvalidArgument);
45 }
46
47 Ok(())
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
55 use crate::operations::psa_key_attributes::{EccFamily, Lifetime, Policy, Type, UsageFlags};
56
57 fn get_attrs() -> Attributes {
58 let mut usage_flags = UsageFlags::default();
59 let _ = usage_flags.set_sign_hash();
60
61 Attributes {
62 lifetime: Lifetime::Persistent,
63 key_type: Type::EccKeyPair {
64 curve_family: EccFamily::SecpR1,
65 },
66 bits: 256,
67 policy: Policy {
68 usage_flags,
69 permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa {
70 hash_alg: Hash::Sha256.into(),
71 }),
72 },
73 }
74 }
75
76 #[test]
77 fn validate_success() {
78 (Operation {
79 key_name: String::from("some key"),
80 alg: AsymmetricSignature::Ecdsa {
81 hash_alg: Hash::Sha256.into(),
82 },
83 hash: vec![0xff; 32].into(),
84 })
85 .validate(get_attrs())
86 .unwrap();
87 }
88
89 #[test]
90 fn cannot_sign() {
91 let mut attrs = get_attrs();
92 attrs.policy.usage_flags = UsageFlags::default();
93 assert_eq!(
94 (Operation {
95 key_name: String::from("some key"),
96 alg: AsymmetricSignature::Ecdsa {
97 hash_alg: Hash::Sha256.into(),
98 },
99 hash: vec![0xff; 32].into(),
100 })
101 .validate(attrs)
102 .unwrap_err(),
103 ResponseStatus::PsaErrorNotPermitted
104 );
105 }
106
107 #[test]
108 fn wrong_algorithm() {
109 assert_eq!(
110 (Operation {
111 key_name: String::from("some key"),
112 alg: AsymmetricSignature::Ecdsa {
113 hash_alg: Hash::Sha224.into(),
114 },
115 hash: vec![0xff; 28].into(),
116 })
117 .validate(get_attrs())
118 .unwrap_err(),
119 ResponseStatus::PsaErrorNotPermitted
120 );
121 }
122
123 #[test]
124 fn wrong_scheme() {
125 assert_eq!(
126 (Operation {
127 key_name: String::from("some key"),
128 alg: AsymmetricSignature::RsaPss {
129 hash_alg: Hash::Sha224.into(),
130 },
131 hash: vec![0xff; 28].into(),
132 })
133 .validate(get_attrs())
134 .unwrap_err(),
135 ResponseStatus::PsaErrorNotPermitted
136 );
137 }
138
139 #[test]
140 fn invalid_hash() {
141 assert_eq!(
142 (Operation {
143 key_name: String::from("some key"),
144 alg: AsymmetricSignature::Ecdsa {
145 hash_alg: Hash::Sha256.into(),
146 },
147 hash: vec![0xff; 16].into(),
148 })
149 .validate(get_attrs())
150 .unwrap_err(),
151 ResponseStatus::PsaErrorInvalidArgument
152 );
153 }
154}