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;