1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use super::psa_key_attributes::Attributes;
use crate::operations::psa_algorithm::{KeyAgreement, RawKeyAgreement};
use derivative::Derivative;
#[derive(Derivative)]
#[derivative(Debug)]
pub struct Operation {
pub alg: RawKeyAgreement,
pub private_key_name: String,
#[derivative(Debug = "ignore")]
pub peer_key: zeroize::Zeroizing<Vec<u8>>,
}
#[derive(Derivative)]
#[derivative(Debug)]
pub struct Result {
#[derivative(Debug = "ignore")]
pub shared_secret: crate::secrecy::Secret<Vec<u8>>,
}
impl Operation {
pub fn validate(&self, key_attributes: Attributes) -> crate::requests::Result<()> {
key_attributes.can_derive_from()?;
key_attributes.permits_alg(KeyAgreement::Raw(self.alg).into())?;
key_attributes.compatible_with_alg(KeyAgreement::Raw(self.alg).into())?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::operations::psa_algorithm::{KeyAgreement, RawKeyAgreement};
use crate::operations::psa_key_attributes::{EccFamily, Lifetime, Policy, Type, UsageFlags};
use crate::requests::ResponseStatus;
fn get_attrs() -> Attributes {
Attributes {
lifetime: Lifetime::Persistent,
key_type: Type::EccKeyPair {
curve_family: EccFamily::SecpR1,
},
bits: 256,
policy: Policy {
usage_flags: UsageFlags {
export: false,
copy: false,
cache: false,
encrypt: false,
decrypt: false,
sign_message: false,
verify_message: false,
sign_hash: false,
verify_hash: false,
derive: true,
},
permitted_algorithms: KeyAgreement::Raw(RawKeyAgreement::Ecdh).into(),
},
}
}
#[test]
fn validate_success() {
(Operation {
private_key_name: String::from("some key"),
alg: RawKeyAgreement::Ecdh,
peer_key: vec![0xff, 32].into(),
})
.validate(get_attrs())
.unwrap();
}
#[test]
fn cannot_derive() {
let mut attrs = get_attrs();
attrs.policy.usage_flags.derive = false;
assert_eq!(
(Operation {
private_key_name: String::from("some key"),
alg: RawKeyAgreement::Ecdh,
peer_key: vec![0xff, 32].into(),
})
.validate(attrs)
.unwrap_err(),
ResponseStatus::PsaErrorNotPermitted
);
}
#[test]
fn wrong_algorithm() {
assert_eq!(
(Operation {
private_key_name: String::from("some key"),
alg: RawKeyAgreement::Ffdh,
peer_key: vec![0xff, 32].into(),
})
.validate(get_attrs())
.unwrap_err(),
ResponseStatus::PsaErrorNotPermitted
);
}
}