@@ -152,6 +152,41 @@ pub unsafe extern "C" fn key_manager_destroy_kem_key(uuid_bytes: *const u8) -> i
152152 . unwrap_or ( -1 )
153153}
154154
155+ /// Internal function to decapsulate and reseal a shared secret.
156+ fn decap_and_seal_internal (
157+ uuid : Uuid ,
158+ encapsulated_key : & [ u8 ] ,
159+ aad : & [ u8 ] ,
160+ ) -> Result < ( Vec < u8 > , Vec < u8 > ) , i32 > {
161+ // Get key record from registry
162+ let Some ( key_record) = KEY_REGISTRY . get_key ( & uuid) else {
163+ Err ( -1 ) ? // Key not found
164+ } ;
165+
166+ let KeySpec :: KemWithBindingPub {
167+ algo : hpke_algo,
168+ binding_public_key,
169+ ..
170+ } = & key_record. meta . spec
171+ else {
172+ Err ( -1 ) ? // Invalid key type
173+ } ;
174+
175+ let priv_key = key_record. get_private_key ( ) ;
176+
177+ // Decapsulate
178+ let shared_secret = match km_common:: crypto:: decaps ( & priv_key, encapsulated_key) {
179+ Ok ( s) => s,
180+ Err ( _) => return Err ( -3 ) ,
181+ } ;
182+
183+ // Seal
184+ match km_common:: crypto:: hpke_seal ( binding_public_key, & shared_secret, aad, hpke_algo) {
185+ Ok ( ( enc, ct) ) => Ok ( ( enc. to_vec ( ) , ct. to_vec ( ) ) ) ,
186+ Err ( _) => Err ( -4 ) ,
187+ }
188+ }
189+
155190/// Decapsulates a shared secret using a stored KEM key and immediately reseals it using the associated binding public key.
156191///
157192/// ## Arguments
@@ -161,10 +196,10 @@ pub unsafe extern "C" fn key_manager_destroy_kem_key(uuid_bytes: *const u8) -> i
161196/// * `aad` - A pointer to the Additional Authenticated Data (AAD) for the sealing operation.
162197/// * `aad_len` - The length of the AAD.
163198/// * `out_encapsulated_key` - A pointer to a buffer where the new encapsulated key will be written.
164- /// * `out_encapsulated_key_len` - A pointer to a `usize` containing the size of `out_encapsulated_key`.
199+ /// * `out_encapsulated_key_len` - The size of `out_encapsulated_key`.
165200/// On success, updated with the actual size.
166201/// * `out_ciphertext` - A pointer to a buffer where the sealed ciphertext will be written.
167- /// * `out_ciphertext_len` - A pointer to a `usize` containing the size of `out_ciphertext`.
202+ /// * `out_ciphertext_len` -The size of `out_ciphertext`.
168203/// On success, updated with the actual size.
169204///
170205/// ## Safety
@@ -208,7 +243,7 @@ pub unsafe extern "C" fn key_manager_decap_and_seal(
208243 }
209244
210245 // Convert to Safe Types
211- let uuid = unsafe { std :: slice:: from_raw_parts ( uuid_bytes, 16 ) } ;
246+ let uuid_slice = unsafe { slice:: from_raw_parts ( uuid_bytes, 16 ) } ;
212247 let enc_key_slice =
213248 unsafe { slice:: from_raw_parts ( encapsulated_key, encapsulated_key_len) } ;
214249 let aad_slice = if !aad. is_null ( ) && aad_len > 0 {
@@ -218,65 +253,26 @@ pub unsafe extern "C" fn key_manager_decap_and_seal(
218253 } ;
219254 let out_encapsulated_key_slice =
220255 unsafe { slice:: from_raw_parts_mut ( out_encapsulated_key, out_encapsulated_key_len) } ;
221- let out_ciphertext =
256+ let out_ciphertext_slice =
222257 unsafe { slice:: from_raw_parts_mut ( out_ciphertext, out_ciphertext_len) } ;
223258
224259 let uuid = match Uuid :: from_slice ( uuid_slice) {
225260 Ok ( u) => u,
226261 Err ( _) => return -1 ,
227262 } ;
228263
229- // Get key record from registry
230- let key_record = match KEY_REGISTRY . get_key ( & uuid_val) {
231- Some ( record) => record,
232- None => return -1 ,
233- } ;
234-
235- let ( hpke_algo, binding_public_key) = match & key_record. meta . spec {
236- KeySpec :: KemWithBindingPub {
237- algo,
238- binding_public_key,
239- ..
240- } => ( algo, binding_public_key) ,
241- _ => return -1 , // Wrong key type
242- } ;
243-
244- let _kem_algo = match km_common:: algorithms:: KemAlgorithm :: try_from ( hpke_algo. kem ) {
245- Ok ( k) => k,
246- Err ( _) => return -1 , // Invalid KEM algorithm
247- } ;
248-
249- let priv_key = key_record. get_private_key ( ) ;
250-
251- // Decapsulate
252- let shared_secret = match km_common:: crypto:: decaps ( & priv_key, enc_key_slice) {
253- Ok ( s) => s,
254- Err ( _) => return -3 ,
255- } ;
256-
257- // Seal
258- let ( enc_key, sealed_ciphertext) = match km_common:: crypto:: hpke_seal (
259- binding_public_key,
260- & shared_secret,
261- aad_slice,
262- hpke_algo,
263- ) {
264- Ok ( res) => res,
265- Err ( _) => {
266- return -4 ;
264+ // Call Safe Internal Function
265+ match decap_and_seal_internal ( uuid, enc_key_slice, aad_slice) {
266+ Ok ( ( enc, ct) ) => {
267+ if out_encapsulated_key_len != enc. len ( ) || out_ciphertext_len != ct. len ( ) {
268+ return -2 ;
269+ }
270+ out_encapsulated_key_slice. copy_from_slice ( & enc) ;
271+ out_ciphertext_slice. copy_from_slice ( & ct) ;
272+ 0 // Success
267273 }
268- } ;
269-
270- // Copy outputs
271- let enc_len_req = enc_key. len ( ) ;
272- let ct_len_req = sealed_ciphertext. len ( ) ;
273-
274- if out_encapsulated_key_len != enc_len_req || out_ciphertext_len != ct_len_req {
275- return -2 ;
274+ Err ( e) => e,
276275 }
277- out_encapsulated_key. copy_from_slice ( enc_key. as_slice ( ) ) ;
278- out_ciphertext. copy_from_slice ( sealed_ciphertext. as_slice ( ) ) ;
279- 0
280276 } ) )
281277 . unwrap_or ( -1 )
282278}
@@ -462,10 +458,11 @@ mod tests {
462458 kdf : KdfAlgorithm :: HkdfSha256 as i32 ,
463459 aead : AeadAlgorithm :: Aes256Gcm as i32 ,
464460 } ;
465-
461+ let algo_bytes = algo . encode_to_vec ( ) ;
466462 unsafe {
467463 let res = key_manager_generate_kem_keypair (
468- algo,
464+ algo_bytes. as_ptr ( ) ,
465+ algo_bytes. len ( ) ,
469466 binding_pubkey. as_ptr ( ) ,
470467 binding_pubkey. len ( ) ,
471468 3600 ,
@@ -513,10 +510,11 @@ mod tests {
513510 kdf : KdfAlgorithm :: HkdfSha256 as i32 ,
514511 aead : AeadAlgorithm :: Aes256Gcm as i32 ,
515512 } ;
516-
513+ let algo_bytes = algo . encode_to_vec ( ) ;
517514 unsafe {
518515 key_manager_generate_kem_keypair (
519- algo,
516+ algo_bytes. as_ptr ( ) ,
517+ algo_bytes. len ( ) ,
520518 binding_pk. as_bytes ( ) . as_ptr ( ) ,
521519 binding_pk. as_bytes ( ) . len ( ) ,
522520 3600 ,
@@ -632,9 +630,11 @@ mod tests {
632630 kdf : KdfAlgorithm :: HkdfSha256 as i32 ,
633631 aead : AeadAlgorithm :: Aes256Gcm as i32 ,
634632 } ;
633+ let algo_bytes = algo. encode_to_vec ( ) ;
635634 let res = unsafe {
636635 key_manager_generate_kem_keypair (
637- algo,
636+ algo_bytes. as_ptr ( ) ,
637+ algo_bytes. len ( ) ,
638638 binding_pk. as_bytes ( ) . as_ptr ( ) ,
639639 binding_pk. as_bytes ( ) . len ( ) ,
640640 3600 ,
@@ -683,9 +683,12 @@ mod tests {
683683 kdf : KdfAlgorithm :: HkdfSha256 as i32 ,
684684 aead : AeadAlgorithm :: Aes256Gcm as i32 ,
685685 } ;
686+
687+ let algo_bytes = algo. encode_to_vec ( ) ;
686688 let res = unsafe {
687689 key_manager_generate_kem_keypair (
688- algo,
690+ algo_bytes. as_ptr ( ) ,
691+ algo_bytes. len ( ) ,
689692 binding_pk. as_bytes ( ) . as_ptr ( ) ,
690693 binding_pk. as_bytes ( ) . len ( ) ,
691694 3600 ,
0 commit comments