Modern Algorithms in the Web Cryptography API

Draft Community Group Report

Latest published version:
https://www.w3.org/webcrypto-modern-algos/
Latest editor's draft:
https://twiss.github.io/webcrypto-modern-algos/
Editor:
(Proton AG)
Feedback:
GitHub twiss/webcrypto-modern-algos (pull requests, new issue, open issues)

Abstract

This specification defines a number of modern cryptographic algorithms for the Web Cryptography API, namely AES-OCB, ChaCha20-Poly1305, SHA-3, cSHAKE, KMAC, and Argon2.

Status of This Document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

This is an unofficial proposal.

GitHub Issues are preferred for discussion of this specification.

1. Introduction

This section is non-normative.

This proposal aims to modernize the set of cryptographic algorithms available in the Web Cryptography API, such that web applications can make use of the most secure and performant options available. To this end, the following cryptographic algorithms are added:

Additionally, this proposal aims to make feature detection easier, by adding a SubtleCrypto.supports function, which can be used to detect whether a given algorithm identifier (including any parameters) is supported for the given operation.

2. Specification Conventions

This specification follows the conventions laid out in Section 18.3 of [WebCryptoAPI]. None of the algorithms defined here are required to be implemented, but if a conforming User Agent implements an algorithm, it MUST implement all of the supported operations specified in this document, and must perform the steps to define an algorithm specified in section 18.4.3 of [WebCryptoAPI] for each of the supported operations.

3. Terminology

An octet string is an ordered sequence of zero or more integers, each in the range 0 to 255 inclusive.

When this specification states to supply the contents of an ArrayBuffer named data to an underlying cryptographic implementation, the User Agent shall supply a contiguous sequence of bytes that is equal to the result of getting a copy of the bytes held data.

4. Partial SubtleCrypto interface

This section extends the SubtleCrypto interface of [WebCryptoAPI].

WebIDL[SecureContext,Exposed=(Window,Worker)]
partial interface SubtleCrypto {
  static boolean supports(DOMString operation,
                   AlgorithmIdentifier algorithm,
                   optional unsigned long? length = null);
  static boolean supports(DOMString operation,
                   AlgorithmIdentifier algorithm,
                   AlgorithmIdentifier additionalAlgorithm);
};

4.1 Methods and Parameters

4.1.1 The supports method

The supports(operation, algorithm, length) method returns a boolean indicating whether the implementation supports the given operation using the specified AlgorithmIdentifier, with an optional length parameter to indicate the number of bits to be derived when operation is "deriveBits". It behaves as follows:

  1. If operation is not one of "encrypt", "decrypt", "sign", "verify", "digest", "generateKey", "deriveKey", "deriveBits", "importKey", "exportKey", "wrapKey" or "unwrapKey", return false.

  2. Return the result of checking support for an algorithm, with op set to operation, alg set to algorithm, and length set to length.

The supports(operation, algorithm, additionalAlgorithm) method returns a boolean indicating whether the implementation supports the given operation using the specified AlgorithmIdentifier. The additional algorithm indicates the type of key to be derived when operation is "deriveKey", the type of key to be exported before wrapping when operation is "wrapKey", and the type of key to be imported after unwrapping when operation is "unwrapKey". It behaves as follows:

  1. If operation is not one of "encrypt", "decrypt", "sign", "verify", "digest", "generateKey", "deriveKey", "deriveBits", "importKey", "exportKey", "wrapKey" or "unwrapKey", return false.

  2. If operation is "deriveKey":

    If the result of checking support for an algorithm with op set to "importKey" and alg set to additionalAlgorithm is false, or the result of checking support for an algorithm with op set to "get key length" and alg set to additionalAlgorithm is false, return false.

    If operation is "wrapKey":

    If the result of checking support for an algorithm with op set to "exportKey" and alg set to additionalAlgorithm is false, return false.

    If operation is "unwrapKey":

    If the result of checking support for an algorithm with op set to "importKey" and alg set to additionalAlgorithm is false, return false.

  3. Return the result of checking support for an algorithm, with op set to operation and alg set to algorithm.

