1use crate::utils::*;
2use botan_sys::*;
3
4use crate::pubkey::{Privkey, Pubkey};
5use crate::rng::RandomNumberGenerator;
6
7#[derive(Debug)]
8pub struct KeyEncapsulation {
10 obj: botan_pk_op_kem_encrypt_t,
11 encap_length: usize,
12}
13
14unsafe impl Sync for KeyEncapsulation {}
15unsafe impl Send for KeyEncapsulation {}
16
17botan_impl_drop!(KeyEncapsulation, botan_pk_op_kem_encrypt_destroy);
18
19impl KeyEncapsulation {
20 pub fn new(key: &Pubkey, kdf: &str) -> Result<Self> {
22 let kdf = make_cstr(kdf)?;
23 let obj = botan_init!(botan_pk_op_kem_encrypt_create, key.handle(), kdf.as_ptr())?;
24
25 let encap_length = botan_usize!(botan_pk_op_kem_encrypt_encapsulated_key_length, obj)?;
26 Ok(Self { obj, encap_length })
27 }
28
29 pub fn shared_key_length(&self, desired_shared_key_length: usize) -> Result<usize> {
31 let mut val = 0;
32 let rc = unsafe {
33 botan_pk_op_kem_encrypt_shared_key_length(self.obj, desired_shared_key_length, &mut val)
34 };
35 if rc != 0 {
36 Err(Error::from_rc(rc))
37 } else {
38 Ok(val)
39 }
40 }
41
42 pub fn create_shared_key(
44 &self,
45 rng: &mut RandomNumberGenerator,
46 salt: &[u8],
47 desired_key_len: usize,
48 ) -> Result<(Vec<u8>, Vec<u8>)> {
49 let mut shared_key_len = self.shared_key_length(desired_key_len)?;
50 let mut shared_key = vec![0; shared_key_len];
51 let mut encap_key_len = self.encap_length;
52 let mut encap_key = vec![0; encap_key_len];
53
54 let rc = unsafe {
55 botan_pk_op_kem_encrypt_create_shared_key(
56 self.obj,
57 rng.handle(),
58 salt.as_ptr(),
59 salt.len(),
60 desired_key_len,
61 shared_key.as_mut_ptr(),
62 &mut shared_key_len,
63 encap_key.as_mut_ptr(),
64 &mut encap_key_len,
65 )
66 };
67
68 if rc != 0 {
69 return Err(Error::from_rc(rc));
70 }
71
72 Ok((shared_key, encap_key))
73 }
74}
75
76#[derive(Debug)]
77pub struct KeyDecapsulation {
79 obj: botan_pk_op_kem_decrypt_t,
80}
81
82unsafe impl Sync for KeyDecapsulation {}
83unsafe impl Send for KeyDecapsulation {}
84
85botan_impl_drop!(KeyDecapsulation, botan_pk_op_kem_decrypt_destroy);
86
87impl KeyDecapsulation {
88 pub fn new(key: &Privkey, kdf: &str) -> Result<Self> {
90 let kdf = make_cstr(kdf)?;
91 let obj = botan_init!(botan_pk_op_kem_decrypt_create, key.handle(), kdf.as_ptr())?;
92
93 Ok(Self { obj })
94 }
95
96 pub fn shared_key_length(&self, desired_shared_key_length: usize) -> Result<usize> {
98 let mut val = 0;
99 let rc = unsafe {
100 botan_pk_op_kem_decrypt_shared_key_length(self.obj, desired_shared_key_length, &mut val)
101 };
102 if rc != 0 {
103 Err(Error::from_rc(rc))
104 } else {
105 Ok(val)
106 }
107 }
108
109 pub fn decrypt_shared_key(
111 &self,
112 encapsulated_key: &[u8],
113 salt: &[u8],
114 desired_key_len: usize,
115 ) -> Result<Vec<u8>> {
116 let mut shared_key_len = self.shared_key_length(desired_key_len)?;
117 let mut shared_key = vec![0; shared_key_len];
118
119 let rc = unsafe {
120 botan_pk_op_kem_decrypt_shared_key(
121 self.obj,
122 salt.as_ptr(),
123 salt.len(),
124 encapsulated_key.as_ptr(),
125 encapsulated_key.len(),
126 desired_key_len,
127 shared_key.as_mut_ptr(),
128 &mut shared_key_len,
129 )
130 };
131
132 if rc != 0 {
133 return Err(Error::from_rc(rc));
134 }
135
136 Ok(shared_key)
137 }
138}