parsec_interface/operations/
psa_aead_encrypt.rs1use super::psa_key_attributes::Attributes;
8use crate::operations::psa_algorithm::Aead;
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: Aead,
20 #[derivative(Debug = "ignore")]
22 pub nonce: zeroize::Zeroizing<Vec<u8>>,
23 #[derivative(Debug = "ignore")]
25 pub additional_data: zeroize::Zeroizing<Vec<u8>>,
26 #[derivative(Debug = "ignore")]
28 pub plaintext: zeroize::Zeroizing<Vec<u8>>,
29}
30
31impl Operation {
32 pub fn validate(&self, key_attributes: Attributes) -> crate::requests::Result<()> {
41 key_attributes.can_encrypt_message()?;
42 key_attributes.permits_alg(self.alg.into())?;
43 key_attributes.compatible_with_alg(self.alg.into())?;
44 if self.plaintext.is_empty() || self.nonce.is_empty() {
45 return Err(ResponseStatus::PsaErrorInvalidArgument);
46 }
47 Ok(())
48 }
49}
50
51#[derive(Derivative)]
53#[derivative(Debug)]
54pub struct Result {
55 #[derivative(Debug = "ignore")]
59 pub ciphertext: zeroize::Zeroizing<Vec<u8>>,
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use crate::operations::psa_algorithm::AeadWithDefaultLengthTag;
66 use crate::operations::psa_key_attributes::{Lifetime, Policy, Type, UsageFlags};
67 use psa_crypto::types::algorithm::Aead;
68
69 fn get_attrs() -> Attributes {
70 let mut usage_flags = UsageFlags::default();
71 let _ = usage_flags.set_encrypt();
72 Attributes {
73 lifetime: Lifetime::Persistent,
74 key_type: Type::Aes,
75 bits: 0,
76 policy: Policy {
77 usage_flags,
78 permitted_algorithms: Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Ccm)
79 .into(),
80 },
81 }
82 }
83
84 #[test]
85 fn validate_success() {
86 (Operation {
87 key_name: String::from("some key"),
88 alg: AeadWithDefaultLengthTag::Ccm.into(),
89 plaintext: vec![0xff, 32].into(),
90 nonce: vec![0xaa, 12].into(),
91 additional_data: vec![0xff, 16].into(),
92 })
93 .validate(get_attrs())
94 .unwrap();
95 }
96
97 #[test]
98 fn cannot_encrypt() {
99 let mut attrs = get_attrs();
100 attrs.policy.usage_flags = UsageFlags::default();
101 assert_eq!(
102 (Operation {
103 key_name: String::from("some key"),
104 alg: AeadWithDefaultLengthTag::Ccm.into(),
105 plaintext: vec![0xff, 32].into(),
106 nonce: vec![0xaa, 12].into(),
107 additional_data: vec![0xff, 16].into()
108 })
109 .validate(attrs)
110 .unwrap_err(),
111 ResponseStatus::PsaErrorNotPermitted
112 );
113 }
114
115 #[test]
116 fn wrong_algorithm() {
117 assert_eq!(
118 (Operation {
119 key_name: String::from("some key"),
120 alg: AeadWithDefaultLengthTag::Gcm.into(),
121 plaintext: vec![0xff, 32].into(),
122 nonce: vec![0xaa, 12].into(),
123 additional_data: vec![0xff, 16].into()
124 })
125 .validate(get_attrs())
126 .unwrap_err(),
127 ResponseStatus::PsaErrorNotPermitted
128 );
129 }
130
131 #[test]
132 fn invalid_plaintext() {
133 assert_eq!(
134 (Operation {
135 key_name: String::from("some key"),
136 alg: AeadWithDefaultLengthTag::Ccm.into(),
137 plaintext: vec![].into(),
138 nonce: vec![0xaa, 12].into(),
139 additional_data: vec![0xff, 16].into()
140 })
141 .validate(get_attrs())
142 .unwrap_err(),
143 ResponseStatus::PsaErrorInvalidArgument
144 );
145 }
146
147 #[test]
148 fn invalid_nonce() {
149 assert_eq!(
150 (Operation {
151 key_name: String::from("some key"),
152 alg: AeadWithDefaultLengthTag::Ccm.into(),
153 plaintext: vec![0xff, 32].into(),
154 nonce: vec![].into(),
155 additional_data: vec![0xff, 16].into()
156 })
157 .validate(get_attrs())
158 .unwrap_err(),
159 ResponseStatus::PsaErrorInvalidArgument
160 );
161 }
162}