4.2 Checking support for an algorithm

The check support for an algorithm algorithm defines a process for checking whether the given algorithm is supported for the given operation. Its input is an operation name op, an AlgorithmIdentifier alg, and an optional length parameter. Its output is a boolean. It behaves as follows:

  1. If op is "deriveKey", set op is "deriveBits".

  2. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to alg and op set to op.

  3. If an error occurred:
    1. If op is "wrapKey", return the result of checking support for an algorithm with op set to "encrypt" and alg set to alg.

    2. If op is "unwrapKey", return the result of checking support for an algorithm with op set to "decrypt" and alg set to alg.

    3. Otherwise, return false.

  4. If the specified operation or algorithm (or one of its parameter values) is expected to fail (for any key and/or data) for an implementation-specific reason (e.g. known nonconformance to the specification), return false.

  5. If op is "generateKey" or "importKey", let usages be the empty list.

  6. For each of the steps of the operation specified by op of the algorithm specified by normalizedAlgorithm:

    If the step says to throw an error:
    Return false.
    If the step says to generate a key:
    Return true.
    If the step relies on an unavailable parameter, such as key, plaintext or ciphertext:
    Return true.
    If the step says to return a value:
    Return true.
    Otherwise:
    Execute the step.
    Note

    The steps in the referenced algorithm may access the normalizedAlgorithm, length, and usages variables from this context.

  7. Assert: this step is never reached, because one of the steps of the operation will have said to return a value or throw an error, causing us to return true or false, respectively.

5. AES-OCB

5.1 Description

This section is non-normative.

The "AES-OCB" algorithm identifier is used to perform authenticated encryption and decryption using AES in OCB mode, as described in [RFC7253].

5.2 Registration

The recognized algorithm name for this algorithm is "AES-OCB".

Operation Parameters Result
encrypt AeadParams ArrayBuffer
decrypt AeadParams ArrayBuffer
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

5.3 AeadParams dictionary

WebIDLdictionary AeadParams : Algorithm {
  required BufferSource iv;
  BufferSource additionalData;
  [EnforceRange] octet tagLength;
};

The iv member represents the initialization vector to use.

The additionalData member represents the additional authentication data to include.

The tagLength member represents the desired length of the authentication tag.

Note

The AeadParams dictionary is identical to the AesGcmParams dictionary of [WebCryptoAPI], and the latter may be replaced by the former when merging this proposal.

5.4 Operations

Encrypt
  1. If the iv member of normalizedAlgorithm has a length greater than 15 bytes, then throw an OperationError.

  2. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 64, 96 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  3. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  4. Let C be the output that results from performing the OCB-ENCRYPT function described in Section 4.2 of [RFC7253] using AES as the block cipher, using the key represented by [[handle]] internal slot of key as the K input parameter, the contents of the iv member of normalizedAlgorithm as the N input parameter, the contents of additionalData as the A input parameter, the contents of plaintext as the P input parameter, and tagLength as the TAGLEN global parameter.

  5. Return the result of creating an ArrayBuffer containing C.

