crypto_wasi/
raw.rs

1#![allow(dead_code, unused_variables)]
2use core::fmt;
3use core::mem::MaybeUninit;
4#[repr(transparent)]
5#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
6pub struct CryptoErrno(u16);
7/// Operation succeeded.
8pub const CRYPTO_ERRNO_SUCCESS: CryptoErrno = CryptoErrno(0);
9/// An error occurred when trying to during a conversion from a host type to a
10/// guest type.
11///
12/// Only an internal bug can throw this error.
13pub const CRYPTO_ERRNO_GUEST_ERROR: CryptoErrno = CryptoErrno(1);
14/// The requested operation is valid, but not implemented by the host.
15pub const CRYPTO_ERRNO_NOT_IMPLEMENTED: CryptoErrno = CryptoErrno(2);
16/// The requested feature is not supported by the chosen algorithm.
17pub const CRYPTO_ERRNO_UNSUPPORTED_FEATURE: CryptoErrno = CryptoErrno(3);
18/// The requested operation is valid, but was administratively prohibited.
19pub const CRYPTO_ERRNO_PROHIBITED_OPERATION: CryptoErrno = CryptoErrno(4);
20/// Unsupported encoding for an import or export operation.
21pub const CRYPTO_ERRNO_UNSUPPORTED_ENCODING: CryptoErrno = CryptoErrno(5);
22/// The requested algorithm is not supported by the host.
23pub const CRYPTO_ERRNO_UNSUPPORTED_ALGORITHM: CryptoErrno = CryptoErrno(6);
24/// The requested option is not supported by the currently selected algorithm.
25pub const CRYPTO_ERRNO_UNSUPPORTED_OPTION: CryptoErrno = CryptoErrno(7);
26/// An invalid or incompatible key was supplied.
27///
28/// The key may not be valid, or was generated for a different algorithm or
29/// parameters set.
30pub const CRYPTO_ERRNO_INVALID_KEY: CryptoErrno = CryptoErrno(8);
31/// The currently selected algorithm doesn't support the requested output
32/// length.
33///
34/// This error is thrown by non-extensible hash functions, when requesting an
35/// output size larger than they produce out of a single block.
36pub const CRYPTO_ERRNO_INVALID_LENGTH: CryptoErrno = CryptoErrno(9);
37/// A signature or authentication tag verification failed.
38pub const CRYPTO_ERRNO_VERIFICATION_FAILED: CryptoErrno = CryptoErrno(10);
39/// A secure random numbers generator is not available.
40///
41/// The requested operation requires random numbers, but the host cannot
42/// securely generate them at the moment.
43pub const CRYPTO_ERRNO_RNG_ERROR: CryptoErrno = CryptoErrno(11);
44/// An error was returned by the underlying cryptography library.
45///
46/// The host may be running out of memory, parameters may be incompatible with
47/// the chosen implementation of an algorithm or another unexpected error may
48/// have happened.
49///
50/// Ideally, the specification should provide enough details and guidance to
51/// make this error impossible to ever be thrown.
52///
53/// Realistically, the WASI crypto module cannot possibly cover all possible
54/// error types implementations can return, especially since some of these may
55/// be language-specific. This error can thus be thrown when other error types
56/// are not suitable, and when the original error comes from the cryptographic
57/// primitives themselves and not from the WASI module.
58pub const CRYPTO_ERRNO_ALGORITHM_FAILURE: CryptoErrno = CryptoErrno(12);
59/// The supplied signature is invalid, or incompatible with the chosen
60/// algorithm.
61pub const CRYPTO_ERRNO_INVALID_SIGNATURE: CryptoErrno = CryptoErrno(13);
62/// An attempt was made to close a handle that was already closed.
63pub const CRYPTO_ERRNO_CLOSED: CryptoErrno = CryptoErrno(14);
64/// A function was called with an unassigned handle, a closed handle, or handle
65/// of an unexpected type.
66pub const CRYPTO_ERRNO_INVALID_HANDLE: CryptoErrno = CryptoErrno(15);
67/// The host needs to copy data to a guest-allocated buffer, but that buffer is
68/// too small.
69pub const CRYPTO_ERRNO_OVERFLOW: CryptoErrno = CryptoErrno(16);
70/// An internal error occurred.
71///
72/// This error is reserved to internal consistency checks, and must only be sent
73/// if the internal state of the host remains safe after an inconsistency was
74/// detected.
75pub const CRYPTO_ERRNO_INTERNAL_ERROR: CryptoErrno = CryptoErrno(17);
76/// Too many handles are currently open, and a new one cannot be created.
77///
78/// Implementations are free to represent handles as they want, and to enforce
79/// limits to limit resources usage.
80pub const CRYPTO_ERRNO_TOO_MANY_HANDLES: CryptoErrno = CryptoErrno(18);
81/// A key was provided, but the chosen algorithm doesn't support keys.
82///
83/// This is returned by symmetric operations.
84///
85/// Many hash functions, in particular, do not support keys without being used
86/// in particular constructions. Blindly ignoring a key provided by mistake
87/// while trying to open a context for such as function could cause serious
88/// security vulnerabilities.
89///
90/// These functions must refuse to create the context and return this error
91/// instead.
92pub const CRYPTO_ERRNO_KEY_NOT_SUPPORTED: CryptoErrno = CryptoErrno(19);
93/// A key is required for the chosen algorithm, but none was given.
94pub const CRYPTO_ERRNO_KEY_REQUIRED: CryptoErrno = CryptoErrno(20);
95/// The provided authentication tag is invalid or incompatible with the current
96/// algorithm.
97///
98/// This error is returned by decryption functions and tag verification
99/// functions.
100///
101/// Unlike `verification_failed`, this error code is returned when the tag
102/// cannot possibly verify for any input.
103pub const CRYPTO_ERRNO_INVALID_TAG: CryptoErrno = CryptoErrno(21);
104/// The requested operation is incompatible with the current scheme.
105///
106/// For example, the `symmetric_state_encrypt()` function cannot complete if the
107/// selected construction is a key derivation function. This error code will be
108/// returned instead.
109pub const CRYPTO_ERRNO_INVALID_OPERATION: CryptoErrno = CryptoErrno(22);
110/// A nonce is required.
111///
112/// Most encryption schemes require a nonce.
113///
114/// In the absence of a nonce, the WASI cryptography module can automatically
115/// generate one, if that can be done safely. The nonce can be retrieved later
116/// with the `symmetric_state_option_get()` function using the `nonce`
117/// parameter. If automatically generating a nonce cannot be done safely, the
118/// module never falls back to an insecure option and requests an explicit nonce
119/// by throwing that error.
120pub const CRYPTO_ERRNO_NONCE_REQUIRED: CryptoErrno = CryptoErrno(23);
121/// The provided nonce doesn't have a correct size for the given cipher.
122pub const CRYPTO_ERRNO_INVALID_NONCE: CryptoErrno = CryptoErrno(24);
123/// The named option was not set.
124///
125/// The caller tried to read the value of an option that was not set.
126/// This error is used to make the distinction between an empty option, and an
127/// option that was not set and left to its default value.
128pub const CRYPTO_ERRNO_OPTION_NOT_SET: CryptoErrno = CryptoErrno(25);
129/// A key or key pair matching the requested identifier cannot be found using
130/// the supplied information.
131///
132/// This error is returned by a secrets manager via the `keypair_from_id()`
133/// function.
134pub const CRYPTO_ERRNO_NOT_FOUND: CryptoErrno = CryptoErrno(26);
135/// The algorithm requires parameters that haven't been set.
136///
137/// Non-generic options are required and must be given by building an `options`
138/// set and giving that object to functions instantiating that algorithm.
139pub const CRYPTO_ERRNO_PARAMETERS_MISSING: CryptoErrno = CryptoErrno(27);
140/// A requested computation is not done yet, and additional calls to the
141/// function are required.
142///
143/// Some functions, such as functions generating key pairs and password
144/// stretching functions, can take a long time to complete.
145///
146/// In order to avoid a host call to be blocked for too long, these functions
147/// can return prematurely, requiring additional calls with the same parameters
148/// until they complete.
149pub const CRYPTO_ERRNO_IN_PROGRESS: CryptoErrno = CryptoErrno(28);
150/// Multiple keys have been provided, but they do not share the same type.
151///
152/// This error is returned when trying to build a key pair from a public key and
153/// a secret key that were created for different and incompatible algorithms.
154pub const CRYPTO_ERRNO_INCOMPATIBLE_KEYS: CryptoErrno = CryptoErrno(29);
155/// A managed key or secret expired and cannot be used any more.
156pub const CRYPTO_ERRNO_EXPIRED: CryptoErrno = CryptoErrno(30);
157impl CryptoErrno {
158    pub const fn raw(&self) -> u16 {
159        self.0
160    }
161
162    pub fn name(&self) -> &'static str {
163        match self.0 {
164            0 => "SUCCESS",
165            1 => "GUEST_ERROR",
166            2 => "NOT_IMPLEMENTED",
167            3 => "UNSUPPORTED_FEATURE",
168            4 => "PROHIBITED_OPERATION",
169            5 => "UNSUPPORTED_ENCODING",
170            6 => "UNSUPPORTED_ALGORITHM",
171            7 => "UNSUPPORTED_OPTION",
172            8 => "INVALID_KEY",
173            9 => "INVALID_LENGTH",
174            10 => "VERIFICATION_FAILED",
175            11 => "RNG_ERROR",
176            12 => "ALGORITHM_FAILURE",
177            13 => "INVALID_SIGNATURE",
178            14 => "CLOSED",
179            15 => "INVALID_HANDLE",
180            16 => "OVERFLOW",
181            17 => "INTERNAL_ERROR",
182            18 => "TOO_MANY_HANDLES",
183            19 => "KEY_NOT_SUPPORTED",
184            20 => "KEY_REQUIRED",
185            21 => "INVALID_TAG",
186            22 => "INVALID_OPERATION",
187            23 => "NONCE_REQUIRED",
188            24 => "INVALID_NONCE",
189            25 => "OPTION_NOT_SET",
190            26 => "NOT_FOUND",
191            27 => "PARAMETERS_MISSING",
192            28 => "IN_PROGRESS",
193            29 => "INCOMPATIBLE_KEYS",
194            30 => "EXPIRED",
195            _ => unsafe { core::hint::unreachable_unchecked() },
196        }
197    }
198
199    pub fn message(&self) -> &'static str {
200        match self.0 {
201            0 => "Operation succeeded.",
202            1 => {
203                "An error occurred when trying to during a conversion from a host type to a guest \
204                 type.
205
206Only an internal bug can throw this error."
207            }
208            2 => "The requested operation is valid, but not implemented by the host.",
209            3 => "The requested feature is not supported by the chosen algorithm.",
210            4 => "The requested operation is valid, but was administratively prohibited.",
211            5 => "Unsupported encoding for an import or export operation.",
212            6 => "The requested algorithm is not supported by the host.",
213            7 => "The requested option is not supported by the currently selected algorithm.",
214            8 => {
215                "An invalid or incompatible key was supplied.
216
217The key may not be valid, or was generated for a different algorithm or parameters set."
218            }
219            9 => {
220                "The currently selected algorithm doesn't support the requested output length.
221
222This error is thrown by non-extensible hash functions, when requesting an output size larger than \
223                 they produce out of a single block."
224            }
225            10 => "A signature or authentication tag verification failed.",
226            11 => {
227                "A secure random numbers generator is not available.
228
229The requested operation requires random numbers, but the host cannot securely generate them at the \
230                 moment."
231            }
232            12 => {
233                "An error was returned by the underlying cryptography library.
234
235The host may be running out of memory, parameters may be incompatible with the chosen \
236                 implementation of an algorithm or another unexpected error may have happened.
237
238Ideally, the specification should provide enough details and guidance to make this error \
239                 impossible to ever be thrown.
240
241Realistically, the WASI crypto module cannot possibly cover all possible error types \
242                 implementations can return, especially since some of these may be \
243                 language-specific.
244This error can thus be thrown when other error types are not suitable, and when the original error \
245                 comes from the cryptographic primitives themselves and not from the WASI module."
246            }
247            13 => "The supplied signature is invalid, or incompatible with the chosen algorithm.",
248            14 => "An attempt was made to close a handle that was already closed.",
249            15 => {
250                "A function was called with an unassigned handle, a closed handle, or handle of an \
251                 unexpected type."
252            }
253            16 => {
254                "The host needs to copy data to a guest-allocated buffer, but that buffer is too \
255                 small."
256            }
257            17 => {
258                "An internal error occurred.
259
260This error is reserved to internal consistency checks, and must only be sent if the internal state \
261                 of the host remains safe after an inconsistency was detected."
262            }
263            18 => {
264                "Too many handles are currently open, and a new one cannot be created.
265
266Implementations are free to represent handles as they want, and to enforce limits to limit \
267                 resources usage."
268            }
269            19 => {
270                "A key was provided, but the chosen algorithm doesn't support keys.
271
272This is returned by symmetric operations.
273
274Many hash functions, in particular, do not support keys without being used in particular \
275                 constructions.
276Blindly ignoring a key provided by mistake while trying to open a context for such as function \
277                 could cause serious security vulnerabilities.
278
279These functions must refuse to create the context and return this error instead."
280            }
281            20 => "A key is required for the chosen algorithm, but none was given.",
282            21 => {
283                "The provided authentication tag is invalid or incompatible with the current \
284                 algorithm.
285
286This error is returned by decryption functions and tag verification functions.
287
288Unlike `verification_failed`, this error code is returned when the tag cannot possibly verify for \
289                 any input."
290            }
291            22 => {
292                "The requested operation is incompatible with the current scheme.
293
294For example, the `symmetric_state_encrypt()` function cannot complete if the selected construction \
295                 is a key derivation function.
296This error code will be returned instead."
297            }
298            23 => {
299                "A nonce is required.
300
301Most encryption schemes require a nonce.
302
303In the absence of a nonce, the WASI cryptography module can automatically generate one, if that \
304                 can be done safely. The nonce can be retrieved later with the \
305                 `symmetric_state_option_get()` function using the `nonce` parameter.
306If automatically generating a nonce cannot be done safely, the module never falls back to an \
307                 insecure option and requests an explicit nonce by throwing that error."
308            }
309            24 => "The provided nonce doesn't have a correct size for the given cipher.",
310            25 => {
311                "The named option was not set.
312
313The caller tried to read the value of an option that was not set.
314This error is used to make the distinction between an empty option, and an option that was not set \
315                 and left to its default value."
316            }
317            26 => {
318                "A key or key pair matching the requested identifier cannot be found using the \
319                 supplied information.
320
321This error is returned by a secrets manager via the `keypair_from_id()` function."
322            }
323            27 => {
324                "The algorithm requires parameters that haven't been set.
325
326Non-generic options are required and must be given by building an `options` set and giving that \
327                 object to functions instantiating that algorithm."
328            }
329            28 => {
330                "A requested computation is not done yet, and additional calls to the function are \
331                 required.
332
333Some functions, such as functions generating key pairs and password stretching functions, can take \
334                 a long time to complete.
335
336In order to avoid a host call to be blocked for too long, these functions can return prematurely, \
337                 requiring additional calls with the same parameters until they complete."
338            }
339            29 => {
340                "Multiple keys have been provided, but they do not share the same type.
341
342This error is returned when trying to build a key pair from a public key and a secret key that \
343                 were created for different and incompatible algorithms."
344            }
345            30 => "A managed key or secret expired and cannot be used any more.",
346            _ => unsafe { core::hint::unreachable_unchecked() },
347        }
348    }
349}
350impl fmt::Debug for CryptoErrno {
351    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352        f.debug_struct("CryptoErrno")
353            .field("code", &self.0)
354            .field("name", &self.name())
355            .field("message", &self.message())
356            .finish()
357    }
358}
359impl fmt::Display for CryptoErrno {
360    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361        write!(f, "{} (error {})", self.name(), self.0)
362    }
363}
364
365#[cfg(feature = "std")]
366extern crate std;
367#[cfg(feature = "std")]
368impl std::error::Error for CryptoErrno {}
369
370#[repr(transparent)]
371#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
372pub struct KeypairEncoding(u16);
373/// Raw bytes.
374pub const KEYPAIR_ENCODING_RAW: KeypairEncoding = KeypairEncoding(0);
375/// PCSK8/DER encoding.
376pub const KEYPAIR_ENCODING_PKCS8: KeypairEncoding = KeypairEncoding(1);
377/// PEM encoding.
378pub const KEYPAIR_ENCODING_PEM: KeypairEncoding = KeypairEncoding(2);
379/// Implementation-defined encoding.
380pub const KEYPAIR_ENCODING_LOCAL: KeypairEncoding = KeypairEncoding(3);
381impl KeypairEncoding {
382    pub const fn raw(&self) -> u16 {
383        self.0
384    }
385
386    pub fn name(&self) -> &'static str {
387        match self.0 {
388            0 => "RAW",
389            1 => "PKCS8",
390            2 => "PEM",
391            3 => "LOCAL",
392            _ => unsafe { core::hint::unreachable_unchecked() },
393        }
394    }
395
396    pub fn message(&self) -> &'static str {
397        match self.0 {
398            0 => "Raw bytes.",
399            1 => "PCSK8/DER encoding.",
400            2 => "PEM encoding.",
401            3 => "Implementation-defined encoding.",
402            _ => unsafe { core::hint::unreachable_unchecked() },
403        }
404    }
405}
406impl fmt::Debug for KeypairEncoding {
407    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
408        f.debug_struct("KeypairEncoding")
409            .field("code", &self.0)
410            .field("name", &self.name())
411            .field("message", &self.message())
412            .finish()
413    }
414}
415
416#[repr(transparent)]
417#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
418pub struct PublickeyEncoding(u16);
419/// Raw bytes.
420pub const PUBLICKEY_ENCODING_RAW: PublickeyEncoding = PublickeyEncoding(0);
421/// PKCS8/DER encoding.
422pub const PUBLICKEY_ENCODING_PKCS8: PublickeyEncoding = PublickeyEncoding(1);
423/// PEM encoding.
424pub const PUBLICKEY_ENCODING_PEM: PublickeyEncoding = PublickeyEncoding(2);
425/// SEC-1 encoding.
426pub const PUBLICKEY_ENCODING_SEC: PublickeyEncoding = PublickeyEncoding(3);
427/// Implementation-defined encoding.
428pub const PUBLICKEY_ENCODING_LOCAL: PublickeyEncoding = PublickeyEncoding(4);
429impl PublickeyEncoding {
430    pub const fn raw(&self) -> u16 {
431        self.0
432    }
433
434    pub fn name(&self) -> &'static str {
435        match self.0 {
436            0 => "RAW",
437            1 => "PKCS8",
438            2 => "PEM",
439            3 => "SEC",
440            4 => "LOCAL",
441            _ => unsafe { core::hint::unreachable_unchecked() },
442        }
443    }
444
445    pub fn message(&self) -> &'static str {
446        match self.0 {
447            0 => "Raw bytes.",
448            1 => "PKCS8/DER encoding.",
449            2 => "PEM encoding.",
450            3 => "SEC-1 encoding.",
451            4 => "Implementation-defined encoding.",
452            _ => unsafe { core::hint::unreachable_unchecked() },
453        }
454    }
455}
456impl fmt::Debug for PublickeyEncoding {
457    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458        f.debug_struct("PublickeyEncoding")
459            .field("code", &self.0)
460            .field("name", &self.name())
461            .field("message", &self.message())
462            .finish()
463    }
464}
465
466#[repr(transparent)]
467#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
468pub struct SecretkeyEncoding(u16);
469/// Raw bytes.
470pub const SECRETKEY_ENCODING_RAW: SecretkeyEncoding = SecretkeyEncoding(0);
471/// PKCS8/DER encoding.
472pub const SECRETKEY_ENCODING_PKCS8: SecretkeyEncoding = SecretkeyEncoding(1);
473/// PEM encoding.
474pub const SECRETKEY_ENCODING_PEM: SecretkeyEncoding = SecretkeyEncoding(2);
475/// SEC-1 encoding.
476pub const SECRETKEY_ENCODING_SEC: SecretkeyEncoding = SecretkeyEncoding(3);
477/// Implementation-defined encoding.
478pub const SECRETKEY_ENCODING_LOCAL: SecretkeyEncoding = SecretkeyEncoding(4);
479impl SecretkeyEncoding {
480    pub const fn raw(&self) -> u16 {
481        self.0
482    }
483
484    pub fn name(&self) -> &'static str {
485        match self.0 {
486            0 => "RAW",
487            1 => "PKCS8",
488            2 => "PEM",
489            3 => "SEC",
490            4 => "LOCAL",
491            _ => unsafe { core::hint::unreachable_unchecked() },
492        }
493    }
494
495    pub fn message(&self) -> &'static str {
496        match self.0 {
497            0 => "Raw bytes.",
498            1 => "PKCS8/DER encoding.",
499            2 => "PEM encoding.",
500            3 => "SEC-1 encoding.",
501            4 => "Implementation-defined encoding.",
502            _ => unsafe { core::hint::unreachable_unchecked() },
503        }
504    }
505}
506impl fmt::Debug for SecretkeyEncoding {
507    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
508        f.debug_struct("SecretkeyEncoding")
509            .field("code", &self.0)
510            .field("name", &self.name())
511            .field("message", &self.message())
512            .finish()
513    }
514}
515
516#[repr(transparent)]
517#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
518pub struct SignatureEncoding(u16);
519/// Raw bytes.
520pub const SIGNATURE_ENCODING_RAW: SignatureEncoding = SignatureEncoding(0);
521/// DER encoding.
522pub const SIGNATURE_ENCODING_DER: SignatureEncoding = SignatureEncoding(1);
523impl SignatureEncoding {
524    pub const fn raw(&self) -> u16 {
525        self.0
526    }
527
528    pub fn name(&self) -> &'static str {
529        match self.0 {
530            0 => "RAW",
531            1 => "DER",
532            _ => unsafe { core::hint::unreachable_unchecked() },
533        }
534    }
535
536    pub fn message(&self) -> &'static str {
537        match self.0 {
538            0 => "Raw bytes.",
539            1 => "DER encoding.",
540            _ => unsafe { core::hint::unreachable_unchecked() },
541        }
542    }
543}
544impl fmt::Debug for SignatureEncoding {
545    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
546        f.debug_struct("SignatureEncoding")
547            .field("code", &self.0)
548            .field("name", &self.name())
549            .field("message", &self.message())
550            .finish()
551    }
552}
553
554#[repr(transparent)]
555#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
556pub struct AlgorithmType(u16);
557pub const ALGORITHM_TYPE_SIGNATURES: AlgorithmType = AlgorithmType(0);
558pub const ALGORITHM_TYPE_SYMMETRIC: AlgorithmType = AlgorithmType(1);
559pub const ALGORITHM_TYPE_KEY_EXCHANGE: AlgorithmType = AlgorithmType(2);
560impl AlgorithmType {
561    pub const fn raw(&self) -> u16 {
562        self.0
563    }
564
565    pub fn name(&self) -> &'static str {
566        match self.0 {
567            0 => "SIGNATURES",
568            1 => "SYMMETRIC",
569            2 => "KEY_EXCHANGE",
570            _ => unsafe { core::hint::unreachable_unchecked() },
571        }
572    }
573
574    pub fn message(&self) -> &'static str {
575        match self.0 {
576            0 => "",
577            1 => "",
578            2 => "",
579            _ => unsafe { core::hint::unreachable_unchecked() },
580        }
581    }
582}
583impl fmt::Debug for AlgorithmType {
584    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
585        f.debug_struct("AlgorithmType")
586            .field("code", &self.0)
587            .field("name", &self.name())
588            .field("message", &self.message())
589            .finish()
590    }
591}
592
593pub type Version = u64;
594pub type Size = usize;
595pub type Timestamp = u64;
596pub type ArrayOutput = u32;
597pub type Options = u32;
598pub type SecretsManager = u32;
599pub type Keypair = u32;
600pub type SignatureState = u32;
601pub type Signature = u32;
602pub type Publickey = u32;
603pub type Secretkey = u32;
604pub type SignatureVerificationState = u32;
605pub type SymmetricState = u32;
606pub type SymmetricKey = u32;
607pub type SymmetricTag = u32;
608#[repr(transparent)]
609#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
610pub struct OptOptionsU(u8);
611pub const OPT_OPTIONS_U_SOME: OptOptionsU = OptOptionsU(0);
612pub const OPT_OPTIONS_U_NONE: OptOptionsU = OptOptionsU(1);
613impl OptOptionsU {
614    pub const fn raw(&self) -> u8 {
615        self.0
616    }
617
618    pub fn name(&self) -> &'static str {
619        match self.0 {
620            0 => "SOME",
621            1 => "NONE",
622            _ => unsafe { core::hint::unreachable_unchecked() },
623        }
624    }
625
626    pub fn message(&self) -> &'static str {
627        match self.0 {
628            0 => "",
629            1 => "",
630            _ => unsafe { core::hint::unreachable_unchecked() },
631        }
632    }
633}
634impl fmt::Debug for OptOptionsU {
635    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
636        f.debug_struct("OptOptionsU")
637            .field("code", &self.0)
638            .field("name", &self.name())
639            .field("message", &self.message())
640            .finish()
641    }
642}
643
644#[repr(C)]
645#[derive(Copy, Clone)]
646pub union OptOptionsUnion {
647    pub none: (),
648    pub some: Options,
649}
650#[repr(C)]
651#[derive(Copy, Clone)]
652pub struct OptOptions {
653    pub tag: u8,
654    pub u: OptOptionsUnion,
655}
656
657#[repr(transparent)]
658#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
659pub struct OptSymmetricKeyU(u8);
660pub const OPT_SYMMETRIC_KEY_U_SOME: OptSymmetricKeyU = OptSymmetricKeyU(0);
661pub const OPT_SYMMETRIC_KEY_U_NONE: OptSymmetricKeyU = OptSymmetricKeyU(1);
662impl OptSymmetricKeyU {
663    pub const fn raw(&self) -> u8 {
664        self.0
665    }
666
667    pub fn name(&self) -> &'static str {
668        match self.0 {
669            0 => "SOME",
670            1 => "NONE",
671            _ => unsafe { core::hint::unreachable_unchecked() },
672        }
673    }
674
675    pub fn message(&self) -> &'static str {
676        match self.0 {
677            0 => "",
678            1 => "",
679            _ => unsafe { core::hint::unreachable_unchecked() },
680        }
681    }
682}
683impl fmt::Debug for OptSymmetricKeyU {
684    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
685        f.debug_struct("OptSymmetricKeyU")
686            .field("code", &self.0)
687            .field("name", &self.name())
688            .field("message", &self.message())
689            .finish()
690    }
691}
692
693#[repr(C)]
694#[derive(Copy, Clone)]
695pub union OptSymmetricKeyUnion {
696    pub none: (),
697    pub some: SymmetricKey,
698}
699#[repr(C)]
700#[derive(Copy, Clone)]
701pub struct OptSymmetricKey {
702    pub tag: u8,
703    pub u: OptSymmetricKeyUnion,
704}
705
706pub type U64 = u64;
707pub type SignatureKeypair = Keypair;
708pub type SignaturePublickey = Publickey;
709pub type SignatureSecretkey = Secretkey;
710pub type KxKeypair = Keypair;
711pub type KxPublickey = Publickey;
712pub type KxSecretkey = Secretkey;
713/// Create a new object to set non-default options.
714///
715/// Example usage:
716///
717/// ```rust
718/// let options_handle = options_open(AlgorithmType::Symmetric)?;
719/// options_set(options_handle, "context", context)?;
720/// options_set_u64(options_handle, "threads", 4)?;
721/// let state = symmetric_state_open("BLAKE3", None, Some(options_handle))?;
722/// options_close(options_handle)?;
723/// ```
724pub unsafe fn options_open(algorithm_type: AlgorithmType) -> Result<Options, CryptoErrno> {
725    let mut rp0 = MaybeUninit::<Options>::uninit();
726    let ret = wasi_ephemeral_crypto_common::options_open(
727        algorithm_type.0 as i32,
728        rp0.as_mut_ptr() as i32,
729    );
730    match ret {
731        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Options)),
732        _ => Err(CryptoErrno(ret as u16)),
733    }
734}
735
736/// Destroy an options object.
737///
738/// Objects are reference counted. It is safe to close an object immediately
739/// after the last function needing it is called.
740pub unsafe fn options_close(handle: Options) -> Result<(), CryptoErrno> {
741    let ret = wasi_ephemeral_crypto_common::options_close(handle as i32);
742    match ret {
743        0 => Ok(()),
744        _ => Err(CryptoErrno(ret as u16)),
745    }
746}
747
748/// Set or update an option.
749///
750/// This is used to set algorithm-specific parameters, but also to provide
751/// credentials for the secrets management facilities, if required.
752///
753/// This function may return `unsupported_option` if an option that doesn't
754/// exist for any implemented algorithms is specified.
755pub unsafe fn options_set(
756    handle: Options,
757    name: &str,
758    value: *const u8,
759    value_len: Size,
760) -> Result<(), CryptoErrno> {
761    let ret = wasi_ephemeral_crypto_common::options_set(
762        handle as i32,
763        name.as_ptr() as i32,
764        name.len() as i32,
765        value as i32,
766        value_len as i32,
767    );
768    match ret {
769        0 => Ok(()),
770        _ => Err(CryptoErrno(ret as u16)),
771    }
772}
773
774/// Set or update an integer option.
775///
776/// This is used to set algorithm-specific parameters.
777///
778/// This function may return `unsupported_option` if an option that doesn't
779/// exist for any implemented algorithms is specified.
780pub unsafe fn options_set_u64(handle: Options, name: &str, value: u64) -> Result<(), CryptoErrno> {
781    let ret = wasi_ephemeral_crypto_common::options_set_u64(
782        handle as i32,
783        name.as_ptr() as i32,
784        name.len() as i32,
785        value as i64,
786    );
787    match ret {
788        0 => Ok(()),
789        _ => Err(CryptoErrno(ret as u16)),
790    }
791}
792
793/// Set or update a guest-allocated memory that the host can use or return data
794/// into.
795///
796/// This is for example used to set the scratch buffer required by memory-hard
797/// functions.
798///
799/// This function may return `unsupported_option` if an option that doesn't
800/// exist for any implemented algorithms is specified.
801pub unsafe fn options_set_guest_buffer(
802    handle: Options,
803    name: &str,
804    buffer: *mut u8,
805    buffer_len: Size,
806) -> Result<(), CryptoErrno> {
807    let ret = wasi_ephemeral_crypto_common::options_set_guest_buffer(
808        handle as i32,
809        name.as_ptr() as i32,
810        name.len() as i32,
811        buffer as i32,
812        buffer_len as i32,
813    );
814    match ret {
815        0 => Ok(()),
816        _ => Err(CryptoErrno(ret as u16)),
817    }
818}
819
820/// Return the length of an `array_output` object.
821///
822/// This allows a guest to allocate a buffer of the correct size in order to
823/// copy the output of a function returning this object type.
824pub unsafe fn array_output_len(array_output: ArrayOutput) -> Result<Size, CryptoErrno> {
825    let mut rp0 = MaybeUninit::<Size>::uninit();
826    let ret = wasi_ephemeral_crypto_common::array_output_len(
827        array_output as i32,
828        rp0.as_mut_ptr() as i32,
829    );
830    match ret {
831        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
832        _ => Err(CryptoErrno(ret as u16)),
833    }
834}
835
836/// Copy the content of an `array_output` object into an application-allocated
837/// buffer.
838///
839/// Multiple calls to that function can be made in order to consume the data in
840/// a streaming fashion, if necessary.
841///
842/// The function returns the number of bytes that were actually copied. `0`
843/// means that the end of the stream has been reached. The total size always
844/// matches the output of `array_output_len()`.
845///
846/// The handle is automatically closed after all the data has been consumed.
847///
848/// Example usage:
849///
850/// ```rust
851/// let len = array_output_len(output_handle)?;
852/// let mut out = vec![0u8; len];
853/// array_output_pull(output_handle, &mut out)?;
854/// ```
855pub unsafe fn array_output_pull(
856    array_output: ArrayOutput,
857    buf: *mut u8,
858    buf_len: Size,
859) -> Result<Size, CryptoErrno> {
860    let mut rp0 = MaybeUninit::<Size>::uninit();
861    let ret = wasi_ephemeral_crypto_common::array_output_pull(
862        array_output as i32,
863        buf as i32,
864        buf_len as i32,
865        rp0.as_mut_ptr() as i32,
866    );
867    match ret {
868        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
869        _ => Err(CryptoErrno(ret as u16)),
870    }
871}
872
873/// __(optional)__
874/// Create a context to use a secrets manager.
875///
876/// The set of required and supported options is defined by the host.
877///
878/// The function returns the `unsupported_feature` error code if secrets
879/// management facilities are not supported by the host. This is also an
880/// optional import, meaning that the function may not even exist.
881pub unsafe fn secrets_manager_open(options: OptOptions) -> Result<SecretsManager, CryptoErrno> {
882    let mut rp0 = MaybeUninit::<SecretsManager>::uninit();
883    let ret = wasi_ephemeral_crypto_common::secrets_manager_open(
884        &options as *const _ as i32,
885        rp0.as_mut_ptr() as i32,
886    );
887    match ret {
888        0 => Ok(core::ptr::read(
889            rp0.as_mut_ptr() as i32 as *const SecretsManager
890        )),
891        _ => Err(CryptoErrno(ret as u16)),
892    }
893}
894
895/// __(optional)__
896/// Destroy a secrets manager context.
897///
898/// The function returns the `unsupported_feature` error code if secrets
899/// management facilities are not supported by the host. This is also an
900/// optional import, meaning that the function may not even exist.
901pub unsafe fn secrets_manager_close(secrets_manager: SecretsManager) -> Result<(), CryptoErrno> {
902    let ret = wasi_ephemeral_crypto_common::secrets_manager_close(secrets_manager as i32);
903    match ret {
904        0 => Ok(()),
905        _ => Err(CryptoErrno(ret as u16)),
906    }
907}
908
909/// __(optional)__
910/// Invalidate a managed key or key pair given an identifier and a version.
911///
912/// This asks the secrets manager to delete or revoke a stored key, a specific
913/// version of a key.
914///
915/// `key_version` can be set to a version number, to `version.latest` to
916/// invalidate the current version, or to `version.all` to invalidate all
917/// versions of a key.
918///
919/// The function returns `unsupported_feature` if this operation is not
920/// supported by the host, and `not_found` if the identifier and version don't
921/// match any existing key.
922///
923/// This is an optional import, meaning that the function may not even exist.
924pub unsafe fn secrets_manager_invalidate(
925    secrets_manager: SecretsManager,
926    key_id: *const u8,
927    key_id_len: Size,
928    key_version: Version,
929) -> Result<(), CryptoErrno> {
930    let ret = wasi_ephemeral_crypto_common::secrets_manager_invalidate(
931        secrets_manager as i32,
932        key_id as i32,
933        key_id_len as i32,
934        key_version as i64,
935    );
936    match ret {
937        0 => Ok(()),
938        _ => Err(CryptoErrno(ret as u16)),
939    }
940}
941
942pub mod wasi_ephemeral_crypto_common {
943    #[link(wasm_import_module = "wasi_ephemeral_crypto_common")]
944    extern "C" {
945        /// Create a new object to set non-default options.
946        ///
947        /// Example usage:
948        ///
949        /// ```rust
950        /// let options_handle = options_open(AlgorithmType::Symmetric)?;
951        /// options_set(options_handle, "context", context)?;
952        /// options_set_u64(options_handle, "threads", 4)?;
953        /// let state = symmetric_state_open("BLAKE3", None, Some(options_handle))?;
954        /// options_close(options_handle)?;
955        /// ```
956        pub fn options_open(arg0: i32, arg1: i32) -> i32;
957        /// Destroy an options object.
958        ///
959        /// Objects are reference counted. It is safe to close an object
960        /// immediately after the last function needing it is called.
961        pub fn options_close(arg0: i32) -> i32;
962        /// Set or update an option.
963        ///
964        /// This is used to set algorithm-specific parameters, but also to
965        /// provide credentials for the secrets management facilities, if
966        /// required.
967        ///
968        /// This function may return `unsupported_option` if an option that
969        /// doesn't exist for any implemented algorithms is specified.
970        pub fn options_set(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32;
971        /// Set or update an integer option.
972        ///
973        /// This is used to set algorithm-specific parameters.
974        ///
975        /// This function may return `unsupported_option` if an option that
976        /// doesn't exist for any implemented algorithms is specified.
977        pub fn options_set_u64(arg0: i32, arg1: i32, arg2: i32, arg3: i64) -> i32;
978        /// Set or update a guest-allocated memory that the host can use or
979        /// return data into.
980        ///
981        /// This is for example used to set the scratch buffer required by
982        /// memory-hard functions.
983        ///
984        /// This function may return `unsupported_option` if an option that
985        /// doesn't exist for any implemented algorithms is specified.
986        pub fn options_set_guest_buffer(
987            arg0: i32,
988            arg1: i32,
989            arg2: i32,
990            arg3: i32,
991            arg4: i32,
992        ) -> i32;
993        /// Return the length of an `array_output` object.
994        ///
995        /// This allows a guest to allocate a buffer of the correct size in
996        /// order to copy the output of a function returning this object type.
997        pub fn array_output_len(arg0: i32, arg1: i32) -> i32;
998        /// Copy the content of an `array_output` object into an
999        /// application-allocated buffer.
1000        ///
1001        /// Multiple calls to that function can be made in order to consume the
1002        /// data in a streaming fashion, if necessary.
1003        ///
1004        /// The function returns the number of bytes that were actually copied.
1005        /// `0` means that the end of the stream has been reached. The total
1006        /// size always matches the output of `array_output_len()`.
1007        ///
1008        /// The handle is automatically closed after all the data has been
1009        /// consumed.
1010        ///
1011        /// Example usage:
1012        ///
1013        /// ```rust
1014        /// let len = array_output_len(output_handle)?;
1015        /// let mut out = vec![0u8; len];
1016        /// array_output_pull(output_handle, &mut out)?;
1017        /// ```
1018        pub fn array_output_pull(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
1019        /// __(optional)__
1020        /// Create a context to use a secrets manager.
1021        ///
1022        /// The set of required and supported options is defined by the host.
1023        ///
1024        /// The function returns the `unsupported_feature` error code if secrets
1025        /// management facilities are not supported by the host. This is
1026        /// also an optional import, meaning that the function may not even
1027        /// exist.
1028        pub fn secrets_manager_open(arg0: i32, arg1: i32) -> i32;
1029        /// __(optional)__
1030        /// Destroy a secrets manager context.
1031        ///
1032        /// The function returns the `unsupported_feature` error code if secrets
1033        /// management facilities are not supported by the host. This is
1034        /// also an optional import, meaning that the function may not even
1035        /// exist.
1036        pub fn secrets_manager_close(arg0: i32) -> i32;
1037        /// __(optional)__
1038        /// Invalidate a managed key or key pair given an identifier and a
1039        /// version.
1040        ///
1041        /// This asks the secrets manager to delete or revoke a stored key, a
1042        /// specific version of a key.
1043        ///
1044        /// `key_version` can be set to a version number, to `version.latest` to
1045        /// invalidate the current version, or to `version.all` to invalidate
1046        /// all versions of a key.
1047        ///
1048        /// The function returns `unsupported_feature` if this operation is not
1049        /// supported by the host, and `not_found` if the identifier and version
1050        /// don't match any existing key.
1051        ///
1052        /// This is an optional import, meaning that the function may not even
1053        /// exist.
1054        pub fn secrets_manager_invalidate(arg0: i32, arg1: i32, arg2: i32, arg3: i64) -> i32;
1055    }
1056}
1057/// Generate a new key pair.
1058///
1059/// Internally, a key pair stores the supplied algorithm and optional
1060/// parameters.
1061///
1062/// Trying to use that key pair with different parameters will throw an
1063/// `invalid_key` error.
1064///
1065/// This function may return `$crypto_errno.unsupported_feature` if key
1066/// generation is not supported by the host for the chosen algorithm.
1067///
1068/// The function may also return `unsupported_algorithm` if the algorithm is not
1069/// supported by the host.
1070///
1071/// Finally, if generating that type of key pair is an expensive operation, the
1072/// function may return `in_progress`. In that case, the guest should retry with
1073/// the same parameters until the function completes.
1074///
1075/// Example usage:
1076///
1077/// ```rust
1078/// let kp_handle =
1079///     ctx.keypair_generate(AlgorithmType::Signatures, "RSA_PKCS1_2048_SHA256", None)?;
1080/// ```
1081pub unsafe fn keypair_generate(
1082    algorithm_type: AlgorithmType,
1083    algorithm: &str,
1084    options: OptOptions,
1085) -> Result<Keypair, CryptoErrno> {
1086    let mut rp0 = MaybeUninit::<Keypair>::uninit();
1087    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_generate(
1088        algorithm_type.0 as i32,
1089        algorithm.as_ptr() as i32,
1090        algorithm.len() as i32,
1091        &options as *const _ as i32,
1092        rp0.as_mut_ptr() as i32,
1093    );
1094    match ret {
1095        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Keypair)),
1096        _ => Err(CryptoErrno(ret as u16)),
1097    }
1098}
1099
1100/// Import a key pair.
1101///
1102/// This function creates a `keypair` object from existing material.
1103///
1104/// It may return `unsupported_algorithm` if the encoding scheme is not
1105/// supported, or `invalid_key` if the key cannot be decoded.
1106///
1107/// The function may also return `unsupported_algorithm` if the algorithm is not
1108/// supported by the host.
1109///
1110/// Example usage:
1111///
1112/// ```rust
1113/// let kp_handle = ctx.keypair_import(
1114///     AlgorithmType::Signatures,
1115///     "RSA_PKCS1_2048_SHA256",
1116///     KeypairEncoding::PKCS8,
1117/// )?;
1118/// ```
1119pub unsafe fn keypair_import(
1120    algorithm_type: AlgorithmType,
1121    algorithm: &str,
1122    encoded: *const u8,
1123    encoded_len: Size,
1124    encoding: KeypairEncoding,
1125) -> Result<Keypair, CryptoErrno> {
1126    let mut rp0 = MaybeUninit::<Keypair>::uninit();
1127    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_import(
1128        algorithm_type.0 as i32,
1129        algorithm.as_ptr() as i32,
1130        algorithm.len() as i32,
1131        encoded as i32,
1132        encoded_len as i32,
1133        encoding.0 as i32,
1134        rp0.as_mut_ptr() as i32,
1135    );
1136    match ret {
1137        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Keypair)),
1138        _ => Err(CryptoErrno(ret as u16)),
1139    }
1140}
1141
1142/// __(optional)__
1143/// Generate a new managed key pair.
1144///
1145/// The key pair is generated and stored by the secrets management facilities.
1146///
1147/// It may be used through its identifier, but the host may not allow it to be
1148/// exported.
1149///
1150/// The function returns the `unsupported_feature` error code if secrets
1151/// management facilities are not supported by the host,
1152/// or `unsupported_algorithm` if a key cannot be created for the chosen
1153/// algorithm.
1154///
1155/// The function may also return `unsupported_algorithm` if the algorithm is not
1156/// supported by the host.
1157///
1158/// This is also an optional import, meaning that the function may not even
1159/// exist.
1160pub unsafe fn keypair_generate_managed(
1161    secrets_manager: SecretsManager,
1162    algorithm_type: AlgorithmType,
1163    algorithm: &str,
1164    options: OptOptions,
1165) -> Result<Keypair, CryptoErrno> {
1166    let mut rp0 = MaybeUninit::<Keypair>::uninit();
1167    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_generate_managed(
1168        secrets_manager as i32,
1169        algorithm_type.0 as i32,
1170        algorithm.as_ptr() as i32,
1171        algorithm.len() as i32,
1172        &options as *const _ as i32,
1173        rp0.as_mut_ptr() as i32,
1174    );
1175    match ret {
1176        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Keypair)),
1177        _ => Err(CryptoErrno(ret as u16)),
1178    }
1179}
1180
1181/// __(optional)__
1182/// Store a key pair into the secrets manager.
1183///
1184/// On success, the function stores the key pair identifier into `$kp_id`,
1185/// into which up to `$kp_id_max_len` can be written.
1186///
1187/// The function returns `overflow` if the supplied buffer is too small.
1188pub unsafe fn keypair_store_managed(
1189    secrets_manager: SecretsManager,
1190    kp: Keypair,
1191    kp_id: *mut u8,
1192    kp_id_max_len: Size,
1193) -> Result<(), CryptoErrno> {
1194    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_store_managed(
1195        secrets_manager as i32,
1196        kp as i32,
1197        kp_id as i32,
1198        kp_id_max_len as i32,
1199    );
1200    match ret {
1201        0 => Ok(()),
1202        _ => Err(CryptoErrno(ret as u16)),
1203    }
1204}
1205
1206/// __(optional)__
1207/// Replace a managed key pair.
1208///
1209/// This function crates a new version of a managed key pair, by replacing
1210/// `$kp_old` with `$kp_new`.
1211///
1212/// It does several things:
1213///
1214/// - The key identifier for `$kp_new` is set to the one of `$kp_old`.
1215/// - A new, unique version identifier is assigned to `$kp_new`. This version
1216///   will be equivalent to using `$version_latest` until the key is replaced.
1217/// - The `$kp_old` handle is closed.
1218///
1219/// Both keys must share the same algorithm and have compatible parameters. If
1220/// this is not the case, `incompatible_keys` is returned.
1221///
1222/// The function may also return the `unsupported_feature` error code if secrets
1223/// management facilities are not supported by the host, or if keys cannot be
1224/// rotated.
1225///
1226/// Finally, `prohibited_operation` can be returned if `$kp_new` wasn't created
1227/// by the secrets manager, and the secrets manager prohibits imported keys.
1228///
1229/// If the operation succeeded, the new version is returned.
1230///
1231/// This is an optional import, meaning that the function may not even exist.
1232pub unsafe fn keypair_replace_managed(
1233    secrets_manager: SecretsManager,
1234    kp_old: Keypair,
1235    kp_new: Keypair,
1236) -> Result<Version, CryptoErrno> {
1237    let mut rp0 = MaybeUninit::<Version>::uninit();
1238    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_replace_managed(
1239        secrets_manager as i32,
1240        kp_old as i32,
1241        kp_new as i32,
1242        rp0.as_mut_ptr() as i32,
1243    );
1244    match ret {
1245        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Version)),
1246        _ => Err(CryptoErrno(ret as u16)),
1247    }
1248}
1249
1250/// __(optional)__
1251/// Return the key pair identifier and version of a managed key pair.
1252///
1253/// If the key pair is not managed, `unsupported_feature` is returned instead.
1254///
1255/// This is an optional import, meaning that the function may not even exist.
1256pub unsafe fn keypair_id(
1257    kp: Keypair,
1258    kp_id: *mut u8,
1259    kp_id_max_len: Size,
1260) -> Result<(Size, Version), CryptoErrno> {
1261    let mut rp0 = MaybeUninit::<Size>::uninit();
1262    let mut rp1 = MaybeUninit::<Version>::uninit();
1263    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_id(
1264        kp as i32,
1265        kp_id as i32,
1266        kp_id_max_len as i32,
1267        rp0.as_mut_ptr() as i32,
1268        rp1.as_mut_ptr() as i32,
1269    );
1270    match ret {
1271        0 => Ok((
1272            core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size),
1273            core::ptr::read(rp1.as_mut_ptr() as i32 as *const Version),
1274        )),
1275        _ => Err(CryptoErrno(ret as u16)),
1276    }
1277}
1278
1279/// __(optional)__
1280/// Return a managed key pair from a key identifier.
1281///
1282/// `kp_version` can be set to `version_latest` to retrieve the most recent
1283/// version of a key pair.
1284///
1285/// If no key pair matching the provided information is found, `not_found` is
1286/// returned instead.
1287///
1288/// This is an optional import, meaning that the function may not even exist.
1289pub unsafe fn keypair_from_id(
1290    secrets_manager: SecretsManager,
1291    kp_id: *const u8,
1292    kp_id_len: Size,
1293    kp_version: Version,
1294) -> Result<Keypair, CryptoErrno> {
1295    let mut rp0 = MaybeUninit::<Keypair>::uninit();
1296    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_from_id(
1297        secrets_manager as i32,
1298        kp_id as i32,
1299        kp_id_len as i32,
1300        kp_version as i64,
1301        rp0.as_mut_ptr() as i32,
1302    );
1303    match ret {
1304        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Keypair)),
1305        _ => Err(CryptoErrno(ret as u16)),
1306    }
1307}
1308
1309/// Create a key pair from a public key and a secret key.
1310pub unsafe fn keypair_from_pk_and_sk(
1311    publickey: Publickey,
1312    secretkey: Secretkey,
1313) -> Result<Keypair, CryptoErrno> {
1314    let mut rp0 = MaybeUninit::<Keypair>::uninit();
1315    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_from_pk_and_sk(
1316        publickey as i32,
1317        secretkey as i32,
1318        rp0.as_mut_ptr() as i32,
1319    );
1320    match ret {
1321        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Keypair)),
1322        _ => Err(CryptoErrno(ret as u16)),
1323    }
1324}
1325
1326/// Export a key pair as the given encoding format.
1327///
1328/// May return `prohibited_operation` if this operation is denied or
1329/// `unsupported_encoding` if the encoding is not supported.
1330pub unsafe fn keypair_export(
1331    kp: Keypair,
1332    encoding: KeypairEncoding,
1333) -> Result<ArrayOutput, CryptoErrno> {
1334    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
1335    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_export(
1336        kp as i32,
1337        encoding.0 as i32,
1338        rp0.as_mut_ptr() as i32,
1339    );
1340    match ret {
1341        0 => Ok(core::ptr::read(
1342            rp0.as_mut_ptr() as i32 as *const ArrayOutput
1343        )),
1344        _ => Err(CryptoErrno(ret as u16)),
1345    }
1346}
1347
1348/// Get the public key of a key pair.
1349pub unsafe fn keypair_publickey(kp: Keypair) -> Result<Publickey, CryptoErrno> {
1350    let mut rp0 = MaybeUninit::<Publickey>::uninit();
1351    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_publickey(
1352        kp as i32,
1353        rp0.as_mut_ptr() as i32,
1354    );
1355    match ret {
1356        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Publickey)),
1357        _ => Err(CryptoErrno(ret as u16)),
1358    }
1359}
1360
1361/// Get the secret key of a key pair.
1362pub unsafe fn keypair_secretkey(kp: Keypair) -> Result<Secretkey, CryptoErrno> {
1363    let mut rp0 = MaybeUninit::<Secretkey>::uninit();
1364    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_secretkey(
1365        kp as i32,
1366        rp0.as_mut_ptr() as i32,
1367    );
1368    match ret {
1369        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Secretkey)),
1370        _ => Err(CryptoErrno(ret as u16)),
1371    }
1372}
1373
1374/// Destroy a key pair.
1375///
1376/// The host will automatically wipe traces of the secret key from memory.
1377///
1378/// If this is a managed key, the key will not be removed from persistent
1379/// storage, and can be reconstructed later using the key identifier.
1380pub unsafe fn keypair_close(kp: Keypair) -> Result<(), CryptoErrno> {
1381    let ret = wasi_ephemeral_crypto_asymmetric_common::keypair_close(kp as i32);
1382    match ret {
1383        0 => Ok(()),
1384        _ => Err(CryptoErrno(ret as u16)),
1385    }
1386}
1387
1388/// Import a public key.
1389///
1390/// The function may return `unsupported_encoding` if importing from the given
1391/// format is not implemented or incompatible with the key type.
1392///
1393/// It may also return `invalid_key` if the key doesn't appear to match the
1394/// supplied algorithm.
1395///
1396/// Finally, the function may return `unsupported_algorithm` if the algorithm is
1397/// not supported by the host.
1398///
1399/// Example usage:
1400///
1401/// ```rust
1402/// let pk_handle =
1403///     ctx.publickey_import(AlgorithmType::Signatures, encoded, PublicKeyEncoding::Sec)?;
1404/// ```
1405pub unsafe fn publickey_import(
1406    algorithm_type: AlgorithmType,
1407    algorithm: &str,
1408    encoded: *const u8,
1409    encoded_len: Size,
1410    encoding: PublickeyEncoding,
1411) -> Result<Publickey, CryptoErrno> {
1412    let mut rp0 = MaybeUninit::<Publickey>::uninit();
1413    let ret = wasi_ephemeral_crypto_asymmetric_common::publickey_import(
1414        algorithm_type.0 as i32,
1415        algorithm.as_ptr() as i32,
1416        algorithm.len() as i32,
1417        encoded as i32,
1418        encoded_len as i32,
1419        encoding.0 as i32,
1420        rp0.as_mut_ptr() as i32,
1421    );
1422    match ret {
1423        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Publickey)),
1424        _ => Err(CryptoErrno(ret as u16)),
1425    }
1426}
1427
1428/// Export a public key as the given encoding format.
1429///
1430/// May return `unsupported_encoding` if the encoding is not supported.
1431pub unsafe fn publickey_export(
1432    pk: Publickey,
1433    encoding: PublickeyEncoding,
1434) -> Result<ArrayOutput, CryptoErrno> {
1435    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
1436    let ret = wasi_ephemeral_crypto_asymmetric_common::publickey_export(
1437        pk as i32,
1438        encoding.0 as i32,
1439        rp0.as_mut_ptr() as i32,
1440    );
1441    match ret {
1442        0 => Ok(core::ptr::read(
1443            rp0.as_mut_ptr() as i32 as *const ArrayOutput
1444        )),
1445        _ => Err(CryptoErrno(ret as u16)),
1446    }
1447}
1448
1449/// Check that a public key is valid and in canonical form.
1450///
1451/// This function may perform stricter checks than those made during importation
1452/// at the expense of additional CPU cycles.
1453///
1454/// The function returns `invalid_key` if the public key didn't pass the checks.
1455pub unsafe fn publickey_verify(pk: Publickey) -> Result<(), CryptoErrno> {
1456    let ret = wasi_ephemeral_crypto_asymmetric_common::publickey_verify(pk as i32);
1457    match ret {
1458        0 => Ok(()),
1459        _ => Err(CryptoErrno(ret as u16)),
1460    }
1461}
1462
1463/// Compute the public key for a secret key.
1464pub unsafe fn publickey_from_secretkey(sk: Secretkey) -> Result<Publickey, CryptoErrno> {
1465    let mut rp0 = MaybeUninit::<Publickey>::uninit();
1466    let ret = wasi_ephemeral_crypto_asymmetric_common::publickey_from_secretkey(
1467        sk as i32,
1468        rp0.as_mut_ptr() as i32,
1469    );
1470    match ret {
1471        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Publickey)),
1472        _ => Err(CryptoErrno(ret as u16)),
1473    }
1474}
1475
1476/// Destroy a public key.
1477///
1478/// Objects are reference counted. It is safe to close an object immediately
1479/// after the last function needing it is called.
1480pub unsafe fn publickey_close(pk: Publickey) -> Result<(), CryptoErrno> {
1481    let ret = wasi_ephemeral_crypto_asymmetric_common::publickey_close(pk as i32);
1482    match ret {
1483        0 => Ok(()),
1484        _ => Err(CryptoErrno(ret as u16)),
1485    }
1486}
1487
1488/// Import a secret key.
1489///
1490/// The function may return `unsupported_encoding` if importing from the given
1491/// format is not implemented or incompatible with the key type.
1492///
1493/// It may also return `invalid_key` if the key doesn't appear to match the
1494/// supplied algorithm.
1495///
1496/// Finally, the function may return `unsupported_algorithm` if the algorithm is
1497/// not supported by the host.
1498///
1499/// Example usage:
1500///
1501/// ```rust
1502/// let pk_handle = ctx.secretkey_import(AlgorithmType::KX, encoded, SecretKeyEncoding::Raw)?;
1503/// ```
1504pub unsafe fn secretkey_import(
1505    algorithm_type: AlgorithmType,
1506    algorithm: &str,
1507    encoded: *const u8,
1508    encoded_len: Size,
1509    encoding: SecretkeyEncoding,
1510) -> Result<Secretkey, CryptoErrno> {
1511    let mut rp0 = MaybeUninit::<Secretkey>::uninit();
1512    let ret = wasi_ephemeral_crypto_asymmetric_common::secretkey_import(
1513        algorithm_type.0 as i32,
1514        algorithm.as_ptr() as i32,
1515        algorithm.len() as i32,
1516        encoded as i32,
1517        encoded_len as i32,
1518        encoding.0 as i32,
1519        rp0.as_mut_ptr() as i32,
1520    );
1521    match ret {
1522        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Secretkey)),
1523        _ => Err(CryptoErrno(ret as u16)),
1524    }
1525}
1526
1527/// Export a secret key as the given encoding format.
1528///
1529/// May return `unsupported_encoding` if the encoding is not supported.
1530pub unsafe fn secretkey_export(
1531    sk: Secretkey,
1532    encoding: SecretkeyEncoding,
1533) -> Result<ArrayOutput, CryptoErrno> {
1534    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
1535    let ret = wasi_ephemeral_crypto_asymmetric_common::secretkey_export(
1536        sk as i32,
1537        encoding.0 as i32,
1538        rp0.as_mut_ptr() as i32,
1539    );
1540    match ret {
1541        0 => Ok(core::ptr::read(
1542            rp0.as_mut_ptr() as i32 as *const ArrayOutput
1543        )),
1544        _ => Err(CryptoErrno(ret as u16)),
1545    }
1546}
1547
1548/// Destroy a secret key.
1549///
1550/// Objects are reference counted. It is safe to close an object immediately
1551/// after the last function needing it is called.
1552pub unsafe fn secretkey_close(sk: Secretkey) -> Result<(), CryptoErrno> {
1553    let ret = wasi_ephemeral_crypto_asymmetric_common::secretkey_close(sk as i32);
1554    match ret {
1555        0 => Ok(()),
1556        _ => Err(CryptoErrno(ret as u16)),
1557    }
1558}
1559
1560pub mod wasi_ephemeral_crypto_asymmetric_common {
1561    #[link(wasm_import_module = "wasi_ephemeral_crypto_asymmetric_common")]
1562    extern "C" {
1563        /// Generate a new key pair.
1564        ///
1565        /// Internally, a key pair stores the supplied algorithm and optional
1566        /// parameters.
1567        ///
1568        /// Trying to use that key pair with different parameters will throw an
1569        /// `invalid_key` error.
1570        ///
1571        /// This function may return `$crypto_errno.unsupported_feature` if key
1572        /// generation is not supported by the host for the chosen algorithm.
1573        ///
1574        /// The function may also return `unsupported_algorithm` if the
1575        /// algorithm is not supported by the host.
1576        ///
1577        /// Finally, if generating that type of key pair is an expensive
1578        /// operation, the function may return `in_progress`.
1579        /// In that case, the guest should retry with the same parameters until
1580        /// the function completes.
1581        ///
1582        /// Example usage:
1583        ///
1584        /// ```rust
1585        /// let kp_handle =
1586        ///     ctx.keypair_generate(AlgorithmType::Signatures, "RSA_PKCS1_2048_SHA256", None)?;
1587        /// ```
1588        pub fn keypair_generate(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32;
1589        /// Import a key pair.
1590        ///
1591        /// This function creates a `keypair` object from existing material.
1592        ///
1593        /// It may return `unsupported_algorithm` if the encoding scheme is not
1594        /// supported, or `invalid_key` if the key cannot be decoded.
1595        ///
1596        /// The function may also return `unsupported_algorithm` if the
1597        /// algorithm is not supported by the host.
1598        ///
1599        /// Example usage:
1600        ///
1601        /// ```rust
1602        /// let kp_handle = ctx.keypair_import(
1603        ///     AlgorithmType::Signatures,
1604        ///     "RSA_PKCS1_2048_SHA256",
1605        ///     KeypairEncoding::PKCS8,
1606        /// )?;
1607        /// ```
1608        pub fn keypair_import(
1609            arg0: i32,
1610            arg1: i32,
1611            arg2: i32,
1612            arg3: i32,
1613            arg4: i32,
1614            arg5: i32,
1615            arg6: i32,
1616        ) -> i32;
1617        /// __(optional)__
1618        /// Generate a new managed key pair.
1619        ///
1620        /// The key pair is generated and stored by the secrets management
1621        /// facilities.
1622        ///
1623        /// It may be used through its identifier, but the host may not allow it
1624        /// to be exported.
1625        ///
1626        /// The function returns the `unsupported_feature` error code if secrets
1627        /// management facilities are not supported by the host,
1628        /// or `unsupported_algorithm` if a key cannot be created for the chosen
1629        /// algorithm.
1630        ///
1631        /// The function may also return `unsupported_algorithm` if the
1632        /// algorithm is not supported by the host.
1633        ///
1634        /// This is also an optional import, meaning that the function may not
1635        /// even exist.
1636        pub fn keypair_generate_managed(
1637            arg0: i32,
1638            arg1: i32,
1639            arg2: i32,
1640            arg3: i32,
1641            arg4: i32,
1642            arg5: i32,
1643        ) -> i32;
1644        /// __(optional)__
1645        /// Store a key pair into the secrets manager.
1646        ///
1647        /// On success, the function stores the key pair identifier into
1648        /// `$kp_id`, into which up to `$kp_id_max_len` can be written.
1649        ///
1650        /// The function returns `overflow` if the supplied buffer is too small.
1651        pub fn keypair_store_managed(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
1652        /// __(optional)__
1653        /// Replace a managed key pair.
1654        ///
1655        /// This function crates a new version of a managed key pair, by
1656        /// replacing `$kp_old` with `$kp_new`.
1657        ///
1658        /// It does several things:
1659        ///
1660        /// - The key identifier for `$kp_new` is set to the one of `$kp_old`.
1661        /// - A new, unique version identifier is assigned to `$kp_new`. This
1662        ///   version will be equivalent to using `$version_latest` until the
1663        ///   key is replaced.
1664        /// - The `$kp_old` handle is closed.
1665        ///
1666        /// Both keys must share the same algorithm and have compatible
1667        /// parameters. If this is not the case, `incompatible_keys` is
1668        /// returned.
1669        ///
1670        /// The function may also return the `unsupported_feature` error code if
1671        /// secrets management facilities are not supported by the host,
1672        /// or if keys cannot be rotated.
1673        ///
1674        /// Finally, `prohibited_operation` can be returned if `$kp_new` wasn't
1675        /// created by the secrets manager, and the secrets manager prohibits
1676        /// imported keys.
1677        ///
1678        /// If the operation succeeded, the new version is returned.
1679        ///
1680        /// This is an optional import, meaning that the function may not even
1681        /// exist.
1682        pub fn keypair_replace_managed(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
1683        /// __(optional)__
1684        /// Return the key pair identifier and version of a managed key pair.
1685        ///
1686        /// If the key pair is not managed, `unsupported_feature` is returned
1687        /// instead.
1688        ///
1689        /// This is an optional import, meaning that the function may not even
1690        /// exist.
1691        pub fn keypair_id(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32;
1692        /// __(optional)__
1693        /// Return a managed key pair from a key identifier.
1694        ///
1695        /// `kp_version` can be set to `version_latest` to retrieve the most
1696        /// recent version of a key pair.
1697        ///
1698        /// If no key pair matching the provided information is found,
1699        /// `not_found` is returned instead.
1700        ///
1701        /// This is an optional import, meaning that the function may not even
1702        /// exist. ```
1703        pub fn keypair_from_id(arg0: i32, arg1: i32, arg2: i32, arg3: i64, arg4: i32) -> i32;
1704        /// Create a key pair from a public key and a secret key.
1705        pub fn keypair_from_pk_and_sk(arg0: i32, arg1: i32, arg2: i32) -> i32;
1706        /// Export a key pair as the given encoding format.
1707        ///
1708        /// May return `prohibited_operation` if this operation is denied or
1709        /// `unsupported_encoding` if the encoding is not supported.
1710        pub fn keypair_export(arg0: i32, arg1: i32, arg2: i32) -> i32;
1711        /// Get the public key of a key pair.
1712        pub fn keypair_publickey(arg0: i32, arg1: i32) -> i32;
1713        /// Get the secret key of a key pair.
1714        pub fn keypair_secretkey(arg0: i32, arg1: i32) -> i32;
1715        /// Destroy a key pair.
1716        ///
1717        /// The host will automatically wipe traces of the secret key from
1718        /// memory.
1719        ///
1720        /// If this is a managed key, the key will not be removed from
1721        /// persistent storage, and can be reconstructed later using the key
1722        /// identifier.
1723        pub fn keypair_close(arg0: i32) -> i32;
1724        /// Import a public key.
1725        ///
1726        /// The function may return `unsupported_encoding` if importing from the
1727        /// given format is not implemented or incompatible with the key type.
1728        ///
1729        /// It may also return `invalid_key` if the key doesn't appear to match
1730        /// the supplied algorithm.
1731        ///
1732        /// Finally, the function may return `unsupported_algorithm` if the
1733        /// algorithm is not supported by the host.
1734        ///
1735        /// Example usage:
1736        ///
1737        /// ```rust
1738        /// let pk_handle =
1739        ///     ctx.publickey_import(AlgorithmType::Signatures, encoded, PublicKeyEncoding::Sec)?;
1740        /// ```
1741        pub fn publickey_import(
1742            arg0: i32,
1743            arg1: i32,
1744            arg2: i32,
1745            arg3: i32,
1746            arg4: i32,
1747            arg5: i32,
1748            arg6: i32,
1749        ) -> i32;
1750        /// Export a public key as the given encoding format.
1751        ///
1752        /// May return `unsupported_encoding` if the encoding is not supported.
1753        pub fn publickey_export(arg0: i32, arg1: i32, arg2: i32) -> i32;
1754        /// Check that a public key is valid and in canonical form.
1755        ///
1756        /// This function may perform stricter checks than those made during
1757        /// importation at the expense of additional CPU cycles.
1758        ///
1759        /// The function returns `invalid_key` if the public key didn't pass the
1760        /// checks.
1761        pub fn publickey_verify(arg0: i32) -> i32;
1762        /// Compute the public key for a secret key.
1763        pub fn publickey_from_secretkey(arg0: i32, arg1: i32) -> i32;
1764        /// Destroy a public key.
1765        ///
1766        /// Objects are reference counted. It is safe to close an object
1767        /// immediately after the last function needing it is called.
1768        pub fn publickey_close(arg0: i32) -> i32;
1769        /// Import a secret key.
1770        ///
1771        /// The function may return `unsupported_encoding` if importing from the
1772        /// given format is not implemented or incompatible with the key type.
1773        ///
1774        /// It may also return `invalid_key` if the key doesn't appear to match
1775        /// the supplied algorithm.
1776        ///
1777        /// Finally, the function may return `unsupported_algorithm` if the
1778        /// algorithm is not supported by the host.
1779        ///
1780        /// Example usage:
1781        ///
1782        /// ```rust
1783        /// let pk_handle = ctx.secretkey_import(AlgorithmType::KX, encoded, SecretKeyEncoding::Raw)?;
1784        /// ```
1785        pub fn secretkey_import(
1786            arg0: i32,
1787            arg1: i32,
1788            arg2: i32,
1789            arg3: i32,
1790            arg4: i32,
1791            arg5: i32,
1792            arg6: i32,
1793        ) -> i32;
1794        /// Export a secret key as the given encoding format.
1795        ///
1796        /// May return `unsupported_encoding` if the encoding is not supported.
1797        pub fn secretkey_export(arg0: i32, arg1: i32, arg2: i32) -> i32;
1798        /// Destroy a secret key.
1799        ///
1800        /// Objects are reference counted. It is safe to close an object
1801        /// immediately after the last function needing it is called.
1802        pub fn secretkey_close(arg0: i32) -> i32;
1803    }
1804}
1805/// Export a signature.
1806///
1807/// This function exports a signature object using the specified encoding.
1808///
1809/// May return `unsupported_encoding` if the signature cannot be encoded into
1810/// the given format.
1811pub unsafe fn signature_export(
1812    signature: Signature,
1813    encoding: SignatureEncoding,
1814) -> Result<ArrayOutput, CryptoErrno> {
1815    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
1816    let ret = wasi_ephemeral_crypto_signatures::signature_export(
1817        signature as i32,
1818        encoding.0 as i32,
1819        rp0.as_mut_ptr() as i32,
1820    );
1821    match ret {
1822        0 => Ok(core::ptr::read(
1823            rp0.as_mut_ptr() as i32 as *const ArrayOutput
1824        )),
1825        _ => Err(CryptoErrno(ret as u16)),
1826    }
1827}
1828
1829/// Create a signature object.
1830///
1831/// This object can be used along with a public key to verify an existing
1832/// signature.
1833///
1834/// It may return `invalid_signature` if the signature is invalid or
1835/// incompatible with the specified algorithm, as well as `unsupported_encoding`
1836/// if the encoding is not compatible with the signature type.
1837///
1838/// The function may also return `unsupported_algorithm` if the algorithm is not
1839/// supported by the host.
1840///
1841/// Example usage:
1842///
1843/// ```rust
1844/// let signature_handle =
1845///     ctx.signature_import("ECDSA_P256_SHA256", SignatureEncoding::DER, encoded)?;
1846/// ```
1847pub unsafe fn signature_import(
1848    algorithm: &str,
1849    encoded: *const u8,
1850    encoded_len: Size,
1851    encoding: SignatureEncoding,
1852) -> Result<Signature, CryptoErrno> {
1853    let mut rp0 = MaybeUninit::<Signature>::uninit();
1854    let ret = wasi_ephemeral_crypto_signatures::signature_import(
1855        algorithm.as_ptr() as i32,
1856        algorithm.len() as i32,
1857        encoded as i32,
1858        encoded_len as i32,
1859        encoding.0 as i32,
1860        rp0.as_mut_ptr() as i32,
1861    );
1862    match ret {
1863        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Signature)),
1864        _ => Err(CryptoErrno(ret as u16)),
1865    }
1866}
1867
1868/// Create a new state to collect data to compute a signature on.
1869///
1870/// This function allows data to be signed to be supplied in a streaming
1871/// fashion.
1872///
1873/// The state is not closed and can be used after a signature has been computed,
1874/// allowing incremental updates by calling `signature_state_update()` again
1875/// afterwards.
1876///
1877/// Example usage - signature creation
1878///
1879/// ```rust
1880/// let kp_handle = ctx.keypair_import(
1881///     AlgorithmType::Signatures,
1882///     "Ed25519ph",
1883///     keypair,
1884///     KeypairEncoding::Raw,
1885/// )?;
1886/// let state_handle = ctx.signature_state_open(kp_handle)?;
1887/// ctx.signature_state_update(state_handle, b"message part 1")?;
1888/// ctx.signature_state_update(state_handle, b"message part 2")?;
1889/// let sig_handle = ctx.signature_state_sign(state_handle)?;
1890/// let raw_sig = ctx.signature_export(sig_handle, SignatureEncoding::Raw)?;
1891/// ```
1892pub unsafe fn signature_state_open(kp: SignatureKeypair) -> Result<SignatureState, CryptoErrno> {
1893    let mut rp0 = MaybeUninit::<SignatureState>::uninit();
1894    let ret =
1895        wasi_ephemeral_crypto_signatures::signature_state_open(kp as i32, rp0.as_mut_ptr() as i32);
1896    match ret {
1897        0 => Ok(core::ptr::read(
1898            rp0.as_mut_ptr() as i32 as *const SignatureState
1899        )),
1900        _ => Err(CryptoErrno(ret as u16)),
1901    }
1902}
1903
1904/// Absorb data into the signature state.
1905///
1906/// This function may return `unsupported_feature` is the selected algorithm
1907/// doesn't support incremental updates.
1908pub unsafe fn signature_state_update(
1909    state: SignatureState,
1910    input: *const u8,
1911    input_len: Size,
1912) -> Result<(), CryptoErrno> {
1913    let ret = wasi_ephemeral_crypto_signatures::signature_state_update(
1914        state as i32,
1915        input as i32,
1916        input_len as i32,
1917    );
1918    match ret {
1919        0 => Ok(()),
1920        _ => Err(CryptoErrno(ret as u16)),
1921    }
1922}
1923
1924/// Compute a signature for all the data collected up to that point.
1925///
1926/// The function can be called multiple times for incremental signing.
1927pub unsafe fn signature_state_sign(state: SignatureState) -> Result<ArrayOutput, CryptoErrno> {
1928    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
1929    let ret = wasi_ephemeral_crypto_signatures::signature_state_sign(
1930        state as i32,
1931        rp0.as_mut_ptr() as i32,
1932    );
1933    match ret {
1934        0 => Ok(core::ptr::read(
1935            rp0.as_mut_ptr() as i32 as *const ArrayOutput
1936        )),
1937        _ => Err(CryptoErrno(ret as u16)),
1938    }
1939}
1940
1941/// Destroy a signature state.
1942///
1943/// Objects are reference counted. It is safe to close an object immediately
1944/// after the last function needing it is called.
1945///
1946/// Note that closing a signature state doesn't close or invalidate the key pair
1947/// object, that be reused for further signatures.
1948pub unsafe fn signature_state_close(state: SignatureState) -> Result<(), CryptoErrno> {
1949    let ret = wasi_ephemeral_crypto_signatures::signature_state_close(state as i32);
1950    match ret {
1951        0 => Ok(()),
1952        _ => Err(CryptoErrno(ret as u16)),
1953    }
1954}
1955
1956/// Create a new state to collect data to verify a signature on.
1957///
1958/// This is the verification counterpart of `signature_state`.
1959///
1960/// Data can be injected using `signature_verification_state_update()`, and the
1961/// state is not closed after a verification, allowing incremental verification.
1962///
1963/// Example usage - signature verification:
1964///
1965/// ```rust
1966/// let pk_handle = ctx.publickey_import(
1967///     AlgorithmType::Signatures,
1968///     "ECDSA_P256_SHA256",
1969///     encoded_pk,
1970///     PublicKeyEncoding::Sec,
1971/// )?;
1972/// let signature_handle = ctx.signature_import(
1973///     AlgorithmType::Signatures,
1974///     "ECDSA_P256_SHA256",
1975///     encoded_sig,
1976///     SignatureEncoding::Der,
1977/// )?;
1978/// let state_handle = ctx.signature_verification_state_open(pk_handle)?;
1979/// ctx.signature_verification_state_update(state_handle, "message")?;
1980/// ctx.signature_verification_state_verify(signature_handle)?;
1981/// ```
1982pub unsafe fn signature_verification_state_open(
1983    kp: SignaturePublickey,
1984) -> Result<SignatureVerificationState, CryptoErrno> {
1985    let mut rp0 = MaybeUninit::<SignatureVerificationState>::uninit();
1986    let ret = wasi_ephemeral_crypto_signatures::signature_verification_state_open(
1987        kp as i32,
1988        rp0.as_mut_ptr() as i32,
1989    );
1990    match ret {
1991        0 => Ok(core::ptr::read(
1992            rp0.as_mut_ptr() as i32 as *const SignatureVerificationState
1993        )),
1994        _ => Err(CryptoErrno(ret as u16)),
1995    }
1996}
1997
1998/// Absorb data into the signature verification state.
1999///
2000/// This function may return `unsupported_feature` is the selected algorithm
2001/// doesn't support incremental updates.
2002pub unsafe fn signature_verification_state_update(
2003    state: SignatureVerificationState,
2004    input: *const u8,
2005    input_len: Size,
2006) -> Result<(), CryptoErrno> {
2007    let ret = wasi_ephemeral_crypto_signatures::signature_verification_state_update(
2008        state as i32,
2009        input as i32,
2010        input_len as i32,
2011    );
2012    match ret {
2013        0 => Ok(()),
2014        _ => Err(CryptoErrno(ret as u16)),
2015    }
2016}
2017
2018/// Check that the given signature is verifies for the data collected up to that
2019/// point point.
2020///
2021/// The state is not closed and can absorb more data to allow for incremental
2022/// verification.
2023///
2024/// The function returns `invalid_signature` if the signature doesn't appear to
2025/// be valid.
2026pub unsafe fn signature_verification_state_verify(
2027    state: SignatureVerificationState,
2028    signature: Signature,
2029) -> Result<(), CryptoErrno> {
2030    let ret = wasi_ephemeral_crypto_signatures::signature_verification_state_verify(
2031        state as i32,
2032        signature as i32,
2033    );
2034    match ret {
2035        0 => Ok(()),
2036        _ => Err(CryptoErrno(ret as u16)),
2037    }
2038}
2039
2040/// Destroy a signature verification state.
2041///
2042/// Objects are reference counted. It is safe to close an object immediately
2043/// after the last function needing it is called.
2044///
2045/// Note that closing a signature state doesn't close or invalidate the public
2046/// key object, that be reused for further verifications.
2047pub unsafe fn signature_verification_state_close(
2048    state: SignatureVerificationState,
2049) -> Result<(), CryptoErrno> {
2050    let ret = wasi_ephemeral_crypto_signatures::signature_verification_state_close(state as i32);
2051    match ret {
2052        0 => Ok(()),
2053        _ => Err(CryptoErrno(ret as u16)),
2054    }
2055}
2056
2057/// Destroy a signature.
2058///
2059/// Objects are reference counted. It is safe to close an object immediately
2060/// after the last function needing it is called.
2061pub unsafe fn signature_close(signature: Signature) -> Result<(), CryptoErrno> {
2062    let ret = wasi_ephemeral_crypto_signatures::signature_close(signature as i32);
2063    match ret {
2064        0 => Ok(()),
2065        _ => Err(CryptoErrno(ret as u16)),
2066    }
2067}
2068
2069pub mod wasi_ephemeral_crypto_signatures {
2070    #[link(wasm_import_module = "wasi_ephemeral_crypto_signatures")]
2071    extern "C" {
2072        /// Export a signature.
2073        ///
2074        /// This function exports a signature object using the specified
2075        /// encoding.
2076        ///
2077        /// May return `unsupported_encoding` if the signature cannot be encoded
2078        /// into the given format.
2079        pub fn signature_export(arg0: i32, arg1: i32, arg2: i32) -> i32;
2080        /// Create a signature object.
2081        ///
2082        /// This object can be used along with a public key to verify an
2083        /// existing signature.
2084        ///
2085        /// It may return `invalid_signature` if the signature is invalid or
2086        /// incompatible with the specified algorithm, as well as
2087        /// `unsupported_encoding` if the encoding is not compatible with the
2088        /// signature type.
2089        ///
2090        /// The function may also return `unsupported_algorithm` if the
2091        /// algorithm is not supported by the host.
2092        ///
2093        /// Example usage:
2094        ///
2095        /// ```rust
2096        /// let signature_handle =
2097        ///     ctx.signature_import("ECDSA_P256_SHA256", SignatureEncoding::DER, encoded)?;
2098        /// ```
2099        pub fn signature_import(
2100            arg0: i32,
2101            arg1: i32,
2102            arg2: i32,
2103            arg3: i32,
2104            arg4: i32,
2105            arg5: i32,
2106        ) -> i32;
2107        /// Create a new state to collect data to compute a signature on.
2108        ///
2109        /// This function allows data to be signed to be supplied in a streaming
2110        /// fashion.
2111        ///
2112        /// The state is not closed and can be used after a signature has been
2113        /// computed, allowing incremental updates by calling
2114        /// `signature_state_update()` again afterwards.
2115        ///
2116        /// Example usage - signature creation
2117        ///
2118        /// ```rust
2119        /// let kp_handle = ctx.keypair_import(
2120        ///     AlgorithmType::Signatures,
2121        ///     "Ed25519ph",
2122        ///     keypair,
2123        ///     KeypairEncoding::Raw,
2124        /// )?;
2125        /// let state_handle = ctx.signature_state_open(kp_handle)?;
2126        /// ctx.signature_state_update(state_handle, b"message part 1")?;
2127        /// ctx.signature_state_update(state_handle, b"message part 2")?;
2128        /// let sig_handle = ctx.signature_state_sign(state_handle)?;
2129        /// let raw_sig = ctx.signature_export(sig_handle, SignatureEncoding::Raw)?;
2130        /// ```
2131        pub fn signature_state_open(arg0: i32, arg1: i32) -> i32;
2132        /// Absorb data into the signature state.
2133        ///
2134        /// This function may return `unsupported_feature` is the selected
2135        /// algorithm doesn't support incremental updates.
2136        pub fn signature_state_update(arg0: i32, arg1: i32, arg2: i32) -> i32;
2137        /// Compute a signature for all the data collected up to that point.
2138        ///
2139        /// The function can be called multiple times for incremental signing.
2140        pub fn signature_state_sign(arg0: i32, arg1: i32) -> i32;
2141        /// Destroy a signature state.
2142        ///
2143        /// Objects are reference counted. It is safe to close an object
2144        /// immediately after the last function needing it is called.
2145        ///
2146        /// Note that closing a signature state doesn't close or invalidate the
2147        /// key pair object, that be reused for further signatures.
2148        pub fn signature_state_close(arg0: i32) -> i32;
2149        /// Create a new state to collect data to verify a signature on.
2150        ///
2151        /// This is the verification counterpart of `signature_state`.
2152        ///
2153        /// Data can be injected using `signature_verification_state_update()`,
2154        /// and the state is not closed after a verification, allowing
2155        /// incremental verification.
2156        ///
2157        /// Example usage - signature verification:
2158        ///
2159        /// ```rust
2160        /// let pk_handle = ctx.publickey_import(
2161        ///     AlgorithmType::Signatures,
2162        ///     "ECDSA_P256_SHA256",
2163        ///     encoded_pk,
2164        ///     PublicKeyEncoding::Sec,
2165        /// )?;
2166        /// let signature_handle = ctx.signature_import(
2167        ///     AlgorithmType::Signatures,
2168        ///     "ECDSA_P256_SHA256",
2169        ///     encoded_sig,
2170        ///     SignatureEncoding::Der,
2171        /// )?;
2172        /// let state_handle = ctx.signature_verification_state_open(pk_handle)?;
2173        /// ctx.signature_verification_state_update(state_handle, "message")?;
2174        /// ctx.signature_verification_state_verify(signature_handle)?;
2175        /// ```
2176        pub fn signature_verification_state_open(arg0: i32, arg1: i32) -> i32;
2177        /// Absorb data into the signature verification state.
2178        ///
2179        /// This function may return `unsupported_feature` is the selected
2180        /// algorithm doesn't support incremental updates.
2181        pub fn signature_verification_state_update(arg0: i32, arg1: i32, arg2: i32) -> i32;
2182        /// Check that the given signature is verifies for the data collected up
2183        /// to that point point.
2184        ///
2185        /// The state is not closed and can absorb more data to allow for
2186        /// incremental verification.
2187        ///
2188        /// The function returns `invalid_signature` if the signature doesn't
2189        /// appear to be valid.
2190        pub fn signature_verification_state_verify(arg0: i32, arg1: i32) -> i32;
2191        /// Destroy a signature verification state.
2192        ///
2193        /// Objects are reference counted. It is safe to close an object
2194        /// immediately after the last function needing it is called.
2195        ///
2196        /// Note that closing a signature state doesn't close or invalidate the
2197        /// public key object, that be reused for further verifications.
2198        pub fn signature_verification_state_close(arg0: i32) -> i32;
2199        /// Destroy a signature.
2200        ///
2201        /// Objects are reference counted. It is safe to close an object
2202        /// immediately after the last function needing it is called.
2203        pub fn signature_close(arg0: i32) -> i32;
2204    }
2205}
2206/// Generate a new symmetric key for a given algorithm.
2207///
2208/// `options` can be `None` to use the default parameters, or an
2209/// algoritm-specific set of parameters to override.
2210///
2211/// This function may return `unsupported_feature` if key generation is not
2212/// supported by the host for the chosen algorithm, or `unsupported_algorithm`
2213/// if the algorithm is not supported by the host.
2214pub unsafe fn symmetric_key_generate(
2215    algorithm: &str,
2216    options: OptOptions,
2217) -> Result<SymmetricKey, CryptoErrno> {
2218    let mut rp0 = MaybeUninit::<SymmetricKey>::uninit();
2219    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_generate(
2220        algorithm.as_ptr() as i32,
2221        algorithm.len() as i32,
2222        &options as *const _ as i32,
2223        rp0.as_mut_ptr() as i32,
2224    );
2225    match ret {
2226        0 => Ok(core::ptr::read(
2227            rp0.as_mut_ptr() as i32 as *const SymmetricKey
2228        )),
2229        _ => Err(CryptoErrno(ret as u16)),
2230    }
2231}
2232
2233/// Create a symmetric key from raw material.
2234///
2235/// The algorithm is internally stored along with the key, and trying to use the
2236/// key with an operation expecting a different algorithm will return
2237/// `invalid_key`.
2238///
2239/// The function may also return `unsupported_algorithm` if the algorithm is not
2240/// supported by the host.
2241pub unsafe fn symmetric_key_import(
2242    algorithm: &str,
2243    raw: *const u8,
2244    raw_len: Size,
2245) -> Result<SymmetricKey, CryptoErrno> {
2246    let mut rp0 = MaybeUninit::<SymmetricKey>::uninit();
2247    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_import(
2248        algorithm.as_ptr() as i32,
2249        algorithm.len() as i32,
2250        raw as i32,
2251        raw_len as i32,
2252        rp0.as_mut_ptr() as i32,
2253    );
2254    match ret {
2255        0 => Ok(core::ptr::read(
2256            rp0.as_mut_ptr() as i32 as *const SymmetricKey
2257        )),
2258        _ => Err(CryptoErrno(ret as u16)),
2259    }
2260}
2261
2262/// Export a symmetric key as raw material.
2263///
2264/// This is mainly useful to export a managed key.
2265///
2266/// May return `prohibited_operation` if this operation is denied.
2267pub unsafe fn symmetric_key_export(
2268    symmetric_key: SymmetricKey,
2269) -> Result<ArrayOutput, CryptoErrno> {
2270    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
2271    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_export(
2272        symmetric_key as i32,
2273        rp0.as_mut_ptr() as i32,
2274    );
2275    match ret {
2276        0 => Ok(core::ptr::read(
2277            rp0.as_mut_ptr() as i32 as *const ArrayOutput
2278        )),
2279        _ => Err(CryptoErrno(ret as u16)),
2280    }
2281}
2282
2283/// Destroy a symmetric key.
2284///
2285/// Objects are reference counted. It is safe to close an object immediately
2286/// after the last function needing it is called.
2287pub unsafe fn symmetric_key_close(symmetric_key: SymmetricKey) -> Result<(), CryptoErrno> {
2288    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_close(symmetric_key as i32);
2289    match ret {
2290        0 => Ok(()),
2291        _ => Err(CryptoErrno(ret as u16)),
2292    }
2293}
2294
2295/// __(optional)__
2296/// Generate a new managed symmetric key.
2297///
2298/// The key is generated and stored by the secrets management facilities.
2299///
2300/// It may be used through its identifier, but the host may not allow it to be
2301/// exported.
2302///
2303/// The function returns the `unsupported_feature` error code if secrets
2304/// management facilities are not supported by the host,
2305/// or `unsupported_algorithm` if a key cannot be created for the chosen
2306/// algorithm.
2307///
2308/// The function may also return `unsupported_algorithm` if the algorithm is not
2309/// supported by the host.
2310///
2311/// This is also an optional import, meaning that the function may not even
2312/// exist.
2313pub unsafe fn symmetric_key_generate_managed(
2314    secrets_manager: SecretsManager,
2315    algorithm: &str,
2316    options: OptOptions,
2317) -> Result<SymmetricKey, CryptoErrno> {
2318    let mut rp0 = MaybeUninit::<SymmetricKey>::uninit();
2319    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_generate_managed(
2320        secrets_manager as i32,
2321        algorithm.as_ptr() as i32,
2322        algorithm.len() as i32,
2323        &options as *const _ as i32,
2324        rp0.as_mut_ptr() as i32,
2325    );
2326    match ret {
2327        0 => Ok(core::ptr::read(
2328            rp0.as_mut_ptr() as i32 as *const SymmetricKey
2329        )),
2330        _ => Err(CryptoErrno(ret as u16)),
2331    }
2332}
2333
2334/// __(optional)__
2335/// Store a symmetric key into the secrets manager.
2336///
2337/// On success, the function stores the key identifier into `$symmetric_key_id`,
2338/// into which up to `$symmetric_key_id_max_len` can be written.
2339///
2340/// The function returns `overflow` if the supplied buffer is too small.
2341pub unsafe fn symmetric_key_store_managed(
2342    secrets_manager: SecretsManager,
2343    symmetric_key: SymmetricKey,
2344    symmetric_key_id: *mut u8,
2345    symmetric_key_id_max_len: Size,
2346) -> Result<(), CryptoErrno> {
2347    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_store_managed(
2348        secrets_manager as i32,
2349        symmetric_key as i32,
2350        symmetric_key_id as i32,
2351        symmetric_key_id_max_len as i32,
2352    );
2353    match ret {
2354        0 => Ok(()),
2355        _ => Err(CryptoErrno(ret as u16)),
2356    }
2357}
2358
2359/// __(optional)__
2360/// Replace a managed symmetric key.
2361///
2362/// This function crates a new version of a managed symmetric key, by replacing
2363/// `$kp_old` with `$kp_new`.
2364///
2365/// It does several things:
2366///
2367/// - The key identifier for `$symmetric_key_new` is set to the one of
2368///   `$symmetric_key_old`.
2369/// - A new, unique version identifier is assigned to `$kp_new`. This version
2370///   will be equivalent to using `$version_latest` until the key is replaced.
2371/// - The `$symmetric_key_old` handle is closed.
2372///
2373/// Both keys must share the same algorithm and have compatible parameters. If
2374/// this is not the case, `incompatible_keys` is returned.
2375///
2376/// The function may also return the `unsupported_feature` error code if secrets
2377/// management facilities are not supported by the host, or if keys cannot be
2378/// rotated.
2379///
2380/// Finally, `prohibited_operation` can be returned if `$symmetric_key_new`
2381/// wasn't created by the secrets manager, and the secrets manager prohibits
2382/// imported keys.
2383///
2384/// If the operation succeeded, the new version is returned.
2385///
2386/// This is an optional import, meaning that the function may not even exist.
2387pub unsafe fn symmetric_key_replace_managed(
2388    secrets_manager: SecretsManager,
2389    symmetric_key_old: SymmetricKey,
2390    symmetric_key_new: SymmetricKey,
2391) -> Result<Version, CryptoErrno> {
2392    let mut rp0 = MaybeUninit::<Version>::uninit();
2393    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_replace_managed(
2394        secrets_manager as i32,
2395        symmetric_key_old as i32,
2396        symmetric_key_new as i32,
2397        rp0.as_mut_ptr() as i32,
2398    );
2399    match ret {
2400        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Version)),
2401        _ => Err(CryptoErrno(ret as u16)),
2402    }
2403}
2404
2405/// __(optional)__
2406/// Return the key identifier and version of a managed symmetric key.
2407///
2408/// If the key is not managed, `unsupported_feature` is returned instead.
2409///
2410/// This is an optional import, meaning that the function may not even exist.
2411pub unsafe fn symmetric_key_id(
2412    symmetric_key: SymmetricKey,
2413    symmetric_key_id: *mut u8,
2414    symmetric_key_id_max_len: Size,
2415) -> Result<(Size, Version), CryptoErrno> {
2416    let mut rp0 = MaybeUninit::<Size>::uninit();
2417    let mut rp1 = MaybeUninit::<Version>::uninit();
2418    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_id(
2419        symmetric_key as i32,
2420        symmetric_key_id as i32,
2421        symmetric_key_id_max_len as i32,
2422        rp0.as_mut_ptr() as i32,
2423        rp1.as_mut_ptr() as i32,
2424    );
2425    match ret {
2426        0 => Ok((
2427            core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size),
2428            core::ptr::read(rp1.as_mut_ptr() as i32 as *const Version),
2429        )),
2430        _ => Err(CryptoErrno(ret as u16)),
2431    }
2432}
2433
2434/// __(optional)__
2435/// Return a managed symmetric key from a key identifier.
2436///
2437/// `kp_version` can be set to `version_latest` to retrieve the most recent
2438/// version of a symmetric key.
2439///
2440/// If no key matching the provided information is found, `not_found` is
2441/// returned instead.
2442///
2443/// This is an optional import, meaning that the function may not even exist.
2444pub unsafe fn symmetric_key_from_id(
2445    secrets_manager: SecretsManager,
2446    symmetric_key_id: *const u8,
2447    symmetric_key_id_len: Size,
2448    symmetric_key_version: Version,
2449) -> Result<SymmetricKey, CryptoErrno> {
2450    let mut rp0 = MaybeUninit::<SymmetricKey>::uninit();
2451    let ret = wasi_ephemeral_crypto_symmetric::symmetric_key_from_id(
2452        secrets_manager as i32,
2453        symmetric_key_id as i32,
2454        symmetric_key_id_len as i32,
2455        symmetric_key_version as i64,
2456        rp0.as_mut_ptr() as i32,
2457    );
2458    match ret {
2459        0 => Ok(core::ptr::read(
2460            rp0.as_mut_ptr() as i32 as *const SymmetricKey
2461        )),
2462        _ => Err(CryptoErrno(ret as u16)),
2463    }
2464}
2465
2466/// Create a new state to aborb and produce data using symmetric operations.
2467///
2468/// The state remains valid after every operation in order to support
2469/// incremental updates.
2470///
2471/// The function has two optional parameters: a key and an options set.
2472///
2473/// It will fail with a `key_not_supported` error code if a key was provided but
2474/// the chosen algorithm doesn't natively support keying.
2475///
2476/// On the other hand, if a key is required, but was not provided, a
2477/// `key_required` error will be thrown.
2478///
2479/// Some algorithms may require additional parameters. They have to be supplied
2480/// as an options set:
2481///
2482/// ```rust
2483/// let options_handle = ctx.options_open()?;
2484/// ctx.options_set("context", b"My application")?;
2485/// ctx.options_set_u64("fanout", 16)?;
2486/// let state_handle = ctx.symmetric_state_open("BLAKE2b-512", None, Some(options_handle))?;
2487/// ```
2488///
2489/// If some parameters are mandatory but were not set, the `parameters_missing`
2490/// error code will be returned.
2491///
2492/// A notable exception is the `nonce` parameter, that is common to most AEAD
2493/// constructions.
2494///
2495/// If a nonce is required but was not supplied:
2496///
2497/// - If it is safe to do so, the host will automatically generate a nonce. This
2498///   is true for nonces that are large enough to be randomly generated, or if
2499///   the host is able to maintain a global counter.
2500/// - If not, the function will fail and return the dedicated `nonce_required`
2501///   error code.
2502///
2503/// A nonce that was automatically generated can be retrieved after the function
2504/// returns with `symmetric_state_get(state_handle, "nonce")`.
2505///
2506/// **Sample usage patterns:**
2507///
2508/// - **Hashing**
2509///
2510/// ```rust
2511/// let mut out = [0u8; 64];
2512/// let state_handle = ctx.symmetric_state_open("SHAKE-128", None, None)?;
2513/// ctx.symmetric_state_absorb(state_handle, b"data")?;
2514/// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
2515/// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
2516/// ```
2517///
2518/// - **MAC**
2519///
2520/// ```rust
2521/// let mut raw_tag = [0u8; 64];
2522/// let key_handle = ctx.symmetric_key_import("HMAC/SHA-512", b"key")?;
2523/// let state_handle = ctx.symmetric_state_open("HMAC/SHA-512", Some(key_handle), None)?;
2524/// ctx.symmetric_state_absorb(state_handle, b"data")?;
2525/// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
2526/// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
2527/// ctx.symmetric_tag_pull(computed_tag_handle, &mut raw_tag)?;
2528/// ```
2529///
2530/// Verification:
2531///
2532/// ```rust
2533/// let state_handle = ctx.symmetric_state_open("HMAC/SHA-512", Some(key_handle), None)?;
2534/// ctx.symmetric_state_absorb(state_handle, b"data")?;
2535/// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
2536/// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
2537/// ctx.symmetric_tag_verify(computed_tag_handle, expected_raw_tag)?;
2538/// ```
2539///
2540/// - **Tuple hashing**
2541///
2542/// ```rust
2543/// let mut out = [0u8; 64];
2544/// let state_handle = ctx.symmetric_state_open("TupleHashXOF256", None, None)?;
2545/// ctx.symmetric_state_absorb(state_handle, b"value 1")?;
2546/// ctx.symmetric_state_absorb(state_handle, b"value 2")?;
2547/// ctx.symmetric_state_absorb(state_handle, b"value 3")?;
2548/// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
2549/// ```
2550/// Unlike MACs and regular hash functions, inputs are domain separated instead
2551/// of being concatenated.
2552///
2553/// - **Key derivation using extract-and-expand**
2554///
2555/// Extract:
2556///
2557/// ```rust
2558/// let mut prk = vec![0u8; 64];
2559/// let key_handle = ctx.symmetric_key_import("HKDF-EXTRACT/SHA-512", b"key")?;
2560/// let state_handle = ctx.symmetric_state_open("HKDF-EXTRACT/SHA-512", Some(key_handle), None)?;
2561/// ctx.symmetric_state_absorb(state_handle, b"salt")?;
2562/// let prk_handle = ctx.symmetric_state_squeeze_key(state_handle, "HKDF-EXPAND/SHA-512")?;
2563/// ```
2564///
2565/// Expand:
2566///
2567/// ```rust
2568/// let mut subkey = vec![0u8; 32];
2569/// let state_handle = ctx.symmetric_state_open("HKDF-EXPAND/SHA-512", Some(prk_handle), None)?;
2570/// ctx.symmetric_state_absorb(state_handle, b"info")?;
2571/// ctx.symmetric_state_squeeze(state_handle, &mut subkey)?;
2572/// ```
2573///
2574/// - **Key derivation using a XOF**
2575///
2576/// ```rust
2577/// let mut subkey1 = vec![0u8; 32];
2578/// let mut subkey2 = vec![0u8; 32];
2579/// let key_handle = ctx.symmetric_key_import("BLAKE3", b"key")?;
2580/// let state_handle = ctx.symmetric_state_open("BLAKE3", Some(key_handle), None)?;
2581/// ctx.symmetric_absorb(state_handle, b"context")?;
2582/// ctx.squeeze(state_handle, &mut subkey1)?;
2583/// ctx.squeeze(state_handle, &mut subkey2)?;
2584/// ```
2585///
2586/// - **Password hashing**
2587///
2588/// ```rust
2589/// let mut memory = vec![0u8; 1_000_000_000];
2590/// let options_handle = ctx.symmetric_options_open()?;
2591/// ctx.symmetric_options_set_guest_buffer(options_handle, "memory", &mut memory)?;
2592/// ctx.symmetric_options_set_u64(options_handle, "opslimit", 5)?;
2593/// ctx.symmetric_options_set_u64(options_handle, "parallelism", 8)?;
2594///
2595/// let state_handle = ctx.symmetric_state_open("ARGON2-ID-13", None, Some(options))?;
2596/// ctx.symmtric_state_absorb(state_handle, b"password")?;
2597///
2598/// let pw_str_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
2599/// let mut pw_str = vec![0u8; ctx.symmetric_tag_len(pw_str_handle)?];
2600/// ctx.symmetric_tag_pull(pw_str_handle, &mut pw_str)?;
2601/// ```
2602///
2603/// - **AEAD encryption with an explicit nonce**
2604///
2605/// ```rust
2606/// let key_handle = ctx.symmetric_key_generate("AES-256-GCM", None)?;
2607/// let message = b"test";
2608///
2609/// let options_handle = ctx.symmetric_options_open()?;
2610/// ctx.symmetric_options_set(options_handle, "nonce", nonce)?;
2611///
2612/// let state_handle =
2613///     ctx.symmetric_state_open("AES-256-GCM", Some(key_handle), Some(options_handle))?;
2614/// let mut ciphertext = vec![0u8; message.len() + ctx.symmetric_state_max_tag_len(state_handle)?];
2615/// ctx.symmetric_state_absorb(state_handle, "additional data")?;
2616/// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, message)?;
2617/// ```
2618///
2619/// - **AEAD encryption with automatic nonce generation**
2620///
2621/// ```rust
2622/// let key_handle = ctx.symmetric_key_generate("AES-256-GCM-SIV", None)?;
2623/// let message = b"test";
2624/// let mut nonce = [0u8; 24];
2625///
2626/// let state_handle = ctx.symmetric_state_open("AES-256-GCM-SIV", Some(key_handle), None)?;
2627///
2628/// let nonce = ctx.symmetric_state_options_get(state_handle, "nonce")?;
2629///
2630/// let mut ciphertext = vec![0u8; message.len() + ctx.symmetric_state_max_tag_len(state_handle)?];
2631/// ctx.symmetric_state_absorb(state_handle, "additional data")?;
2632/// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, message)?;
2633/// ```
2634///
2635/// - **Session authenticated modes**
2636///
2637/// ```rust
2638/// let mut out = [0u8; 16];
2639/// let mut out2 = [0u8; 16];
2640/// let mut ciphertext = [0u8; 20];
2641/// let key_handle = ctx.symmetric_key_generate("Xoodyak-128", None)?;
2642/// let state_handle = ctx.symmetric_state_open("Xoodyak-128", Some(key_handle), None)?;
2643/// ctx.symmetric_state_absorb(state_handle, b"data")?;
2644/// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, b"abcd")?;
2645/// ctx.symmetric_state_absorb(state_handle, b"more data")?;
2646/// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
2647/// ctx.symmetric_state_squeeze(state_handle, &mut out2)?;
2648/// ctx.symmetric_state_ratchet(state_handle)?;
2649/// ctx.symmetric_state_absorb(state_handle, b"more data")?;
2650/// let next_key_handle = ctx.symmetric_state_squeeze_key(state_handle, "Xoodyak-128")?;
2651/// // ...
2652/// ```
2653pub unsafe fn symmetric_state_open(
2654    algorithm: &str,
2655    key: OptSymmetricKey,
2656    options: OptOptions,
2657) -> Result<SymmetricState, CryptoErrno> {
2658    let mut rp0 = MaybeUninit::<SymmetricState>::uninit();
2659    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_open(
2660        algorithm.as_ptr() as i32,
2661        algorithm.len() as i32,
2662        &key as *const _ as i32,
2663        &options as *const _ as i32,
2664        rp0.as_mut_ptr() as i32,
2665    );
2666    match ret {
2667        0 => Ok(core::ptr::read(
2668            rp0.as_mut_ptr() as i32 as *const SymmetricState
2669        )),
2670        _ => Err(CryptoErrno(ret as u16)),
2671    }
2672}
2673
2674/// Retrieve a parameter from the current state.
2675///
2676/// In particular, `symmetric_state_options_get("nonce")` can be used to get a
2677/// nonce that as automatically generated.
2678///
2679/// The function may return `options_not_set` if an option was not set, which is
2680/// different from an empty value.
2681///
2682/// It may also return `unsupported_option` if the option doesn't exist for the
2683/// chosen algorithm.
2684pub unsafe fn symmetric_state_options_get(
2685    handle: SymmetricState,
2686    name: &str,
2687    value: *mut u8,
2688    value_max_len: Size,
2689) -> Result<Size, CryptoErrno> {
2690    let mut rp0 = MaybeUninit::<Size>::uninit();
2691    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_options_get(
2692        handle as i32,
2693        name.as_ptr() as i32,
2694        name.len() as i32,
2695        value as i32,
2696        value_max_len as i32,
2697        rp0.as_mut_ptr() as i32,
2698    );
2699    match ret {
2700        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
2701        _ => Err(CryptoErrno(ret as u16)),
2702    }
2703}
2704
2705/// Retrieve an integer parameter from the current state.
2706///
2707/// The function may return `options_not_set` if an option was not set.
2708///
2709/// It may also return `unsupported_option` if the option doesn't exist for the
2710/// chosen algorithm.
2711pub unsafe fn symmetric_state_options_get_u64(
2712    handle: SymmetricState,
2713    name: &str,
2714) -> Result<U64, CryptoErrno> {
2715    let mut rp0 = MaybeUninit::<U64>::uninit();
2716    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_options_get_u64(
2717        handle as i32,
2718        name.as_ptr() as i32,
2719        name.len() as i32,
2720        rp0.as_mut_ptr() as i32,
2721    );
2722    match ret {
2723        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const U64)),
2724        _ => Err(CryptoErrno(ret as u16)),
2725    }
2726}
2727
2728/// Clone a symmetric state.
2729///
2730/// The function clones the internal state, assigns a new handle to it and
2731/// returns the new handle.
2732pub unsafe fn symmetric_state_clone(handle: SymmetricState) -> Result<SymmetricState, CryptoErrno> {
2733    let mut rp0 = MaybeUninit::<SymmetricState>::uninit();
2734    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_clone(
2735        handle as i32,
2736        rp0.as_mut_ptr() as i32,
2737    );
2738    match ret {
2739        0 => Ok(core::ptr::read(
2740            rp0.as_mut_ptr() as i32 as *const SymmetricState
2741        )),
2742        _ => Err(CryptoErrno(ret as u16)),
2743    }
2744}
2745
2746/// Destroy a symmetric state.
2747///
2748/// Objects are reference counted. It is safe to close an object immediately
2749/// after the last function needing it is called.
2750pub unsafe fn symmetric_state_close(handle: SymmetricState) -> Result<(), CryptoErrno> {
2751    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_close(handle as i32);
2752    match ret {
2753        0 => Ok(()),
2754        _ => Err(CryptoErrno(ret as u16)),
2755    }
2756}
2757
2758/// Absorb data into the state.
2759///
2760/// - **Hash functions:** adds data to be hashed.
2761/// - **MAC functions:** adds data to be authenticated.
2762/// - **Tuplehash-like constructions:** adds a new tuple to the state.
2763/// - **Key derivation functions:** adds to the IKM or to the subkey
2764///   information.
2765/// - **AEAD constructions:** adds additional data to be authenticated.
2766/// - **Stateful hash objects, permutation-based constructions:** absorbs.
2767///
2768/// If the chosen algorithm doesn't accept input data, the `invalid_operation`
2769/// error code is returned.
2770///
2771/// If too much data has been fed for the algorithm, `overflow` may be thrown.
2772pub unsafe fn symmetric_state_absorb(
2773    handle: SymmetricState,
2774    data: *const u8,
2775    data_len: Size,
2776) -> Result<(), CryptoErrno> {
2777    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_absorb(
2778        handle as i32,
2779        data as i32,
2780        data_len as i32,
2781    );
2782    match ret {
2783        0 => Ok(()),
2784        _ => Err(CryptoErrno(ret as u16)),
2785    }
2786}
2787
2788/// Squeeze bytes from the state.
2789///
2790/// - **Hash functions:** this tries to output an `out_len` bytes digest from
2791///   the absorbed data. The hash function output will be truncated if
2792///   necessary. If the requested size is too large, the `invalid_len` error
2793///   code is returned.
2794/// - **Key derivation functions:** : outputs an arbitrary-long derived key.
2795/// - **RNGs, DRBGs, stream ciphers:**: outputs arbitrary-long data.
2796/// - **Stateful hash objects, permutation-based constructions:** squeeze.
2797///
2798/// Other kinds of algorithms may return `invalid_operation` instead.
2799///
2800/// For password-stretching functions, the function may return `in_progress`.
2801/// In that case, the guest should retry with the same parameters until the
2802/// function completes.
2803pub unsafe fn symmetric_state_squeeze(
2804    handle: SymmetricState,
2805    out: *mut u8,
2806    out_len: Size,
2807) -> Result<(), CryptoErrno> {
2808    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_squeeze(
2809        handle as i32,
2810        out as i32,
2811        out_len as i32,
2812    );
2813    match ret {
2814        0 => Ok(()),
2815        _ => Err(CryptoErrno(ret as u16)),
2816    }
2817}
2818
2819/// Compute and return a tag for all the data injected into the state so far.
2820///
2821/// - **MAC functions**: returns a tag authenticating the absorbed data.
2822/// - **Tuplehash-like constructions:** returns a tag authenticating all the
2823///   absorbed tuples.
2824/// - **Password-hashing functions:** returns a standard string containing all
2825///   the required parameters for password verification.
2826///
2827/// Other kinds of algorithms may return `invalid_operation` instead.
2828///
2829/// For password-stretching functions, the function may return `in_progress`.
2830/// In that case, the guest should retry with the same parameters until the
2831/// function completes.
2832pub unsafe fn symmetric_state_squeeze_tag(
2833    handle: SymmetricState,
2834) -> Result<SymmetricTag, CryptoErrno> {
2835    let mut rp0 = MaybeUninit::<SymmetricTag>::uninit();
2836    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_squeeze_tag(
2837        handle as i32,
2838        rp0.as_mut_ptr() as i32,
2839    );
2840    match ret {
2841        0 => Ok(core::ptr::read(
2842            rp0.as_mut_ptr() as i32 as *const SymmetricTag
2843        )),
2844        _ => Err(CryptoErrno(ret as u16)),
2845    }
2846}
2847
2848/// Use the current state to produce a key for a target algorithm.
2849///
2850/// For extract-then-expand constructions, this returns the PRK.
2851/// For session-base authentication encryption, this returns a key that can be
2852/// used to resume a session without storing a nonce.
2853///
2854/// `invalid_operation` is returned for algorithms not supporting this
2855/// operation.
2856pub unsafe fn symmetric_state_squeeze_key(
2857    handle: SymmetricState,
2858    alg_str: &str,
2859) -> Result<SymmetricKey, CryptoErrno> {
2860    let mut rp0 = MaybeUninit::<SymmetricKey>::uninit();
2861    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_squeeze_key(
2862        handle as i32,
2863        alg_str.as_ptr() as i32,
2864        alg_str.len() as i32,
2865        rp0.as_mut_ptr() as i32,
2866    );
2867    match ret {
2868        0 => Ok(core::ptr::read(
2869            rp0.as_mut_ptr() as i32 as *const SymmetricKey
2870        )),
2871        _ => Err(CryptoErrno(ret as u16)),
2872    }
2873}
2874
2875/// Return the maximum length of an authentication tag for the current
2876/// algorithm.
2877///
2878/// This allows guests to compute the size required to store a ciphertext along
2879/// with its authentication tag.
2880///
2881/// The returned length may include the encryption mode's padding requirements
2882/// in addition to the actual tag.
2883///
2884/// For an encryption operation, the size of the output buffer should be
2885/// `input_len + symmetric_state_max_tag_len()`.
2886///
2887/// For a decryption operation, the size of the buffer that will store the
2888/// decrypted data must be `ciphertext_len - symmetric_state_max_tag_len()`.
2889pub unsafe fn symmetric_state_max_tag_len(handle: SymmetricState) -> Result<Size, CryptoErrno> {
2890    let mut rp0 = MaybeUninit::<Size>::uninit();
2891    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_max_tag_len(
2892        handle as i32,
2893        rp0.as_mut_ptr() as i32,
2894    );
2895    match ret {
2896        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
2897        _ => Err(CryptoErrno(ret as u16)),
2898    }
2899}
2900
2901/// Encrypt data with an attached tag.
2902///
2903/// - **Stream cipher:** adds the input to the stream cipher output. `out_len`
2904///   and `data_len` can be equal, as no authentication tags will be added.
2905/// - **AEAD:** encrypts `data` into `out`, including the authentication tag to
2906///   the output. Additional data must have been previously absorbed using
2907///   `symmetric_state_absorb()`. The `symmetric_state_max_tag_len()` function
2908///   can be used to retrieve the overhead of adding the tag, as well as padding
2909///   if necessary.
2910/// - **SHOE, Xoodyak, Strobe:** encrypts data, squeezes a tag and appends it to
2911///   the output.
2912///
2913/// If `out` and `data` are the same address, encryption may happen in-place.
2914///
2915/// The function returns the actual size of the ciphertext along with the tag.
2916///
2917/// `invalid_operation` is returned for algorithms not supporting encryption.
2918pub unsafe fn symmetric_state_encrypt(
2919    handle: SymmetricState,
2920    out: *mut u8,
2921    out_len: Size,
2922    data: *const u8,
2923    data_len: Size,
2924) -> Result<Size, CryptoErrno> {
2925    let mut rp0 = MaybeUninit::<Size>::uninit();
2926    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_encrypt(
2927        handle as i32,
2928        out as i32,
2929        out_len as i32,
2930        data as i32,
2931        data_len as i32,
2932        rp0.as_mut_ptr() as i32,
2933    );
2934    match ret {
2935        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
2936        _ => Err(CryptoErrno(ret as u16)),
2937    }
2938}
2939
2940/// Encrypt data, with a detached tag.
2941///
2942/// - **Stream cipher:** returns `invalid_operation` since stream ciphers do not
2943///   include authentication tags.
2944/// - **AEAD:** encrypts `data` into `out` and returns the tag separately.
2945///   Additional data must have been previously absorbed using
2946///   `symmetric_state_absorb()`. The output and input buffers must be of the
2947///   same length.
2948/// - **SHOE, Xoodyak, Strobe:** encrypts data and squeezes a tag.
2949///
2950/// If `out` and `data` are the same address, encryption may happen in-place.
2951///
2952/// The function returns the tag.
2953///
2954/// `invalid_operation` is returned for algorithms not supporting encryption.
2955pub unsafe fn symmetric_state_encrypt_detached(
2956    handle: SymmetricState,
2957    out: *mut u8,
2958    out_len: Size,
2959    data: *const u8,
2960    data_len: Size,
2961) -> Result<SymmetricTag, CryptoErrno> {
2962    let mut rp0 = MaybeUninit::<SymmetricTag>::uninit();
2963    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_encrypt_detached(
2964        handle as i32,
2965        out as i32,
2966        out_len as i32,
2967        data as i32,
2968        data_len as i32,
2969        rp0.as_mut_ptr() as i32,
2970    );
2971    match ret {
2972        0 => Ok(core::ptr::read(
2973            rp0.as_mut_ptr() as i32 as *const SymmetricTag
2974        )),
2975        _ => Err(CryptoErrno(ret as u16)),
2976    }
2977}
2978
2979/// - **Stream cipher:** adds the input to the stream cipher output. `out_len`
2980///   and `data_len` can be equal, as no authentication tags will be added.
2981/// - **AEAD:** decrypts `data` into `out`. Additional data must have been
2982///   previously absorbed using `symmetric_state_absorb()`.
2983/// - **SHOE, Xoodyak, Strobe:** decrypts data, squeezes a tag and verify that
2984///   it matches the one that was appended to the ciphertext.
2985///
2986/// If `out` and `data` are the same address, decryption may happen in-place.
2987///
2988/// `out_len` must be exactly `data_len` + `max_tag_len` bytes.
2989///
2990/// The function returns the actual size of the decrypted message, which can be
2991/// smaller than `out_len` for modes that requires padding.
2992///
2993/// `invalid_tag` is returned if the tag didn't verify.
2994///
2995/// `invalid_operation` is returned for algorithms not supporting encryption.
2996pub unsafe fn symmetric_state_decrypt(
2997    handle: SymmetricState,
2998    out: *mut u8,
2999    out_len: Size,
3000    data: *const u8,
3001    data_len: Size,
3002) -> Result<Size, CryptoErrno> {
3003    let mut rp0 = MaybeUninit::<Size>::uninit();
3004    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_decrypt(
3005        handle as i32,
3006        out as i32,
3007        out_len as i32,
3008        data as i32,
3009        data_len as i32,
3010        rp0.as_mut_ptr() as i32,
3011    );
3012    match ret {
3013        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
3014        _ => Err(CryptoErrno(ret as u16)),
3015    }
3016}
3017
3018/// - **Stream cipher:** returns `invalid_operation` since stream ciphers do not
3019///   include authentication tags.
3020/// - **AEAD:** decrypts `data` into `out`. Additional data must have been
3021///   previously absorbed using `symmetric_state_absorb()`.
3022/// - **SHOE, Xoodyak, Strobe:** decrypts data, squeezes a tag and verify that
3023///   it matches the expected one.
3024///
3025/// `raw_tag` is the expected tag, as raw bytes.
3026///
3027/// `out` and `data` be must have the same length.
3028/// If they also share the same address, decryption may happen in-place.
3029///
3030/// The function returns the actual size of the decrypted message.
3031///
3032/// `invalid_tag` is returned if the tag verification failed.
3033///
3034/// `invalid_operation` is returned for algorithms not supporting encryption.
3035pub unsafe fn symmetric_state_decrypt_detached(
3036    handle: SymmetricState,
3037    out: *mut u8,
3038    out_len: Size,
3039    data: *const u8,
3040    data_len: Size,
3041    raw_tag: *const u8,
3042    raw_tag_len: Size,
3043) -> Result<Size, CryptoErrno> {
3044    let mut rp0 = MaybeUninit::<Size>::uninit();
3045    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_decrypt_detached(
3046        handle as i32,
3047        out as i32,
3048        out_len as i32,
3049        data as i32,
3050        data_len as i32,
3051        raw_tag as i32,
3052        raw_tag_len as i32,
3053        rp0.as_mut_ptr() as i32,
3054    );
3055    match ret {
3056        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
3057        _ => Err(CryptoErrno(ret as u16)),
3058    }
3059}
3060
3061/// Make it impossible to recover the previous state.
3062///
3063/// This operation is supported by some systems keeping a rolling state over an
3064/// entire session, for forward security.
3065///
3066/// `invalid_operation` is returned for algorithms not supporting ratcheting.
3067pub unsafe fn symmetric_state_ratchet(handle: SymmetricState) -> Result<(), CryptoErrno> {
3068    let ret = wasi_ephemeral_crypto_symmetric::symmetric_state_ratchet(handle as i32);
3069    match ret {
3070        0 => Ok(()),
3071        _ => Err(CryptoErrno(ret as u16)),
3072    }
3073}
3074
3075/// Return the length of an authentication tag.
3076///
3077/// This function can be used by a guest to allocate the correct buffer size to
3078/// copy a computed authentication tag.
3079pub unsafe fn symmetric_tag_len(symmetric_tag: SymmetricTag) -> Result<Size, CryptoErrno> {
3080    let mut rp0 = MaybeUninit::<Size>::uninit();
3081    let ret = wasi_ephemeral_crypto_symmetric::symmetric_tag_len(
3082        symmetric_tag as i32,
3083        rp0.as_mut_ptr() as i32,
3084    );
3085    match ret {
3086        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
3087        _ => Err(CryptoErrno(ret as u16)),
3088    }
3089}
3090
3091/// Copy an authentication tag into a guest-allocated buffer.
3092///
3093/// The handle automatically becomes invalid after this operation. Manually
3094/// closing it is not required.
3095///
3096/// Example usage:
3097///
3098/// ```rust
3099/// let mut raw_tag = [0u8; 16];
3100/// ctx.symmetric_tag_pull(raw_tag_handle, &mut raw_tag)?;
3101/// ```
3102///
3103/// The function returns `overflow` if the supplied buffer is too small to copy
3104/// the tag.
3105///
3106/// Otherwise, it returns the number of bytes that have been copied.
3107pub unsafe fn symmetric_tag_pull(
3108    symmetric_tag: SymmetricTag,
3109    buf: *mut u8,
3110    buf_len: Size,
3111) -> Result<Size, CryptoErrno> {
3112    let mut rp0 = MaybeUninit::<Size>::uninit();
3113    let ret = wasi_ephemeral_crypto_symmetric::symmetric_tag_pull(
3114        symmetric_tag as i32,
3115        buf as i32,
3116        buf_len as i32,
3117        rp0.as_mut_ptr() as i32,
3118    );
3119    match ret {
3120        0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Size)),
3121        _ => Err(CryptoErrno(ret as u16)),
3122    }
3123}
3124
3125/// Verify that a computed authentication tag matches the expected value, in
3126/// constant-time.
3127///
3128/// The expected tag must be provided as a raw byte string.
3129///
3130/// The function returns `invalid_tag` if the tags don't match.
3131///
3132/// Example usage:
3133///
3134/// ```rust
3135/// let key_handle = ctx.symmetric_key_import("HMAC/SHA-256", b"key")?;
3136/// let state_handle = ctx.symmetric_state_open("HMAC/SHA-256", Some(key_handle), None)?;
3137/// ctx.symmetric_state_absorb(state_handle, b"data")?;
3138/// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
3139/// ctx.symmetric_tag_verify(computed_tag_handle, expected_raw_tag)?;
3140/// ```
3141pub unsafe fn symmetric_tag_verify(
3142    symmetric_tag: SymmetricTag,
3143    expected_raw_tag_ptr: *const u8,
3144    expected_raw_tag_len: Size,
3145) -> Result<(), CryptoErrno> {
3146    let ret = wasi_ephemeral_crypto_symmetric::symmetric_tag_verify(
3147        symmetric_tag as i32,
3148        expected_raw_tag_ptr as i32,
3149        expected_raw_tag_len as i32,
3150    );
3151    match ret {
3152        0 => Ok(()),
3153        _ => Err(CryptoErrno(ret as u16)),
3154    }
3155}
3156
3157/// Explicitly destroy an unused authentication tag.
3158///
3159/// This is usually not necessary, as `symmetric_tag_pull()` automatically
3160/// closes a tag after it has been copied.
3161///
3162/// Objects are reference counted. It is safe to close an object immediately
3163/// after the last function needing it is called.
3164pub unsafe fn symmetric_tag_close(symmetric_tag: SymmetricTag) -> Result<(), CryptoErrno> {
3165    let ret = wasi_ephemeral_crypto_symmetric::symmetric_tag_close(symmetric_tag as i32);
3166    match ret {
3167        0 => Ok(()),
3168        _ => Err(CryptoErrno(ret as u16)),
3169    }
3170}
3171
3172pub mod wasi_ephemeral_crypto_symmetric {
3173    #[link(wasm_import_module = "wasi_ephemeral_crypto_symmetric")]
3174    extern "C" {
3175        /// Generate a new symmetric key for a given algorithm.
3176        ///
3177        /// `options` can be `None` to use the default parameters, or an
3178        /// algoritm-specific set of parameters to override.
3179        ///
3180        /// This function may return `unsupported_feature` if key generation is
3181        /// not supported by the host for the chosen algorithm, or
3182        /// `unsupported_algorithm` if the algorithm is not supported by the
3183        /// host.
3184        pub fn symmetric_key_generate(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3185        /// Create a symmetric key from raw material.
3186        ///
3187        /// The algorithm is internally stored along with the key, and trying to
3188        /// use the key with an operation expecting a different algorithm will
3189        /// return `invalid_key`.
3190        ///
3191        /// The function may also return `unsupported_algorithm` if the
3192        /// algorithm is not supported by the host.
3193        pub fn symmetric_key_import(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32;
3194        /// Export a symmetric key as raw material.
3195        ///
3196        /// This is mainly useful to export a managed key.
3197        ///
3198        /// May return `prohibited_operation` if this operation is denied.
3199        pub fn symmetric_key_export(arg0: i32, arg1: i32) -> i32;
3200        /// Destroy a symmetric key.
3201        ///
3202        /// Objects are reference counted. It is safe to close an object
3203        /// immediately after the last function needing it is called.
3204        pub fn symmetric_key_close(arg0: i32) -> i32;
3205        /// __(optional)__
3206        /// Generate a new managed symmetric key.
3207        ///
3208        /// The key is generated and stored by the secrets management
3209        /// facilities.
3210        ///
3211        /// It may be used through its identifier, but the host may not allow it
3212        /// to be exported.
3213        ///
3214        /// The function returns the `unsupported_feature` error code if secrets
3215        /// management facilities are not supported by the host,
3216        /// or `unsupported_algorithm` if a key cannot be created for the chosen
3217        /// algorithm.
3218        ///
3219        /// The function may also return `unsupported_algorithm` if the
3220        /// algorithm is not supported by the host.
3221        ///
3222        /// This is also an optional import, meaning that the function may not
3223        /// even exist.
3224        pub fn symmetric_key_generate_managed(
3225            arg0: i32,
3226            arg1: i32,
3227            arg2: i32,
3228            arg3: i32,
3229            arg4: i32,
3230        ) -> i32;
3231        /// __(optional)__
3232        /// Store a symmetric key into the secrets manager.
3233        ///
3234        /// On success, the function stores the key identifier into
3235        /// `$symmetric_key_id`, into which up to
3236        /// `$symmetric_key_id_max_len` can be written.
3237        ///
3238        /// The function returns `overflow` if the supplied buffer is too small.
3239        pub fn symmetric_key_store_managed(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3240        /// __(optional)__
3241        /// Replace a managed symmetric key.
3242        ///
3243        /// This function crates a new version of a managed symmetric key, by
3244        /// replacing `$kp_old` with `$kp_new`.
3245        ///
3246        /// It does several things:
3247        ///
3248        /// - The key identifier for `$symmetric_key_new` is set to the one of
3249        ///   `$symmetric_key_old`.
3250        /// - A new, unique version identifier is assigned to `$kp_new`. This
3251        ///   version will be equivalent to using `$version_latest` until the
3252        ///   key is replaced.
3253        /// - The `$symmetric_key_old` handle is closed.
3254        ///
3255        /// Both keys must share the same algorithm and have compatible
3256        /// parameters. If this is not the case, `incompatible_keys` is
3257        /// returned.
3258        ///
3259        /// The function may also return the `unsupported_feature` error code if
3260        /// secrets management facilities are not supported by the host,
3261        /// or if keys cannot be rotated.
3262        ///
3263        /// Finally, `prohibited_operation` can be returned if
3264        /// `$symmetric_key_new` wasn't created by the secrets manager, and the
3265        /// secrets manager prohibits imported keys.
3266        ///
3267        /// If the operation succeeded, the new version is returned.
3268        ///
3269        /// This is an optional import, meaning that the function may not even
3270        /// exist.
3271        pub fn symmetric_key_replace_managed(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3272        /// __(optional)__
3273        /// Return the key identifier and version of a managed symmetric key.
3274        ///
3275        /// If the key is not managed, `unsupported_feature` is returned
3276        /// instead.
3277        ///
3278        /// This is an optional import, meaning that the function may not even
3279        /// exist.
3280        pub fn symmetric_key_id(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32;
3281        /// __(optional)__
3282        /// Return a managed symmetric key from a key identifier.
3283        ///
3284        /// `kp_version` can be set to `version_latest` to retrieve the most
3285        /// recent version of a symmetric key.
3286        ///
3287        /// If no key matching the provided information is found, `not_found` is
3288        /// returned instead.
3289        ///
3290        /// This is an optional import, meaning that the function may not even
3291        /// exist.
3292        pub fn symmetric_key_from_id(arg0: i32, arg1: i32, arg2: i32, arg3: i64, arg4: i32) -> i32;
3293        /// Create a new state to aborb and produce data using symmetric
3294        /// operations.
3295        ///
3296        /// The state remains valid after every operation in order to support
3297        /// incremental updates.
3298        ///
3299        /// The function has two optional parameters: a key and an options set.
3300        ///
3301        /// It will fail with a `key_not_supported` error code if a key was
3302        /// provided but the chosen algorithm doesn't natively support keying.
3303        ///
3304        /// On the other hand, if a key is required, but was not provided, a
3305        /// `key_required` error will be thrown.
3306        ///
3307        /// Some algorithms may require additional parameters. They have to be
3308        /// supplied as an options set:
3309        ///
3310        /// ```rust
3311        /// let options_handle = ctx.options_open()?;
3312        /// ctx.options_set("context", b"My application")?;
3313        /// ctx.options_set_u64("fanout", 16)?;
3314        /// let state_handle = ctx.symmetric_state_open("BLAKE2b-512", None, Some(options_handle))?;
3315        /// ```
3316        ///
3317        /// If some parameters are mandatory but were not set, the
3318        /// `parameters_missing` error code will be returned.
3319        ///
3320        /// A notable exception is the `nonce` parameter, that is common to most
3321        /// AEAD constructions.
3322        ///
3323        /// If a nonce is required but was not supplied:
3324        ///
3325        /// - If it is safe to do so, the host will automatically generate a
3326        ///   nonce. This is true for nonces that are large enough to be
3327        ///   randomly generated, or if the host is able to maintain a global
3328        ///   counter.
3329        /// - If not, the function will fail and return the dedicated
3330        ///   `nonce_required` error code.
3331        ///
3332        /// A nonce that was automatically generated can be retrieved after the
3333        /// function returns with `symmetric_state_get(state_handle, "nonce")`.
3334        ///
3335        /// **Sample usage patterns:**
3336        ///
3337        /// - **Hashing**
3338        ///
3339        /// ```rust
3340        /// let mut out = [0u8; 64];
3341        /// let state_handle = ctx.symmetric_state_open("SHAKE-128", None, None)?;
3342        /// ctx.symmetric_state_absorb(state_handle, b"data")?;
3343        /// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
3344        /// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
3345        /// ```
3346        ///
3347        /// - **MAC**
3348        ///
3349        /// ```rust
3350        /// let mut raw_tag = [0u8; 64];
3351        /// let key_handle = ctx.symmetric_key_import("HMAC/SHA-512", b"key")?;
3352        /// let state_handle = ctx.symmetric_state_open("HMAC/SHA-512", Some(key_handle), None)?;
3353        /// ctx.symmetric_state_absorb(state_handle, b"data")?;
3354        /// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
3355        /// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
3356        /// ctx.symmetric_tag_pull(computed_tag_handle, &mut raw_tag)?;
3357        /// ```
3358        ///
3359        /// Verification:
3360        ///
3361        /// ```rust
3362        /// let state_handle = ctx.symmetric_state_open("HMAC/SHA-512", Some(key_handle), None)?;
3363        /// ctx.symmetric_state_absorb(state_handle, b"data")?;
3364        /// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
3365        /// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
3366        /// ctx.symmetric_tag_verify(computed_tag_handle, expected_raw_tag)?;
3367        /// ```
3368        ///
3369        /// - **Tuple hashing**
3370        ///
3371        /// ```rust
3372        /// let mut out = [0u8; 64];
3373        /// let state_handle = ctx.symmetric_state_open("TupleHashXOF256", None, None)?;
3374        /// ctx.symmetric_state_absorb(state_handle, b"value 1")?;
3375        /// ctx.symmetric_state_absorb(state_handle, b"value 2")?;
3376        /// ctx.symmetric_state_absorb(state_handle, b"value 3")?;
3377        /// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
3378        /// ```
3379        /// Unlike MACs and regular hash functions, inputs are domain separated
3380        /// instead of being concatenated.
3381        ///
3382        /// - **Key derivation using extract-and-expand**
3383        ///
3384        /// Extract:
3385        ///
3386        /// ```rust
3387        /// let mut prk = vec![0u8; 64];
3388        /// let key_handle = ctx.symmetric_key_import("HKDF-EXTRACT/SHA-512", b"key")?;
3389        /// let state_handle = ctx.symmetric_state_open("HKDF-EXTRACT/SHA-512", Some(key_handle), None)?;
3390        /// ctx.symmetric_state_absorb(state_handle, b"salt")?;
3391        /// let prk_handle = ctx.symmetric_state_squeeze_key(state_handle, "HKDF-EXPAND/SHA-512")?;
3392        /// ```
3393        ///
3394        /// Expand:
3395        ///
3396        /// ```rust
3397        /// let mut subkey = vec![0u8; 32];
3398        /// let state_handle = ctx.symmetric_state_open("HKDF-EXPAND/SHA-512", Some(prk_handle), None)?;
3399        /// ctx.symmetric_state_absorb(state_handle, b"info")?;
3400        /// ctx.symmetric_state_squeeze(state_handle, &mut subkey)?;
3401        /// ```
3402        ///
3403        /// - **Key derivation using a XOF**
3404        ///
3405        /// ```rust
3406        /// let mut subkey1 = vec![0u8; 32];
3407        /// let mut subkey2 = vec![0u8; 32];
3408        /// let key_handle = ctx.symmetric_key_import("BLAKE3", b"key")?;
3409        /// let state_handle = ctx.symmetric_state_open("BLAKE3", Some(key_handle), None)?;
3410        /// ctx.symmetric_absorb(state_handle, b"context")?;
3411        /// ctx.squeeze(state_handle, &mut subkey1)?;
3412        /// ctx.squeeze(state_handle, &mut subkey2)?;
3413        /// ```
3414        ///
3415        /// - **Password hashing**
3416        ///
3417        /// ```rust
3418        /// let mut memory = vec![0u8; 1_000_000_000];
3419        /// let options_handle = ctx.symmetric_options_open()?;
3420        /// ctx.symmetric_options_set_guest_buffer(options_handle, "memory", &mut memory)?;
3421        /// ctx.symmetric_options_set_u64(options_handle, "opslimit", 5)?;
3422        /// ctx.symmetric_options_set_u64(options_handle, "parallelism", 8)?;
3423        ///
3424        /// let state_handle = ctx.symmetric_state_open("ARGON2-ID-13", None, Some(options))?;
3425        /// ctx.symmtric_state_absorb(state_handle, b"password")?;
3426        ///
3427        /// let pw_str_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
3428        /// let mut pw_str = vec![0u8; ctx.symmetric_tag_len(pw_str_handle)?];
3429        /// ctx.symmetric_tag_pull(pw_str_handle, &mut pw_str)?;
3430        /// ```
3431        ///
3432        /// - **AEAD encryption with an explicit nonce**
3433        ///
3434        /// ```rust
3435        /// let key_handle = ctx.symmetric_key_generate("AES-256-GCM", None)?;
3436        /// let message = b"test";
3437        ///
3438        /// let options_handle = ctx.symmetric_options_open()?;
3439        /// ctx.symmetric_options_set(options_handle, "nonce", nonce)?;
3440        ///
3441        /// let state_handle =
3442        ///     ctx.symmetric_state_open("AES-256-GCM", Some(key_handle), Some(options_handle))?;
3443        /// let mut ciphertext = vec![0u8; message.len() + ctx.symmetric_state_max_tag_len(state_handle)?];
3444        /// ctx.symmetric_state_absorb(state_handle, "additional data")?;
3445        /// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, message)?;
3446        /// ```
3447        ///
3448        /// - **AEAD encryption with automatic nonce generation**
3449        ///
3450        /// ```rust
3451        /// let key_handle = ctx.symmetric_key_generate("AES-256-GCM-SIV", None)?;
3452        /// let message = b"test";
3453        /// let mut nonce = [0u8; 24];
3454        ///
3455        /// let state_handle = ctx.symmetric_state_open("AES-256-GCM-SIV", Some(key_handle), None)?;
3456        ///
3457        /// let nonce = ctx.symmetric_state_options_get(state_handle, "nonce")?;
3458        ///
3459        /// let mut ciphertext = vec![0u8; message.len() + ctx.symmetric_state_max_tag_len(state_handle)?];
3460        /// ctx.symmetric_state_absorb(state_handle, "additional data")?;
3461        /// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, message)?;
3462        /// ```
3463        ///
3464        /// - **Session authenticated modes**
3465        ///
3466        /// ```rust
3467        /// let mut out = [0u8; 16];
3468        /// let mut out2 = [0u8; 16];
3469        /// let mut ciphertext = [0u8; 20];
3470        /// let key_handle = ctx.symmetric_key_generate("Xoodyak-128", None)?;
3471        /// let state_handle = ctx.symmetric_state_open("Xoodyak-128", Some(key_handle), None)?;
3472        /// ctx.symmetric_state_absorb(state_handle, b"data")?;
3473        /// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, b"abcd")?;
3474        /// ctx.symmetric_state_absorb(state_handle, b"more data")?;
3475        /// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
3476        /// ctx.symmetric_state_squeeze(state_handle, &mut out2)?;
3477        /// ctx.symmetric_state_ratchet(state_handle)?;
3478        /// ctx.symmetric_state_absorb(state_handle, b"more data")?;
3479        /// let next_key_handle = ctx.symmetric_state_squeeze_key(state_handle, "Xoodyak-128")?;
3480        /// // ...
3481        /// ```
3482        pub fn symmetric_state_open(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32;
3483        /// Retrieve a parameter from the current state.
3484        ///
3485        /// In particular, `symmetric_state_options_get("nonce")` can be used to
3486        /// get a nonce that as automatically generated.
3487        ///
3488        /// The function may return `options_not_set` if an option was not set,
3489        /// which is different from an empty value.
3490        ///
3491        /// It may also return `unsupported_option` if the option doesn't exist
3492        /// for the chosen algorithm.
3493        pub fn symmetric_state_options_get(
3494            arg0: i32,
3495            arg1: i32,
3496            arg2: i32,
3497            arg3: i32,
3498            arg4: i32,
3499            arg5: i32,
3500        ) -> i32;
3501        /// Retrieve an integer parameter from the current state.
3502        ///
3503        /// The function may return `options_not_set` if an option was not set.
3504        ///
3505        /// It may also return `unsupported_option` if the option doesn't exist
3506        /// for the chosen algorithm.
3507        pub fn symmetric_state_options_get_u64(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3508        /// Clone a symmetric state.
3509        ///
3510        /// The function clones the internal state, assigns a new handle to it
3511        /// and returns the new handle.
3512        pub fn symmetric_state_clone(arg0: i32, arg1: i32) -> i32;
3513        /// Destroy a symmetric state.
3514        ///
3515        /// Objects are reference counted. It is safe to close an object
3516        /// immediately after the last function needing it is called.
3517        pub fn symmetric_state_close(arg0: i32) -> i32;
3518        /// Absorb data into the state.
3519        ///
3520        /// - **Hash functions:** adds data to be hashed.
3521        /// - **MAC functions:** adds data to be authenticated.
3522        /// - **Tuplehash-like constructions:** adds a new tuple to the state.
3523        /// - **Key derivation functions:** adds to the IKM or to the subkey
3524        ///   information.
3525        /// - **AEAD constructions:** adds additional data to be authenticated.
3526        /// - **Stateful hash objects, permutation-based constructions:**
3527        ///   absorbs.
3528        ///
3529        /// If the chosen algorithm doesn't accept input data, the
3530        /// `invalid_operation` error code is returned.
3531        ///
3532        /// If too much data has been fed for the algorithm, `overflow` may be
3533        /// thrown.
3534        pub fn symmetric_state_absorb(arg0: i32, arg1: i32, arg2: i32) -> i32;
3535        /// Squeeze bytes from the state.
3536        ///
3537        /// - **Hash functions:** this tries to output an `out_len` bytes digest
3538        ///   from the absorbed data. The hash function output will be truncated
3539        ///   if necessary. If the requested size is too large, the
3540        ///   `invalid_len` error code is returned.
3541        /// - **Key derivation functions:** : outputs an arbitrary-long derived
3542        ///   key.
3543        /// - **RNGs, DRBGs, stream ciphers:**: outputs arbitrary-long data.
3544        /// - **Stateful hash objects, permutation-based constructions:**
3545        ///   squeeze.
3546        ///
3547        /// Other kinds of algorithms may return `invalid_operation` instead.
3548        ///
3549        /// For password-stretching functions, the function may return
3550        /// `in_progress`. In that case, the guest should retry with the
3551        /// same parameters until the function completes.
3552        pub fn symmetric_state_squeeze(arg0: i32, arg1: i32, arg2: i32) -> i32;
3553        /// Compute and return a tag for all the data injected into the state so
3554        /// far.
3555        ///
3556        /// - **MAC functions**: returns a tag authenticating the absorbed data.
3557        /// - **Tuplehash-like constructions:** returns a tag authenticating all
3558        ///   the absorbed tuples.
3559        /// - **Password-hashing functions:** returns a standard string
3560        ///   containing all the required parameters for password verification.
3561        ///
3562        /// Other kinds of algorithms may return `invalid_operation` instead.
3563        ///
3564        /// For password-stretching functions, the function may return
3565        /// `in_progress`. In that case, the guest should retry with the
3566        /// same parameters until the function completes.
3567        pub fn symmetric_state_squeeze_tag(arg0: i32, arg1: i32) -> i32;
3568        /// Use the current state to produce a key for a target algorithm.
3569        ///
3570        /// For extract-then-expand constructions, this returns the PRK.
3571        /// For session-base authentication encryption, this returns a key that
3572        /// can be used to resume a session without storing a nonce.
3573        ///
3574        /// `invalid_operation` is returned for algorithms not supporting this
3575        /// operation.
3576        pub fn symmetric_state_squeeze_key(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3577        /// Return the maximum length of an authentication tag for the current
3578        /// algorithm.
3579        ///
3580        /// This allows guests to compute the size required to store a
3581        /// ciphertext along with its authentication tag.
3582        ///
3583        /// The returned length may include the encryption mode's padding
3584        /// requirements in addition to the actual tag.
3585        ///
3586        /// For an encryption operation, the size of the output buffer should be
3587        /// `input_len + symmetric_state_max_tag_len()`.
3588        ///
3589        /// For a decryption operation, the size of the buffer that will store
3590        /// the decrypted data must be `ciphertext_len -
3591        /// symmetric_state_max_tag_len()`.
3592        pub fn symmetric_state_max_tag_len(arg0: i32, arg1: i32) -> i32;
3593        /// Encrypt data with an attached tag.
3594        ///
3595        /// - **Stream cipher:** adds the input to the stream cipher output.
3596        ///   `out_len` and `data_len` can be equal, as no authentication tags
3597        ///   will be added.
3598        /// - **AEAD:** encrypts `data` into `out`, including the authentication
3599        ///   tag to the output. Additional data must have been previously
3600        ///   absorbed using `symmetric_state_absorb()`. The
3601        ///   `symmetric_state_max_tag_len()` function can be used to retrieve
3602        ///   the overhead of adding the tag, as well as padding if necessary.
3603        /// - **SHOE, Xoodyak, Strobe:** encrypts data, squeezes a tag and
3604        ///   appends it to the output.
3605        ///
3606        /// If `out` and `data` are the same address, encryption may happen
3607        /// in-place.
3608        ///
3609        /// The function returns the actual size of the ciphertext along with
3610        /// the tag.
3611        ///
3612        /// `invalid_operation` is returned for algorithms not supporting
3613        /// encryption.
3614        pub fn symmetric_state_encrypt(
3615            arg0: i32,
3616            arg1: i32,
3617            arg2: i32,
3618            arg3: i32,
3619            arg4: i32,
3620            arg5: i32,
3621        ) -> i32;
3622        /// Encrypt data, with a detached tag.
3623        ///
3624        /// - **Stream cipher:** returns `invalid_operation` since stream
3625        ///   ciphers do not include authentication tags.
3626        /// - **AEAD:** encrypts `data` into `out` and returns the tag
3627        ///   separately. Additional data must have been previously absorbed
3628        ///   using `symmetric_state_absorb()`. The output and input buffers
3629        ///   must be of the same length.
3630        /// - **SHOE, Xoodyak, Strobe:** encrypts data and squeezes a tag.
3631        ///
3632        /// If `out` and `data` are the same address, encryption may happen
3633        /// in-place.
3634        ///
3635        /// The function returns the tag.
3636        ///
3637        /// `invalid_operation` is returned for algorithms not supporting
3638        /// encryption.
3639        pub fn symmetric_state_encrypt_detached(
3640            arg0: i32,
3641            arg1: i32,
3642            arg2: i32,
3643            arg3: i32,
3644            arg4: i32,
3645            arg5: i32,
3646        ) -> i32;
3647        /// - **Stream cipher:** adds the input to the stream cipher output.
3648        ///   `out_len` and `data_len` can be equal, as no authentication tags
3649        ///   will be added.
3650        /// - **AEAD:** decrypts `data` into `out`. Additional data must have
3651        ///   been previously absorbed using `symmetric_state_absorb()`.
3652        /// - **SHOE, Xoodyak, Strobe:** decrypts data, squeezes a tag and
3653        ///   verify that it matches the one that was appended to the
3654        ///   ciphertext.
3655        ///
3656        /// If `out` and `data` are the same address, decryption may happen
3657        /// in-place.
3658        ///
3659        /// `out_len` must be exactly `data_len` + `max_tag_len` bytes.
3660        ///
3661        /// The function returns the actual size of the decrypted message, which
3662        /// can be smaller than `out_len` for modes that requires padding.
3663        ///
3664        /// `invalid_tag` is returned if the tag didn't verify.
3665        ///
3666        /// `invalid_operation` is returned for algorithms not supporting
3667        /// encryption.
3668        pub fn symmetric_state_decrypt(
3669            arg0: i32,
3670            arg1: i32,
3671            arg2: i32,
3672            arg3: i32,
3673            arg4: i32,
3674            arg5: i32,
3675        ) -> i32;
3676        /// - **Stream cipher:** returns `invalid_operation` since stream
3677        ///   ciphers do not include authentication tags.
3678        /// - **AEAD:** decrypts `data` into `out`. Additional data must have
3679        ///   been previously absorbed using `symmetric_state_absorb()`.
3680        /// - **SHOE, Xoodyak, Strobe:** decrypts data, squeezes a tag and
3681        ///   verify that it matches the expected one.
3682        ///
3683        /// `raw_tag` is the expected tag, as raw bytes.
3684        ///
3685        /// `out` and `data` be must have the same length.
3686        /// If they also share the same address, decryption may happen in-place.
3687        ///
3688        /// The function returns the actual size of the decrypted message.
3689        ///
3690        /// `invalid_tag` is returned if the tag verification failed.
3691        ///
3692        /// `invalid_operation` is returned for algorithms not supporting
3693        /// encryption.
3694        pub fn symmetric_state_decrypt_detached(
3695            arg0: i32,
3696            arg1: i32,
3697            arg2: i32,
3698            arg3: i32,
3699            arg4: i32,
3700            arg5: i32,
3701            arg6: i32,
3702            arg7: i32,
3703        ) -> i32;
3704        /// Make it impossible to recover the previous state.
3705        ///
3706        /// This operation is supported by some systems keeping a rolling state
3707        /// over an entire session, for forward security.
3708        ///
3709        /// `invalid_operation` is returned for algorithms not supporting
3710        /// ratcheting.
3711        pub fn symmetric_state_ratchet(arg0: i32) -> i32;
3712        /// Return the length of an authentication tag.
3713        ///
3714        /// This function can be used by a guest to allocate the correct buffer
3715        /// size to copy a computed authentication tag.
3716        pub fn symmetric_tag_len(arg0: i32, arg1: i32) -> i32;
3717        /// Copy an authentication tag into a guest-allocated buffer.
3718        ///
3719        /// The handle automatically becomes invalid after this operation.
3720        /// Manually closing it is not required.
3721        ///
3722        /// Example usage:
3723        ///
3724        /// ```rust
3725        /// let mut raw_tag = [0u8; 16];
3726        /// ctx.symmetric_tag_pull(raw_tag_handle, &mut raw_tag)?;
3727        /// ```
3728        ///
3729        /// The function returns `overflow` if the supplied buffer is too small
3730        /// to copy the tag.
3731        ///
3732        /// Otherwise, it returns the number of bytes that have been copied.
3733        pub fn symmetric_tag_pull(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3734        /// Verify that a computed authentication tag matches the expected
3735        /// value, in constant-time.
3736        ///
3737        /// The expected tag must be provided as a raw byte string.
3738        ///
3739        /// The function returns `invalid_tag` if the tags don't match.
3740        ///
3741        /// Example usage:
3742        ///
3743        /// ```rust
3744        /// let key_handle = ctx.symmetric_key_import("HMAC/SHA-256", b"key")?;
3745        /// let state_handle = ctx.symmetric_state_open("HMAC/SHA-256", Some(key_handle), None)?;
3746        /// ctx.symmetric_state_absorb(state_handle, b"data")?;
3747        /// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
3748        /// ctx.symmetric_tag_verify(computed_tag_handle, expected_raw_tag)?;
3749        /// ```
3750        pub fn symmetric_tag_verify(arg0: i32, arg1: i32, arg2: i32) -> i32;
3751        /// Explicitly destroy an unused authentication tag.
3752        ///
3753        /// This is usually not necessary, as `symmetric_tag_pull()`
3754        /// automatically closes a tag after it has been copied.
3755        ///
3756        /// Objects are reference counted. It is safe to close an object
3757        /// immediately after the last function needing it is called.
3758        pub fn symmetric_tag_close(arg0: i32) -> i32;
3759    }
3760}
3761/// Perform a simple Diffie-Hellman key exchange.
3762///
3763/// Both keys must be of the same type, or else the
3764/// `$crypto_errno.incompatible_keys` error is returned. The algorithm also has
3765/// to support this kind of key exchange. If this is not the case, the
3766/// `$crypto_errno.invalid_operation` error is returned.
3767///
3768/// Otherwide, a raw shared key is returned, and can be imported as a symmetric
3769/// key. ```
3770pub unsafe fn kx_dh(pk: Publickey, sk: Secretkey) -> Result<ArrayOutput, CryptoErrno> {
3771    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
3772    let ret = wasi_ephemeral_crypto_kx::kx_dh(pk as i32, sk as i32, rp0.as_mut_ptr() as i32);
3773    match ret {
3774        0 => Ok(core::ptr::read(
3775            rp0.as_mut_ptr() as i32 as *const ArrayOutput
3776        )),
3777        _ => Err(CryptoErrno(ret as u16)),
3778    }
3779}
3780
3781/// Create a shared secret and encrypt it for the given public key.
3782///
3783/// This operation is only compatible with specific algorithms.
3784/// If a selected algorithm doesn't support it,
3785/// `$crypto_errno.invalid_operation` is returned.
3786///
3787/// On success, both the shared secret and its encrypted version are returned.
3788pub unsafe fn kx_encapsulate(pk: Publickey) -> Result<(ArrayOutput, ArrayOutput), CryptoErrno> {
3789    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
3790    let mut rp1 = MaybeUninit::<ArrayOutput>::uninit();
3791    let ret = wasi_ephemeral_crypto_kx::kx_encapsulate(
3792        pk as i32,
3793        rp0.as_mut_ptr() as i32,
3794        rp1.as_mut_ptr() as i32,
3795    );
3796    match ret {
3797        0 => Ok((
3798            core::ptr::read(rp0.as_mut_ptr() as i32 as *const ArrayOutput),
3799            core::ptr::read(rp1.as_mut_ptr() as i32 as *const ArrayOutput),
3800        )),
3801        _ => Err(CryptoErrno(ret as u16)),
3802    }
3803}
3804
3805/// Decapsulate an encapsulated secret crated with `kx_encapsulate`
3806///
3807/// Return the secret, or `$crypto_errno.verification_failed` on error.
3808pub unsafe fn kx_decapsulate(
3809    sk: Secretkey,
3810    encapsulated_secret: *const u8,
3811    encapsulated_secret_len: Size,
3812) -> Result<ArrayOutput, CryptoErrno> {
3813    let mut rp0 = MaybeUninit::<ArrayOutput>::uninit();
3814    let ret = wasi_ephemeral_crypto_kx::kx_decapsulate(
3815        sk as i32,
3816        encapsulated_secret as i32,
3817        encapsulated_secret_len as i32,
3818        rp0.as_mut_ptr() as i32,
3819    );
3820    match ret {
3821        0 => Ok(core::ptr::read(
3822            rp0.as_mut_ptr() as i32 as *const ArrayOutput
3823        )),
3824        _ => Err(CryptoErrno(ret as u16)),
3825    }
3826}
3827
3828pub mod wasi_ephemeral_crypto_kx {
3829    #[link(wasm_import_module = "wasi_ephemeral_crypto_kx")]
3830    extern "C" {
3831        /// Perform a simple Diffie-Hellman key exchange.
3832        ///
3833        /// Both keys must be of the same type, or else the
3834        /// `$crypto_errno.incompatible_keys` error is returned.
3835        /// The algorithm also has to support this kind of key exchange. If this
3836        /// is not the case, the `$crypto_errno.invalid_operation` error is
3837        /// returned.
3838        ///
3839        /// Otherwide, a raw shared key is returned, and can be imported as a
3840        /// symmetric key. ```
3841        pub fn kx_dh(arg0: i32, arg1: i32, arg2: i32) -> i32;
3842        /// Create a shared secret and encrypt it for the given public key.
3843        ///
3844        /// This operation is only compatible with specific algorithms.
3845        /// If a selected algorithm doesn't support it,
3846        /// `$crypto_errno.invalid_operation` is returned.
3847        ///
3848        /// On success, both the shared secret and its encrypted version are
3849        /// returned.
3850        pub fn kx_encapsulate(arg0: i32, arg1: i32, arg2: i32) -> i32;
3851        /// Decapsulate an encapsulated secret crated with `kx_encapsulate`
3852        ///
3853        /// Return the secret, or `$crypto_errno.verification_failed` on error.
3854        pub fn kx_decapsulate(arg0: i32, arg1: i32, arg2: i32, arg3: i32) -> i32;
3855    }
3856}
3857pub const VERSION_UNSPECIFIED: Version = 18374686479671623680;
3858pub const VERSION_LATEST: Version = 18374686479671623681;
3859pub const VERSION_ALL: Version = 18374686479671623682;