Skip to content

Latest commit

 

History

History
1200 lines (845 loc) · 38 KB

markdown.md

File metadata and controls

1200 lines (845 loc) · 38 KB

Module: wasi_ephemeral_crypto_symmetric

Table of contents

Types list:

[All] - [crypto_errno] - [keypair_encoding] - [publickey_encoding] - [secretkey_encoding] - [signature_encoding] - [algorithm_type] - [version] - [size] - [timestamp] - [u64] - [array_output] - [options] - [secrets_manager] - [keypair] - [signature_state] - [signature] - [publickey] - [secretkey] - [signature_verification_state] - [symmetric_state] - [symmetric_key] - [symmetric_tag] - [opt_options_u] - [opt_options] - [opt_symmetric_key_u] - [opt_symmetric_key]

Functions list:

[All] - [symmetric_key_generate()] - [symmetric_key_import()] - [symmetric_key_export()] - [symmetric_key_close()] - [symmetric_key_generate_managed()] - [symmetric_key_store_managed()] - [symmetric_key_replace_managed()] - [symmetric_key_id()] - [symmetric_key_from_id()] - [symmetric_state_open()] - [symmetric_state_options_get()] - [symmetric_state_options_get_u64()] - [symmetric_state_close()] - [symmetric_state_absorb()] - [symmetric_state_squeeze()] - [symmetric_state_squeeze_tag()] - [symmetric_state_squeeze_key()] - [symmetric_state_max_tag_len()] - [symmetric_state_encrypt()] - [symmetric_state_encrypt_detached()] - [symmetric_state_decrypt()] - [symmetric_state_decrypt_detached()] - [symmetric_state_ratchet()] - [symmetric_tag_len()] - [symmetric_tag_pull()] - [symmetric_tag_verify()] - [symmetric_tag_close()]

Types

Enumeration with tag type: u16, and the following members:

Error codes.


Enumeration with tag type: u16, and the following members:

Encoding to use for importing or exporting a key pair.


Enumeration with tag type: u16, and the following members:

Encoding to use for importing or exporting a public key.


Enumeration with tag type: u16, and the following members:

Encoding to use for importing or exporting a secret key.


Enumeration with tag type: u16, and the following members:

Encoding to use for importing or exporting a signature.


Enumeration with tag type: u16, and the following members:

An algorithm category.


Alias for u64.

Version of a managed key.

A version can be an arbitrary u64 integer, with the expection of some reserved values.


Alias for usize.

Size of a value.


Alias for u64.

A UNIX timestamp, in seconds since 01/01/1970.


Alias for u64.

A 64-bit value


Alias for handle.

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.


Alias for 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.


Alias for handle.

A handle to the optional secrets management facilities offered by a host.

This is used to generate, retrieve and invalidate managed keys.


Alias for handle.

A key pair.


Alias for 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.


Alias for handle.

A signature.


Alias for handle.

A public key, for key exchange and signature verification.


Alias for handle.

A secret key, for key exchange mechanisms.


Alias for handle.

A state to absorb signed data to be verified.


Alias for 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.


Alias for 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.


Alias for 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.


Enumeration with tag type: u8, and the following members:

Options index, only required by the Interface Types translation layer.


Tagged union with tag type: u8 and the following possibilities:

An optional options set.

This union simulates an Option\<Options\> type to make the options parameter of some functions optional.


Enumeration with tag type: u8, and the following members:

Symmetric key index, only required by the Interface Types translation layer.


Tagged union with tag type: u8 and the following possibilities:

An optional symmetric key.

This union simulates an Option\<SymmetricKey\> type to make the symmetric_key parameter of some functions optional.


Functions

Returned error type: crypto_errno

Input:

Output:

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.


Returned error type: crypto_errno

Input:

  • algorithm: string
  • raw: u8 pointer
  • raw_len: size

Output:

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.


Returned error type: crypto_errno

Input:

Output:

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.


Returned error type: crypto_errno

Input:

This function has no output.

Destroy a symmetric key.

Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.


Returned error type: crypto_errno

Input:

Output:

(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.


Returned error type: crypto_errno

Input:

This function has no output.

(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.


Returned error type: crypto_errno

Input:

Output:

(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.


Returned error type: crypto_errno

Input:

  • symmetric_key: symmetric_key
  • symmetric_key_id: u8 mutable pointer
  • symmetric_key_id_max_len: size

Output:

(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.


Returned error type: crypto_errno

Input:

Output:

(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.


Returned error type: crypto_errno

Input:

Output:

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:

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
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
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:

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
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:

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:

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
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
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
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
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
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")?;
// ...

Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer

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.


Returned error type: crypto_errno

Input:

Output:

  • u64 mutable pointer

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.


Returned error type: crypto_errno

Input:

This function has no output.

Destroy a symmetric state.

Objects are reference counted. It is safe to close an object immediately after the last function needing it is called.


Returned error type: crypto_errno

Input:

This function has no output.

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.


Returned error type: crypto_errno

Input:

This function has no output.

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.


Returned error type: crypto_errno

Input:

Output:

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.


Returned error type: crypto_errno

Input:

Output:

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.


Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer

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 must be ciphertext_len - symmetric_state_max_tag_len().


Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer

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.


Returned error type: crypto_errno

Input:

Output:

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.


Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer
  • 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.

out_len must be exactly data_len + max_tag_len bytes.

The function returns the actual size of the decrypted message, which can be smaller than out_len for modes that requires padding.

invalid_tag is returned if the tag didn't verify.

invalid_operation is returned for algorithms not supporting encryption.


Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer
  • 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.


Returned error type: crypto_errno

Input:

This function has no output.

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.


Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer

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.


Returned error type: crypto_errno

Input:

Output:

  • size mutable pointer

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:

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.


Returned error type: crypto_errno

Input:

  • symmetric_tag: symmetric_tag
  • expected_raw_tag_ptr: u8 pointer
  • expected_raw_tag_len: size

This function has no output.

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:

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)?;

Returned error type: crypto_errno

Input:

This function has no output.

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.