parsec_interface/operations/
psa_verify_hash.rs1use super::psa_key_attributes::Attributes;
7use crate::operations::psa_algorithm::AsymmetricSignature;
8use crate::requests::ResponseStatus;
9
10#[derive(Debug)]
12pub struct Operation {
13 pub key_name: String,
15 pub alg: AsymmetricSignature,
18 pub hash: zeroize::Zeroizing<Vec<u8>>,
21 pub signature: zeroize::Zeroizing<Vec<u8>>,
23}
24
25#[derive(Copy, Clone, Debug)]
29pub struct Result;
30
31impl Operation {
32 pub fn validate(&self, key_attributes: Attributes) -> crate::requests::Result<()> {
40 key_attributes.can_verify_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_verify_hash();
60 Attributes {
61 lifetime: Lifetime::Persistent,
62 key_type: Type::EccKeyPair {
63 curve_family: EccFamily::SecpR1,
64 },
65 bits: 256,
66 policy: Policy {
67 usage_flags,
68 permitted_algorithms: Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa {
69 hash_alg: Hash::Sha256.into(),
70 }),
71 },
72 }
73 }
74
75 #[test]
76 fn validate_success() {
77 (Operation {
78 key_name: String::from("some key"),
79 alg: AsymmetricSignature::Ecdsa {
80 hash_alg: Hash::Sha256.into(),
81 },
82 hash: vec![0xff; 32].into(),
83 signature: vec![0xa5; 65].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 signature: vec![0xa5; 65].into(),
101 })
102 .validate(attrs)
103 .unwrap_err(),
104 ResponseStatus::PsaErrorNotPermitted
105 );
106 }
107
108 #[test]
109 fn wrong_algorithm() {
110 assert_eq!(
111 (Operation {
112 key_name: String::from("some key"),
113 alg: AsymmetricSignature::Ecdsa {
114 hash_alg: Hash::Sha224.into(),
115 },
116 hash: vec![0xff; 28].into(),
117 signature: vec![0xa5; 65].into(),
118 })
119 .validate(get_attrs())
120 .unwrap_err(),
121 ResponseStatus::PsaErrorNotPermitted
122 );
123 }
124
125 #[test]
126 fn wrong_scheme() {
127 assert_eq!(
128 (Operation {
129 key_name: String::from("some key"),
130 alg: AsymmetricSignature::RsaPss {
131 hash_alg: Hash::Sha224.into(),
132 },
133 hash: vec![0xff; 28].into(),
134 signature: vec![0xa5; 65].into(),
135 })
136 .validate(get_attrs())
137 .unwrap_err(),
138 ResponseStatus::PsaErrorNotPermitted
139 );
140 }
141
142 #[test]
143 fn invalid_hash() {
144 assert_eq!(
145 (Operation {
146 key_name: String::from("some key"),
147 alg: AsymmetricSignature::Ecdsa {
148 hash_alg: Hash::Sha256.into(),
149 },
150 hash: vec![0xff; 16].into(),
151 signature: vec![0xa5; 65].into(),
152 })
153 .validate(get_attrs())
154 .unwrap_err(),
155 ResponseStatus::PsaErrorInvalidArgument
156 );
157 }
158}