1use wasi_crypto::{
14 AlgorithmType as HostAlgorithmType, CryptoCtx, CryptoError, Handle, KeyPairEncoding,
15 PublicKeyEncoding, SecretKeyEncoding, SignatureEncoding, Version,
16};
17use wiggle::{GuestError, GuestMemory, GuestPtr};
18
19pub struct WasiCryptoCtx {
23 ctx: CryptoCtx,
24}
25
26impl Default for WasiCryptoCtx {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl WasiCryptoCtx {
33 pub fn new() -> Self {
34 Self {
35 ctx: CryptoCtx::new(),
36 }
37 }
38}
39
40#[derive(Debug, thiserror::Error)]
44pub enum WasiCryptoError {
45 #[error("crypto error: {0}")]
46 Crypto(#[from] CryptoError),
47 #[error("guest memory error: {0}")]
48 Guest(#[from] GuestError),
49}
50
51type WResult<T> = Result<T, WasiCryptoError>;
52
53mod generated {
54 use super::{WasiCryptoCtx, WasiCryptoError};
55 wiggle::from_witx!({
56 witx: ["witx/wasi_ephemeral_crypto.witx"],
57 errors: { crypto_errno => WasiCryptoError },
58 });
59
60 impl wiggle::GuestErrorType for types::CryptoErrno {
61 fn success() -> Self {
62 Self::Success
63 }
64 }
65
66 impl types::UserErrorConversion for WasiCryptoCtx {
67 fn crypto_errno_from_wasi_crypto_error(
68 &mut self,
69 e: super::WasiCryptoError,
70 ) -> wiggle::error::Result<types::CryptoErrno> {
71 Ok(super::to_errno(e))
72 }
73 }
74}
75
76pub use generated::types;
77
78pub fn add_to_linker<T: 'static>(
81 linker: &mut wiggle::wasmtime_crate::Linker<T>,
82 get_cx: impl Fn(&mut T) -> &mut WasiCryptoCtx + Send + Sync + Copy + 'static,
83) -> wiggle::error::Result<()> {
84 use generated::*;
85 wasi_ephemeral_crypto_common::add_to_linker(linker, get_cx)?;
86 wasi_ephemeral_crypto_asymmetric_common::add_to_linker(linker, get_cx)?;
87 wasi_ephemeral_crypto_signatures::add_to_linker(linker, get_cx)?;
88 wasi_ephemeral_crypto_symmetric::add_to_linker(linker, get_cx)?;
89 wasi_ephemeral_crypto_kx::add_to_linker(linker, get_cx)?;
90 Ok(())
91}
92
93fn to_errno(e: WasiCryptoError) -> types::CryptoErrno {
94 use types::CryptoErrno as E;
95 let crypto = match e {
96 WasiCryptoError::Crypto(c) => c,
97 WasiCryptoError::Guest(_) => return E::GuestError,
100 };
101 match crypto {
102 CryptoError::Success => E::Success,
103 CryptoError::GuestError(_) => E::GuestError,
104 CryptoError::NotImplemented => E::NotImplemented,
105 CryptoError::UnsupportedFeature => E::UnsupportedFeature,
106 CryptoError::ProhibitedOperation => E::ProhibitedOperation,
107 CryptoError::UnsupportedEncoding => E::UnsupportedEncoding,
108 CryptoError::UnsupportedAlgorithm => E::UnsupportedAlgorithm,
109 CryptoError::UnsupportedOption => E::UnsupportedOption,
110 CryptoError::InvalidKey => E::InvalidKey,
111 CryptoError::InvalidLength => E::InvalidLength,
112 CryptoError::VerificationFailed => E::VerificationFailed,
113 CryptoError::RNGError => E::RngError,
114 CryptoError::AlgorithmFailure => E::AlgorithmFailure,
115 CryptoError::InvalidSignature => E::InvalidSignature,
116 CryptoError::Closed => E::Closed,
117 CryptoError::InvalidHandle => E::InvalidHandle,
118 CryptoError::Overflow => E::Overflow,
119 CryptoError::InternalError => E::InternalError,
120 CryptoError::TooManyHandles => E::TooManyHandles,
121 CryptoError::KeyNotSupported => E::KeyNotSupported,
122 CryptoError::KeyRequired => E::KeyRequired,
123 CryptoError::InvalidTag => E::InvalidTag,
124 CryptoError::InvalidOperation => E::InvalidOperation,
125 CryptoError::NonceRequired => E::NonceRequired,
126 CryptoError::InvalidNonce => E::InvalidNonce,
127 CryptoError::OptionNotSet => E::OptionNotSet,
128 CryptoError::NotFound => E::NotFound,
129 CryptoError::ParametersMissing => E::ParametersMissing,
130 CryptoError::IncompatibleKeys => E::IncompatibleKeys,
131 CryptoError::Expired => E::Expired,
132 }
133}
134
135fn read_bytes(mem: &GuestMemory<'_>, ptr: GuestPtr<u8>, len: types::Size) -> WResult<Vec<u8>> {
141 Ok(mem.as_cow(ptr.as_array(len))?.into_owned())
142}
143
144fn read_str(mem: &GuestMemory<'_>, ptr: GuestPtr<str>) -> WResult<String> {
146 Ok(mem.as_cow_str(ptr)?.into_owned())
147}
148
149fn write_bytes(
153 mem: &mut GuestMemory<'_>,
154 ptr: GuestPtr<u8>,
155 max_len: types::Size,
156 data: &[u8],
157) -> WResult<types::Size> {
158 if data.len() > max_len as usize {
159 return Err(CryptoError::Overflow.into());
160 }
161 mem.copy_from_slice(data, ptr.as_array(data.len() as u32))?;
162 Ok(data.len() as types::Size)
163}
164
165fn fill_out_buf(
171 mem: &mut GuestMemory<'_>,
172 ptr: GuestPtr<u8>,
173 len: types::Size,
174 fill: impl FnOnce(&mut [u8]) -> Result<usize, CryptoError>,
175) -> WResult<types::Size> {
176 if let Some(dst) = mem.as_slice_mut(ptr.as_array(len))? {
177 let n = fill(dst)?;
178 return Ok(n as types::Size);
179 }
180 let mut tmp = vec![0u8; len as usize];
181 let n = fill(&mut tmp)?;
182 write_bytes(mem, ptr, len, &tmp[..n])
183}
184
185impl From<types::AlgorithmType> for HostAlgorithmType {
188 fn from(a: types::AlgorithmType) -> Self {
189 match a {
190 types::AlgorithmType::Signatures => HostAlgorithmType::Signatures,
191 types::AlgorithmType::Symmetric => HostAlgorithmType::Symmetric,
192 types::AlgorithmType::KeyExchange => HostAlgorithmType::KeyExchange,
193 }
194 }
195}
196
197impl From<types::KeypairEncoding> for KeyPairEncoding {
198 fn from(e: types::KeypairEncoding) -> Self {
199 match e {
200 types::KeypairEncoding::Raw => KeyPairEncoding::Raw,
201 types::KeypairEncoding::Pkcs8 => KeyPairEncoding::Pkcs8,
202 types::KeypairEncoding::Pem => KeyPairEncoding::Pem,
203 types::KeypairEncoding::Local => KeyPairEncoding::Local,
204 }
205 }
206}
207
208impl From<types::PublickeyEncoding> for PublicKeyEncoding {
209 fn from(e: types::PublickeyEncoding) -> Self {
210 match e {
211 types::PublickeyEncoding::Raw => PublicKeyEncoding::Raw,
212 types::PublickeyEncoding::Pkcs8 => PublicKeyEncoding::Pkcs8,
213 types::PublickeyEncoding::Pem => PublicKeyEncoding::Pem,
214 types::PublickeyEncoding::Sec => PublicKeyEncoding::Sec,
215 types::PublickeyEncoding::Local => PublicKeyEncoding::Local,
216 }
217 }
218}
219
220impl From<types::SecretkeyEncoding> for SecretKeyEncoding {
221 fn from(e: types::SecretkeyEncoding) -> Self {
222 match e {
223 types::SecretkeyEncoding::Raw => SecretKeyEncoding::Raw,
224 types::SecretkeyEncoding::Pkcs8 => SecretKeyEncoding::Pkcs8,
225 types::SecretkeyEncoding::Pem => SecretKeyEncoding::Pem,
226 types::SecretkeyEncoding::Sec => SecretKeyEncoding::Sec,
227 types::SecretkeyEncoding::Local => SecretKeyEncoding::Local,
228 }
229 }
230}
231
232impl From<types::SignatureEncoding> for SignatureEncoding {
233 fn from(e: types::SignatureEncoding) -> Self {
234 match e {
235 types::SignatureEncoding::Raw => SignatureEncoding::Raw,
236 types::SignatureEncoding::Der => SignatureEncoding::Der,
237 }
238 }
239}
240
241fn opt_options(o: &types::OptOptions) -> Option<Handle> {
242 match o {
243 types::OptOptions::Some(h) => Some((*h).into()),
244 types::OptOptions::None => None,
245 }
246}
247
248fn opt_symmetric_key(o: &types::OptSymmetricKey) -> Option<Handle> {
249 match o {
250 types::OptSymmetricKey::Some(h) => Some((*h).into()),
251 types::OptSymmetricKey::None => None,
252 }
253}
254
255impl generated::wasi_ephemeral_crypto_common::WasiEphemeralCryptoCommon for WasiCryptoCtx {
258 fn options_open(
259 &mut self,
260 _mem: &mut GuestMemory<'_>,
261 algorithm_type: types::AlgorithmType,
262 ) -> WResult<types::Options> {
263 Ok(self.ctx.options_open(algorithm_type.into())?.into())
264 }
265
266 fn options_close(&mut self, _mem: &mut GuestMemory<'_>, handle: types::Options) -> WResult<()> {
267 Ok(self.ctx.options_close(handle.into())?)
268 }
269
270 fn options_set(
271 &mut self,
272 mem: &mut GuestMemory<'_>,
273 handle: types::Options,
274 name: GuestPtr<str>,
275 value: GuestPtr<u8>,
276 value_len: types::Size,
277 ) -> WResult<()> {
278 let name = read_str(mem, name)?;
279 let value = read_bytes(mem, value, value_len)?;
280 Ok(self.ctx.options_set(handle.into(), &name, &value)?)
281 }
282
283 fn options_set_u64(
284 &mut self,
285 mem: &mut GuestMemory<'_>,
286 handle: types::Options,
287 name: GuestPtr<str>,
288 value: u64,
289 ) -> WResult<()> {
290 let name = read_str(mem, name)?;
291 Ok(self.ctx.options_set_u64(handle.into(), &name, value)?)
292 }
293
294 fn options_set_guest_buffer(
295 &mut self,
296 mem: &mut GuestMemory<'_>,
297 _handle: types::Options,
298 name: GuestPtr<str>,
299 _buffer: GuestPtr<u8>,
300 _buffer_len: types::Size,
301 ) -> WResult<()> {
302 let _ = read_str(mem, name)?;
309 Ok(())
310 }
311
312 fn array_output_len(
313 &mut self,
314 _mem: &mut GuestMemory<'_>,
315 array_output: types::ArrayOutput,
316 ) -> WResult<types::Size> {
317 Ok(self.ctx.array_output_len(array_output.into())? as types::Size)
318 }
319
320 fn array_output_pull(
321 &mut self,
322 mem: &mut GuestMemory<'_>,
323 array_output: types::ArrayOutput,
324 buf: GuestPtr<u8>,
325 buf_len: types::Size,
326 ) -> WResult<types::Size> {
327 fill_out_buf(mem, buf, buf_len, |out| {
328 self.ctx.array_output_pull(array_output.into(), out)
329 })
330 }
331
332 fn secrets_manager_open(
333 &mut self,
334 _mem: &mut GuestMemory<'_>,
335 options: &types::OptOptions,
336 ) -> WResult<types::SecretsManager> {
337 Ok(self.ctx.secrets_manager_open(opt_options(options))?.into())
338 }
339
340 fn secrets_manager_close(
341 &mut self,
342 _mem: &mut GuestMemory<'_>,
343 secrets_manager: types::SecretsManager,
344 ) -> WResult<()> {
345 Ok(self.ctx.secrets_manager_close(secrets_manager.into())?)
346 }
347
348 fn secrets_manager_invalidate(
349 &mut self,
350 mem: &mut GuestMemory<'_>,
351 secrets_manager: types::SecretsManager,
352 key_id: GuestPtr<u8>,
353 key_id_len: types::Size,
354 key_version: types::Version,
355 ) -> WResult<()> {
356 let key_id = read_bytes(mem, key_id, key_id_len)?;
357 Ok(self.ctx.secrets_manager_invalidate(
358 secrets_manager.into(),
359 &key_id,
360 Version(key_version),
361 )?)
362 }
363}
364
365impl generated::wasi_ephemeral_crypto_asymmetric_common::WasiEphemeralCryptoAsymmetricCommon
368 for WasiCryptoCtx
369{
370 fn keypair_generate(
371 &mut self,
372 mem: &mut GuestMemory<'_>,
373 algorithm_type: types::AlgorithmType,
374 algorithm: GuestPtr<str>,
375 options: &types::OptOptions,
376 ) -> WResult<types::Keypair> {
377 let alg = read_str(mem, algorithm)?;
378 Ok(self
379 .ctx
380 .keypair_generate(algorithm_type.into(), &alg, opt_options(options))?
381 .into())
382 }
383
384 fn keypair_import(
385 &mut self,
386 mem: &mut GuestMemory<'_>,
387 algorithm_type: types::AlgorithmType,
388 algorithm: GuestPtr<str>,
389 encoded: GuestPtr<u8>,
390 encoded_len: types::Size,
391 encoding: types::KeypairEncoding,
392 ) -> WResult<types::Keypair> {
393 let alg = read_str(mem, algorithm)?;
394 let encoded = read_bytes(mem, encoded, encoded_len)?;
395 Ok(self
396 .ctx
397 .keypair_import(algorithm_type.into(), &alg, &encoded, encoding.into())?
398 .into())
399 }
400
401 fn keypair_generate_managed(
402 &mut self,
403 mem: &mut GuestMemory<'_>,
404 secrets_manager: types::SecretsManager,
405 algorithm_type: types::AlgorithmType,
406 algorithm: GuestPtr<str>,
407 options: &types::OptOptions,
408 ) -> WResult<types::Keypair> {
409 let alg = read_str(mem, algorithm)?;
410 Ok(self
411 .ctx
412 .keypair_generate_managed(
413 secrets_manager.into(),
414 algorithm_type.into(),
415 &alg,
416 opt_options(options),
417 )?
418 .into())
419 }
420
421 fn keypair_store_managed(
422 &mut self,
423 mem: &mut GuestMemory<'_>,
424 secrets_manager: types::SecretsManager,
425 kp: types::Keypair,
426 kp_id: GuestPtr<u8>,
427 kp_id_max_len: types::Size,
428 ) -> WResult<()> {
429 let mut tmp = vec![0u8; kp_id_max_len as usize];
430 self.ctx
431 .keypair_store_managed(secrets_manager.into(), kp.into(), &mut tmp)?;
432 write_bytes(mem, kp_id, kp_id_max_len, &tmp)?;
433 Ok(())
434 }
435
436 fn keypair_replace_managed(
437 &mut self,
438 _mem: &mut GuestMemory<'_>,
439 secrets_manager: types::SecretsManager,
440 kp_old: types::Keypair,
441 kp_new: types::Keypair,
442 ) -> WResult<types::Version> {
443 Ok(self
444 .ctx
445 .keypair_replace_managed(secrets_manager.into(), kp_old.into(), kp_new.into())?
446 .0)
447 }
448
449 fn keypair_id(
450 &mut self,
451 mem: &mut GuestMemory<'_>,
452 kp: types::Keypair,
453 kp_id: GuestPtr<u8>,
454 kp_id_max_len: types::Size,
455 ) -> WResult<(types::Size, types::Version)> {
456 let (id, version) = self.ctx.keypair_id(kp.into())?;
457 let n = write_bytes(mem, kp_id, kp_id_max_len, &id)?;
458 Ok((n, version.0))
459 }
460
461 fn keypair_from_id(
462 &mut self,
463 mem: &mut GuestMemory<'_>,
464 secrets_manager: types::SecretsManager,
465 kp_id: GuestPtr<u8>,
466 kp_id_len: types::Size,
467 kp_version: types::Version,
468 ) -> WResult<types::Keypair> {
469 let kp_id = read_bytes(mem, kp_id, kp_id_len)?;
470 Ok(self
471 .ctx
472 .keypair_from_id(secrets_manager.into(), &kp_id, Version(kp_version))?
473 .into())
474 }
475
476 fn keypair_from_pk_and_sk(
477 &mut self,
478 _mem: &mut GuestMemory<'_>,
479 publickey: types::Publickey,
480 secretkey: types::Secretkey,
481 ) -> WResult<types::Keypair> {
482 Ok(self
483 .ctx
484 .keypair_from_pk_and_sk(publickey.into(), secretkey.into())?
485 .into())
486 }
487
488 fn keypair_export(
489 &mut self,
490 _mem: &mut GuestMemory<'_>,
491 kp: types::Keypair,
492 encoding: types::KeypairEncoding,
493 ) -> WResult<types::ArrayOutput> {
494 Ok(self.ctx.keypair_export(kp.into(), encoding.into())?.into())
495 }
496
497 fn keypair_publickey(
498 &mut self,
499 _mem: &mut GuestMemory<'_>,
500 kp: types::Keypair,
501 ) -> WResult<types::Publickey> {
502 Ok(self.ctx.keypair_publickey(kp.into())?.into())
503 }
504
505 fn keypair_secretkey(
506 &mut self,
507 _mem: &mut GuestMemory<'_>,
508 kp: types::Keypair,
509 ) -> WResult<types::Secretkey> {
510 Ok(self.ctx.keypair_secretkey(kp.into())?.into())
511 }
512
513 fn keypair_close(&mut self, _mem: &mut GuestMemory<'_>, kp: types::Keypair) -> WResult<()> {
514 Ok(self.ctx.keypair_close(kp.into())?)
515 }
516
517 fn publickey_import(
518 &mut self,
519 mem: &mut GuestMemory<'_>,
520 algorithm_type: types::AlgorithmType,
521 algorithm: GuestPtr<str>,
522 encoded: GuestPtr<u8>,
523 encoded_len: types::Size,
524 encoding: types::PublickeyEncoding,
525 ) -> WResult<types::Publickey> {
526 let alg = read_str(mem, algorithm)?;
527 let encoded = read_bytes(mem, encoded, encoded_len)?;
528 Ok(self
529 .ctx
530 .publickey_import(algorithm_type.into(), &alg, &encoded, encoding.into())?
531 .into())
532 }
533
534 fn publickey_export(
535 &mut self,
536 _mem: &mut GuestMemory<'_>,
537 pk: types::Publickey,
538 encoding: types::PublickeyEncoding,
539 ) -> WResult<types::ArrayOutput> {
540 Ok(self
541 .ctx
542 .publickey_export(pk.into(), encoding.into())?
543 .into())
544 }
545
546 fn publickey_verify(
547 &mut self,
548 _mem: &mut GuestMemory<'_>,
549 pk: types::Publickey,
550 ) -> WResult<()> {
551 Ok(self.ctx.publickey_verify(pk.into())?)
552 }
553
554 fn publickey_from_secretkey(
555 &mut self,
556 _mem: &mut GuestMemory<'_>,
557 sk: types::Secretkey,
558 ) -> WResult<types::Publickey> {
559 Ok(self.ctx.publickey(sk.into())?.into())
560 }
561
562 fn publickey_close(&mut self, _mem: &mut GuestMemory<'_>, pk: types::Publickey) -> WResult<()> {
563 Ok(self.ctx.publickey_close(pk.into())?)
564 }
565
566 fn secretkey_import(
567 &mut self,
568 mem: &mut GuestMemory<'_>,
569 algorithm_type: types::AlgorithmType,
570 algorithm: GuestPtr<str>,
571 encoded: GuestPtr<u8>,
572 encoded_len: types::Size,
573 encoding: types::SecretkeyEncoding,
574 ) -> WResult<types::Secretkey> {
575 let alg = read_str(mem, algorithm)?;
576 let encoded = read_bytes(mem, encoded, encoded_len)?;
577 Ok(self
578 .ctx
579 .secretkey_import(algorithm_type.into(), &alg, &encoded, encoding.into())?
580 .into())
581 }
582
583 fn secretkey_export(
584 &mut self,
585 _mem: &mut GuestMemory<'_>,
586 sk: types::Secretkey,
587 encoding: types::SecretkeyEncoding,
588 ) -> WResult<types::ArrayOutput> {
589 Ok(self
590 .ctx
591 .secretkey_export(sk.into(), encoding.into())?
592 .into())
593 }
594
595 fn secretkey_close(&mut self, _mem: &mut GuestMemory<'_>, sk: types::Secretkey) -> WResult<()> {
596 Ok(self.ctx.secretkey_close(sk.into())?)
597 }
598}
599
600impl generated::wasi_ephemeral_crypto_signatures::WasiEphemeralCryptoSignatures for WasiCryptoCtx {
603 fn signature_export(
604 &mut self,
605 _mem: &mut GuestMemory<'_>,
606 signature: types::Signature,
607 encoding: types::SignatureEncoding,
608 ) -> WResult<types::ArrayOutput> {
609 Ok(self
610 .ctx
611 .signature_export(signature.into(), encoding.into())?
612 .into())
613 }
614
615 fn signature_import(
616 &mut self,
617 mem: &mut GuestMemory<'_>,
618 algorithm: GuestPtr<str>,
619 encoded: GuestPtr<u8>,
620 encoded_len: types::Size,
621 encoding: types::SignatureEncoding,
622 ) -> WResult<types::Signature> {
623 let alg = read_str(mem, algorithm)?;
624 let encoded = read_bytes(mem, encoded, encoded_len)?;
625 Ok(self
626 .ctx
627 .signature_import(&alg, &encoded, encoding.into())?
628 .into())
629 }
630
631 fn signature_state_open(
632 &mut self,
633 _mem: &mut GuestMemory<'_>,
634 kp: types::SignatureKeypair,
635 ) -> WResult<types::SignatureState> {
636 Ok(self.ctx.signature_state_open(kp.into())?.into())
637 }
638
639 fn signature_state_update(
640 &mut self,
641 mem: &mut GuestMemory<'_>,
642 state: types::SignatureState,
643 input: GuestPtr<u8>,
644 input_len: types::Size,
645 ) -> WResult<()> {
646 let input = read_bytes(mem, input, input_len)?;
647 Ok(self.ctx.signature_state_update(state.into(), &input)?)
648 }
649
650 fn signature_state_sign(
651 &mut self,
652 _mem: &mut GuestMemory<'_>,
653 state: types::SignatureState,
654 ) -> WResult<types::ArrayOutput> {
655 Ok(self.ctx.signature_state_sign(state.into())?.into())
656 }
657
658 fn signature_state_close(
659 &mut self,
660 _mem: &mut GuestMemory<'_>,
661 state: types::SignatureState,
662 ) -> WResult<()> {
663 Ok(self.ctx.signature_state_close(state.into())?)
664 }
665
666 fn signature_verification_state_open(
667 &mut self,
668 _mem: &mut GuestMemory<'_>,
669 kp: types::SignaturePublickey,
670 ) -> WResult<types::SignatureVerificationState> {
671 Ok(self
672 .ctx
673 .signature_verification_state_open(kp.into())?
674 .into())
675 }
676
677 fn signature_verification_state_update(
678 &mut self,
679 mem: &mut GuestMemory<'_>,
680 state: types::SignatureVerificationState,
681 input: GuestPtr<u8>,
682 input_len: types::Size,
683 ) -> WResult<()> {
684 let input = read_bytes(mem, input, input_len)?;
685 Ok(self
686 .ctx
687 .signature_verification_state_update(state.into(), &input)?)
688 }
689
690 fn signature_verification_state_verify(
691 &mut self,
692 _mem: &mut GuestMemory<'_>,
693 state: types::SignatureVerificationState,
694 signature: types::Signature,
695 ) -> WResult<()> {
696 Ok(self
697 .ctx
698 .signature_verification_state_verify(state.into(), signature.into())?)
699 }
700
701 fn signature_verification_state_close(
702 &mut self,
703 _mem: &mut GuestMemory<'_>,
704 state: types::SignatureVerificationState,
705 ) -> WResult<()> {
706 Ok(self.ctx.signature_verification_state_close(state.into())?)
707 }
708
709 fn signature_close(
710 &mut self,
711 _mem: &mut GuestMemory<'_>,
712 signature: types::Signature,
713 ) -> WResult<()> {
714 Ok(self.ctx.signature_close(signature.into())?)
715 }
716}
717
718impl generated::wasi_ephemeral_crypto_kx::WasiEphemeralCryptoKx for WasiCryptoCtx {
721 fn kx_dh(
722 &mut self,
723 _mem: &mut GuestMemory<'_>,
724 pk: types::Publickey,
725 sk: types::Secretkey,
726 ) -> WResult<types::ArrayOutput> {
727 Ok(self.ctx.kx_dh(pk.into(), sk.into())?.into())
728 }
729
730 fn kx_encapsulate(
731 &mut self,
732 _mem: &mut GuestMemory<'_>,
733 pk: types::Publickey,
734 ) -> WResult<(types::ArrayOutput, types::ArrayOutput)> {
735 let (secret, encapsulated) = self.ctx.kx_encapsulate(pk.into())?;
736 Ok((secret.into(), encapsulated.into()))
737 }
738
739 fn kx_decapsulate(
740 &mut self,
741 mem: &mut GuestMemory<'_>,
742 sk: types::Secretkey,
743 encapsulated_secret: GuestPtr<u8>,
744 encapsulated_secret_len: types::Size,
745 ) -> WResult<types::ArrayOutput> {
746 let encapsulated = read_bytes(mem, encapsulated_secret, encapsulated_secret_len)?;
747 Ok(self.ctx.kx_decapsulate(sk.into(), &encapsulated)?.into())
748 }
749}
750
751impl generated::wasi_ephemeral_crypto_symmetric::WasiEphemeralCryptoSymmetric for WasiCryptoCtx {
754 fn symmetric_key_generate(
755 &mut self,
756 mem: &mut GuestMemory<'_>,
757 algorithm: GuestPtr<str>,
758 options: &types::OptOptions,
759 ) -> WResult<types::SymmetricKey> {
760 let alg = read_str(mem, algorithm)?;
761 Ok(self
762 .ctx
763 .symmetric_key_generate(&alg, opt_options(options))?
764 .into())
765 }
766
767 fn symmetric_key_import(
768 &mut self,
769 mem: &mut GuestMemory<'_>,
770 algorithm: GuestPtr<str>,
771 raw: GuestPtr<u8>,
772 raw_len: types::Size,
773 ) -> WResult<types::SymmetricKey> {
774 let alg = read_str(mem, algorithm)?;
775 let raw = read_bytes(mem, raw, raw_len)?;
776 Ok(self.ctx.symmetric_key_import(&alg, &raw)?.into())
777 }
778
779 fn symmetric_key_export(
780 &mut self,
781 _mem: &mut GuestMemory<'_>,
782 symmetric_key: types::SymmetricKey,
783 ) -> WResult<types::ArrayOutput> {
784 Ok(self.ctx.symmetric_key_export(symmetric_key.into())?.into())
785 }
786
787 fn symmetric_key_close(
788 &mut self,
789 _mem: &mut GuestMemory<'_>,
790 symmetric_key: types::SymmetricKey,
791 ) -> WResult<()> {
792 Ok(self.ctx.symmetric_key_close(symmetric_key.into())?)
793 }
794
795 fn symmetric_key_generate_managed(
796 &mut self,
797 mem: &mut GuestMemory<'_>,
798 secrets_manager: types::SecretsManager,
799 algorithm: GuestPtr<str>,
800 options: &types::OptOptions,
801 ) -> WResult<types::SymmetricKey> {
802 let alg = read_str(mem, algorithm)?;
803 Ok(self
804 .ctx
805 .symmetric_key_generate_managed(secrets_manager.into(), &alg, opt_options(options))?
806 .into())
807 }
808
809 fn symmetric_key_store_managed(
810 &mut self,
811 mem: &mut GuestMemory<'_>,
812 secrets_manager: types::SecretsManager,
813 symmetric_key: types::SymmetricKey,
814 symmetric_key_id: GuestPtr<u8>,
815 symmetric_key_id_max_len: types::Size,
816 ) -> WResult<()> {
817 let mut tmp = vec![0u8; symmetric_key_id_max_len as usize];
818 self.ctx.symmetric_key_store_managed(
819 secrets_manager.into(),
820 symmetric_key.into(),
821 &mut tmp,
822 )?;
823 write_bytes(mem, symmetric_key_id, symmetric_key_id_max_len, &tmp)?;
824 Ok(())
825 }
826
827 fn symmetric_key_replace_managed(
828 &mut self,
829 _mem: &mut GuestMemory<'_>,
830 secrets_manager: types::SecretsManager,
831 symmetric_key_old: types::SymmetricKey,
832 symmetric_key_new: types::SymmetricKey,
833 ) -> WResult<types::Version> {
834 Ok(self
835 .ctx
836 .symmetric_key_replace_managed(
837 secrets_manager.into(),
838 symmetric_key_old.into(),
839 symmetric_key_new.into(),
840 )?
841 .0)
842 }
843
844 fn symmetric_key_id(
845 &mut self,
846 mem: &mut GuestMemory<'_>,
847 symmetric_key: types::SymmetricKey,
848 symmetric_key_id: GuestPtr<u8>,
849 symmetric_key_id_max_len: types::Size,
850 ) -> WResult<(types::Size, types::Version)> {
851 let (id, version) = self.ctx.symmetric_key_id(symmetric_key.into())?;
852 let n = write_bytes(mem, symmetric_key_id, symmetric_key_id_max_len, &id)?;
853 Ok((n, version.0))
854 }
855
856 fn symmetric_key_from_id(
857 &mut self,
858 mem: &mut GuestMemory<'_>,
859 secrets_manager: types::SecretsManager,
860 symmetric_key_id: GuestPtr<u8>,
861 symmetric_key_id_len: types::Size,
862 symmetric_key_version: types::Version,
863 ) -> WResult<types::SymmetricKey> {
864 let id = read_bytes(mem, symmetric_key_id, symmetric_key_id_len)?;
865 Ok(self
866 .ctx
867 .symmetric_key_from_id(secrets_manager.into(), &id, Version(symmetric_key_version))?
868 .into())
869 }
870
871 fn symmetric_state_open(
872 &mut self,
873 mem: &mut GuestMemory<'_>,
874 algorithm: GuestPtr<str>,
875 key: &types::OptSymmetricKey,
876 options: &types::OptOptions,
877 ) -> WResult<types::SymmetricState> {
878 let alg = read_str(mem, algorithm)?;
879 Ok(self
880 .ctx
881 .symmetric_state_open(&alg, opt_symmetric_key(key), opt_options(options))?
882 .into())
883 }
884
885 fn symmetric_state_options_get(
886 &mut self,
887 mem: &mut GuestMemory<'_>,
888 handle: types::SymmetricState,
889 name: GuestPtr<str>,
890 value: GuestPtr<u8>,
891 value_max_len: types::Size,
892 ) -> WResult<types::Size> {
893 let name = read_str(mem, name)?;
894 fill_out_buf(mem, value, value_max_len, |out| {
895 self.ctx
896 .symmetric_state_options_get(handle.into(), &name, out)
897 })
898 }
899
900 fn symmetric_state_options_get_u64(
901 &mut self,
902 mem: &mut GuestMemory<'_>,
903 handle: types::SymmetricState,
904 name: GuestPtr<str>,
905 ) -> WResult<u64> {
906 let name = read_str(mem, name)?;
907 Ok(self
908 .ctx
909 .symmetric_state_options_get_u64(handle.into(), &name)?)
910 }
911
912 fn symmetric_state_clone(
913 &mut self,
914 _mem: &mut GuestMemory<'_>,
915 handle: types::SymmetricState,
916 ) -> WResult<types::SymmetricState> {
917 Ok(self.ctx.symmetric_state_clone(handle.into())?.into())
918 }
919
920 fn symmetric_state_close(
921 &mut self,
922 _mem: &mut GuestMemory<'_>,
923 handle: types::SymmetricState,
924 ) -> WResult<()> {
925 Ok(self.ctx.symmetric_state_close(handle.into())?)
926 }
927
928 fn symmetric_state_absorb(
929 &mut self,
930 mem: &mut GuestMemory<'_>,
931 handle: types::SymmetricState,
932 data: GuestPtr<u8>,
933 data_len: types::Size,
934 ) -> WResult<()> {
935 let data = read_bytes(mem, data, data_len)?;
936 Ok(self.ctx.symmetric_state_absorb(handle.into(), &data)?)
937 }
938
939 fn symmetric_state_squeeze(
940 &mut self,
941 mem: &mut GuestMemory<'_>,
942 handle: types::SymmetricState,
943 out: GuestPtr<u8>,
944 out_len: types::Size,
945 ) -> WResult<()> {
946 let mut tmp = vec![0u8; out_len as usize];
947 self.ctx.symmetric_state_squeeze(handle.into(), &mut tmp)?;
948 write_bytes(mem, out, out_len, &tmp)?;
949 Ok(())
950 }
951
952 fn symmetric_state_squeeze_tag(
953 &mut self,
954 _mem: &mut GuestMemory<'_>,
955 handle: types::SymmetricState,
956 ) -> WResult<types::SymmetricTag> {
957 Ok(self.ctx.symmetric_state_squeeze_tag(handle.into())?.into())
958 }
959
960 fn symmetric_state_squeeze_key(
961 &mut self,
962 mem: &mut GuestMemory<'_>,
963 handle: types::SymmetricState,
964 alg_str: GuestPtr<str>,
965 ) -> WResult<types::SymmetricKey> {
966 let alg = read_str(mem, alg_str)?;
967 Ok(self
968 .ctx
969 .symmetric_state_squeeze_key(handle.into(), &alg)?
970 .into())
971 }
972
973 fn symmetric_state_max_tag_len(
974 &mut self,
975 _mem: &mut GuestMemory<'_>,
976 handle: types::SymmetricState,
977 ) -> WResult<types::Size> {
978 Ok(self.ctx.symmetric_state_max_tag_len(handle.into())? as types::Size)
979 }
980
981 fn symmetric_state_encrypt(
982 &mut self,
983 mem: &mut GuestMemory<'_>,
984 handle: types::SymmetricState,
985 out: GuestPtr<u8>,
986 out_len: types::Size,
987 data: GuestPtr<u8>,
988 data_len: types::Size,
989 ) -> WResult<types::Size> {
990 let data = read_bytes(mem, data, data_len)?;
991 fill_out_buf(mem, out, out_len, |buf| {
992 self.ctx.symmetric_state_encrypt(handle.into(), buf, &data)
993 })
994 }
995
996 fn symmetric_state_encrypt_detached(
997 &mut self,
998 mem: &mut GuestMemory<'_>,
999 handle: types::SymmetricState,
1000 out: GuestPtr<u8>,
1001 out_len: types::Size,
1002 data: GuestPtr<u8>,
1003 data_len: types::Size,
1004 ) -> WResult<types::SymmetricTag> {
1005 let data = read_bytes(mem, data, data_len)?;
1006 let mut tmp = vec![0u8; out_len as usize];
1007 let tag = self
1008 .ctx
1009 .symmetric_state_encrypt_detached(handle.into(), &mut tmp, &data)?;
1010 write_bytes(mem, out, out_len, &tmp)?;
1011 Ok(tag.into())
1012 }
1013
1014 fn symmetric_state_decrypt(
1015 &mut self,
1016 mem: &mut GuestMemory<'_>,
1017 handle: types::SymmetricState,
1018 out: GuestPtr<u8>,
1019 out_len: types::Size,
1020 data: GuestPtr<u8>,
1021 data_len: types::Size,
1022 ) -> WResult<types::Size> {
1023 let data = read_bytes(mem, data, data_len)?;
1024 fill_out_buf(mem, out, out_len, |buf| {
1025 self.ctx.symmetric_state_decrypt(handle.into(), buf, &data)
1026 })
1027 }
1028
1029 fn symmetric_state_decrypt_detached(
1030 &mut self,
1031 mem: &mut GuestMemory<'_>,
1032 handle: types::SymmetricState,
1033 out: GuestPtr<u8>,
1034 out_len: types::Size,
1035 data: GuestPtr<u8>,
1036 data_len: types::Size,
1037 raw_tag: GuestPtr<u8>,
1038 raw_tag_len: types::Size,
1039 ) -> WResult<types::Size> {
1040 let data = read_bytes(mem, data, data_len)?;
1041 let raw_tag = read_bytes(mem, raw_tag, raw_tag_len)?;
1042 fill_out_buf(mem, out, out_len, |buf| {
1043 self.ctx
1044 .symmetric_state_decrypt_detached(handle.into(), buf, &data, &raw_tag)
1045 })
1046 }
1047
1048 fn symmetric_state_ratchet(
1049 &mut self,
1050 _mem: &mut GuestMemory<'_>,
1051 handle: types::SymmetricState,
1052 ) -> WResult<()> {
1053 Ok(self.ctx.symmetric_state_ratchet(handle.into())?)
1054 }
1055
1056 fn symmetric_tag_len(
1057 &mut self,
1058 _mem: &mut GuestMemory<'_>,
1059 symmetric_tag: types::SymmetricTag,
1060 ) -> WResult<types::Size> {
1061 Ok(self.ctx.symmetric_tag_len(symmetric_tag.into())? as types::Size)
1062 }
1063
1064 fn symmetric_tag_pull(
1065 &mut self,
1066 mem: &mut GuestMemory<'_>,
1067 symmetric_tag: types::SymmetricTag,
1068 buf: GuestPtr<u8>,
1069 buf_len: types::Size,
1070 ) -> WResult<types::Size> {
1071 fill_out_buf(mem, buf, buf_len, |out| {
1072 self.ctx.symmetric_tag_pull(symmetric_tag.into(), out)
1073 })
1074 }
1075
1076 fn symmetric_tag_verify(
1077 &mut self,
1078 mem: &mut GuestMemory<'_>,
1079 symmetric_tag: types::SymmetricTag,
1080 expected_raw_tag_ptr: GuestPtr<u8>,
1081 expected_raw_tag_len: types::Size,
1082 ) -> WResult<()> {
1083 let expected = read_bytes(mem, expected_raw_tag_ptr, expected_raw_tag_len)?;
1084 Ok(self
1085 .ctx
1086 .symmetric_tag_verify(symmetric_tag.into(), &expected)?)
1087 }
1088
1089 fn symmetric_tag_close(
1090 &mut self,
1091 _mem: &mut GuestMemory<'_>,
1092 symmetric_tag: types::SymmetricTag,
1093 ) -> WResult<()> {
1094 Ok(self.ctx.symmetric_tag_close(symmetric_tag.into())?)
1095 }
1096}