parsec_interface/operations/
psa_cipher_decrypt.rs1use super::psa_key_attributes::Attributes;
8use crate::operations::psa_algorithm::Cipher;
9use crate::requests::ResponseStatus;
10use derivative::Derivative;
11
12#[derive(Derivative)]
14#[derivative(Debug)]
15pub struct Operation {
16 pub key_name: String,
18 pub alg: Cipher,
20 #[derivative(Debug = "ignore")]
22 pub ciphertext: zeroize::Zeroizing<Vec<u8>>,
23}
24
25impl Operation {
26 pub fn validate(&self, key_attributes: Attributes) -> crate::requests::Result<()> {
34 key_attributes.can_decrypt_message()?;
35 key_attributes.permits_alg(self.alg.into())?;
36 key_attributes.compatible_with_alg(self.alg.into())?;
37 if self.ciphertext.is_empty() {
38 return Err(ResponseStatus::PsaErrorInvalidArgument);
39 }
40 Ok(())
41 }
42}
43
44#[derive(Derivative)]
48#[derivative(Debug)]
49pub struct Result {
50 #[derivative(Debug = "ignore")]
52 pub plaintext: zeroize::Zeroizing<Vec<u8>>,
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::operations::psa_algorithm::Cipher;
59 use crate::operations::psa_key_attributes::{Lifetime, Policy, Type, UsageFlags};
60
61 fn get_attrs() -> Attributes {
62 let mut usage_flags = UsageFlags::default();
63 let _ = usage_flags.set_decrypt();
64 Attributes {
65 lifetime: Lifetime::Persistent,
66 key_type: Type::Arc4,
67 bits: 256,
68 policy: Policy {
69 usage_flags,
70 permitted_algorithms: Cipher::StreamCipher.into(),
71 },
72 }
73 }
74
75 #[test]
76 fn validate_success() {
77 (Operation {
78 key_name: String::from("some key"),
79 alg: Cipher::StreamCipher,
80 ciphertext: vec![0xff, 32].into(),
81 })
82 .validate(get_attrs())
83 .unwrap();
84 }
85
86 #[test]
87 fn cannot_decrypt() {
88 let mut attrs = get_attrs();
89 attrs.policy.usage_flags = UsageFlags::default();
90 assert_eq!(
91 (Operation {
92 key_name: String::from("some key"),
93 alg: Cipher::StreamCipher,
94 ciphertext: vec![0xff, 32].into(),
95 })
96 .validate(attrs)
97 .unwrap_err(),
98 ResponseStatus::PsaErrorNotPermitted
99 );
100 }
101
102 #[test]
103 fn wrong_algorithm() {
104 assert_eq!(
105 (Operation {
106 key_name: String::from("some key"),
107 alg: Cipher::Cfb,
108 ciphertext: vec![0xff, 32].into(),
109 })
110 .validate(get_attrs())
111 .unwrap_err(),
112 ResponseStatus::PsaErrorNotPermitted
113 );
114 }
115
116 #[test]
117 fn invalid_ciphertext() {
118 assert_eq!(
119 (Operation {
120 key_name: String::from("some key"),
121 alg: Cipher::StreamCipher,
122 ciphertext: vec![].into(),
123 })
124 .validate(get_attrs())
125 .unwrap_err(),
126 ResponseStatus::PsaErrorInvalidArgument
127 );
128 }
129}