Decrypt
  1. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 64, 96 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  2. If ciphertext has a length less than tagLength bits, then throw an OperationError.

  3. If the iv member of normalizedAlgorithm has a length greater than 15 bytes, then throw an OperationError.

  4. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  5. Perform the OCB-DECRYPT function described in Section 4.3 of [RFC7253] using AES as the block cipher, using the key represented by [[handle]] internal slot of key as the K input parameter, the contents of the iv member of normalizedAlgorithm as the N input parameter, the contents of additionalData as the A input parameter, the contents of ciphertext as the C input parameter, and tagLength as the TAGLEN global parameter.

    If the result of the algorithm is the indication of authentication failure, "INVALID":
    throw an OperationError
    Otherwise:
    Let plaintext be the output P of OCB-DECRYPT.
  6. Return the result of creating an ArrayBuffer containing plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-OCB".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. If keyData is a JsonWebKey dictionary:

      Let jwk equal keyData.

      Otherwise:

      Throw a DataError.

    2. If the kty field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms [JWA], then throw a DataError.

    4. Let data be the octet string obtained by decoding the k field of jwk.

    5. If data has length 128 bits:
      If the alg field of jwk is present, and is not "A128OCB", then throw a DataError.
      If data has length 192 bits:
      If the alg field of jwk is present, and is not "A192OCB", then throw a DataError.
      If data has length 256 bits:
      If the alg field of jwk is present, and is not "A256OCB", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If usages is non-empty and the use field of jwk is present and is not "enc", then throw a DataError.

    7. If the key_ops field of jwk is present, and is invalid according to the requirements of JSON Web Key [JWK] or does not contain all of the specified usages values, then throw a DataError.

    8. If the ext field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new {{CryptoKey}} object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-OCB".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be the result of creating an ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms [JWA].

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128OCB".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192OCB".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256OCB".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

6. ChaCha20-Poly1305

6.1 Description

This section is non-normative.

The "ChaCha20-Poly1305" algorithm identifier is used to perform authenticated encryption and decryption using AEAD_CHACHA20_POLY1305, as described in [RFC8439].

6.2 Registration

The recognized algorithm name for this algorithm is "ChaCha20-Poly1305".

Operation Parameters Result
encrypt AeadParams ArrayBuffer
decrypt AeadParams ArrayBuffer
generateKey None CryptoKey
importKey None CryptoKey
exportKey None object
get key length None Integer

6.3 Operations

Encrypt
  1. If the iv member of normalizedAlgorithm does not have a length of 12 bytes, then throw an OperationError.

  2. If the tagLength member of normalizedAlgorithm is present and is not 128, then throw an OperationError.

  3. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  4. Let ciphertext be the output that results from performing the AEAD_CHACHA20_POLY1305 encryption algorithm described in Section 2.8 of [RFC8439], using the key represented by [[handle]] internal slot of key as the key input parameter, the contents of the iv member of normalizedAlgorithm as the nonce input parameter, the contents of plaintext as the plaintext input parameter, and the contents of additionalData as the additional authenticated data (AAD) input parameter.

  5. Return the result of creating an ArrayBuffer containing ciphertext.

Decrypt
  1. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 64, 96 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  2. If ciphertext has a length less than tagLength bits, then throw an OperationError.

  3. If the iv member of normalizedAlgorithm has a length greater than 15 bytes, then throw an OperationError.

  4. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  5. Perform the AEAD_CHACHA20_POLY1305 decryption algorithm described in Section 2.8 of [RFC8439], using the key represented by [[handle]] internal slot of key as the key input parameter, the contents of the iv member of normalizedAlgorithm as the nonce input parameter, the contents of ciphertext as the ciphertext input parameter, and the contents of additionalData as the additional authenticated data (AAD) input parameter.

    If the result of the algorithm is the indication of authentication failure:
    throw an OperationError
    Otherwise:
    Let plaintext be the resulting plaintext.
  6. Return the result of creating an ArrayBuffer containing plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. Generate a 256-bit key.

  3. If the key generation step fails, then throw an OperationError.

  4. Let key be a new CryptoKey object representing the generated key.

  5. Let algorithm be a new KeyAlgorithm.

  6. Set the name attribute of algorithm to "ChaCha20-Poly1305".

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Set the [[extractable]] internal slot of key to be extractable.

  9. Set the [[usages]] internal slot of key to be usages.

  10. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 256 then throw a DataError.

    If format is "jwk":
    1. If keyData is a JsonWebKey dictionary:

      Let jwk equal keyData.

      Otherwise:

      Throw a DataError.

    2. If the kty field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms [JWA], then throw a DataError.

    4. Let data be the octet string obtained by decoding the k field of jwk.

    5. If the alg field of jwk is present, and is not "CC20P1305", then throw a DataError.

    6. If usages is non-empty and the use field of jwk is present and is not "enc", then throw a DataError.

    7. If the key_ops field of jwk is present, and is invalid according to the requirements of JSON Web Key [JWK] or does not contain all of the specified usages values, then throw a DataError.

    8. If the ext field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new {{CryptoKey}} object representing a key with value data.

  4. Let algorithm be a new KeyAlgorithm.

  5. Set the name attribute of algorithm to "ChaCha20-Poly1305".

  6. Set the [[algorithm]] internal slot of key to algorithm.

  7. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be the result of creating an ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms [JWA].

    4. Set the alg attribute of jwk to the string "CC20P1305".

    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. Return 256.

