Skip to content

Instantly share code, notes, and snippets.

@jedisct1
Created November 10, 2020 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedisct1/8d7a1ff22048e1f5eef31172cee92cd3 to your computer and use it in GitHub Desktop.
Save jedisct1/8d7a1ff22048e1f5eef31172cee92cd3 to your computer and use it in GitHub Desktop.
// This file was automatically generated by zig-witx - Do not edit manually.
pub const handle = i32;
pub const char = u8;
pub const untyped_ptr = usize;
pub const wasi_string_ptr = *u8;
// Error codes.
pub const crypto_errno = enum(u16) {
// Operation succeeded.
SUCCESS = 0,
// An error occurred when trying to during a conversion from a host type to a guest type.
//
// Only an internal bug can throw this error.
GUEST_ERROR = 1,
// The requested operation is valid, but not implemented by the host.
NOT_IMPLEMENTED = 2,
// The requested feature is not supported by the chosen algorithm.
UNSUPPORTED_FEATURE = 3,
// The requested operation is valid, but was administratively prohibited.
PROHIBITED_OPERATION = 4,
// Unsupported encoding for an import or export operation.
UNSUPPORTED_ENCODING = 5,
// The requested algorithm is not supported by the host.
UNSUPPORTED_ALGORITHM = 6,
// The requested option is not supported by the currently selected algorithm.
UNSUPPORTED_OPTION = 7,
// An invalid or incompatible key was supplied.
//
// The key may not be valid, or was generated for a different algorithm or parameters set.
INVALID_KEY = 8,
// The currently selected algorithm doesn't support the requested output length.
//
// This error is thrown by non-extensible hash functions, when requesting an output size larger than they produce out of a single block.
INVALID_LENGTH = 9,
// A signature or authentication tag verification failed.
VERIFICATION_FAILED = 10,
// A secure random numbers generator is not available.
//
// The requested operation requires random numbers, but the host cannot securely generate them at the moment.
RNG_ERROR = 11,
// An error was returned by the underlying cryptography library.
//
// The host may be running out of memory, parameters may be incompatible with the chosen implementation of an algorithm or another unexpected error may have happened.
//
// Ideally, the specification should provide enough details and guidance to make this error impossible to ever be thrown.
//
// Realistically, the WASI crypto module cannot possibly cover all possible error types implementations can return, especially since some of these may be language-specific.
// This error can thus be thrown when other error types are not suitable, and when the original error comes from the cryptographic primitives themselves and not from the WASI module.
ALGORITHM_FAILURE = 12,
// The supplied signature is invalid, or incompatible with the chosen algorithm.
INVALID_SIGNATURE = 13,
// An attempt was made to close a handle that was already closed.
CLOSED = 14,
// A function was called with an unassigned handle, a closed handle, or handle of an unexpected type.
INVALID_HANDLE = 15,
// The host needs to copy data to a guest-allocated buffer, but that buffer is too small.
OVERFLOW = 16,
// An internal error occurred.
//
// This error is reserved to internal consistency checks, and must only be sent if the internal state of the host remains safe after an inconsistency was detected.
INTERNAL_ERROR = 17,
// Too many handles are currently open, and a new one cannot be created.
//
// Implementations are free to represent handles as they want, and to enforce limits to limit resources usage.
TOO_MANY_HANDLES = 18,
// A key was provided, but the chosen algorithm doesn't support keys.
//
// This is returned by symmetric operations.
//
// Many hash functions, in particular, do not support keys without being used in particular constructions.
// Blindly ignoring a key provided by mistake while trying to open a context for such as function could cause serious security vulnerabilities.
//
// These functions must refuse to create the context and return this error instead.
KEY_NOT_SUPPORTED = 19,
// A key is required for the chosen algorithm, but none was given.
KEY_REQUIRED = 20,
// The provided authentication tag is invalid or incompatible with the current algorithm.
//
// This error is returned by decryption functions and tag verification functions.
//
// Unlike `verification_failed`, this error code is returned when the tag cannot possibly verify for any input.
INVALID_TAG = 21,
// The requested operation is incompatible with the current scheme.
//
// For example, the `symmetric_state_encrypt()` function cannot complete if the selected construction is a key derivation function.
// This error code will be returned instead.
INVALID_OPERATION = 22,
// A nonce is required.
//
// Most encryption schemes require a nonce.
//
// In the absence of a nonce, the WASI cryptography module can automatically generate one, if that can be done safely. The nonce can be retrieved later with the `symmetric_state_option_get()` function using the `nonce` parameter.
// If automatically generating a nonce cannot be done safely, the module never falls back to an insecure option and requests an explicit nonce by throwing that error.
NONCE_REQUIRED = 23,
// The named option was not set.
//
// The caller tried to read the value of an option that was not set.
// This error is used to make the distinction between an empty option, and an option that was not set and left to its default value.
OPTION_NOT_SET = 24,
// A key or key pair matching the requested identifier cannot be found using the supplied information.
//
// This error is returned by a secrets manager via the `keypair_from_id()` function.
NOT_FOUND = 25,
// The algorithm requires parameters that haven't been set.
//
// Non-generic options are required and must be given by building an `options` set and giving that object to functions instantiating that algorithm.
PARAMETERS_MISSING = 26,
// A requested computation is not done yet, and additional calls to the function are required.
//
// Some functions, such as functions generating key pairs and password stretching functions, can take a long time to complete.
//
// In order to avoid a host call to be blocked for too long, these functions can return prematurely, requiring additional calls with the same parameters until they complete.
IN_PROGRESS = 27,
// Multiple keys have been provided, but they do not share the same type.
//
// This error is returned when trying to build a key pair from a public key and a secret key that were created for different and incompatible algorithms.
INCOMPATIBLE_KEYS = 28,
// A managed key or secret expired and cannot be used any more.
EXPIRED = 29,
};
// Encoding to use for importing or exporting a key pair.
pub const keypair_encoding = enum(u16) {
// Raw bytes.
RAW = 0,
// PCSK8 encoding.
PKCS8 = 1,
// DER encoding.
DER = 2,
// PEM encoding.
PEM = 3,
};
// Encoding to use for importing or exporting a public key.
pub const publickey_encoding = enum(u16) {
// Raw bytes.
RAW = 0,
// DER encoding.
DER = 1,
// PEM encoding.
PEM = 2,
// SEC encoding.
SEC = 3,
// Compressed SEC encoding.
COMPRESSED_SEC = 4,
};
// Encoding to use for importing or exporting a secret key.
pub const secretkey_encoding = enum(u16) {
// Raw bytes.
RAW = 0,
// DER encoding.
DER = 1,
// PEM encoding.
PEM = 2,
// SEC encoding.
SEC = 3,
// Compressed SEC encoding.
COMPRESSED_SEC = 4,
};
// Encoding to use for importing or exporting a signature.
pub const signature_encoding = enum(u16) {
// Raw bytes.
RAW = 0,
// DER encoding.
DER = 1,
};
// An algorithm category.
pub const algorithm_type = enum(u16) {
SIGNATURES = 0,
SYMMETRIC = 1,
KEY_EXCHANGE = 2,
};
// Version of a managed key.
//
// A version can be an arbitrary `u64` integer, with the expection of some reserved values.
pub const version_values = struct {
// Key doesn't support versioning.
pub const UNSPECIFIED: version = 0;
// Use the latest version of a key.
pub const LATEST: version = 1;
// Perform an operation over all versions of a key.
pub const ALL: version = 2;
};
pub const version = u64;
// Size of a value.
pub const size = usize;
// A UNIX timestamp, in seconds since 01/01/1970.
pub const timestamp = u64;
// Handle for functions returning output whose size may be large or not known in advance.
//
// An `array_output` object contains a host-allocated byte array.
//
// A guest can get the size of that array after a function returns in order to then allocate a buffer of the correct size.
// In addition, the content of such an object can be consumed by a guest in a streaming fashion.
//
// An `array_output` handle is automatically closed after its full content has been consumed.
pub const array_output = handle;
// A set of options.
//
// This type is used to set non-default parameters.
//
// The exact set of allowed options depends on the algorithm being used.
pub const options = handle;
// A handle to the optional secrets management facilities offered by a host.
//
// This is used to generate, retrieve and invalidate managed keys.
pub const secrets_manager = handle;
// A key pair.
pub const keypair = handle;
// A state to absorb data to be signed.
//
// After a signature has been computed or verified, the state remains valid for further operations.
//
// A subsequent signature would sign all the data accumulated since the creation of the state object.
pub const signature_state = handle;
// A signature.
pub const signature = handle;
// A public key, for key exchange and signature verification.
pub const publickey = handle;
// A secret key, for key exchange mechanisms.
pub const secretkey = handle;
// A state to absorb signed data to be verified.
pub const signature_verification_state = handle;
// A state to perform symmetric operations.
//
// The state is not reset nor invalidated after an option has been performed.
// Incremental updates and sessions are thus supported.
pub const symmetric_state = handle;
// A symmetric key.
//
// The key can be imported from raw bytes, or can be a reference to a managed key.
//
// If it was imported, the host will wipe it from memory as soon as the handle is closed.
pub const symmetric_key = handle;
// An authentication tag.
//
// This is an object returned by functions computing authentication tags.
//
// A tag can be compared against another tag (directly supplied as raw bytes) in constant time with the `symmetric_tag_verify()` function.
//
// This object type can't be directly created from raw bytes. They are only returned by functions computing MACs.
//
// The host is reponsible for securely wiping them from memory on close.
pub const symmetric_tag = handle;
// Options index, only required by the Interface Types translation layer.
pub const opt_options_u = enum(u8) {
SOME = 0,
NONE = 1,
};
// An optional options set.
//
// This union simulates an `Option<Options>` type to make the `options` parameter of some functions optional.
pub const opt_options = struct {
tag: opt_options_u = undefined,
__pad64_0: u64 = 0,
const Self = @This();
pub fn new(tag: opt_options_u) void {
return Self{ .tag = tag };
}
pub fn init(comptime T: type, tag: u8, val: T) opt_options {
var tu = opt_options.new(tag);
tu.set(val);
return tu;
}
pub fn get(self: *const Self, comptime T: type) T {
const valBuf = @ptrToInt(self) + 4;
return @intToPtr(*const T, valBuf).*;
}
pub fn set(self: *Self, comptime T: type, val: T) void {
var valBuf = @ptrToInt(self) + 4;
mem.set(@intToPtr([4]u8, valBuf), 0);
@intToPtr(*T, valBuf).* = val;
}
// --- some: options if tag=0
pub fn some(val: options) opt_options {
return opt_options.new(0, val);
}
pub fn set_some(self: *Self, val: options) void {
self.tag = 0;
self.set(val);
}
pub fn is_some(self: Self) bool {
return self.tag == 0;
}
pub fn get_some(self: Self) options {
return self.get(options);
}
// --- none: void if tag=1
pub fn none() opt_options {
return opt_options.new(1);
}
pub fn set_none(self: *Self) void {
self.tag = 1;
}
pub fn is_none(self: Self) bool {
return self.tag == 1;
}
};
// Symmetric key index, only required by the Interface Types translation layer.
pub const opt_symmetric_key_u = enum(u8) {
SOME = 0,
NONE = 1,
};
// An optional symmetric key.
//
// This union simulates an `Option<SymmetricKey>` type to make the `symmetric_key` parameter of some functions optional.
pub const opt_symmetric_key = struct {
tag: opt_symmetric_key_u = undefined,
__pad64_0: u64 = 0,
const Self = @This();
pub fn new(tag: opt_symmetric_key_u) void {
return Self{ .tag = tag };
}
pub fn init(comptime T: type, tag: u8, val: T) opt_symmetric_key {
var tu = opt_symmetric_key.new(tag);
tu.set(val);
return tu;
}
pub fn get(self: *const Self, comptime T: type) T {
const valBuf = @ptrToInt(self) + 4;
return @intToPtr(*const T, valBuf).*;
}
pub fn set(self: *Self, comptime T: type, val: T) void {
var valBuf = @ptrToInt(self) + 4;
mem.set(@intToPtr([4]u8, valBuf), 0);
@intToPtr(*T, valBuf).* = val;
}
// --- some: symmetric_key if tag=0
pub fn some(val: symmetric_key) opt_symmetric_key {
return opt_symmetric_key.new(0, val);
}
pub fn set_some(self: *Self, val: symmetric_key) void {
self.tag = 0;
self.set(val);
}
pub fn is_some(self: Self) bool {
return self.tag == 0;
}
pub fn get_some(self: Self) symmetric_key {
return self.get(symmetric_key);
}
// --- none: void if tag=1
pub fn none() opt_symmetric_key {
return opt_symmetric_key.new(1);
}
pub fn set_none(self: *Self) void {
self.tag = 1;
}
pub fn is_none(self: Self) bool {
return self.tag == 1;
}
};
// `$signature_keypair` is just an alias for `$keypair`
//
// However, bindings may want to define a specialized type `signature_keypair` as a super class of `keypair`, with additional methods such as `sign`.
pub const signature_keypair = keypair;
// `$signature_publickey` is just an alias for `$publickey`
//
// However, bindings may want to define a specialized type `signature_publickey` as a super class of `publickey`, with additional methods such as `verify`.
pub const signature_publickey = publickey;
// `$signature_secretkey` is just an alias for `$secretkey`
//
// However, bindings may want to define a specialized type `signature_secretkey` as a super class of `secretkey`.
pub const signature_secretkey = secretkey;
// `$kx_keypair` is just an alias for `$keypair`
//
// However, bindings may want to define a specialized type `kx_keypair` as a super class of `keypair`.
pub const kx_keypair = keypair;
// `$kx_publickey` is just an alias for `$publickey`
//
// However, bindings may want to define a specialized type `kx_publickey` as a super class of `publickey`, with additional methods such as `dh`.
pub const kx_publickey = publickey;
// `$kx_secretkey` is just an alias for `$secretkey`
//
// However, bindings may want to define a specialized type `kx_secretkey` as a super class of `secretkeykey`, with additional methods such as `dh`.
pub const kx_secretkey = secretkey;
// ----------------------[wasi_ephemeral_crypto_common]----------------------
pub const mod_wasi_ephemeral_crypto_common = struct {
// Create a new object to set non-default options.
//
// Example usage:
//
// ```rust
// let options_handle = options_open(AlgorithmType::Symmetric)?;
// options_set(options_handle, "context", context)?;
// options_set_u64(options_handle, "threads", 4)?;
// let state = symmetric_state_open("BLAKE3", None, Some(options_handle))?;
// options_close(options_handle)?;
// ```
// in: algorithm_type
// out: error, handle
extern "wasi_ephemeral_crypto_common" fn options_open(algorithm_type: algorithm_type, handle_ptr: *options) crypto_errno;
// Destroy an options object.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: handle
// out: error
extern "wasi_ephemeral_crypto_common" fn options_close(handle: options) crypto_errno;
// Set or update an option.
//
// This is used to set algorithm-specific parameters, but also to provide credentials for the secrets management facilities, if required.
//
// This function may return `unsupported_option` if an option that doesn't exist for any implemented algorithms is specified.
// in: handle, name, value, value_len
// out: error
extern "wasi_ephemeral_crypto_common" fn options_set(handle: options, name_ptr: wasi_string_ptr, name_len: usize, value: *const u8, value_len: size) crypto_errno;
// Set or update an integer option.
//
// This is used to set algorithm-specific parameters.
//
// This function may return `unsupported_option` if an option that doesn't exist for any implemented algorithms is specified.
// in: handle, name, value
// out: error
extern "wasi_ephemeral_crypto_common" fn options_set_u64(handle: options, name_ptr: wasi_string_ptr, name_len: usize, value: u64) crypto_errno;
// Set or update a guest-allocated memory that the host can use or return data into.
//
// This is for example used to set the scratch buffer required by memory-hard functions.
//
// This function may return `unsupported_option` if an option that doesn't exist for any implemented algorithms is specified.
// in: handle, name, buffer, buffer_len
// out: error
extern "wasi_ephemeral_crypto_common" fn options_set_guest_buffer(handle: options, name_ptr: wasi_string_ptr, name_len: usize, buffer: *u8, buffer_len: size) crypto_errno;
// Return the length of an `array_output` object.
//
// This allows a guest to allocate a buffer of the correct size in order to copy the output of a function returning this object type.
// in: array_output
// out: error, len
extern "wasi_ephemeral_crypto_common" fn array_output_len(array_output: array_output, len_ptr: *size) crypto_errno;
// Copy the content of an `array_output` object into an application-allocated buffer.
//
// Multiple calls to that function can be made in order to consume the data in a streaming fashion, if necessary.
//
// The function returns the number of bytes that were actually copied. `0` means that the end of the stream has been reached. The total size always matches the output of `array_output_len()`.
//
// The handle is automatically closed after all the data has been consumed.
//
// Example usage:
//
// ```rust
// let len = array_output_len(output_handle)?;
// let mut out = vec![0u8; len];
// array_output_pull(output_handle, &mut out)?;
// ```
// in: array_output, buf, buf_len
// out: error, len
extern "wasi_ephemeral_crypto_common" fn array_output_pull(array_output: array_output, buf: *u8, buf_len: size, len_ptr: *size) crypto_errno;
// __(optional)__
// Create a context to use a secrets manager.
//
// The set of required and supported options is defined by the host.
//
// The function returns the `unsupported_feature` error code if secrets management facilities are not supported by the host.
// This is also an optional import, meaning that the function may not even exist.
// in: options
// out: error, handle
extern "wasi_ephemeral_crypto_common" fn secrets_manager_open(options: opt_options, handle_ptr: *secrets_manager) crypto_errno;
// __(optional)__
// Destroy a secrets manager context.
//
// The function returns the `unsupported_feature` error code if secrets management facilities are not supported by the host.
// This is also an optional import, meaning that the function may not even exist.
// in: secrets_manager
// out: error
extern "wasi_ephemeral_crypto_common" fn secrets_manager_close(secrets_manager: secrets_manager) crypto_errno;
// __(optional)__
// Invalidate a managed key or key pair given an identifier and a version.
//
// This asks the secrets manager to delete or revoke a stored key, a specific version of a key.
//
// `key_version` can be set to a version number, to `version.latest` to invalidate the current version, or to `version.all` to invalidate all versions of a key.
//
// The function returns `unsupported_feature` if this operation is not supported by the host, and `not_found` if the identifier and version don't match any existing key.
//
// This is an optional import, meaning that the function may not even exist.
// in: secrets_manager, key_id, key_id_len, key_version
// out: error
extern "wasi_ephemeral_crypto_common" fn secrets_manager_invalidate(secrets_manager: secrets_manager, key_id: *const u8, key_id_len: size, key_version: version) crypto_errno;
};
// ----------------------[wasi_ephemeral_crypto_asymmetric_common]----------------------
pub const mod_wasi_ephemeral_crypto_asymmetric_common = struct {
// Generate a new key pair.
//
// Internally, a key pair stores the supplied algorithm and optional parameters.
//
// Trying to use that key pair with different parameters will throw an `invalid_key` error.
//
// This function may return `$crypto_errno.unsupported_feature` if key generation is not supported by the host for the chosen algorithm.
//
// The function may also return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// Finally, if generating that type of key pair is an expensive operation, the function may return `in_progress`.
// In that case, the guest should retry with the same parameters until the function completes.
//
// Example usage:
//
// ```rust
// let kp_handle = ctx.keypair_generate(AlgorithmType::Signatures, "RSA_PKCS1_2048_8192_SHA512", None)?;
// ```
// in: algorithm_type, algorithm, options
// out: error, handle
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_generate(algorithm_type: algorithm_type, algorithm_ptr: wasi_string_ptr, algorithm_len: usize, options: opt_options, handle_ptr: *keypair) crypto_errno;
// Import a key pair.
//
// This function creates a `keypair` object from existing material.
//
// It may return `unsupported_algorithm` if the encoding scheme is not supported, or `invalid_key` if the key cannot be decoded.
//
// The function may also return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// Example usage:
//
// ```rust
// let kp_handle = ctx.keypair_import(AlgorithmType::Signatures, "RSA_PKCS1_2048_8192_SHA512", KeypairEncoding::PKCS8)?;
// ```
// in: algorithm_type, algorithm, encoded, encoded_len, encoding
// out: error, handle
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_import(algorithm_type: algorithm_type, algorithm_ptr: wasi_string_ptr, algorithm_len: usize, encoded: *const u8, encoded_len: size, encoding: keypair_encoding, handle_ptr: *keypair) crypto_errno;
// __(optional)__
// Generate a new managed key pair.
//
// The key pair is generated and stored by the secrets management facilities.
//
// It may be used through its identifier, but the host may not allow it to be exported.
//
// The function returns the `unsupported_feature` error code if secrets management facilities are not supported by the host,
// or `unsupported_algorithm` if a key cannot be created for the chosen algorithm.
//
// The function may also return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// This is also an optional import, meaning that the function may not even exist.
// in: secrets_manager, algorithm_type, algorithm, options
// out: error, handle
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_generate_managed(secrets_manager: secrets_manager, algorithm_type: algorithm_type, algorithm_ptr: wasi_string_ptr, algorithm_len: usize, options: opt_options, handle_ptr: *keypair) crypto_errno;
// __(optional)__
// Store a key pair into the secrets manager.
//
// On success, the function stores the key pair identifier into `$kp_id`,
// into which up to `$kp_id_max_len` can be written.
//
// The function returns `overflow` if the supplied buffer is too small.
// in: secrets_manager, kp, kp_id, kp_id_max_len
// out: error
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_store_managed(secrets_manager: secrets_manager, kp: keypair, kp_id: *u8, kp_id_max_len: size) crypto_errno;
// __(optional)__
// Replace a managed key pair.
//
// This function crates a new version of a managed key pair, by replacing `$kp_old` with `$kp_new`.
//
// It does several things:
//
// - The key identifier for `$kp_new` is set to the one of `$kp_old`.
// - A new, unique version identifier is assigned to `$kp_new`. This version will be equivalent to using `$version_latest` until the key is replaced.
// - The `$kp_old` handle is closed.
//
// Both keys must share the same algorithm and have compatible parameters. If this is not the case, `incompatible_keys` is returned.
//
// The function may also return the `unsupported_feature` error code if secrets management facilities are not supported by the host,
// or if keys cannot be rotated.
//
// Finally, `prohibited_operation` can be returned if `$kp_new` wasn't created by the secrets manager, and the secrets manager prohibits imported keys.
//
// If the operation succeeded, the new version is returned.
//
// This is an optional import, meaning that the function may not even exist.
// in: secrets_manager, kp_old, kp_new
// out: error, version
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_replace_managed(secrets_manager: secrets_manager, kp_old: keypair, kp_new: keypair, version_ptr: *version) crypto_errno;
// __(optional)__
// Return the key pair identifier and version of a managed key pair.
//
// If the key pair is not managed, `unsupported_feature` is returned instead.
//
// This is an optional import, meaning that the function may not even exist.
// in: kp, kp_id, kp_id_max_len
// out: error, kp_id_len, version
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_id(kp: keypair, kp_id: *u8, kp_id_max_len: size, kp_id_len_ptr: *size, version_ptr: *version) crypto_errno;
// __(optional)__
// Return a managed key pair from a key identifier.
//
// `kp_version` can be set to `version_latest` to retrieve the most recent version of a key pair.
//
// If no key pair matching the provided information is found, `not_found` is returned instead.
//
// This is an optional import, meaning that the function may not even exist.
// ```
// in: secrets_manager, kp_id, kp_id_len, kp_version
// out: error, handle
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_from_id(secrets_manager: secrets_manager, kp_id: *const u8, kp_id_len: size, kp_version: version, handle_ptr: *keypair) crypto_errno;
// Create a key pair from a public key and a secret key.
// in: publickey, secretkey
// out: error, handle
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_from_pk_and_sk(publickey: publickey, secretkey: secretkey, handle_ptr: *keypair) crypto_errno;
// Export a key pair as the given encoding format.
//
// May return `prohibited_operation` if this operation is denied or `unsupported_encoding` if the encoding is not supported.
// in: kp, encoding
// out: error, encoded
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_export(kp: keypair, encoding: keypair_encoding, encoded_ptr: *array_output) crypto_errno;
// Get the public key of a key pair.
// in: kp
// out: error, pk
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_publickey(kp: keypair, pk_ptr: *publickey) crypto_errno;
// Get the secret key of a key pair.
// in: kp
// out: error, sk
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_secretkey(kp: keypair, sk_ptr: *secretkey) crypto_errno;
// Destroy a key pair.
//
// The host will automatically wipe traces of the secret key from memory.
//
// If this is a managed key, the key will not be removed from persistent storage, and can be reconstructed later using the key identifier.
// in: kp
// out: error
extern "wasi_ephemeral_crypto_asymmetric_common" fn keypair_close(kp: keypair) crypto_errno;
// Import a public key.
//
// The function may return `unsupported_encoding` if importing from the given format is not implemented or incompatible with the key type.
//
// It may also return `invalid_key` if the key doesn't appear to match the supplied algorithm.
//
// Finally, the function may return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// Example usage:
//
// ```rust
// let pk_handle = ctx.publickey_import(AlgorithmType::Signatures, encoded, PublicKeyEncoding::Sec)?;
// ```
// in: algorithm_type, algorithm, encoded, encoded_len, encoding
// out: error, pk
extern "wasi_ephemeral_crypto_asymmetric_common" fn publickey_import(algorithm_type: algorithm_type, algorithm_ptr: wasi_string_ptr, algorithm_len: usize, encoded: *const u8, encoded_len: size, encoding: publickey_encoding, pk_ptr: *publickey) crypto_errno;
// Export a public key as the given encoding format.
//
// May return `unsupported_encoding` if the encoding is not supported.
// in: pk, encoding
// out: error, encoded
extern "wasi_ephemeral_crypto_asymmetric_common" fn publickey_export(pk: publickey, encoding: publickey_encoding, encoded_ptr: *array_output) crypto_errno;
// Check that a public key is valid and in canonical form.
//
// This function may perform stricter checks than those made during importation at the expense of additional CPU cycles.
//
// The function returns `invalid_key` if the public key didn't pass the checks.
// in: pk
// out: error
extern "wasi_ephemeral_crypto_asymmetric_common" fn publickey_verify(pk: publickey) crypto_errno;
// Compute the public key for a secret key.
// in: sk
// out: error, pk
extern "wasi_ephemeral_crypto_asymmetric_common" fn publickey_from_secretkey(sk: secretkey, pk_ptr: *publickey) crypto_errno;
// Destroy a public key.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: pk
// out: error
extern "wasi_ephemeral_crypto_asymmetric_common" fn publickey_close(pk: publickey) crypto_errno;
// Import a secret key.
//
// The function may return `unsupported_encoding` if importing from the given format is not implemented or incompatible with the key type.
//
// It may also return `invalid_key` if the key doesn't appear to match the supplied algorithm.
//
// Finally, the function may return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// Example usage:
//
// ```rust
// let pk_handle = ctx.secretkey_import(AlgorithmType::KX, encoded, SecretKeyEncoding::Raw)?;
// ```
// in: algorithm_type, algorithm, encoded, encoded_len, encoding
// out: error, sk
extern "wasi_ephemeral_crypto_asymmetric_common" fn secretkey_import(algorithm_type: algorithm_type, algorithm_ptr: wasi_string_ptr, algorithm_len: usize, encoded: *const u8, encoded_len: size, encoding: secretkey_encoding, sk_ptr: *secretkey) crypto_errno;
// Export a secret key as the given encoding format.
//
// May return `unsupported_encoding` if the encoding is not supported.
// in: sk, encoding
// out: error, encoded
extern "wasi_ephemeral_crypto_asymmetric_common" fn secretkey_export(sk: secretkey, encoding: secretkey_encoding, encoded_ptr: *array_output) crypto_errno;
// Destroy a secret key.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: sk
// out: error
extern "wasi_ephemeral_crypto_asymmetric_common" fn secretkey_close(sk: secretkey) crypto_errno;
};
// ----------------------[wasi_ephemeral_crypto_signatures]----------------------
pub const mod_wasi_ephemeral_crypto_signatures = struct {
// Export a signature.
//
// This function exports a signature object using the specified encoding.
//
// May return `unsupported_encoding` if the signature cannot be encoded into the given format.
// in: signature, encoding
// out: error, encoded
extern "wasi_ephemeral_crypto_signatures" fn signature_export(signature: signature, encoding: signature_encoding, encoded_ptr: *array_output) crypto_errno;
// Create a signature object.
//
// This object can be used along with a public key to verify an existing signature.
//
// It may return `invalid_signature` if the signature is invalid or incompatible with the specified algorithm, as well as `unsupported_encoding` if the encoding is not compatible with the signature type.
//
// The function may also return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// Example usage:
//
// ```rust
// let signature_handle = ctx.signature_import("ECDSA_P256_SHA256", SignatureEncoding::DER, encoded)?;
// ```
// in: algorithm, encoded, encoded_len, encoding
// out: error, signature
extern "wasi_ephemeral_crypto_signatures" fn signature_import(algorithm_ptr: wasi_string_ptr, algorithm_len: usize, encoded: *const u8, encoded_len: size, encoding: signature_encoding, signature_ptr: *signature) crypto_errno;
// Create a new state to collect data to compute a signature on.
//
// This function allows data to be signed to be supplied in a streaming fashion.
//
// The state is not closed and can be used after a signature has been computed, allowing incremental updates by calling `signature_state_update()` again afterwards.
//
// Example usage - signature creation
//
// ```rust
// let kp_handle = ctx.keypair_import(AlgorithmType::Signatures, "Ed25519ph", keypair, KeypairEncoding::Raw)?;
// let state_handle = ctx.signature_state_open(kp_handle)?;
// ctx.signature_state_update(state_handle, b"message part 1")?;
// ctx.signature_state_update(state_handle, b"message part 2")?;
// let sig_handle = ctx.signature_state_sign(state_handle)?;
// let raw_sig = ctx.signature_export(sig_handle, SignatureEncoding::Raw)?;
// ```
// in: kp
// out: error, state
extern "wasi_ephemeral_crypto_signatures" fn signature_state_open(kp: signature_keypair, state_ptr: *signature_state) crypto_errno;
// Absorb data into the signature state.
//
// This function may return `unsupported_feature` is the selected algorithm doesn't support incremental updates.
// in: state, input, input_len
// out: error
extern "wasi_ephemeral_crypto_signatures" fn signature_state_update(state: signature_state, input: *const u8, input_len: size) crypto_errno;
// Compute a signature for all the data collected up to that point.
//
// The function can be called multiple times for incremental signing.
// in: state
// out: error, signature
extern "wasi_ephemeral_crypto_signatures" fn signature_state_sign(state: signature_state, signature_ptr: *array_output) crypto_errno;
// Destroy a signature state.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
//
// Note that closing a signature state doesn't close or invalidate the key pair object, that be reused for further signatures.
// in: state
// out: error
extern "wasi_ephemeral_crypto_signatures" fn signature_state_close(state: signature_state) crypto_errno;
// Create a new state to collect data to verify a signature on.
//
// This is the verification counterpart of `signature_state`.
//
// Data can be injected using `signature_verification_state_update()`, and the state is not closed after a verification, allowing incremental verification.
//
// Example usage - signature verification:
//
// ```rust
// let pk_handle = ctx.publickey_import(AlgorithmType::Signatures, "ECDSA_P256_SHA256", encoded_pk, PublicKeyEncoding::CompressedSec)?;
// let signature_handle = ctx.signature_import(AlgorithmType::Signatures, "ECDSA_P256_SHA256", encoded_sig, PublicKeyEncoding::Der)?;
// let state_handle = ctx.signature_verification_state_open(pk_handle)?;
// ctx.signature_verification_state_update(state_handle, "message")?;
// ctx.signature_verification_state_verify(signature_handle)?;
// ```
// in: kp
// out: error, state
extern "wasi_ephemeral_crypto_signatures" fn signature_verification_state_open(kp: signature_publickey, state_ptr: *signature_verification_state) crypto_errno;
// Absorb data into the signature verification state.
//
// This function may return `unsupported_feature` is the selected algorithm doesn't support incremental updates.
// in: state, input, input_len
// out: error
extern "wasi_ephemeral_crypto_signatures" fn signature_verification_state_update(state: signature_verification_state, input: *const u8, input_len: size) crypto_errno;
// Check that the given signature is verifies for the data collected up to that point point.
//
// The state is not closed and can absorb more data to allow for incremental verification.
//
// The function returns `invalid_signature` if the signature doesn't appear to be valid.
// in: state, signature
// out: error
extern "wasi_ephemeral_crypto_signatures" fn signature_verification_state_verify(state: signature_verification_state, signature: signature) crypto_errno;
// Destroy a signature verification state.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
//
// Note that closing a signature state doesn't close or invalidate the public key object, that be reused for further verifications.
// in: state
// out: error
extern "wasi_ephemeral_crypto_signatures" fn signature_verification_state_close(state: signature_verification_state) crypto_errno;
// Destroy a signature.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: signature
// out: error
extern "wasi_ephemeral_crypto_signatures" fn signature_close(signature: signature) crypto_errno;
};
// ----------------------[wasi_ephemeral_crypto_symmetric]----------------------
pub const mod_wasi_ephemeral_crypto_symmetric = struct {
// Generate a new symmetric key for a given algorithm.
//
// `options` can be `None` to use the default parameters, or an algoritm-specific set of parameters to override.
//
// This function may return `unsupported_feature` if key generation is not supported by the host for the chosen algorithm, or `unsupported_algorithm` if the algorithm is not supported by the host.
// in: algorithm, options
// out: error, handle
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_generate(algorithm_ptr: wasi_string_ptr, algorithm_len: usize, options: opt_options, handle_ptr: *symmetric_key) crypto_errno;
// Create a symmetric key from raw material.
//
// The algorithm is internally stored along with the key, and trying to use the key with an operation expecting a different algorithm will return `invalid_key`.
//
// The function may also return `unsupported_algorithm` if the algorithm is not supported by the host.
// in: algorithm, raw, raw_len
// out: error, handle
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_import(algorithm_ptr: wasi_string_ptr, algorithm_len: usize, raw: *const u8, raw_len: size, handle_ptr: *symmetric_key) crypto_errno;
// Export a symmetric key as raw material.
//
// This is mainly useful to export a managed key.
//
// May return `prohibited_operation` if this operation is denied.
// in: symmetric_key
// out: error, encoded
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_export(symmetric_key: symmetric_key, encoded_ptr: *array_output) crypto_errno;
// Destroy a symmetric key.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: symmetric_key
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_close(symmetric_key: symmetric_key) crypto_errno;
// __(optional)__
// Generate a new managed symmetric key.
//
// The key is generated and stored by the secrets management facilities.
//
// It may be used through its identifier, but the host may not allow it to be exported.
//
// The function returns the `unsupported_feature` error code if secrets management facilities are not supported by the host,
// or `unsupported_algorithm` if a key cannot be created for the chosen algorithm.
//
// The function may also return `unsupported_algorithm` if the algorithm is not supported by the host.
//
// This is also an optional import, meaning that the function may not even exist.
// in: secrets_manager, algorithm, options
// out: error, handle
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_generate_managed(secrets_manager: secrets_manager, algorithm_ptr: wasi_string_ptr, algorithm_len: usize, options: opt_options, handle_ptr: *symmetric_key) crypto_errno;
// __(optional)__
// Store a symmetric key into the secrets manager.
//
// On success, the function stores the key identifier into `$symmetric_key_id`,
// into which up to `$symmetric_key_id_max_len` can be written.
//
// The function returns `overflow` if the supplied buffer is too small.
// in: secrets_manager, symmetric_key, symmetric_key_id, symmetric_key_id_max_len
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_store_managed(secrets_manager: secrets_manager, symmetric_key: symmetric_key, symmetric_key_id: *u8, symmetric_key_id_max_len: size) crypto_errno;
// __(optional)__
// Replace a managed symmetric key.
//
// This function crates a new version of a managed symmetric key, by replacing `$kp_old` with `$kp_new`.
//
// It does several things:
//
// - The key identifier for `$symmetric_key_new` is set to the one of `$symmetric_key_old`.
// - A new, unique version identifier is assigned to `$kp_new`. This version will be equivalent to using `$version_latest` until the key is replaced.
// - The `$symmetric_key_old` handle is closed.
//
// Both keys must share the same algorithm and have compatible parameters. If this is not the case, `incompatible_keys` is returned.
//
// The function may also return the `unsupported_feature` error code if secrets management facilities are not supported by the host,
// or if keys cannot be rotated.
//
// Finally, `prohibited_operation` can be returned if `$symmetric_key_new` wasn't created by the secrets manager, and the secrets manager prohibits imported keys.
//
// If the operation succeeded, the new version is returned.
//
// This is an optional import, meaning that the function may not even exist.
// in: secrets_manager, symmetric_key_old, symmetric_key_new
// out: error, version
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_replace_managed(secrets_manager: secrets_manager, symmetric_key_old: symmetric_key, symmetric_key_new: symmetric_key, version_ptr: *version) crypto_errno;
// __(optional)__
// Return the key identifier and version of a managed symmetric key.
//
// If the key is not managed, `unsupported_feature` is returned instead.
//
// This is an optional import, meaning that the function may not even exist.
// in: symmetric_key, symmetric_key_id, symmetric_key_id_max_len
// out: error, symmetric_key_id_len, version
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_id(symmetric_key: symmetric_key, symmetric_key_id: *u8, symmetric_key_id_max_len: size, symmetric_key_id_len_ptr: *size, version_ptr: *version) crypto_errno;
// __(optional)__
// Return a managed symmetric key from a key identifier.
//
// `kp_version` can be set to `version_latest` to retrieve the most recent version of a symmetric key.
//
// If no key matching the provided information is found, `not_found` is returned instead.
//
// This is an optional import, meaning that the function may not even exist.
// in: secrets_manager, symmetric_key_id, symmetric_key_id_len, symmetric_key_version
// out: error, handle
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_key_from_id(secrets_manager: secrets_manager, symmetric_key_id: *const u8, symmetric_key_id_len: size, symmetric_key_version: version, handle_ptr: *symmetric_key) crypto_errno;
// Create a new state to aborb and produce data using symmetric operations.
//
// The state remains valid after every operation in order to support incremental updates.
//
// The function has two optional parameters: a key and an options set.
//
// It will fail with a `key_not_supported` error code if a key was provided but the chosen algorithm doesn't natively support keying.
//
// On the other hand, if a key is required, but was not provided, a `key_required` error will be thrown.
//
// Some algorithms may require additional parameters. They have to be supplied as an options set:
//
// ```rust
// let options_handle = ctx.options_open()?;
// ctx.options_set("context", b"My application")?;
// ctx.options_set_u64("fanout", 16)?;
// let state_handle = ctx.symmetric_state_open("BLAKE2b-512", None, Some(options_handle))?;
// ```
//
// If some parameters are mandatory but were not set, the `parameters_missing` error code will be returned.
//
// A notable exception is the `nonce` parameter, that is common to most AEAD constructions.
//
// If a nonce is required but was not supplied:
//
// - If it is safe to do so, the host will automatically generate a nonce. This is true for nonces that are large enough to be randomly generated, or if the host is able to maintain a global counter.
// - If not, the function will fail and return the dedicated `nonce_required` error code.
//
// A nonce that was automatically generated can be retrieved after the function returns with `symmetric_state_get(state_handle, "nonce")`.
//
// **Sample usage patterns:**
//
// - **Hashing**
//
// ```rust
// let mut out = [0u8; 64];
// let state_handle = ctx.symmetric_state_open("SHAKE-128", None, None)?;
// ctx.symmetric_state_absorb(state_handle, b"data")?;
// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
// ```
//
// - **MAC**
//
// ```rust
// let mut raw_tag = [0u8; 64];
// let key_handle = ctx.symmetric_key_import("HMAC/SHA-512", b"key")?;
// let state_handle = ctx.symmetric_state_open("HMAC/SHA-512", Some(key_handle), None)?;
// ctx.symmetric_state_absorb(state_handle, b"data")?;
// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
// ctx.symmetric_tag_pull(computed_tag_handle, &mut raw_tag)?;
// ```
//
// Verification:
//
// ```rust
// let state_handle = ctx.symmetric_state_open("HMAC/SHA-512", Some(key_handle), None)?;
// ctx.symmetric_state_absorb(state_handle, b"data")?;
// ctx.symmetric_state_absorb(state_handle, b"more_data")?;
// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
// ctx.symmetric_tag_verify(computed_tag_handle, expected_raw_tag)?;
// ```
//
// - **Tuple hashing**
//
// ```rust
// let mut out = [0u8; 64];
// let state_handle = ctx.symmetric_state_open("TupleHashXOF256", None, None)?;
// ctx.symmetric_state_absorb(state_handle, b"value 1")?;
// ctx.symmetric_state_absorb(state_handle, b"value 2")?;
// ctx.symmetric_state_absorb(state_handle, b"value 3")?;
// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
// ```
// Unlike MACs and regular hash functions, inputs are domain separated instead of being concatenated.
//
// - **Key derivation using extract-and-expand**
//
// Extract:
//
// ```rust
// let mut prk = vec![0u8; 64];
// let key_handle = ctx.symmetric_key_import("HKDF-EXTRACT/SHA-512", b"key")?;
// let state_handle = ctx.symmetric_state_open("HKDF-EXTRACT/SHA-512", Some(key_handle), None)?;
// ctx.symmetric_state_absorb(state_handle, b"salt")?;
// let prk_handle = ctx.symmetric_state_squeeze_key(state_handle, "HKDF-EXPAND/SHA-512")?;
// ```
//
// Expand:
//
// ```rust
// let mut subkey = vec![0u8; 32];
// let state_handle = ctx.symmetric_state_open("HKDF-EXPAND/SHA-512", Some(prk_handle), None)?;
// ctx.symmetric_state_absorb(state_handle, b"info")?;
// ctx.symmetric_state_squeeze(state_handle, &mut subkey)?;
// ```
//
// - **Key derivation using a XOF**
//
// ```rust
// let mut subkey1 = vec![0u8; 32];
// let mut subkey2 = vec![0u8; 32];
// let key_handle = ctx.symmetric_key_import("BLAKE3", b"key")?;
// let state_handle = ctx.symmetric_state_open("BLAKE3", Some(key_handle), None)?;
// ctx.symmetric_absorb(state_handle, b"context")?;
// ctx.squeeze(state_handle, &mut subkey1)?;
// ctx.squeeze(state_handle, &mut subkey2)?;
// ```
//
// - **Password hashing**
//
// ```rust
// let mut memory = vec![0u8; 1_000_000_000];
// let options_handle = ctx.symmetric_options_open()?;
// ctx.symmetric_options_set_guest_buffer(options_handle, "memory", &mut memory)?;
// ctx.symmetric_options_set_u64(options_handle, "opslimit", 5)?;
// ctx.symmetric_options_set_u64(options_handle, "parallelism", 8)?;
//
// let state_handle = ctx.symmetric_state_open("ARGON2-ID-13", None, Some(options))?;
// ctx.symmtric_state_absorb(state_handle, b"password")?;
//
// let pw_str_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
// let mut pw_str = vec![0u8; ctx.symmetric_tag_len(pw_str_handle)?];
// ctx.symmetric_tag_pull(pw_str_handle, &mut pw_str)?;
// ```
//
// - **AEAD encryption with an explicit nonce**
//
// ```rust
// let key_handle = ctx.symmetric_key_generate("AES-256-GCM", None)?;
// let message = b"test";
//
// let options_handle = ctx.symmetric_options_open()?;
// ctx.symmetric_options_set(options_handle, "nonce", nonce)?;
//
// let state_handle = ctx.symmetric_state_open("AES-256-GCM", Some(key_handle), Some(options_handle))?;
// let mut ciphertext = vec![0u8; message.len() + ctx.symmetric_state_max_tag_len(state_handle)?];
// ctx.symmetric_state_absorb(state_handle, "additional data")?;
// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, message)?;
// ```
//
// - **AEAD encryption with automatic nonce generation**
//
// ```rust
// let key_handle = ctx.symmetric_key_generate("AES-256-GCM-SIV", None)?;
// let message = b"test";
// let mut nonce = [0u8; 24];
//
// let state_handle = ctx.symmetric_state_open("AES-256-GCM-SIV", Some(key_handle), None)?;
//
// let nonce_handle = ctx.symmetric_state_options_get(state_handle, "nonce")?;
// ctx.array_output_pull(nonce_handle, &mut nonce)?;
//
// let mut ciphertext = vec![0u8; message.len() + ctx.symmetric_state_max_tag_len(state_handle)?];
// ctx.symmetric_state_absorb(state_handle, "additional data")?;
// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, message)?;
// ```
//
// - **Session authenticated modes**
//
// ```rust
// let mut out = [0u8; 16];
// let mut out2 = [0u8; 16];
// let mut ciphertext = [0u8; 20];
// let key_handle = ctx.symmetric_key_generate("Xoodyak-128", None)?;
// let state_handle = ctx.symmetric_state_open("Xoodyak-128", Some(key_handle), None)?;
// ctx.symmetric_state_absorb(state_handle, b"data")?;
// ctx.symmetric_state_encrypt(state_handle, &mut ciphertext, b"abcd")?;
// ctx.symmetric_state_absorb(state_handle, b"more data")?;
// ctx.symmetric_state_squeeze(state_handle, &mut out)?;
// ctx.symmetric_state_squeeze(state_handle, &mut out2)?;
// ctx.symmetric_state_ratchet(state_handle)?;
// ctx.symmetric_state_absorb(state_handle, b"more data")?;
// let next_key_handle = ctx.symmetric_state_squeeze_key(state_handle, "Xoodyak-128")?;
// // ...
// ```
// in: algorithm, key, options
// out: error, symmetric_state
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_open(algorithm_ptr: wasi_string_ptr, algorithm_len: usize, key: opt_symmetric_key, options: opt_options, symmetric_state_ptr: *symmetric_state) crypto_errno;
// Retrieve a parameter from the current state.
//
// In particular, `symmetric_state_options_get("nonce")` can be used to get a nonce that as automatically generated.
//
// The function may return `options_not_set` if an option was not set, which is different from an empty value.
//
// It may also return `unsupported_option` if the option doesn't exist for the chosen algorithm.
// in: handle, name, value, value_max_len
// out: error, value_len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_options_get(handle: symmetric_state, name_ptr: wasi_string_ptr, name_len: usize, value: *u8, value_max_len: size, value_len_ptr: *size) crypto_errno;
// Retrieve an integer parameter from the current state.
//
// In particular, `symmetric_state_options_get("nonce")` can be used to get a nonce that as automatically generated.
//
// The function may return `options_not_set` if an option was not set.
//
// It may also return `unsupported_option` if the option doesn't exist for the chosen algorithm.
// in: handle, name
// out: error, value
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_options_get_u64(handle: symmetric_state, name_ptr: wasi_string_ptr, name_len: usize, value_ptr: *u64) crypto_errno;
// Destroy a symmetric state.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: handle
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_close(handle: symmetric_state) crypto_errno;
// Absorb data into the state.
//
// - **Hash functions:** adds data to be hashed.
// - **MAC functions:** adds data to be authenticated.
// - **Tuplehash-like constructions:** adds a new tuple to the state.
// - **Key derivation functions:** adds to the IKM or to the subkey information.
// - **AEAD constructions:** adds additional data to be authenticated.
// - **Stateful hash objects, permutation-based constructions:** absorbs.
//
// If the chosen algorithm doesn't accept input data, the `invalid_operation` error code is returned.
//
// If too much data has been fed for the algorithm, `overflow` may be thrown.
// in: handle, data, data_len
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_absorb(handle: symmetric_state, data: *const u8, data_len: size) crypto_errno;
// Squeeze bytes from the state.
//
// - **Hash functions:** this tries to output an `out_len` bytes digest from the absorbed data. The hash function output will be truncated if necessary. If the requested size is too large, the `invalid_len` error code is returned.
// - **Key derivation functions:** : outputs an arbitrary-long derived key.
// - **RNGs, DRBGs, stream ciphers:**: outputs arbitrary-long data.
// - **Stateful hash objects, permutation-based constructions:** squeeze.
//
// Other kinds of algorithms may return `invalid_operation` instead.
//
// For password-stretching functions, the function may return `in_progress`.
// In that case, the guest should retry with the same parameters until the function completes.
// in: handle, out, out_len
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_squeeze(handle: symmetric_state, out: *u8, out_len: size) crypto_errno;
// Compute and return a tag for all the data injected into the state so far.
//
// - **MAC functions**: returns a tag authenticating the absorbed data.
// - **Tuplehash-like constructions:** returns a tag authenticating all the absorbed tuples.
// - **Password-hashing functions:** returns a standard string containing all the required parameters for password verification.
//
// Other kinds of algorithms may return `invalid_operation` instead.
//
// For password-stretching functions, the function may return `in_progress`.
// In that case, the guest should retry with the same parameters until the function completes.
// in: handle
// out: error, symmetric_tag
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_squeeze_tag(handle: symmetric_state, symmetric_tag_ptr: *symmetric_tag) crypto_errno;
// Use the current state to produce a key for a target algorithm.
//
// For extract-then-expand constructions, this returns the PRK.
// For session-base authentication encryption, this returns a key that can be used to resume a session without storing a nonce.
//
// `invalid_operation` is returned for algorithms not supporting this operation.
// in: handle, alg_str
// out: error, symmetric_key
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_squeeze_key(handle: symmetric_state, alg_str_ptr: wasi_string_ptr, alg_str_len: usize, symmetric_key_ptr: *symmetric_key) crypto_errno;
// Return the maximum length of an authentication tag for the current algorithm.
//
// This allows guests to compute the size required to store a ciphertext along with its authentication tag.
//
// The returned length may include the encryption mode's padding requirements in addition to the actual tag.
//
// For an encryption operation, the size of the output buffer should be `input_len + symmetric_state_max_tag_len()`.
//
// For a decryption operation, the size of the buffer that will store the decrypted data can be reduced to `ciphertext_len - symmetric_state_max_tag_len()` only if the algorithm is known to have a fixed tag length.
// in: handle
// out: error, len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_max_tag_len(handle: symmetric_state, len_ptr: *size) crypto_errno;
// Encrypt data with an attached tag.
//
// - **Stream cipher:** adds the input to the stream cipher output. `out_len` and `data_len` can be equal, as no authentication tags will be added.
// - **AEAD:** encrypts `data` into `out`, including the authentication tag to the output. Additional data must have been previously absorbed using `symmetric_state_absorb()`. The `symmetric_state_max_tag_len()` function can be used to retrieve the overhead of adding the tag, as well as padding if necessary.
// - **SHOE, Xoodyak, Strobe:** encrypts data, squeezes a tag and appends it to the output.
//
// If `out` and `data` are the same address, encryption may happen in-place.
//
// The function returns the actual size of the ciphertext along with the tag.
//
// `invalid_operation` is returned for algorithms not supporting encryption.
// in: handle, out, out_len, data, data_len
// out: error, actual_out_len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_encrypt(handle: symmetric_state, out: *u8, out_len: size, data: *const u8, data_len: size, actual_out_len_ptr: *size) crypto_errno;
// Encrypt data, with a detached tag.
//
// - **Stream cipher:** returns `invalid_operation` since stream ciphers do not include authentication tags.
// - **AEAD:** encrypts `data` into `out` and returns the tag separately. Additional data must have been previously absorbed using `symmetric_state_absorb()`. The output and input buffers must be of the same length.
// - **SHOE, Xoodyak, Strobe:** encrypts data and squeezes a tag.
//
// If `out` and `data` are the same address, encryption may happen in-place.
//
// The function returns the tag.
//
// `invalid_operation` is returned for algorithms not supporting encryption.
// in: handle, out, out_len, data, data_len
// out: error, symmetric_tag
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_encrypt_detached(handle: symmetric_state, out: *u8, out_len: size, data: *const u8, data_len: size, symmetric_tag_ptr: *symmetric_tag) crypto_errno;
// - **Stream cipher:** adds the input to the stream cipher output. `out_len` and `data_len` can be equal, as no authentication tags will be added.
// - **AEAD:** decrypts `data` into `out`. Additional data must have been previously absorbed using `symmetric_state_absorb()`.
// - **SHOE, Xoodyak, Strobe:** decrypts data, squeezes a tag and verify that it matches the one that was appended to the ciphertext.
//
// If `out` and `data` are the same address, decryption may happen in-place.
//
// The function returns the actual size of the decrypted message.
//
// `invalid_tag` is returned if the tag didn't verify.
//
// `invalid_operation` is returned for algorithms not supporting encryption.
// in: handle, out, out_len, data, data_len
// out: error, actual_out_len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_decrypt(handle: symmetric_state, out: *u8, out_len: size, data: *const u8, data_len: size, actual_out_len_ptr: *size) crypto_errno;
// - **Stream cipher:** returns `invalid_operation` since stream ciphers do not include authentication tags.
// - **AEAD:** decrypts `data` into `out`. Additional data must have been previously absorbed using `symmetric_state_absorb()`.
// - **SHOE, Xoodyak, Strobe:** decrypts data, squeezes a tag and verify that it matches the expected one.
//
// `raw_tag` is the expected tag, as raw bytes.
//
// `out` and `data` be must have the same length.
// If they also share the same address, decryption may happen in-place.
//
// The function returns the actual size of the decrypted message.
//
// `invalid_tag` is returned if the tag verification failed.
//
// `invalid_operation` is returned for algorithms not supporting encryption.
// in: handle, out, out_len, data, data_len, raw_tag, raw_tag_len
// out: error, actual_out_len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_decrypt_detached(handle: symmetric_state, out: *u8, out_len: size, data: *const u8, data_len: size, raw_tag: *const u8, raw_tag_len: size, actual_out_len_ptr: *size) crypto_errno;
// Make it impossible to recover the previous state.
//
// This operation is supported by some systems keeping a rolling state over an entire session, for forward security.
//
// `invalid_operation` is returned for algorithms not supporting ratcheting.
// in: handle
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_state_ratchet(handle: symmetric_state) crypto_errno;
// Return the length of an authentication tag.
//
// This function can be used by a guest to allocate the correct buffer size to copy a computed authentication tag.
// in: symmetric_tag
// out: error, len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_tag_len(symmetric_tag: symmetric_tag, len_ptr: *size) crypto_errno;
// Copy an authentication tag into a guest-allocated buffer.
//
// The handle automatically becomes invalid after this operation. Manually closing it is not required.
//
// Example usage:
//
// ```rust
// let mut raw_tag = [0u8; 16];
// ctx.symmetric_tag_pull(raw_tag_handle, &mut raw_tag)?;
// ```
//
// The function returns `overflow` if the supplied buffer is too small to copy the tag.
//
// Otherwise, it returns the number of bytes that have been copied.
// in: symmetric_tag, buf, buf_len
// out: error, len
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_tag_pull(symmetric_tag: symmetric_tag, buf: *u8, buf_len: size, len_ptr: *size) crypto_errno;
// Verify that a computed authentication tag matches the expected value, in constant-time.
//
// The expected tag must be provided as a raw byte string.
//
// The function returns `invalid_tag` if the tags don't match.
//
// Example usage:
//
// ```rust
// let key_handle = ctx.symmetric_key_import("HMAC/SHA-256", b"key")?;
// let state_handle = ctx.symmetric_state_open("HMAC/SHA-256", Some(key_handle), None)?;
// ctx.symmetric_state_absorb(state_handle, b"data")?;
// let computed_tag_handle = ctx.symmetric_state_squeeze_tag(state_handle)?;
// ctx.symmetric_tag_verify(computed_tag_handle, expected_raw_tag)?;
// ```
// in: symmetric_tag, expected_raw_tag_ptr, expected_raw_tag_len
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_tag_verify(symmetric_tag: symmetric_tag, expected_raw_tag_ptr: *const u8, expected_raw_tag_len: size) crypto_errno;
// Explicitly destroy an unused authentication tag.
//
// This is usually not necessary, as `symmetric_tag_pull()` automatically closes a tag after it has been copied.
//
// Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.
// in: symmetric_tag
// out: error
extern "wasi_ephemeral_crypto_symmetric" fn symmetric_tag_close(symmetric_tag: symmetric_tag) crypto_errno;
};
// ----------------------[wasi_ephemeral_crypto_kx]----------------------
pub const mod_wasi_ephemeral_crypto_kx = struct {
// Perform a simple Diffie-Hellman key exchange.
//
// Both keys must be of the same type, or else the `$crypto_errno.incompatible_keys` error is returned.
// The algorithm also has to support this kind of key exchange. If this is not the case, the `$crypto_errno.invalid_operation` error is returned.
//
// Otherwide, a raw shared key is returned, and can be imported as a symmetric key.
// ```
// in: pk, sk
// out: error, shared_secret
extern "wasi_ephemeral_crypto_kx" fn kx_dh(pk: publickey, sk: secretkey, shared_secret_ptr: *array_output) crypto_errno;
// Create a shared secret and encrypt it for the given public key.
//
// This operation is only compatible with specific algorithms.
// If a selected algorithm doesn't support it, `$crypto_errno.invalid_operation` is returned.
//
// On success, both the shared secret and its encrypted version are returned.
// in: pk
// out: error, secret, encapsulated_secret
extern "wasi_ephemeral_crypto_kx" fn kx_encapsulate(pk: publickey, secret_ptr: *array_output, encapsulated_secret_ptr: *array_output) crypto_errno;
// Decapsulate an encapsulated secret crated with `kx_encapsulate`
//
// Return the secret, or `$crypto_errno.verification_failed` on error.
// in: sk, encapsulated_secret, encapsulated_secret_len
// out: error, secret
extern "wasi_ephemeral_crypto_kx" fn kx_decapsulate(sk: secretkey, encapsulated_secret: *const u8, encapsulated_secret_len: size, secret_ptr: *array_output) crypto_errno;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment