botan/
pk_ops_kem.rs

1use crate::utils::*;
2use botan_sys::*;
3
4use crate::pubkey::{Privkey, Pubkey};
5use crate::rng::RandomNumberGenerator;
6
7#[derive(Debug)]
8/// An object that can perform key encapsulation
9pub 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    /// Create a KeyEncapsulation operation
21    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    /// Return the shared key length
30    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    /// Create a new encapsulated key
43    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)]
77/// An object that can perform key decapsulation
78pub 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    /// Create a KeyDecapsulation operation
89    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    /// Return the shared key length
97    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    /// Decrypt an encapsulated key
110    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}