7. SHA-3

7.1 Description

This section is non-normative.

This describes the SHA-3 family of hash functions, as specified by [FIPS-202].

7.2 Registration

The recognized algorithm names are "SHA3-256", "SHA3-384", and "SHA3-512" for the respective SHA-3 algorithms.

Operation Parameters Result
digest None ArrayBuffer

7.3 Operations

Digest
  1. If the name member of normalizedAlgorithm is a case-sensitive string match for "SHA3-256":
    Let result be the result of performing the SHA3-256 hash function defined in Section 6.1 of [FIPS-202] using message as the input message, M.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "SHA3-384":
    Let result be the result of performing the SHA3-384 hash function defined in Section 6.1 of [FIPS-202] using message as the input message, M.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "SHA3-512":
    Let result be the result of performing the SHA3-512 hash function defined in Section 6.1 of [FIPS-202] using message as the input message, M.
  2. If performing the operation results in an error, then throw an OperationError.

  3. Return a new ArrayBuffer containing result.

8. cSHAKE

8.1 Description

This section is non-normative.

This describes cSHAKE128 and cSHAKE256, as specified by [NIST-SP800-185].

8.2 Registration

The recognized algorithm names are "cSHAKE128" and "cSHAKE256".

Operation Parameters Result
digest CShakeParams ArrayBuffer

8.3 CShakeParams dictionary

WebIDLdictionary CShakeParams : Algorithm {
  required [EnforceRange] unsigned long length;
  BufferSource functionName;
  BufferSource customization;
};

The length member represents the requested output length in bits.

The functionName member represents the function name, used by NIST to define functions based on cSHAKE. When used, it should only be set to values defined by NIST.

The customization member represents the customization string. The application selects this string to define a variant of the function.

8.4 Operations

Digest
  1. If the name member of normalizedAlgorithm is a case-sensitive string match for "cSHAKE128":
    Let result be the result of performing the cSHAKE128 function defined in Section 3 of [NIST-SP800-185] using message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, the contents of the functionName member of normalizedAlgorithm as the N input parameter, and the contents of the customization member of normalizedAlgorithm as the S input parameter.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "cSHAKE256":
    Let result be the result of performing the cSHAKE256 function defined in Section 3 of [NIST-SP800-185] using message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, the contents of the functionName member of normalizedAlgorithm as the N input parameter, and the contents of the customization member of normalizedAlgorithm as the S input parameter.
  2. If performing the operation results in an error, then throw an OperationError.

  3. Return a new ArrayBuffer containing result.

9. KMAC

9.1 Description

This section is non-normative.

This describes KMAC128 and KMAC256, as specified by [NIST-SP800-185].

9.2 Registration

The recognized algorithm names are "KMAC128" and "KMAC256".

Operation Parameters Result
sign KmacParams ArrayBuffer
verify KmacParams boolean
generateKey KmacKeyGenParams CryptoKey
importKey KmacImportParams CryptoKey
exportKey None object
get key length KmacImportParams Integer

9.3 KmacKeyGenParams dictionary

WebIDLdictionary KmacKeyGenParams : Algorithm {
  [EnforceRange] unsigned long length;
};

The length member represents the length (in bits) of the key to generate. If unspecified, the recommended length will be used, which is 128 for KMAC128 and 256 for KMAC256.

9.4 KmacImportParams dictionary

WebIDLdictionary KmacImportParams : Algorithm {
  [EnforceRange] unsigned long length;
};

The length member represents the length (in bits) of the key.

9.5 KmacKeyAlgorithm dictionary

WebIDLdictionary KmacKeyAlgorithm : KeyAlgorithm {
  required unsigned long length;
};

The length member represents the length (in bits) of the key.

9.6 KmacParams dictionary

WebIDLdictionary KmacParams : Algorithm {
  required [EnforceRange] unsigned long length;
  BufferSource customization;
};

The length member represents the requested output length in bits.

The customization member represents the customization string. The application selects this string to define a variant of the function.

9.7 Operations

Sign
  1. Let customization be the contents of the customization member of normalizedAlgorithm if present or the empty octet string otherwise.

  2. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let mac be the result of performing the KMAC128 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let mac be the result of performing the KMAC256 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
  3. Return the result of creating an ArrayBuffer containing mac.

Verify
  1. Let customization be the contents of the customization member of normalizedAlgorithm if present or the empty octet string otherwise.

  2. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let mac be the result of performing the KMAC128 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let mac be the result of performing the KMAC256 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
  3. Return true if mac is equal to signature and false otherwise.

Generate Key
  1. If usages contains any entry which is not "sign" or "verify", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is present:
    Let length be equal to the length member of normalizedAlgorithm.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let length be 128.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let length be 256.
  3. Generate a key of length length bits.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated key.

  6. Let algorithm be a new KmacKeyAlgorithm.

  7. Set the name attribute of algorithm to "KMAC".

  8. Set the [[algorithm]] internal slot of key to algorithm.

  9. Set the [[extractable]] internal slot of key to be extractable.

  10. Set the [[usages]] internal slot of key to be usages.

  11. Return key.

Import Key
  1. Let keyData be the key data to be imported.

  2. If usages contains an entry which is not "sign" or "verify", then throw a SyntaxError.

  3. If format is "raw":
    1. Let data be the octet string contained in keyData.

    If format is "jwk":
    1. If keyData is a JsonWebKey dictionary:

      Let jwk equal keyData.

      Otherwise:

      Throw a DataError.

    2. If the kty field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms [JWA], then throw a DataError.

    4. Let data be the octet string obtained by decoding the k field of jwk.

    5. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
      If the alg field of jwk is present and is not "K128", then throw a DataError.
      If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
      If the alg field of jwk is present and is not "K256", then throw a DataError.
    6. If usages is non-empty and the use field of jwk is present and is not "sign", then throw a DataError.

    7. If the key_ops field of jwk is present, and is invalid according to the requirements of JSON Web Key [JWK] or does not contain all of the specified usages values, then throw a DataError.

    8. If the ext field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  4. Let length be equivalent to the length, in octets, of data, multiplied by 8.

  5. If length is zero then throw a DataError.

  6. If the length member of normalizedAlgorithm is present:
    If the length member of normalizedAlgorithm is greater than length:
    throw a DataError.
    If the length member of normalizedAlgorithm, is less than or equal to length minus eight:
    throw a DataError.
    Otherwise:
    Set length equal to the length member of normalizedAlgorithm.
  7. Let key be a new {{CryptoKey}} object representing an KMAC key with the first length bits of data.

  8. Let algorithm be a new KmacKeyAlgorithm.

  9. Set the name attribute of algorithm to "KMAC".

  10. Set the length attribute of algorithm to length.

  11. Set the [[algorithm]] internal slot of key to algorithm.

  12. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. Let bits be the raw bits of the key represented by [[handle]] internal slot of key.

  3. Let data be an octet string containing bits.

  4. If format is "raw":
    1. Let result be the result of creating an ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing data, encoded according to Section 6.4 of JSON Web Algorithms [JWA].

    4. Let algorithm be the [[algorithm]] internal slot of key.

    5. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
      Set the alg attribute of jwk to the string "K128".
      If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
      Set the alg attribute of jwk to the string "K256".
    6. Set the key_ops attribute of jwk to equal the usages attribute of key.

    7. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    8. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  5. Return result.

Get key length
  1. If the length member of normalizedAlgorithm is present:
    Let length be equal to the length member of normalizedAlgorithm.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let length be 128.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let length be 256.
  2. Return length.

10. Argon2

10.1 Description

This section is non-normative.

This describes the Argon2 function for password hashing and key derivation, as defined in [RFC9106].

10.2 Registration

The recognized algorithm names are "Argon2d", "Argon2i", and "Argon2id" for the respective Argon2 types.

Operation Parameters Result
deriveBits Argon2Params ArrayBuffer
importKey None CryptoKey
Get key length None null

10.3 Argon2Params dictionary

WebIDLdictionary Argon2Params : Algorithm {
  required BufferSource nonce;
  required [EnforceRange] unsigned long parallelism;
  required [EnforceRange] unsigned long memory;
  required [EnforceRange] unsigned long passes;
  [EnforceRange] octet version;
  BufferSource secretValue;
  BufferSource associatedData;
};

The nonce member represents the nonce, which is a salt for password hashing applications.

The parallelism member represents the degree of parallelism.

The memory member represents the memory size in kibibytes. It must be at least 8 times the degree of parallelism.

The passes member represents the number of passes.

The version member represents the version number. The default and currently only defined version is 19 (0x13).

The secretValue member represents the optional secret value.

The associatedData member represents the optional associated data.

Note

For the recommended values of the parameters, see section 4 of [RFC9106].

10.4 Operations

Derive Bits
  1. If length is null, or is less than 32 (4*8), then throw an OperationError.

  2. If the version member of normalizedAlgorithm is present and is not 19 (0x13), then throw an OperationError.

  3. If the parallelism member of normalizedAlgorithm is zero, or greater than 16777215 (2^24-1), then throw an OperationError.

  4. If the memory member of normalizedAlgorithm is less than 8 times the parallelism member of normalizedAlgorithm, then throw an OperationError.

  5. If the passes member of normalizedAlgorithm is zero, then throw an OperationError.

  6. If the name member of normalizedAlgorithm is a case-sensitive string match for "Argon2d":
    Let type be 0.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "Argon2i":
    Let type be 1.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "Argon2id":
    Let type be 2.
  7. Let secretValue be the contents of the secretValue member of normalizedAlgorithm, if present.

  8. Let associatedData be the contents of the associatedData member of normalizedAlgorithm, if present.

  9. Let result be the result of performing the Argon2 function defined in Section 3 of [RFC9106] using the password represented by [[handle]] internal slot of key as the message, P, the contents of the nonce attribute of normalizedAlgorithm as the nonce, S, the value of the parallelism attribute of normalizedAlgorithm as the degree of parallelism, p, the value of the memory attribute of normalizedAlgorithm as the memory size, m, the value of the passes attribute of normalizedAlgorithm as the number of passes, t, 0x13 as the version number, v, secretValue (if present) as the secret value, K, associatedData (if present) as the associated data, X, type as the type, y, and length divided by 8 as the tag length, T.

  10. If the key derivation operation fails, then throw an OperationError.

  11. Return result

Import key
  1. If format is not "raw", throw a NotSupportedError

  2. If usages contains a value that is not "deriveKey" or "deriveBits", then throw a SyntaxError.

  3. If extractable is not false, then throw a SyntaxError.

  4. Let key be a new CryptoKey representing keyData.

  5. Set the [[type]] internal slot of key to "secret".

  6. Set the [[extractable]] internal slot of key to false.

  7. Let algorithm be a new KeyAlgorithm object.

  8. Set the name attribute of algorithm to the name member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Return key.

Get key length
  1. Return null.

11. Usage Example

This example derives a key from a password using Argon2, if available, or PBKDF2, otherwise; and then encrypts and decrypts some text with it using AES-OCB, if available, and AES-GCM, otherwise.

Example 1: Encrypt some data using a key derived from a password
const password = 'correct horse battery staple';
const derivationAlg =
  SubtleCrypto.supports?.('importKey', 'Argon2id') ?
    'Argon2id' :
    'PBKDF2';
const encryptionAlg =
  SubtleCrypto.supports?.('importKey', 'AES-OCB') ?
    'AES-OCB' :
    'AES-GCM';
const passwordKey = await crypto.subtle.importKey(
  'raw',
  new TextEncoder().encode(password),
  derivationAlg,
  /* extractable: */ false,
  ['deriveKey']
);
const nonce = crypto.getRandomValues(new Uint8Array(16));
const derivationParams =
  derivationAlg === 'Argon2id' ?
    {
      nonce,
      parallelism: 4,
      memory: 2 ** 21,
      passes: 1
    } :
    {
      salt: nonce,
      iterations: 100_000,
      hash: 'SHA-256'
    };
const key = await crypto.subtle.deriveKey(
  {
    name: derivationAlg,
    ...derivationParams
  },
  passwordKey,
  {
    name: encryptionAlg,
    length: 256
  },
  /* extractable: */ false,
  ['encrypt', 'decrypt']
);
const plaintext = 'Hello, world!';
const iv = crypto.getRandomValues(new Uint8Array(16));
const encrypted = await crypto.subtle.encrypt(
  { name: encryptionAlg, iv },
  key,
  new TextEncoder().encode(plaintext)
);
// Store the derivation and encryption algorithm and parameters
// as well as the ciphertext (e.g. in IndexedDB or a database),
// and retrieve them later. Then, derive the key using the
// original parameters and the password. Here we immediately
// use the same key object to decrypt again.
const decrypted = new TextDecoder().decode(await crypto.subtle.decrypt(
  { name: encryptionAlg, iv },
  key,
  encrypted
));

A. Mapping between JSON Web Key / JSON Web Algorithm

This section is non-normative.

Refer to algorithm-specific sections for the normative requirements of importing and exporting JWK.

A.1 Algorithm mappings

JSON Web Key AlgorithmIdentifier
{ kty: "oct",
alg: "A128OCB" }
{ name: "AES-OCB",
length: 128 }
{ kty: "oct",
alg: "A192OCB" }
{ name: "AES-OCB",
length: 192 }
{ kty: "oct",
alg: "A256OCB" }
{ name: "AES-OCB",
length: 256 }
{ kty: "oct",
alg: "CC20P1305" }
{ name: "ChaCha20-Poly1305" }
{ kty: "oct",
alg: "K128" }
{ name: "KMAC128" }
{ kty: "oct",
alg: "K256" }
{ name: "KMAC256" }
TODO: register A128OCB, A192OCB, A256OCB, CC20P1305, K128 and K256(?) with IANA in the JSON Web Signature and Encryption Algorithms registry.

B. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key word MUST in this document is to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

C. References

C.1 Normative references

[FIPS-202]
SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. NIST. August 2015. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[JWA]
JSON Web Algorithms (JWA). M. Jones. IETF. May 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7518
[JWK]
JSON Web Key (JWK). M. Jones. IETF. May 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7517
[NIST-SP800-185]
NIST Special Publication 800-185: SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash. NIST. December 2016. URL: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC7253]
The OCB Authenticated-Encryption Algorithm. T. Krovetz; P. Rogaway. IETF. May 2014. Informational. URL: https://www.rfc-editor.org/rfc/rfc7253
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8439]
ChaCha20 and Poly1305 for IETF Protocols. Y. Nir; A. Langley. IETF. June 2018. Informational. URL: https://www.rfc-editor.org/rfc/rfc8439
[RFC9106]
Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications. A. Biryukov; D. Dinu; D. Khovratovich; S. Josefsson. IETF. September 2021. Informational. URL: https://www.rfc-editor.org/rfc/rfc9106
[WebCryptoAPI]
Web Cryptography API. Mark Watson. W3C. 26 January 2017. W3C Recommendation. URL: https://www.w3.org/TR/WebCryptoAPI/
[WebIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/