diff --git a/spec/Overview.html b/spec/Overview.html index a23c17f..9197d52 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -3938,4791 +3938,6369 @@

RsaHashedImportParams dic

Operations

-
-
Sign
-
-
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Perform the signature generation operation defined in Section 8.2 of [[RFC3447]] with the key represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - as the signer's private key and |message| as - |M| and using the hash function specified in the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| as the Hash option for the EMSA-PKCS1-v1_5 encoding method. -

    -
  4. -
  5. -

    - If performing the operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  6. -
  7. -

    - Let |signature| be the value |S| that results from - performing the operation. -

    -
  8. -
  9. -

    - Return |signature|. -

    -
  10. -
-
- -
Verify
-
-
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Perform the signature verification operation defined in Section 8.2 of - [[RFC3447]] with the key represented by the - {{CryptoKey/[[handle]]}} internal slot of - |key| as the signer's RSA public key and |message| as - |M| and - |signature| as |S| and using the hash function specified - in the {{RsaHashedKeyAlgorithm/hash}} attribute of the - {{CryptoKey/[[algorithm]]}} internal slot of - |key| as the Hash option for the EMSA-PKCS1-v1_5 encoding method. -

    -
  4. -
  5. -

    - Let |result| be a boolean with value true if the - result of the operation was "valid signature" and the value - false otherwise. -

    -
  6. -
  7. -

    Return |result|.

    -
  8. -
-
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains an entry which is not - "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -

    - Generate an RSA key pair, as defined in [[RFC3447]], with RSA modulus length equal to the - {{RsaKeyGenParams/modulusLength}} attribute of - |normalizedAlgorithm| and RSA public exponent equal to the - {{RsaKeyGenParams/publicExponent}} attribute of - |normalizedAlgorithm|. -

    -
  4. -
  5. -

    - If generation of the key pair fails, - then [= exception/throw =] an - {{OperationError}}. -

    -
  6. -
  7. -

    - Let |algorithm| be a new - {{RsaHashedKeyAlgorithm}} - dictionary. -

    -
  8. -
  9. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`RSASSA-PKCS1-v1_5`". -

    -
  10. -
  11. -

    - Set the - {{RsaKeyAlgorithm/modulusLength}} - attribute of |algorithm| to equal the - {{RsaKeyGenParams/modulusLength}} - attribute of |normalizedAlgorithm|. -

    -
  12. -
  13. -

    - Set the - {{RsaKeyAlgorithm/publicExponent}} - attribute of |algorithm| to equal the - {{RsaKeyGenParams/publicExponent}} - attribute of |normalizedAlgorithm|. -

    -
  14. -
  15. -

    - Set the {{RsaHashedKeyAlgorithm/hash}} attribute - of |algorithm| to equal the - {{RsaHashedKeyGenParams/hash}} member of - |normalizedAlgorithm|. -

    -
  16. -
  17. -

    - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

    -
  18. -
  19. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

    -
  20. -
  21. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |publicKey| to |algorithm|. -

    -
  22. -
  23. -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |publicKey| to true. -

    -
  24. -
  25. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the [= usage - intersection =] of |usages| and `[ "verify" ]`. -

    -
  26. -
  27. -

    - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

    -
  28. -
  29. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  30. -
  31. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |privateKey| to |algorithm|. -

    -
  32. -
  33. -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |privateKey| to |extractable|. -

    -
  34. -
  35. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the [= usage - intersection =] of |usages| and `[ "sign" ]`. -

    -
  36. -
  37. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  38. -
  39. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

    -
  40. -
  41. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

    -
  42. -
  43. -

    - Return |result|. -

    -
  44. -
-
- -
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `rsaEncryption` - object identifier defined in [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - Let |publicKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the - `subjectPublicKeyInfo` field of |spki|, - |structure| as the `RSAPublicKey` structure - specified in Section A.1.1 of [[RFC3447]], and - |exactData| set to true. -

      -
    10. -
    11. -

      - If an error occurred while parsing, or it can be determined that |publicKey| - is not a valid public key according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} - that represents the RSA public key identified by - |publicKey|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

      -
    16. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `rsaEncryption` object identifier defined in [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - Let |rsaPrivateKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the - `privateKey` field of |privateKeyInfo|, - |structure| as the `RSAPrivateKey` structure - specified in Section A.1.2 of [[RFC3447]], and - |exactData| set to true. -

      -
    10. -
    11. -

      - If an error occurred while parsing, or if |rsaPrivateKey| is not - a valid RSA private key according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} - that represents the RSA private key identified by - |rsaPrivateKey|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to {{KeyType/"private"}} -

      -
    16. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/Throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field of |jwk| is present and - |usages| contains an entry which is not - "`sign`", or, if the {{JsonWebKey/d}} field of |jwk| - is not present and - |usages| contains an entry which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not a - case-sensitive string match to "`RSA`", - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not a case-sensitive string match to "`sig`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/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 [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |hash| be a be a string whose initial value is - undefined. -

      -
    14. -
    15. -
      -
      - If the {{JsonWebKey/alg}} field of |jwk| is not - present: -
      -
      -

      - Let |hash| be undefined. -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`RS1`": -
      -
      -

      - Let |hash| be the string "`SHA-1`". -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`RS256`": -
      -
      -

      - Let |hash| be the string "`SHA-256`". -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`RS384`": -
      -
      -

      - Let |hash| be the string "`SHA-384`". -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`RS512`": -
      -
      -

      - Let |hash| be the string "`SHA-512`". -

      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= RSASSA-PKCS1-v1_5 key import steps | key - import steps =] defined by - other applicable - specifications, passing |format|, |jwk| - and obtaining |hash|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    16. -
    17. -
      -
      - If |hash| is not undefined: -
      -
      -
        -
      1. -

        - Let |normalizedHash| be the result of - normalize an algorithm - with `alg` set to |hash| and `op` set - to `digest`. -

        -
      2. -
      3. -

        - If |normalizedHash| is not equal to the - {{RsaHashedImportParams/hash}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

        -
      4. -
      -
      -
      -
    18. -
    19. -
      -
      If the {{JsonWebKey/d}} field of |jwk| is present:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - Section 6.3.2 of JSON Web Algorithms [[JWA]], - then [= exception/throw =] a - {{DataError}}. -

        -
      2. -
      3. -

        - Let |privateKey| represents the - RSA private key identified by interpreting |jwk| - according to Section 6.3.2 of JSON Web - Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - If |privateKey| is not a valid RSA private key - according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} object that represents - |privateKey|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} - internal slot of |key| to {{KeyType/"private"}} -

        -
      10. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of Section - 6.3.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |publicKey| represent the - RSA public key identified by interpreting |jwk| - according to Section 6.3.1 of JSON Web Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - If |publicKey| can be determined to not be a valid RSA public key - according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} representing |publicKey|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} - internal slot of |key| to "`public`" -

        -
      10. -
      -
      -
      -
    20. -
    -
    -
    Otherwise:
    -
    - [= exception/throw =] a - {{NotSupportedError}}. -
    -
    -
  4. -
  5. -

    - Let |algorithm| be a new - {{RsaHashedKeyAlgorithm}} dictionary. -

    -
  6. -
  7. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`RSASSA-PKCS1-v1_5`" -

    -
  8. -
  9. -

    - Set the {{RsaKeyAlgorithm/modulusLength}} - attribute of |algorithm| to the length, in bits, of the RSA public - modulus. -

    -
  10. -
  11. -

    - Set the publicExponent - attribute of |algorithm| to the BigInteger - representation of the RSA public exponent. -

    -
  12. -
  13. -

    - Set the {{RsaHashedKeyAlgorithm/hash}} attribute of - |algorithm| to the {{RsaHashedImportParams/hash}} member of - |normalizedAlgorithm|. -

    -
  14. -
  15. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

    -
  16. -
  17. -

    Return |key|.

    -
  18. -
-
-
Export Key
-
-
    -
  1. -

    - Let |key| be the key to be exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `rsaEncryption` defined in - [[RFC3447]]. -

          -
        • -
        • -

          - Set the |params| field to the ASN.1 type NULL. -

          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to the result of - DER-encoding an `RSAPublicKey` ASN.1 type, as defined - in [[RFC3447]], Appendix A.1.1, that - represents the RSA public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `rsaEncryption` defined in - [[RFC3447]]. -

          -
        • -
        • -

          - Set the |params| field to the ASN.1 type NULL. -

          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to the result of DER-encoding - an `RSAPrivateKey` ASN.1 type, as defined in [[RFC3447]], Appendix A.1.2, that represents the - RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

        -
        - [[RFC5208]] specifies that the encoding of - this field should be BER encoded in Section 5 (as a "for - example"). However, to avoid requiring WebCrypto implementations - support BER-encoding and BER-decoding, only DER encodings - are produced or accepted. -
        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      Let |jwk| be a new {{JsonWebKey}} - dictionary.

      -
    2. -
    3. -

      Set the `kty` attribute of |jwk| to the string - "`RSA`".

      -
    4. -
    5. -

      - Let |hash| be the {{KeyAlgorithm/name}} - attribute of the {{RsaHashedKeyAlgorithm/hash}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key|. -

      -
    6. -
    7. -
      -
      If |hash| is "`SHA-1`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RS1`". -

      -
      -
      If |hash| is "`SHA-256`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RS256`". -

      -
      -
      If |hash| is "`SHA-384`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RS384`". -

      -
      -
      If |hash| is "`SHA-512`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RS512`". -

      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= RSASSA-PKCS1-v1_5 key import steps | key - export steps =] defined by - other applicable - specifications, passing |format|, |key| - and obtaining |alg|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{NotSupportedError}}. -

        -
      4. -
      5. -

        - Set the `alg` attribute of |jwk| to |alg|. -

        -
      6. -
      -
      -
      -
    8. -
    9. -

      - Set the attributes {{JsonWebKey/n}} and {{JsonWebKey/e}} of |jwk| - according to the corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.1. -

      -
    10. -
    11. -
      -
      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is {{KeyType/"private"}}: -
      -
      -
        -
      1. -

        - Set the attributes named {{JsonWebKey/d}}, {{JsonWebKey/p}}, - {{JsonWebKey/q}}, {{JsonWebKey/dp}}, {{JsonWebKey/dq}}, and - {{JsonWebKey/qi}} of |jwk| according to the - corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.2. -

        -
      2. -
      3. -

        - If the underlying RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot - of |key| is represented by more than two primes, set - the attribute named {{JsonWebKey/oth}} of |jwk| - according to the corresponding definition in JSON Web Algorithms [[JWA]], Section 6.3.2.7 -

        -
      4. -
      -
      -
      -
    12. -
    13. -

      - Set the `key_ops` attribute of |jwk| to the usages attribute of |key|. -

      -
    14. -
    15. -

      - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

      -
    16. -
    17. -

      - Let |result| be |jwk|. -

      -
    18. -
    -
    -
    Otherwise
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  6. -
  7. -

    - Return |result|. -

    -
  8. -
-
-
-
- +
+
Sign
-
-

RSA-PSS

-
-

Description

-

- The "`RSA-PSS`" algorithm identifier is used to perform signing - and verification using the RSASSA-PSS algorithm specified in - [[RFC3447]], using the SHA hash functions defined - in this specification and the mask generation - formula MGF1. -

-

- Other specifications - may specify the use of additional hash algorithms with RSASSA-PSS. Such specifications - must define the digest operation for the additional hash algorithms and - key import steps and - key export steps for RSASSA-PSS. -

-
-
-

Registration

-

- The [= recognized algorithm name =] for - this algorithm is "`RSA-PSS`". -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationParametersResult
sign{{RsaPssParams}}[= byte sequence =]
verify{{RsaPssParams}}boolean
generateKey{{RsaHashedKeyGenParams}}{{CryptoKeyPair}}
importKey{{RsaHashedImportParams}}{{CryptoKey}}
exportKeyNoneobject
-
-
-

RsaPssParams dictionary

-
-dictionary RsaPssParams : Algorithm {
-  required [EnforceRange] unsigned long saltLength;
-};
-          
-

The saltLength member represents the desired length of the random salt in bytes.

-
-
-

Operations

-
-
Sign
-
-
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Perform the signature generation operation defined in Section 8.1 of [[RFC3447]] with the key represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - as the signer's private key, |K|, and |message| as - the message to be signed, |M|, and using the hash function specified - by the {{RsaHashedKeyAlgorithm/hash}} attribute of the - {{CryptoKey/[[algorithm]]}} internal slot of - |key| as the Hash option, MGF1 (defined in Section B.2.1 of [[RFC3447]]) as the MGF option and the saltLength member of - |normalizedAlgorithm| as the salt length option for the - EMSA-PSS-ENCODE operation. -

    -
  4. -
  5. -

    - If performing the operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  6. -
  7. -

    - Let |signature| be the - signature, S, that results from performing the operation. -

    -
  8. -
  9. -

    - Return |signature|. -

    -
  10. -
-
+
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Perform the signature generation operation defined in Section 8.2 of [[RFC3447]] with the key represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + as the signer's private key and |message| as + |M| and using the hash function specified in the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option for the EMSA-PKCS1-v1_5 encoding method. +

    +
  4. +
  5. +

    + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |signature| be the value |S| that results from + performing the operation. +

    +
  8. +
  9. +

    + Return |signature|. +

    +
  10. +
+
-
Verify
-
-
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Perform the signature verification operation defined in Section 8.1 of - [[RFC3447]] with the key represented by the - {{CryptoKey/[[handle]]}} internal slot of - |key| as the signer's RSA public key and |message| as - |M| and - |signature| as |S| and using the hash function specified - by the {{RsaHashedKeyAlgorithm/hash}} attribute of the - {{CryptoKey/[[algorithm]]}} internal slot of - |key| as the Hash option, MGF1 (defined in Section B.2.1 of [[RFC3447]]) as the MGF option and the saltLength member of - |normalizedAlgorithm| as the salt length option for the - EMSA-PSS-VERIFY operation. -

    -
  4. -
  5. -

    - Let |result| be a boolean with the value true if the - result of the operation was "valid signature" and the value - false otherwise. -

    -
  6. -
-
+
+
Verify
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains an entry which is not - "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -

    - Generate an RSA key pair, as defined in [[RFC3447]], with RSA modulus length equal to the - {{RsaKeyGenParams/modulusLength}} member of - |normalizedAlgorithm| and RSA public exponent equal to the - {{RsaKeyGenParams/publicExponent}} member of - |normalizedAlgorithm|. -

    -
  4. -
  5. -

    - If performing the operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  6. -
  7. -

    - Let |algorithm| be a new - {{RsaHashedKeyAlgorithm}} - dictionary. -

    -
  8. -
  9. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`RSA-PSS`". -

    -
  10. -
  11. -

    - Set the - {{RsaKeyAlgorithm/modulusLength}} - attribute of |algorithm| to equal the - {{RsaKeyGenParams/modulusLength}} - member of |normalizedAlgorithm|. -

    -
  12. -
  13. -

    - Set the - {{RsaKeyAlgorithm/publicExponent}} - attribute of |algorithm| to equal the - {{RsaKeyGenParams/publicExponent}} - member of |normalizedAlgorithm|. -

    -
  14. -
  15. -

    - Set the {{RsaHashedKeyAlgorithm/hash}} attribute - of |algorithm| to equal the - {{RsaHashedKeyGenParams/hash}} member of - |normalizedAlgorithm|. -

    -
  16. -
  17. -

    - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

    -
  18. -
  19. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

    -
  20. -
  21. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |publicKey| to |algorithm|. -

    -
  22. -
  23. -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |publicKey| to true. -

    -
  24. -
  25. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the [= usage - intersection =] of |usages| and `[ "verify" ]`. -

    -
  26. -
  27. -

    - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

    -
  28. -
  29. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  30. -
  31. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |privateKey| to |algorithm|. -

    -
  32. -
  33. -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |privateKey| to |extractable|. -

    -
  34. -
  35. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the [= usage - intersection =] of |usages| and `[ "sign" ]`. -

    -
  36. -
  37. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  38. -
  39. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to |publicKey|. -

    -
  40. -
  41. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to |privateKey|. -

    -
  42. -
  43. -

    - Return |result|. -

    -
  44. -
-
+
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Perform the signature verification operation defined in Section 8.2 of + [[RFC3447]] with the key represented by the + {{CryptoKey/[[handle]]}} internal slot of + |key| as the signer's RSA public key and |message| as + |M| and + |signature| as |S| and using the hash function specified + in the {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option for the EMSA-PKCS1-v1_5 encoding method. +

    +
  4. +
  5. +

    + Let |result| be a boolean with value true if the + result of the operation was "valid signature" and the value + false otherwise. +

    +
  6. +
  7. +

    Return |result|.

    +
  8. +
+
-
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `rsaEncryption` - object identifier defined in [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - Let |publicKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the - `subjectPublicKeyInfo` field of |spki|, - |structure| as the `RSAPublicKey` structure - specified in Section A.1.1 of [[RFC3447]], and - |exactData| set to true. -

      -
    10. -
    11. -

      - If an error occurred while parsing, or it can be determined that |publicKey| - is not a valid public key according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} - that represents the RSA public key identified by - |publicKey|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

      -
    16. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, then [= exception/throw =] a {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `rsaEncryption` object identifier defined in [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - Let |rsaPrivateKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the - `privateKey` field of |privateKeyInfo|, - |structure| as the `RSAPrivateKey` structure - specified in Section A.1.2 of [[RFC3447]], and - |exactData| set to true. -

      -
    10. -
    11. -

      - If an error occurred while parsing, or if |rsaPrivateKey| is not - a valid RSA private key according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} - that represents the RSA private key identified by - |rsaPrivateKey|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to {{KeyType/"private"}} -

      -
    16. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field of |jwk| is present and - |usages| contains an entry which is not - "`sign`", or, if the {{JsonWebKey/d}} field of |jwk| - is not present and - |usages| contains an entry which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not a - case-sensitive string match to "`RSA`", - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not a case-sensitive string match to "`sig`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/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 [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -
      -
      - If the {{JsonWebKey/alg}} field of |jwk| is not - present: -
      -
      -

      - Let |hash| be undefined. -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`PS1`": -
      -
      -

      - Let |hash| be the string "`SHA-1`". -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`PS256`": -
      -
      -

      - Let |hash| be the string "`SHA-256`". -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`PS384`": -
      -
      -

      - Let |hash| be the string "`SHA-384`". -

      -
      -
      - If the {{JsonWebKey/alg}} field is equal to the string - "`PS512`": -
      -
      -

      - Let |hash| be the string "`SHA-512`". -

      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= RSA-PSS key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |jwk| - and obtaining |hash|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    14. -
    15. -
      -
      - If |hash| is not undefined: -
      -
      -
        -
      1. -

        - Let |normalizedHash| be the result of - normalize an algorithm - with `alg` set to |hash| and `op` set - to `digest`. -

        -
      2. -
      3. -

        - If |normalizedHash| is not equal to the - {{RsaHashedImportParams/hash}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

        -
      4. -
      -
      -
      -
    16. -
    17. -
      -
      If the {{JsonWebKey/d}} field of |jwk| is present:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - Section 6.3.2 of JSON Web Algorithms [[JWA]], - then [= exception/throw =] a - {{DataError}}. -

        -
      2. -
      3. -

        - Let |privateKey| represent the - RSA private key identified by interpreting |jwk| - according to Section 6.3.2 of JSON Web - Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - If |privateKey| can be determined to not be a valid RSA private key - according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} representing |privateKey|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} - internal slot of |key| to {{KeyType/"private"}} -

        -
      10. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of Section - 6.3.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |publicKey| represent the - RSA public key identified by interpreting |jwk| - according to Section 6.3.1 of JSON Web Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - If |publicKey| can be determined to not be a valid RSA public key - according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} representing |publicKey|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} - internal slot of |key| to "`public`" -

        -
      10. -
      -
      -
      -
    18. -
    -
    -
    Otherwise:
    -
    - [= exception/throw =] a - {{NotSupportedError}}. -
    -
    -
  4. -
  5. -

    - Let |algorithm| be a new - {{RsaHashedKeyAlgorithm}} dictionary. -

    -
  6. -
  7. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`RSA-PSS`" -

    -
  8. -
  9. -

    - Set the {{RsaKeyAlgorithm/modulusLength}} - attribute of |algorithm| to the length, in bits, of the RSA public - modulus. -

    -
  10. -
  11. -

    - Set the {{RsaKeyAlgorithm/publicExponent}} - attribute of |algorithm| to the {{BigInteger}} - representation of the RSA public exponent. -

    -
  12. -
  13. -

    - Set the {{RsaHashedKeyAlgorithm/hash}} attribute of - |algorithm| to the {{RsaHashedImportParams/hash}} member of - |normalizedAlgorithm|. -

    -
  14. -
  15. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm| -

    -
  16. -
  17. -

    Return |key|.

    -
  18. -
-
+
+
Generate Key
-
Export Key
-
-
    -
  1. -

    - Let |key| be the key to be exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `rsaEncryption` defined in - [[RFC3447]]. -

          -
        • -
        • -

          - Set the |params| field to the ASN.1 type NULL. -

          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to the result of - DER-encoding an `RSAPublicKey` ASN.1 type, as defined - in [[RFC3447]], Appendix A.1.1, that - represents the RSA public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `rsaEncryption` defined in - [[RFC3447]]. -

          -
        • -
        • -

          - Set the |params| field to the ASN.1 type NULL. -

          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to the result of DER-encoding - an `RSAPrivateKey` ASN.1 type, as defined in [[RFC3447]], Appendix A.1.2, that represents the - RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

        -
        - [[RFC5208]] specifies that the encoding of - this field should be BER encoded in Section 5 (as a "for - example"). However, to avoid requiring WebCrypto implementations - support BER-encoding and BER-decoding, only DER encodings - are produced or accepted. -
        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      Let |jwk| be a new {{JsonWebKey}} dictionary.

      -
    2. -
    3. -

      Set the `kty` attribute of |jwk| to the string - "`RSA`".

      -
    4. -
    5. -

      - Let |hash| be the {{KeyAlgorithm/name}} - attribute of the {{RsaHashedKeyAlgorithm/hash}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key|. -

      -
    6. -
    7. -
      -
      If |hash| is "`SHA-1`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`PS1`". -

      -
      -
      If |hash| is "`SHA-256`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`PS256`". -

      -
      -
      If |hash| is "`SHA-384`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`PS384`". -

      -
      -
      If |hash| is "`SHA-512`":
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`PS512`". -

      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= RSA-PSS key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{RsaHashedKeyAlgorithm/hash}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |alg|. -

        -
      2. -
      3. -

        - Set the `alg` attribute of |jwk| to |alg|. -

        -
      4. -
      -
      -
      -
    8. -
    9. -

      - Set the attributes {{JsonWebKey/n}} and {{JsonWebKey/e}} of |jwk| - according to the corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.1. -

      -
    10. -
    11. -
      -
      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is {{KeyType/"private"}}: -
      -
      -
        -
      1. -

        - Set the attributes named {{JsonWebKey/d}}, {{JsonWebKey/p}}, - {{JsonWebKey/q}}, {{JsonWebKey/dp}}, {{JsonWebKey/dq}}, and - {{JsonWebKey/qi}} of |jwk| according to the - corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.2. -

        -
      2. -
      3. -

        - If the underlying RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot - of |key| is represented by more than two primes, set - the attribute named {{JsonWebKey/oth}} of |jwk| - according to the corresponding definition in JSON Web Algorithms [[JWA]], Section 6.3.2.7 -

        -
      4. -
      -
      -
      -
    12. -
    13. -

      - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

      -
    14. -
    15. -

      - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

      -
    16. -
    17. -

      - Let |result| be |jwk|. -

      -
    18. -
    -
    -
    Otherwise
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  6. -
  7. -

    - Return |result|. -

    -
  8. -
-
- -
-
+
    +
  1. +

    + If |usages| contains an entry which is not + "`sign`" or "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

    +
  2. +
  3. +

    + Generate an RSA key pair, as defined in [[RFC3447]], with RSA modulus length equal to the + {{RsaKeyGenParams/modulusLength}} attribute of + |normalizedAlgorithm| and RSA public exponent equal to the + {{RsaKeyGenParams/publicExponent}} attribute of + |normalizedAlgorithm|. +

    +
  4. +
  5. +

    + If generation of the key pair fails, + then [= exception/throw =] an + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |algorithm| be a new + {{RsaHashedKeyAlgorithm}} + dictionary. +

    +
  8. +
  9. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`RSASSA-PKCS1-v1_5`". +

    +
  10. +
  11. +

    + Set the + {{RsaKeyAlgorithm/modulusLength}} + attribute of |algorithm| to equal the + {{RsaKeyGenParams/modulusLength}} + attribute of |normalizedAlgorithm|. +

    +
  12. +
  13. +

    + Set the + {{RsaKeyAlgorithm/publicExponent}} + attribute of |algorithm| to equal the + {{RsaKeyGenParams/publicExponent}} + attribute of |normalizedAlgorithm|. +

    +
  14. +
  15. +

    + Set the {{RsaHashedKeyAlgorithm/hash}} attribute + of |algorithm| to equal the + {{RsaHashedKeyGenParams/hash}} member of + |normalizedAlgorithm|. +

    +
  16. +
  17. +

    + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

    +
  18. +
  19. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

    +
  20. +
  21. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |publicKey| to |algorithm|. +

    +
  22. +
  23. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |publicKey| to true. +

    +
  24. +
  25. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the [= usage + intersection =] of |usages| and `[ "verify" ]`. +

    +
  26. +
  27. +

    + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

    +
  28. +
  29. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

    +
  30. +
  31. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |privateKey| to |algorithm|. +

    +
  32. +
  33. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |privateKey| to |extractable|. +

    +
  34. +
  35. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the [= usage + intersection =] of |usages| and `[ "sign" ]`. +

    +
  36. +
  37. +

    + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

    +
  38. +
  39. +

    + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

    +
  40. +
  41. +

    + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

    +
  42. +
  43. +

    + Return |result|. +

    +
  44. +
+
-
-

RSA-OAEP

-
-

Description

-

- The "`RSA-OAEP`" algorithm identifier is used to perform encryption - and decryption ordering to the RSAES-OAEP algorithm specified in - [[RFC3447]], using the SHA hash functions defined - in this specification and using the mask - generation function MGF1. -

-

- Other specifications - may specify the use of additional hash algorithms with RSAES-OAEP. Such specifications - must define the digest operation for the additional hash algorithm and - key import steps and - key export steps for RSAES-OAEP. -

-
-
-

Registration

-

- The [= recognized algorithm name =] for - this algorithm is "`RSA-OAEP`". -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationParametersResult
encrypt{{RsaOaepParams}}[= byte sequence =]
decrypt{{RsaOaepParams}}[= byte sequence =]
generateKey{{RsaHashedKeyGenParams}}{{CryptoKeyPair}}
importKey{{RsaHashedImportParams}}{{CryptoKey}}
exportKeyNoneobject
-
- -
-

RsaOaepParams dictionary

-
-dictionary RsaOaepParams : Algorithm {
-  BufferSource label;
-};
-          
-

The label member represents the optional label/application data to associate with the message.

-
-
-

Operations

-
-
Encrypt
-
-
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of |key| - is not "`public`", - then [= exception/throw =] an - {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Let |label| be the {{RsaOaepParams/label}} member of - |normalizedAlgorithm| or the empty byte sequence if the - {{RsaOaepParams/label}} member of - |normalizedAlgorithm| is not present. -

    -
  4. -
  5. -

    - Perform the encryption operation defined in Section 7.1 of [[RFC3447]] with the key represented by |key| - as the recipient's RSA public key, |plaintext| - as the message to be encrypted, |M| and |label| - as the label, |L|, and with the hash - function specified by the {{RsaHashedKeyAlgorithm/hash}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| as the Hash option and MGF1 (defined in Section B.2.1 of - [[RFC3447]]) as the MGF option. -

    -
  6. -
  7. -

    - If performing the operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  8. -
  9. -

    - Let |ciphertext| be the value |C| that results from performing the - operation. -

    -
  10. -
  11. -

    - Return |ciphertext|. -

    -
  12. -
-
-
Decrypt
-
-
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of |key| - is not {{KeyType/"private"}}, - then [= exception/throw =] an - {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Let |label| be the {{RsaOaepParams/label}} member of - |normalizedAlgorithm| or the empty byte sequence if the - {{RsaOaepParams/label}} member of - |normalizedAlgorithm| is not present. -

    -
  4. -
  5. -

    - Perform the decryption operation defined in Section 7.1 of [[RFC3447]] with the key represented by |key| - as the recipient's RSA private key, |ciphertext| - as the ciphertext to be decrypted, C, and |label| - as the label, |L|, and with the hash - function specified by the {{RsaHashedKeyAlgorithm/hash}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| as the Hash option and MGF1 (defined in Section B.2.1 of - [[RFC3447]]) as the MGF option. -

    -
  6. -
  7. -

    - If performing the operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  8. -
  9. -

    - Let |plaintext| the value |M| that results from performing the - operation. -

    -
  10. -
  11. -

    - Return |plaintext|. -

    -
  12. -
-
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains an entry which is not - "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -

    - Generate an RSA key pair, as defined in [[RFC3447]], with RSA modulus length equal to the - {{RsaKeyGenParams/modulusLength}} member of - |normalizedAlgorithm| and RSA public exponent equal to the - {{RsaKeyGenParams/publicExponent}} member of - |normalizedAlgorithm|. -

    -
  4. -
  5. -

    - If performing the operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  6. -
  7. -

    - Let |algorithm| be a new - {{RsaHashedKeyAlgorithm}} - object. -

    -
  8. -
  9. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`RSA-OAEP`". -

    -
  10. -
  11. -

    - Set the - {{RsaKeyAlgorithm/modulusLength}} - attribute of |algorithm| to equal the - {{RsaKeyGenParams/modulusLength}} - member of |normalizedAlgorithm|. -

    -
  12. -
  13. -

    - Set the - {{RsaKeyAlgorithm/publicExponent}} - attribute of |algorithm| to equal the - {{RsaKeyGenParams/publicExponent}} - member of |normalizedAlgorithm|. -

    -
  14. -
  15. -

    - Set the {{RsaHashedKeyAlgorithm/hash}} attribute - of |algorithm| to equal the - {{RsaHashedKeyGenParams/hash}} member of - |normalizedAlgorithm|. -

    -
  16. -
  17. -

    - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

    -
  18. -
  19. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

    -
  20. -
  21. -

    - Set the {{CryptoKey/[[algorithm]]}} internal slot of - |publicKey| to |algorithm|. -

    -
  22. -
  23. -

    - Set the {{CryptoKey/[[extractable]]}} internal slot of - |publicKey| to true. -

    -
  24. -
  25. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the - [= usage intersection =] of - |usages| and `[ "encrypt", "wrapKey" ]`. -

    -
  26. -
  27. -

    - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

    -
  28. -
  29. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  30. -
  31. -

    - Set the {{CryptoKey/[[algorithm]]}} internal slot of - |privateKey| to |algorithm|. -

    -
  32. -
  33. -

    - Set the {{CryptoKey/[[extractable]]}} internal slot of - |privateKey| to |extractable|. -

    -
  34. -
  35. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the - [= usage intersection =] of - |usages| and `[ "decrypt", "unwrapKey" ]`. -

    -
  36. -
  37. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  38. -
  39. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

    -
  40. -
  41. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

    -
  42. -
  43. -

    - Return |result|. -

    -
  44. -
-
- -
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`encrypt`" or - "`wrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `rsaEncryption` - object identifier defined in [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - Let |publicKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the - `subjectPublicKeyInfo` field of |spki|, - |structure| as the `RSAPublicKey` structure - specified in Section A.1.1 of [[RFC3447]], and - |exactData| set to true. -

      -
    10. -
    11. -

      - If an error occurred while parsing, or it can be determined that |publicKey| - is not a valid public key according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} - that represents the RSA public key identified by - |publicKey|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to "`public`" -

      -
    16. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`decrypt`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, then [= exception/throw =] a {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `rsaEncryption` object identifier defined in [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - Let |rsaPrivateKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the - `privateKey` field of |privateKeyInfo|, - |structure| as the `RSAPrivateKey` structure - specified in Section A.1.2 of [[RFC3447]], and - |exactData| set to true. -

      -
    10. -
    11. -

      - If an error occurred while parsing, or if |rsaPrivateKey| is not - a valid RSA private key according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} - that represents the RSA private key identified by - |rsaPrivateKey|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"private"}} -

      -
    16. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/Throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field of |jwk| is present and - |usages| contains an entry which is not - "`decrypt`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/d}} field of |jwk| is not present and - |usages| contains an entry which is not - "`encrypt`" or "`wrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    6. -
    7. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not a - case-sensitive string match to "`RSA`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not a case-sensitive string match to "`enc`", - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If the {{JsonWebKey/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 [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -
      -
      If the `alg` field of |jwk| is not present:
      -
      Let |hash| be undefined.
      -
      - If the `alg` field of |jwk| is equal to - "`RSA-OAEP`": -
      -
      Let |hash| be the string "`SHA-1`".
      -
      - If the `alg` field of |jwk| is equal to - "`RSA-OAEP-256`": -
      -
      Let |hash| be the string "`SHA-256`".
      -
      - If the `alg` field of |jwk| is equal to - "`RSA-OAEP-384`": -
      -
      Let |hash| be the string "`SHA-384`".
      -
      - If the `alg` field of |jwk| is equal to - "`RSA-OAEP-512`": -
      -
      Let |hash| be the string "`SHA-512`".
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= RSA-OAEP key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |jwk| - and obtaining |hash|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    16. -
    17. -
      -
      - If |hash| is not undefined: -
      -
      -
        -
      1. -

        - Let |normalizedHash| be the result of - normalize an algorithm - with `alg` set to |hash| and `op` set - to `digest`. -

        -
      2. -
      3. -

        - If |normalizedHash| is not equal to the - {{RsaHashedImportParams/hash}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

        -
      4. -
      -
      -
      -
    18. -
    19. -
      -
      If the {{JsonWebKey/d}} field of |jwk| is present:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of Section - 6.3.2 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |privateKey| represent the - RSA private key identified by interpreting |jwk| - according to Section 6.3.2 of JSON Web Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - If |privateKey| can be determined to not be a valid RSA private key - according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} representing |privateKey|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"private"}} -

        -
      10. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of Section - 6.3.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |publicKey| represent the - RSA public key identified by interpreting |jwk| - according to Section 6.3.1 of JSON Web Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - If |publicKey| can be determined to not be a valid RSA public key - according to [[RFC3447]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} representing |publicKey|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to "`public`" -

        -
      10. -
      -
      -
      -
    20. -
    -
    -
    Otherwise:
    -
    - [= exception/throw =] a - {{NotSupportedError}}. -
    -
    -
  4. -
  5. -

    - Let |algorithm| be a new - {{RsaHashedKeyAlgorithm}}. -

    -
  6. -
  7. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`RSA-OAEP`" -

    -
  8. -
  9. -

    - Set the {{RsaKeyAlgorithm/modulusLength}} - attribute of |algorithm| to the length, in bits, of the RSA public - modulus. -

    -
  10. -
  11. -

    - Set the {{RsaKeyAlgorithm/publicExponent}} - attribute of |algorithm| to the {{BigInteger}} - representation of the RSA public exponent. -

    -
  12. -
  13. -

    - Set the {{RsaHashedKeyAlgorithm/hash}} attribute of - |algorithm| to the {{RsaHashedImportParams/hash}} member of - |normalizedAlgorithm|. -

    -
  14. -
  15. -

    - Set the {{CryptoKey/[[algorithm]]}} internal slot of - |key| to |algorithm| -

    -
  16. -
  17. -

    Return |key|.

    -
  18. -
-
- -
Export Key
-
-
    -
  1. -

    - Let |key| be the key to be exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `rsaEncryption` defined in - [[RFC3447]]. -

          -
        • -
        • -

          - Set the |params| field to the ASN.1 type NULL. -

          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to the result of - DER-encoding an `RSAPublicKey` ASN.1 type, as defined - in [[RFC3447]], Appendix A.1.1, that - represents the RSA public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `rsaEncryption` defined in - [[RFC3447]]. -

          -
        • -
        • -

          - Set the |params| field to the ASN.1 type NULL. -

          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to the result of DER-encoding - an `RSAPrivateKey` ASN.1 type, as defined in [[RFC3447]], Appendix A.1.2, that represents the - RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

        -
        - [[RFC5208]] specifies that the encoding of - this field should be BER encoded in Section 5 (as a "for - example"). However, to avoid requiring WebCrypto implementations - support BER-encoding and BER-decoding, only DER encodings - are produced or accepted. -
        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

      -
    2. -
    3. -

      - Set the `kty` attribute of |jwk| to the string - "`RSA`". -

      -
    4. -
    5. -

      - Let |hash| be the {{KeyAlgorithm/name}} - attribute of the {{RsaHashedKeyAlgorithm/hash}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key|. -

      -
    6. -
    7. -
      -
      - If |hash| is "`SHA-1`": -
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RSA-OAEP`". -

      -
      -
      - If |hash| is "`SHA-256`": -
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RSA-OAEP-256`". -

      -
      -
      - If |hash| is "`SHA-384`": -
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RSA-OAEP-384`". -

      -
      -
      - If |hash| is "`SHA-512`": -
      -
      -

      - Set the `alg` attribute of |jwk| to the string - "`RSA-OAEP-512`". -

      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= RSA-OAEP key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{RsaHashedKeyAlgorithm/hash}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |alg|. -

        -
      2. -
      3. -

        - Set the `alg` attribute of |jwk| to |alg|. -

        -
      4. -
      -
      -
      -
    8. -
    9. -

      - Set the attributes {{JsonWebKey/n}} and {{JsonWebKey/e}} of |jwk| - according to the corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.1. -

      -
    10. -
    11. -
      -
      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is {{KeyType/"private"}}: -
      -
      -
        -
      1. -

        - Set the attributes named {{JsonWebKey/d}}, {{JsonWebKey/p}}, - {{JsonWebKey/q}}, {{JsonWebKey/dp}}, {{JsonWebKey/dq}}, and - {{JsonWebKey/qi}} of |jwk| according to the - corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.2. -

        -
      2. -
      3. -

        - If the underlying RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot - of |key| is represented by more than two primes, set - the attribute named {{JsonWebKey/oth}} of |jwk| - according to the corresponding definition in JSON Web Algorithms [[JWA]], Section 6.3.2.7 -

        -
      4. -
      -
      -
      -
    12. -
    13. -

      - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

      -
    14. -
    15. -

      - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

      -
    16. -
    17. -

      - Let |result| be |jwk|. -

      -
    18. -
    -
    -
    Otherwise
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  6. -
  7. -

    - Return |result|. -

    -
  8. -
-
-
-
-
- -
-

ECDSA

-
-

Description

-

- The "`ECDSA`" algorithm identifier is used to perform signing - and verification using the ECDSA algorithm specified in - [[RFC6090]] and using the SHA hash functions and elliptic - curves defined in this specification. -

-

- Other specifications - may specify the use of additional elliptic curves and hash algorithms with ECDSA. To - specify additional hash algorithms to be used with ECDSA, a specification must define - a registered algorithm that supports the digest operation. - To specify an additional elliptic curve a specification must define - the curve name, - ECDSA signature steps, - ECDSA verification steps, - ECDSA generation steps, - ECDSA key import steps and - ECDSA key export steps. -

-
-
-

Registration

-

- The [= recognized algorithm name =] for - this algorithm is "`ECDSA`". -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationParametersResult
sign{{EcdsaParams}}[= byte sequence =]
verify{{EcdsaParams}}boolean
generateKey{{EcKeyGenParams}}{{CryptoKeyPair}}
importKey{{EcKeyImportParams}}{{CryptoKey}}
exportKeyNoneobject
-
-
-

EcdsaParams dictionary

-
-dictionary EcdsaParams : Algorithm {
-  required HashAlgorithmIdentifier hash;
-};
-          
-

The hash member represents the hash algorithm to use.

-
-
-

EcKeyGenParams dictionary

-
-typedef DOMString NamedCurve;
+          
+
Import Key
-dictionary EcKeyGenParams : Algorithm { - required NamedCurve namedCurve; -}; -
-

- The NamedCurve type represents named elliptic curves, - which are a convenient way to specify the domain parameters of well-known elliptic - curves. The following values defined by this specification: -

-
-
"`P-256`"
-
NIST recommended curve P-256, also known as `secp256r1`.
-
"`P-384`"
-
NIST recommended curve P-384, also known as `secp384r1`.
-
"`P-521`"
-
NIST recommended curve P-521, also known as `secp521r1`.
-
-

- Other specifications may define - additional values. -

-

The namedCurve member of the {{EcKeyGenParams}} dictionary represents a named curve.

-
-
-

EcKeyAlgorithm dictionary

-
-dictionary EcKeyAlgorithm : KeyAlgorithm {
-  required NamedCurve namedCurve;
-};
-          
-

The namedCurve member represents the named curve that the key uses.

-
-
-

EcKeyImportParams dictionary

-
-dictionary EcKeyImportParams : Algorithm {
-  required NamedCurve namedCurve;
-};
-          
-

The namedCurve member represents a named curve.

-
+
    +
  1. +

    Let |keyData| be the key data to be imported.

    +
  2. +
  3. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `rsaEncryption` + object identifier defined in [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + Let |publicKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the + `subjectPublicKeyInfo` field of |spki|, + |structure| as the `RSAPublicKey` structure + specified in Section A.1.1 of [[RFC3447]], and + |exactData| set to true. +

      +
    10. +
    11. +

      + If an error occurred while parsing, or it can be determined that |publicKey| + is not a valid public key according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} + that represents the RSA public key identified by + |publicKey|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

      +
    16. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`sign`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `rsaEncryption` object identifier defined in [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + Let |rsaPrivateKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the + `privateKey` field of |privateKeyInfo|, + |structure| as the `RSAPrivateKey` structure + specified in Section A.1.2 of [[RFC3447]], and + |exactData| set to true. +

      +
    10. +
    11. +

      + If an error occurred while parsing, or if |rsaPrivateKey| is not + a valid RSA private key according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} + that represents the RSA private key identified by + |rsaPrivateKey|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to {{KeyType/"private"}} +

      +
    16. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +
      +
      If |keyData| is a {{JsonWebKey}} dictionary:
      +

      Let |jwk| equal |keyData|.

      +
      Otherwise:
      +

      [= exception/Throw =] a {{DataError}}.

      +
      +
    2. +
    3. +

      + If the {{JsonWebKey/d}} field of |jwk| is present and + |usages| contains an entry which is not + "`sign`", or, if the {{JsonWebKey/d}} field of |jwk| + is not present and + |usages| contains an entry which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + If the {{JsonWebKey/kty}} field of |jwk| is not a + case-sensitive string match to "`RSA`", + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not a case-sensitive string match to "`sig`", + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |hash| be a be a string whose initial value is + undefined. +

      +
    14. +
    15. +
      +
      + If the {{JsonWebKey/alg}} field of |jwk| is not + present: +
      +
      +

      + Let |hash| be undefined. +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`RS1`": +
      +
      +

      + Let |hash| be the string "`SHA-1`". +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`RS256`": +
      +
      +

      + Let |hash| be the string "`SHA-256`". +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`RS384`": +
      +
      +

      + Let |hash| be the string "`SHA-384`". +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`RS512`": +
      +
      +

      + Let |hash| be the string "`SHA-512`". +

      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= RSASSA-PKCS1-v1_5 key import steps | key + import steps =] defined by + other applicable + specifications, passing |format|, |jwk| + and obtaining |hash|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    16. +
    17. +
      +
      + If |hash| is not undefined: +
      +
      +
        +
      1. +

        + Let |normalizedHash| be the result of + normalize an algorithm + with `alg` set to |hash| and `op` set + to `digest`. +

        +
      2. +
      3. +

        + If |normalizedHash| is not equal to the + {{RsaHashedImportParams/hash}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

        +
      4. +
      +
      +
      +
    18. +
    19. +
      +
      If the {{JsonWebKey/d}} field of |jwk| is present:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of + Section 6.3.2 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

        +
      2. +
      3. +

        + Let |privateKey| represents the + RSA private key identified by interpreting |jwk| + according to Section 6.3.2 of JSON Web + Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + If |privateKey| is not a valid RSA private key + according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} object that represents + |privateKey|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} + internal slot of |key| to {{KeyType/"private"}} +

        +
      10. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of Section + 6.3.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |publicKey| represent the + RSA public key identified by interpreting |jwk| + according to Section 6.3.1 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + If |publicKey| can be determined to not be a valid RSA public key + according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} representing |publicKey|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} + internal slot of |key| to "`public`" +

        +
      10. +
      +
      +
      +
    20. +
    +
    +
    Otherwise:
    +
    + [= exception/throw =] a + {{NotSupportedError}}. +
    +
    +
  4. +
  5. +

    + Let |algorithm| be a new + {{RsaHashedKeyAlgorithm}} dictionary. +

    +
  6. +
  7. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`RSASSA-PKCS1-v1_5`" +

    +
  8. +
  9. +

    + Set the {{RsaKeyAlgorithm/modulusLength}} + attribute of |algorithm| to the length, in bits, of the RSA public + modulus. +

    +
  10. +
  11. +

    + Set the publicExponent + attribute of |algorithm| to the BigInteger + representation of the RSA public exponent. +

    +
  12. +
  13. +

    + Set the {{RsaHashedKeyAlgorithm/hash}} attribute of + |algorithm| to the {{RsaHashedImportParams/hash}} member of + |normalizedAlgorithm|. +

    +
  14. +
  15. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

    +
  16. +
  17. +

    Return |key|.

    +
  18. +
+
-
-

Operations

-
-
Sign
-
- When signing, the following algorithm should be used: -
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Let |hashAlgorithm| be the {{EcdsaParams/hash}} - member of |normalizedAlgorithm|. -

    -
  4. -
  5. -

    - Let |M| be the result of performing the digest operation specified by - |hashAlgorithm| using |message|. -

    -
  6. -
  7. -

    - Let |d| be the ECDSA private key associated with |key|. -

    -
  8. -
  9. -

    - Let |params| be the EC domain parameters associated with - |key|. -

    -
  10. -
  11. -
    -
    - If the {{EcKeyAlgorithm/namedCurve}} attribute of the - {{CryptoKey/[[algorithm]]}} internal slot of - |key| is "`P-256`", "`P-384`" or "`P-521`": -
    -
    -
      -
    1. -

      - Perform the ECDSA signing process, as specified in [[RFC6090]], - Section 5.4, with |M| as the message, using |params| as the - EC domain parameters, and with |d| as the private key. -

      -
    2. -
    3. -

      - Let |r| and |s| be the pair of integers resulting from - performing the ECDSA signing process. -

      -
    4. -
    5. -

      - Let |result| be an empty [= byte sequence =]. -

      -
    6. -
    7. -

      - Let |n| be the smallest integer such that |n| * 8 is greater than - the logarithm to base 2 of the order of the base point of the elliptic curve identified - by |params|. -

      -
    8. -
    9. -

      - Convert |r| to a byte sequence of - length |n| and append it to |result|. -

      -
    10. -
    11. -

      - Convert |s| to a byte sequence of - length |n| and append it to |result|. -

      -
    12. -
    -
    -
    - Otherwise, the {{EcKeyAlgorithm/namedCurve}} attribute - of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| is a value specified in an - applicable specification: -
    -
    -

    - Perform the [= ECDSA signature steps =] - specified in that specification, passing in |M|, |params| - and |d| and resulting in |result|. -

    -
    -
    -
  12. -
  13. -

    - Return |result|. -

    -
  14. -
-
-
Verify
-
- When verifying, the following algorithm should be used: -
    -
  1. -

    - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  2. -
  3. -

    - Let |hashAlgorithm| be the {{EcdsaParams/hash}} - member of - |normalizedAlgorithm|. -

    -
  4. -
  5. -

    - Let |M| be the result of performing the digest operation specified by - |hashAlgorithm| using |message|. -

    -
  6. -
  7. -

    - Let |Q| be the ECDSA public key associated with |key|. -

    -
  8. -
  9. -

    - Let |params| be the EC domain parameters associated with - |key|. -

    -
  10. -
  11. -
    -
    - If the {{EcKeyAlgorithm/namedCurve}} attribute of the - {{CryptoKey/[[algorithm]]}} internal slot of - |key| is "`P-256`", "`P-384`" or "`P-521`": -
    -
    -

    - Perform the ECDSA verifying process, as specified in [[RFC6090]], Section 5.3, with |M| as the received - message, |signature| as the received signature and using - |params| as the EC domain parameters, and - |Q| as the public key. -

    -
    -
    - Otherwise, the {{EcKeyAlgorithm/namedCurve}} attribute - of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| is a value specified in an - applicable specification: -
    -
    -

    - Perform the [= ECDSA verification steps =] - specified in that specification passing in |M|, |signature|, - |params| and |Q| and resulting in an indication of whether - or not the purported signature is valid. -

    -
    -
    -
  12. -
  13. -

    - Let |result| be a boolean with the value `true` if the signature is valid - and the value `false` otherwise. -

    -
  14. -
  15. -

    - Return |result|. -

    -
  16. -
-
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains a value which is not - one of "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -
    -
    - If the {{EcKeyGenParams/namedCurve}} member of - |normalizedAlgorithm| is "`P-256`", "`P-384`" - or "`P-521`": -
    -
    -

    - Generate an Elliptic Curve key pair, as defined in [[RFC6090]] - with domain parameters for the curve identified by - the {{EcKeyGenParams/namedCurve}} member of - |normalizedAlgorithm|. -

    -
    -
    - If the {{EcKeyGenParams/namedCurve}} member of - |normalizedAlgorithm| is a value specified in an - applicable specification: -
    -
    -

    - Perform the [=ECDSA - generation steps =] specified in that specification, passing in - |normalizedAlgorithm| and resulting in an elliptic curve key pair. -

    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}} -

    -
    -
    -
  4. -
  5. -

    - If performing the key generation operation results in an error, - then [= exception/throw =] an - {{OperationError}}. -

    -
  6. -
  7. -

    - Let |algorithm| be a new - {{EcKeyAlgorithm}} - object. -

    -
  8. -
  9. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDSA`". -

    -
  10. -
  11. -

    - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to equal the - {{namedCurve}} member of - |normalizedAlgorithm|. -

    -
  12. -
  13. -

    - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

    -
  14. -
  15. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

    -
  16. -
  17. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |publicKey| to |algorithm|. -

    -
  18. -
  19. -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |publicKey| to true. -

    -
  20. -
  21. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the [= usage - intersection =] of |usages| and `[ "verify" ]`. -

    -
  22. -
  23. -

    - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

    -
  24. -
  25. -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  26. -
  27. -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |privateKey| to |algorithm|. -

    -
  28. -
  29. -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |privateKey| to |extractable|. -

    -
  30. -
  31. -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the [= usage - intersection =] of |usages| and `[ "sign" ]`. -

    -
  32. -
  33. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  34. -
  35. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

    -
  36. -
  37. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

    -
  38. -
  39. -

    - Return |result|. -

    -
  40. -
-
+
+
Export Key
+ +
    +
  1. +

    + Let |key| be the key to be exported. +

    +
  2. +
  3. +

    + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

    +
  4. +
  5. +
    +
    If |format| is {{KeyFormat/"spki"}}
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

      +
        +
      • +

        + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `rsaEncryption` defined in + [[RFC3447]]. +

          +
        • +
        • +

          + Set the |params| field to the ASN.1 type NULL. +

          +
        • +
        +
      • +
      • +

        + Set the |subjectPublicKey| field to the result of + DER-encoding an `RSAPublicKey` ASN.1 type, as defined + in [[RFC3447]], Appendix A.1.1, that + represents the RSA public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

      +
        +
      • +

        + Set the |version| field to `0`. +

        +
      • +
      • +

        + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `rsaEncryption` defined in + [[RFC3447]]. +

          +
        • +
        • +

          + Set the |params| field to the ASN.1 type NULL. +

          +
        • +
        +
      • +
      • +

        + Set the |privateKey| field to the result of DER-encoding + an `RSAPrivateKey` ASN.1 type, as defined in [[RFC3447]], Appendix A.1.2, that represents the + RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

        +
        + [[RFC5208]] specifies that the encoding of + this field should be BER encoded in Section 5 (as a "for + example"). However, to avoid requiring WebCrypto implementations + support BER-encoding and BER-decoding, only DER encodings + are produced or accepted. +
        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +

      Let |jwk| be a new {{JsonWebKey}} + dictionary.

      +
    2. +
    3. +

      Set the `kty` attribute of |jwk| to the string + "`RSA`".

      +
    4. +
    5. +

      + Let |hash| be the {{KeyAlgorithm/name}} + attribute of the {{RsaHashedKeyAlgorithm/hash}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key|. +

      +
    6. +
    7. +
      +
      If |hash| is "`SHA-1`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RS1`". +

      +
      +
      If |hash| is "`SHA-256`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RS256`". +

      +
      +
      If |hash| is "`SHA-384`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RS384`". +

      +
      +
      If |hash| is "`SHA-512`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RS512`". +

      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= RSASSA-PKCS1-v1_5 key import steps | key + export steps =] defined by + other applicable + specifications, passing |format|, |key| + and obtaining |alg|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{NotSupportedError}}. +

        +
      4. +
      5. +

        + Set the `alg` attribute of |jwk| to |alg|. +

        +
      6. +
      +
      +
      +
    8. +
    9. +

      + Set the attributes {{JsonWebKey/n}} and {{JsonWebKey/e}} of |jwk| + according to the corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.1. +

      +
    10. +
    11. +
      +
      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is {{KeyType/"private"}}: +
      +
      +
        +
      1. +

        + Set the attributes named {{JsonWebKey/d}}, {{JsonWebKey/p}}, + {{JsonWebKey/q}}, {{JsonWebKey/dp}}, {{JsonWebKey/dq}}, and + {{JsonWebKey/qi}} of |jwk| according to the + corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.2. +

        +
      2. +
      3. +

        + If the underlying RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot + of |key| is represented by more than two primes, set + the attribute named {{JsonWebKey/oth}} of |jwk| + according to the corresponding definition in JSON Web Algorithms [[JWA]], Section 6.3.2.7 +

        +
      4. +
      +
      +
      +
    12. +
    13. +

      + Set the `key_ops` attribute of |jwk| to the usages attribute of |key|. +

      +
    14. +
    15. +

      + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

      +
    16. +
    17. +

      + Let |result| be |jwk|. +

      +
    18. +
    +
    +
    Otherwise
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    +
    +
  6. +
  7. +

    + Return |result|. +

    +
  8. +
+
+
+ + +
+

RSA-PSS

+
+

Description

+

+ The "`RSA-PSS`" algorithm identifier is used to perform signing + and verification using the RSASSA-PSS algorithm specified in + [[RFC3447]], using the SHA hash functions defined + in this specification and the mask generation + formula MGF1. +

+

+ Other specifications + may specify the use of additional hash algorithms with RSASSA-PSS. Such specifications + must define the digest operation for the additional hash algorithms and + key import steps and + key export steps for RSASSA-PSS. +

+
+
+

Registration

+

+ The [= recognized algorithm name =] for + this algorithm is "`RSA-PSS`". +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperationParametersResult
sign{{RsaPssParams}}[= byte sequence =]
verify{{RsaPssParams}}boolean
generateKey{{RsaHashedKeyGenParams}}{{CryptoKeyPair}}
importKey{{RsaHashedImportParams}}{{CryptoKey}}
exportKeyNoneobject
+
+
+

RsaPssParams dictionary

+
+dictionary RsaPssParams : Algorithm {
+  required [EnforceRange] unsigned long saltLength;
+};
+          
+

The saltLength member represents the desired length of the random salt in bytes.

+
+
+

Operations

+ +
+
Sign
+ +
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Perform the signature generation operation defined in Section 8.1 of [[RFC3447]] with the key represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + as the signer's private key, |K|, and |message| as + the message to be signed, |M|, and using the hash function specified + by the {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option, MGF1 (defined in Section B.2.1 of [[RFC3447]]) as the MGF option and the saltLength member of + |normalizedAlgorithm| as the salt length option for the + EMSA-PSS-ENCODE operation. +

    +
  4. +
  5. +

    + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |signature| be the + signature, S, that results from performing the operation. +

    +
  8. +
  9. +

    + Return |signature|. +

    +
  10. +
+
+ +
+
Verify
+ +
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Perform the signature verification operation defined in Section 8.1 of + [[RFC3447]] with the key represented by the + {{CryptoKey/[[handle]]}} internal slot of + |key| as the signer's RSA public key and |message| as + |M| and + |signature| as |S| and using the hash function specified + by the {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option, MGF1 (defined in Section B.2.1 of [[RFC3447]]) as the MGF option and the saltLength member of + |normalizedAlgorithm| as the salt length option for the + EMSA-PSS-VERIFY operation. +

    +
  4. +
  5. +

    + Let |result| be a boolean with the value true if the + result of the operation was "valid signature" and the value + false otherwise. +

    +
  6. +
+
+ +
+
Generate Key
+ +
    +
  1. +

    + If |usages| contains an entry which is not + "`sign`" or "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

    +
  2. +
  3. +

    + Generate an RSA key pair, as defined in [[RFC3447]], with RSA modulus length equal to the + {{RsaKeyGenParams/modulusLength}} member of + |normalizedAlgorithm| and RSA public exponent equal to the + {{RsaKeyGenParams/publicExponent}} member of + |normalizedAlgorithm|. +

    +
  4. +
  5. +

    + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |algorithm| be a new + {{RsaHashedKeyAlgorithm}} + dictionary. +

    +
  8. +
  9. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`RSA-PSS`". +

    +
  10. +
  11. +

    + Set the + {{RsaKeyAlgorithm/modulusLength}} + attribute of |algorithm| to equal the + {{RsaKeyGenParams/modulusLength}} + member of |normalizedAlgorithm|. +

    +
  12. +
  13. +

    + Set the + {{RsaKeyAlgorithm/publicExponent}} + attribute of |algorithm| to equal the + {{RsaKeyGenParams/publicExponent}} + member of |normalizedAlgorithm|. +

    +
  14. +
  15. +

    + Set the {{RsaHashedKeyAlgorithm/hash}} attribute + of |algorithm| to equal the + {{RsaHashedKeyGenParams/hash}} member of + |normalizedAlgorithm|. +

    +
  16. +
  17. +

    + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

    +
  18. +
  19. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

    +
  20. +
  21. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |publicKey| to |algorithm|. +

    +
  22. +
  23. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |publicKey| to true. +

    +
  24. +
  25. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the [= usage + intersection =] of |usages| and `[ "verify" ]`. +

    +
  26. +
  27. +

    + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

    +
  28. +
  29. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

    +
  30. +
  31. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |privateKey| to |algorithm|. +

    +
  32. +
  33. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |privateKey| to |extractable|. +

    +
  34. +
  35. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the [= usage + intersection =] of |usages| and `[ "sign" ]`. +

    +
  36. +
  37. +

    + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

    +
  38. +
  39. +

    + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to |publicKey|. +

    +
  40. +
  41. +

    + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to |privateKey|. +

    +
  42. +
  43. +

    + Return |result|. +

    +
  44. +
+
+ +
+
Import Key
+ +
    +
  1. +

    Let |keyData| be the key data to be imported.

    +
  2. +
  3. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `rsaEncryption` + object identifier defined in [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + Let |publicKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the + `subjectPublicKeyInfo` field of |spki|, + |structure| as the `RSAPublicKey` structure + specified in Section A.1.1 of [[RFC3447]], and + |exactData| set to true. +

      +
    10. +
    11. +

      + If an error occurred while parsing, or it can be determined that |publicKey| + is not a valid public key according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} + that represents the RSA public key identified by + |publicKey|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

      +
    16. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`sign`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, then [= exception/throw =] a {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `rsaEncryption` object identifier defined in [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + Let |rsaPrivateKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the + `privateKey` field of |privateKeyInfo|, + |structure| as the `RSAPrivateKey` structure + specified in Section A.1.2 of [[RFC3447]], and + |exactData| set to true. +

      +
    10. +
    11. +

      + If an error occurred while parsing, or if |rsaPrivateKey| is not + a valid RSA private key according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} + that represents the RSA private key identified by + |rsaPrivateKey|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to {{KeyType/"private"}} +

      +
    16. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +
      +
      If |keyData| is a {{JsonWebKey}} dictionary:
      +

      Let |jwk| equal |keyData|.

      +
      Otherwise:
      +

      [= exception/throw =] a {{DataError}}.

      +
      +
    2. +
    3. +

      + If the {{JsonWebKey/d}} field of |jwk| is present and + |usages| contains an entry which is not + "`sign`", or, if the {{JsonWebKey/d}} field of |jwk| + is not present and + |usages| contains an entry which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + If the {{JsonWebKey/kty}} field of |jwk| is not a + case-sensitive string match to "`RSA`", + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not a case-sensitive string match to "`sig`", + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +
      +
      + If the {{JsonWebKey/alg}} field of |jwk| is not + present: +
      +
      +

      + Let |hash| be undefined. +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`PS1`": +
      +
      +

      + Let |hash| be the string "`SHA-1`". +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`PS256`": +
      +
      +

      + Let |hash| be the string "`SHA-256`". +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`PS384`": +
      +
      +

      + Let |hash| be the string "`SHA-384`". +

      +
      +
      + If the {{JsonWebKey/alg}} field is equal to the string + "`PS512`": +
      +
      +

      + Let |hash| be the string "`SHA-512`". +

      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= RSA-PSS key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |jwk| + and obtaining |hash|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    14. +
    15. +
      +
      + If |hash| is not undefined: +
      +
      +
        +
      1. +

        + Let |normalizedHash| be the result of + normalize an algorithm + with `alg` set to |hash| and `op` set + to `digest`. +

        +
      2. +
      3. +

        + If |normalizedHash| is not equal to the + {{RsaHashedImportParams/hash}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

        +
      4. +
      +
      +
      +
    16. +
    17. +
      +
      If the {{JsonWebKey/d}} field of |jwk| is present:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of + Section 6.3.2 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

        +
      2. +
      3. +

        + Let |privateKey| represent the + RSA private key identified by interpreting |jwk| + according to Section 6.3.2 of JSON Web + Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + If |privateKey| can be determined to not be a valid RSA private key + according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} representing |privateKey|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} + internal slot of |key| to {{KeyType/"private"}} +

        +
      10. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of Section + 6.3.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |publicKey| represent the + RSA public key identified by interpreting |jwk| + according to Section 6.3.1 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + If |publicKey| can be determined to not be a valid RSA public key + according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} representing |publicKey|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} + internal slot of |key| to "`public`" +

        +
      10. +
      +
      +
      +
    18. +
    +
    +
    Otherwise:
    +
    + [= exception/throw =] a + {{NotSupportedError}}. +
    +
    +
  4. +
  5. +

    + Let |algorithm| be a new + {{RsaHashedKeyAlgorithm}} dictionary. +

    +
  6. +
  7. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`RSA-PSS`" +

    +
  8. +
  9. +

    + Set the {{RsaKeyAlgorithm/modulusLength}} + attribute of |algorithm| to the length, in bits, of the RSA public + modulus. +

    +
  10. +
  11. +

    + Set the {{RsaKeyAlgorithm/publicExponent}} + attribute of |algorithm| to the {{BigInteger}} + representation of the RSA public exponent. +

    +
  12. +
  13. +

    + Set the {{RsaHashedKeyAlgorithm/hash}} attribute of + |algorithm| to the {{RsaHashedImportParams/hash}} member of + |normalizedAlgorithm|. +

    +
  14. +
  15. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm| +

    +
  16. +
  17. +

    Return |key|.

    +
  18. +
+
+ +
+
Export Key
+ +
    +
  1. +

    + Let |key| be the key to be exported. +

    +
  2. +
  3. +

    + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

    +
  4. +
  5. +
    +
    If |format| is {{KeyFormat/"spki"}}
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

      +
        +
      • +

        + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `rsaEncryption` defined in + [[RFC3447]]. +

          +
        • +
        • +

          + Set the |params| field to the ASN.1 type NULL. +

          +
        • +
        +
      • +
      • +

        + Set the |subjectPublicKey| field to the result of + DER-encoding an `RSAPublicKey` ASN.1 type, as defined + in [[RFC3447]], Appendix A.1.1, that + represents the RSA public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

      +
        +
      • +

        + Set the |version| field to `0`. +

        +
      • +
      • +

        + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `rsaEncryption` defined in + [[RFC3447]]. +

          +
        • +
        • +

          + Set the |params| field to the ASN.1 type NULL. +

          +
        • +
        +
      • +
      • +

        + Set the |privateKey| field to the result of DER-encoding + an `RSAPrivateKey` ASN.1 type, as defined in [[RFC3447]], Appendix A.1.2, that represents the + RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

        +
        + [[RFC5208]] specifies that the encoding of + this field should be BER encoded in Section 5 (as a "for + example"). However, to avoid requiring WebCrypto implementations + support BER-encoding and BER-decoding, only DER encodings + are produced or accepted. +
        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +

      Let |jwk| be a new {{JsonWebKey}} dictionary.

      +
    2. +
    3. +

      Set the `kty` attribute of |jwk| to the string + "`RSA`".

      +
    4. +
    5. +

      + Let |hash| be the {{KeyAlgorithm/name}} + attribute of the {{RsaHashedKeyAlgorithm/hash}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key|. +

      +
    6. +
    7. +
      +
      If |hash| is "`SHA-1`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`PS1`". +

      +
      +
      If |hash| is "`SHA-256`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`PS256`". +

      +
      +
      If |hash| is "`SHA-384`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`PS384`". +

      +
      +
      If |hash| is "`SHA-512`":
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`PS512`". +

      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= RSA-PSS key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{RsaHashedKeyAlgorithm/hash}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |alg|. +

        +
      2. +
      3. +

        + Set the `alg` attribute of |jwk| to |alg|. +

        +
      4. +
      +
      +
      +
    8. +
    9. +

      + Set the attributes {{JsonWebKey/n}} and {{JsonWebKey/e}} of |jwk| + according to the corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.1. +

      +
    10. +
    11. +
      +
      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is {{KeyType/"private"}}: +
      +
      +
        +
      1. +

        + Set the attributes named {{JsonWebKey/d}}, {{JsonWebKey/p}}, + {{JsonWebKey/q}}, {{JsonWebKey/dp}}, {{JsonWebKey/dq}}, and + {{JsonWebKey/qi}} of |jwk| according to the + corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.2. +

        +
      2. +
      3. +

        + If the underlying RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot + of |key| is represented by more than two primes, set + the attribute named {{JsonWebKey/oth}} of |jwk| + according to the corresponding definition in JSON Web Algorithms [[JWA]], Section 6.3.2.7 +

        +
      4. +
      +
      +
      +
    12. +
    13. +

      + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

      +
    14. +
    15. +

      + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

      +
    16. +
    17. +

      + Let |result| be |jwk|. +

      +
    18. +
    +
    +
    Otherwise
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    +
    +
  6. +
  7. +

    + Return |result|. +

    +
  8. +
+
+
+
+ +
+

RSA-OAEP

+
+

Description

+

+ The "`RSA-OAEP`" algorithm identifier is used to perform encryption + and decryption ordering to the RSAES-OAEP algorithm specified in + [[RFC3447]], using the SHA hash functions defined + in this specification and using the mask + generation function MGF1. +

+

+ Other specifications + may specify the use of additional hash algorithms with RSAES-OAEP. Such specifications + must define the digest operation for the additional hash algorithm and + key import steps and + key export steps for RSAES-OAEP. +

+
+
+

Registration

+

+ The [= recognized algorithm name =] for + this algorithm is "`RSA-OAEP`". +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperationParametersResult
encrypt{{RsaOaepParams}}[= byte sequence =]
decrypt{{RsaOaepParams}}[= byte sequence =]
generateKey{{RsaHashedKeyGenParams}}{{CryptoKeyPair}}
importKey{{RsaHashedImportParams}}{{CryptoKey}}
exportKeyNoneobject
+
+ +
+

RsaOaepParams dictionary

+
+dictionary RsaOaepParams : Algorithm {
+  BufferSource label;
+};
+          
+

The label member represents the optional label/application data to associate with the message.

+
+
+

Operations

+ +
+
Encrypt
+ +
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of |key| + is not "`public`", + then [= exception/throw =] an + {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Let |label| be the {{RsaOaepParams/label}} member of + |normalizedAlgorithm| or the empty byte sequence if the + {{RsaOaepParams/label}} member of + |normalizedAlgorithm| is not present. +

    +
  4. +
  5. +

    + Perform the encryption operation defined in Section 7.1 of [[RFC3447]] with the key represented by |key| + as the recipient's RSA public key, |plaintext| + as the message to be encrypted, |M| and |label| + as the label, |L|, and with the hash + function specified by the {{RsaHashedKeyAlgorithm/hash}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option and MGF1 (defined in Section B.2.1 of + [[RFC3447]]) as the MGF option. +

    +
  6. +
  7. +

    + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  8. +
  9. +

    + Let |ciphertext| be the value |C| that results from performing the + operation. +

    +
  10. +
  11. +

    + Return |ciphertext|. +

    +
  12. +
+
+ +
+
Decrypt
+ +
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of |key| + is not {{KeyType/"private"}}, + then [= exception/throw =] an + {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Let |label| be the {{RsaOaepParams/label}} member of + |normalizedAlgorithm| or the empty byte sequence if the + {{RsaOaepParams/label}} member of + |normalizedAlgorithm| is not present. +

    +
  4. +
  5. +

    + Perform the decryption operation defined in Section 7.1 of [[RFC3447]] with the key represented by |key| + as the recipient's RSA private key, |ciphertext| + as the ciphertext to be decrypted, C, and |label| + as the label, |L|, and with the hash + function specified by the {{RsaHashedKeyAlgorithm/hash}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option and MGF1 (defined in Section B.2.1 of + [[RFC3447]]) as the MGF option. +

    +
  6. +
  7. +

    + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  8. +
  9. +

    + Let |plaintext| the value |M| that results from performing the + operation. +

    +
  10. +
  11. +

    + Return |plaintext|. +

    +
  12. +
+
+ +
+
Generate Key
+ +
    +
  1. +

    + If |usages| contains an entry which is not + "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

    +
  2. +
  3. +

    + Generate an RSA key pair, as defined in [[RFC3447]], with RSA modulus length equal to the + {{RsaKeyGenParams/modulusLength}} member of + |normalizedAlgorithm| and RSA public exponent equal to the + {{RsaKeyGenParams/publicExponent}} member of + |normalizedAlgorithm|. +

    +
  4. +
  5. +

    + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |algorithm| be a new + {{RsaHashedKeyAlgorithm}} + object. +

    +
  8. +
  9. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`RSA-OAEP`". +

    +
  10. +
  11. +

    + Set the + {{RsaKeyAlgorithm/modulusLength}} + attribute of |algorithm| to equal the + {{RsaKeyGenParams/modulusLength}} + member of |normalizedAlgorithm|. +

    +
  12. +
  13. +

    + Set the + {{RsaKeyAlgorithm/publicExponent}} + attribute of |algorithm| to equal the + {{RsaKeyGenParams/publicExponent}} + member of |normalizedAlgorithm|. +

    +
  14. +
  15. +

    + Set the {{RsaHashedKeyAlgorithm/hash}} attribute + of |algorithm| to equal the + {{RsaHashedKeyGenParams/hash}} member of + |normalizedAlgorithm|. +

    +
  16. +
  17. +

    + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

    +
  18. +
  19. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

    +
  20. +
  21. +

    + Set the {{CryptoKey/[[algorithm]]}} internal slot of + |publicKey| to |algorithm|. +

    +
  22. +
  23. +

    + Set the {{CryptoKey/[[extractable]]}} internal slot of + |publicKey| to true. +

    +
  24. +
  25. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the + [= usage intersection =] of + |usages| and `[ "encrypt", "wrapKey" ]`. +

    +
  26. +
  27. +

    + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

    +
  28. +
  29. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

    +
  30. +
  31. +

    + Set the {{CryptoKey/[[algorithm]]}} internal slot of + |privateKey| to |algorithm|. +

    +
  32. +
  33. +

    + Set the {{CryptoKey/[[extractable]]}} internal slot of + |privateKey| to |extractable|. +

    +
  34. +
  35. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the + [= usage intersection =] of + |usages| and `[ "decrypt", "unwrapKey" ]`. +

    +
  36. +
  37. +

    + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

    +
  38. +
  39. +

    + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

    +
  40. +
  41. +

    + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

    +
  42. +
  43. +

    + Return |result|. +

    +
  44. +
+
+ +
+
Import Key
+ +
    +
  1. +

    Let |keyData| be the key data to be imported.

    +
  2. +
  3. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`encrypt`" or + "`wrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `rsaEncryption` + object identifier defined in [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + Let |publicKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the + `subjectPublicKeyInfo` field of |spki|, + |structure| as the `RSAPublicKey` structure + specified in Section A.1.1 of [[RFC3447]], and + |exactData| set to true. +

      +
    10. +
    11. +

      + If an error occurred while parsing, or it can be determined that |publicKey| + is not a valid public key according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} + that represents the RSA public key identified by + |publicKey|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to "`public`" +

      +
    16. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`decrypt`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, then [= exception/throw =] a {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `rsaEncryption` object identifier defined in [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + Let |rsaPrivateKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the + `privateKey` field of |privateKeyInfo|, + |structure| as the `RSAPrivateKey` structure + specified in Section A.1.2 of [[RFC3447]], and + |exactData| set to true. +

      +
    10. +
    11. +

      + If an error occurred while parsing, or if |rsaPrivateKey| is not + a valid RSA private key according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} + that represents the RSA private key identified by + |rsaPrivateKey|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"private"}} +

      +
    16. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +
      +
      If |keyData| is a {{JsonWebKey}} dictionary:
      +

      Let |jwk| equal |keyData|.

      +
      Otherwise:
      +

      [= exception/Throw =] a {{DataError}}.

      +
      +
    2. +
    3. +

      + If the {{JsonWebKey/d}} field of |jwk| is present and + |usages| contains an entry which is not + "`decrypt`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + If the {{JsonWebKey/d}} field of |jwk| is not present and + |usages| contains an entry which is not + "`encrypt`" or "`wrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    6. +
    7. +

      + If the {{JsonWebKey/kty}} field of |jwk| is not a + case-sensitive string match to "`RSA`", + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not a case-sensitive string match to "`enc`", + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

      +
    14. +
    15. +
      +
      If the `alg` field of |jwk| is not present:
      +
      Let |hash| be undefined.
      +
      + If the `alg` field of |jwk| is equal to + "`RSA-OAEP`": +
      +
      Let |hash| be the string "`SHA-1`".
      +
      + If the `alg` field of |jwk| is equal to + "`RSA-OAEP-256`": +
      +
      Let |hash| be the string "`SHA-256`".
      +
      + If the `alg` field of |jwk| is equal to + "`RSA-OAEP-384`": +
      +
      Let |hash| be the string "`SHA-384`".
      +
      + If the `alg` field of |jwk| is equal to + "`RSA-OAEP-512`": +
      +
      Let |hash| be the string "`SHA-512`".
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= RSA-OAEP key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |jwk| + and obtaining |hash|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    16. +
    17. +
      +
      + If |hash| is not undefined: +
      +
      +
        +
      1. +

        + Let |normalizedHash| be the result of + normalize an algorithm + with `alg` set to |hash| and `op` set + to `digest`. +

        +
      2. +
      3. +

        + If |normalizedHash| is not equal to the + {{RsaHashedImportParams/hash}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

        +
      4. +
      +
      +
      +
    18. +
    19. +
      +
      If the {{JsonWebKey/d}} field of |jwk| is present:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of Section + 6.3.2 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |privateKey| represent the + RSA private key identified by interpreting |jwk| + according to Section 6.3.2 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + If |privateKey| can be determined to not be a valid RSA private key + according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} representing |privateKey|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"private"}} +

        +
      10. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of Section + 6.3.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |publicKey| represent the + RSA public key identified by interpreting |jwk| + according to Section 6.3.1 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + If |publicKey| can be determined to not be a valid RSA public key + according to [[RFC3447]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} representing |publicKey|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to "`public`" +

        +
      10. +
      +
      +
      +
    20. +
    +
    +
    Otherwise:
    +
    + [= exception/throw =] a + {{NotSupportedError}}. +
    +
    +
  4. +
  5. +

    + Let |algorithm| be a new + {{RsaHashedKeyAlgorithm}}. +

    +
  6. +
  7. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`RSA-OAEP`" +

    +
  8. +
  9. +

    + Set the {{RsaKeyAlgorithm/modulusLength}} + attribute of |algorithm| to the length, in bits, of the RSA public + modulus. +

    +
  10. +
  11. +

    + Set the {{RsaKeyAlgorithm/publicExponent}} + attribute of |algorithm| to the {{BigInteger}} + representation of the RSA public exponent. +

    +
  12. +
  13. +

    + Set the {{RsaHashedKeyAlgorithm/hash}} attribute of + |algorithm| to the {{RsaHashedImportParams/hash}} member of + |normalizedAlgorithm|. +

    +
  14. +
  15. +

    + Set the {{CryptoKey/[[algorithm]]}} internal slot of + |key| to |algorithm| +

    +
  16. +
  17. +

    Return |key|.

    +
  18. +
+
+ +
+
Export Key
+ +
    +
  1. +

    + Let |key| be the key to be exported. +

    +
  2. +
  3. +

    + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

    +
  4. +
  5. +
    +
    If |format| is {{KeyFormat/"spki"}}
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

      +
        +
      • +

        + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `rsaEncryption` defined in + [[RFC3447]]. +

          +
        • +
        • +

          + Set the |params| field to the ASN.1 type NULL. +

          +
        • +
        +
      • +
      • +

        + Set the |subjectPublicKey| field to the result of + DER-encoding an `RSAPublicKey` ASN.1 type, as defined + in [[RFC3447]], Appendix A.1.1, that + represents the RSA public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

      +
        +
      • +

        + Set the |version| field to `0`. +

        +
      • +
      • +

        + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `rsaEncryption` defined in + [[RFC3447]]. +

          +
        • +
        • +

          + Set the |params| field to the ASN.1 type NULL. +

          +
        • +
        +
      • +
      • +

        + Set the |privateKey| field to the result of DER-encoding + an `RSAPrivateKey` ASN.1 type, as defined in [[RFC3447]], Appendix A.1.2, that represents the + RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

        +
        + [[RFC5208]] specifies that the encoding of + this field should be BER encoded in Section 5 (as a "for + example"). However, to avoid requiring WebCrypto implementations + support BER-encoding and BER-decoding, only DER encodings + are produced or accepted. +
        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +

      + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

      +
    2. +
    3. +

      + Set the `kty` attribute of |jwk| to the string + "`RSA`". +

      +
    4. +
    5. +

      + Let |hash| be the {{KeyAlgorithm/name}} + attribute of the {{RsaHashedKeyAlgorithm/hash}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key|. +

      +
    6. +
    7. +
      +
      + If |hash| is "`SHA-1`": +
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RSA-OAEP`". +

      +
      +
      + If |hash| is "`SHA-256`": +
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RSA-OAEP-256`". +

      +
      +
      + If |hash| is "`SHA-384`": +
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RSA-OAEP-384`". +

      +
      +
      + If |hash| is "`SHA-512`": +
      +
      +

      + Set the `alg` attribute of |jwk| to the string + "`RSA-OAEP-512`". +

      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= RSA-OAEP key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{RsaHashedKeyAlgorithm/hash}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |alg|. +

        +
      2. +
      3. +

        + Set the `alg` attribute of |jwk| to |alg|. +

        +
      4. +
      +
      +
      +
    8. +
    9. +

      + Set the attributes {{JsonWebKey/n}} and {{JsonWebKey/e}} of |jwk| + according to the corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.1. +

      +
    10. +
    11. +
      +
      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is {{KeyType/"private"}}: +
      +
      +
        +
      1. +

        + Set the attributes named {{JsonWebKey/d}}, {{JsonWebKey/p}}, + {{JsonWebKey/q}}, {{JsonWebKey/dp}}, {{JsonWebKey/dq}}, and + {{JsonWebKey/qi}} of |jwk| according to the + corresponding definitions in JSON Web Algorithms [[JWA]], Section 6.3.2. +

        +
      2. +
      3. +

        + If the underlying RSA private key represented by the {{CryptoKey/[[handle]]}} internal slot + of |key| is represented by more than two primes, set + the attribute named {{JsonWebKey/oth}} of |jwk| + according to the corresponding definition in JSON Web Algorithms [[JWA]], Section 6.3.2.7 +

        +
      4. +
      +
      +
      +
    12. +
    13. +

      + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

      +
    14. +
    15. +

      + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

      +
    16. +
    17. +

      + Let |result| be |jwk|. +

      +
    18. +
    +
    +
    Otherwise
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    +
    +
  6. +
  7. +

    + Return |result|. +

    +
  8. +
+
+
+
+ +
+

ECDSA

+
+

Description

+

+ The "`ECDSA`" algorithm identifier is used to perform signing + and verification using the ECDSA algorithm specified in + [[RFC6090]] and using the SHA hash functions and elliptic + curves defined in this specification. +

+

+ Other specifications + may specify the use of additional elliptic curves and hash algorithms with ECDSA. To + specify additional hash algorithms to be used with ECDSA, a specification must define + a registered algorithm that supports the digest operation. + To specify an additional elliptic curve a specification must define + the curve name, + ECDSA signature steps, + ECDSA verification steps, + ECDSA generation steps, + ECDSA key import steps and + ECDSA key export steps. +

+
+
+

Registration

+

+ The [= recognized algorithm name =] for + this algorithm is "`ECDSA`". +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperationParametersResult
sign{{EcdsaParams}}[= byte sequence =]
verify{{EcdsaParams}}boolean
generateKey{{EcKeyGenParams}}{{CryptoKeyPair}}
importKey{{EcKeyImportParams}}{{CryptoKey}}
exportKeyNoneobject
+
+
+

EcdsaParams dictionary

+
+dictionary EcdsaParams : Algorithm {
+  required HashAlgorithmIdentifier hash;
+};
+          
+

The hash member represents the hash algorithm to use.

+
+
+

EcKeyGenParams dictionary

+
+typedef DOMString NamedCurve;
+
+dictionary EcKeyGenParams : Algorithm {
+  required NamedCurve namedCurve;
+};
+          
+

+ The NamedCurve type represents named elliptic curves, + which are a convenient way to specify the domain parameters of well-known elliptic + curves. The following values defined by this specification: +

+
+
"`P-256`"
+
NIST recommended curve P-256, also known as `secp256r1`.
+
"`P-384`"
+
NIST recommended curve P-384, also known as `secp384r1`.
+
"`P-521`"
+
NIST recommended curve P-521, also known as `secp521r1`.
+
+

+ Other specifications may define + additional values. +

+

The namedCurve member of the {{EcKeyGenParams}} dictionary represents a named curve.

+
+
+

EcKeyAlgorithm dictionary

+
+dictionary EcKeyAlgorithm : KeyAlgorithm {
+  required NamedCurve namedCurve;
+};
+          
+

The namedCurve member represents the named curve that the key uses.

+
+
+

EcKeyImportParams dictionary

+
+dictionary EcKeyImportParams : Algorithm {
+  required NamedCurve namedCurve;
+};
+          
+

The namedCurve member represents a named curve.

+
+ +
+

Operations

+ +
+
Sign
+ +
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Let |hashAlgorithm| be the {{EcdsaParams/hash}} + member of |normalizedAlgorithm|. +

    +
  4. +
  5. +

    + Let |M| be the result of performing the digest operation specified by + |hashAlgorithm| using |message|. +

    +
  6. +
  7. +

    + Let |d| be the ECDSA private key associated with |key|. +

    +
  8. +
  9. +

    + Let |params| be the EC domain parameters associated with + |key|. +

    +
  10. +
  11. +
    +
    + If the {{EcKeyAlgorithm/namedCurve}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| is "`P-256`", "`P-384`" or "`P-521`": +
    +
    +
      +
    1. +

      + Perform the ECDSA signing process, as specified in [[RFC6090]], + Section 5.4, with |M| as the message, using |params| as the + EC domain parameters, and with |d| as the private key. +

      +
    2. +
    3. +

      + Let |r| and |s| be the pair of integers resulting from + performing the ECDSA signing process. +

      +
    4. +
    5. +

      + Let |result| be an empty [= byte sequence =]. +

      +
    6. +
    7. +

      + Let |n| be the smallest integer such that |n| * 8 is greater than + the logarithm to base 2 of the order of the base point of the elliptic curve identified + by |params|. +

      +
    8. +
    9. +

      + Convert |r| to a byte sequence of + length |n| and append it to |result|. +

      +
    10. +
    11. +

      + Convert |s| to a byte sequence of + length |n| and append it to |result|. +

      +
    12. +
    +
    +
    + Otherwise, the {{EcKeyAlgorithm/namedCurve}} attribute + of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| is a value specified in an + applicable specification: +
    +
    +

    + Perform the [= ECDSA signature steps =] + specified in that specification, passing in |M|, |params| + and |d| and resulting in |result|. +

    +
    +
    +
  12. +
  13. +

    + Return |result|. +

    +
  14. +
+
+ +
+
Verify
+
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Let |hashAlgorithm| be the {{EcdsaParams/hash}} + member of + |normalizedAlgorithm|. +

    +
  4. +
  5. +

    + Let |M| be the result of performing the digest operation specified by + |hashAlgorithm| using |message|. +

    +
  6. +
  7. +

    + Let |Q| be the ECDSA public key associated with |key|. +

    +
  8. +
  9. +

    + Let |params| be the EC domain parameters associated with + |key|. +

    +
  10. +
  11. +
    +
    + If the {{EcKeyAlgorithm/namedCurve}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| is "`P-256`", "`P-384`" or "`P-521`": +
    +
    +

    + Perform the ECDSA verifying process, as specified in [[RFC6090]], Section 5.3, with |M| as the received + message, |signature| as the received signature and using + |params| as the EC domain parameters, and + |Q| as the public key. +

    +
    +
    + Otherwise, the {{EcKeyAlgorithm/namedCurve}} attribute + of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| is a value specified in an + applicable specification: +
    +
    +

    + Perform the [= ECDSA verification steps =] + specified in that specification passing in |M|, |signature|, + |params| and |Q| and resulting in an indication of whether + or not the purported signature is valid. +

    +
    +
    +
  12. +
  13. +

    + Let |result| be a boolean with the value `true` if the signature is valid + and the value `false` otherwise. +

    +
  14. +
  15. +

    + Return |result|. +

    +
  16. +
+
+ +
+
Generate Key
+ +
    +
  1. +

    + If |usages| contains a value which is not + one of "`sign`" or "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

    +
  2. +
  3. +
    +
    + If the {{EcKeyGenParams/namedCurve}} member of + |normalizedAlgorithm| is "`P-256`", "`P-384`" + or "`P-521`": +
    +
    +

    + Generate an Elliptic Curve key pair, as defined in [[RFC6090]] + with domain parameters for the curve identified by + the {{EcKeyGenParams/namedCurve}} member of + |normalizedAlgorithm|. +

    +
    +
    + If the {{EcKeyGenParams/namedCurve}} member of + |normalizedAlgorithm| is a value specified in an + applicable specification: +
    +
    +

    + Perform the [=ECDSA + generation steps =] specified in that specification, passing in + |normalizedAlgorithm| and resulting in an elliptic curve key pair. +

    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}} +

    +
    +
    +
  4. +
  5. +

    + If performing the key generation operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |algorithm| be a new + {{EcKeyAlgorithm}} + object. +

    +
  8. +
  9. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDSA`". +

    +
  10. +
  11. +

    + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to equal the + {{namedCurve}} member of + |normalizedAlgorithm|. +

    +
  12. +
  13. +

    + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

    +
  14. +
  15. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

    +
  16. +
  17. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |publicKey| to |algorithm|. +

    +
  18. +
  19. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |publicKey| to true. +

    +
  20. +
  21. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the [= usage + intersection =] of |usages| and `[ "verify" ]`. +

    +
  22. +
  23. +

    + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

    +
  24. +
  25. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

    +
  26. +
  27. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |privateKey| to |algorithm|. +

    +
  28. +
  29. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |privateKey| to |extractable|. +

    +
  30. +
  31. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the [= usage + intersection =] of |usages| and `[ "sign" ]`. +

    +
  32. +
  33. +

    + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

    +
  34. +
  35. +

    + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

    +
  36. +
  37. +

    + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

    +
  38. +
  39. +

    + Return |result|. +

    +
  40. +
+
+ +
+
Import Key
+ +
    +
  1. +

    Let |keyData| be the key data to be imported.

    +
  2. +
  3. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If |usages| contains a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData| +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `id-ecPublicKey` + object identifier defined in [[RFC5480]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is absent, + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + Let |params| be the `parameters` field of the + `algorithm` AlgorithmIdentifier field of |spki|. +

      +
    12. +
    13. +

      + If |params| is not an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] that specifies a + `namedCurve`, then [= exception/throw =] a {{DataError}}. +

      +
    14. +
    15. +

      + Let |namedCurve| be a string whose initial value is + undefined. +

      +
    16. +
    17. +
      +
      + If |params| is equivalent to the `secp256r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-256`". +

      +
      +
      + If |params| is equivalent to the `secp384r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-384`". +

      +
      +
      + If |params| is equivalent to the `secp521r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-521`". +

      +
      +
      +
    18. +
    19. +
      +
      If |namedCurve| is not undefined:
      +
      +
        +
      1. +

        + Let |publicKey| be the Elliptic Curve public key identified by + performing the conversion steps defined in Section 2.3.4 of [[SEC1]] using the `subjectPublicKey` + field of |spki|. +

        +

        + The uncompressed point format MUST be supported. +

        +
      2. +
      3. +

        + If the implementation does not support the compressed point format and + a compressed point is provided, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If a decode error occurs or an identity point is found, + [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + that represents |publicKey|. +

        +
      8. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= ECDSA key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |spki| + and obtaining |namedCurve| and |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    20. +
    21. +

      + If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

      +
    22. +
    23. +

      + If the public key value is not a valid point on the Elliptic Curve + identified by the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. +

      +
    24. +
    25. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

      +
    26. +
    27. +

      + Let |algorithm| be a new {{EcKeyAlgorithm}}. +

      +
    28. +
    29. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDSA`". +

      +
    30. +
    31. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to |namedCurve|. +

      +
    32. +
    33. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    34. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If |usages| contains a value which is not + "`sign`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurs while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `id-ecPublicKey` object identifier defined in [[RFC5480]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is not present, + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + Let |params| be the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo|. +

      +
    12. +
    13. +

      + If |params| is not an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] that specifies a + `namedCurve`, then [= exception/throw =] a {{DataError}}. +

      +
    14. +
    15. +

      + Let |namedCurve| be a string whose initial value is + undefined. +

      +
    16. +
    17. +
      +
      + If |params| is equivalent to the `secp256r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-256`". +

      +
      +
      + If |params| is equivalent to the `secp384r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-384`". +

      +
      +
      + If |params| is equivalent to the `secp521r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-521`". +

      +
      +
      +
    18. +
    19. +
      +
      If |namedCurve| is not undefined:
      +
      +
        +
      1. +

        + Let |ecPrivateKey| be the result of performing the [= parse an ASN.1 structure =] + algorithm, with |data| as the `privateKey` field + of |privateKeyInfo|, |structure| as the ASN.1 + `ECPrivateKey` structure specified in Section 3 of [[RFC5915]], and |exactData| set to true. +

        +
      2. +
      3. +

        + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If the `parameters` field of |ecPrivateKey| is + present, and is not an instance of the `namedCurve` ASN.1 + type defined in [[RFC5480]], or does not contain + the same object identifier as the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo|, + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + that represents the Elliptic Curve private key identified by + performing the conversion steps defined in Section 3 of [[RFC5915]] using |ecPrivateKey|. +

        +
      8. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= ECDSA key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |privateKeyInfo| + and obtaining |namedCurve| and |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    20. +
    21. +

      + If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

      +
    22. +
    23. +

      + If the private key value is not a valid point on the Elliptic Curve + identified by the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. +

      +
    24. +
    25. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to {{KeyType/"private"}} +

      +
    26. +
    27. +

      + Let |algorithm| be a new {{EcKeyAlgorithm}}. +

      +
    28. +
    29. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDSA`". +

      +
    30. +
    31. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to |namedCurve|. +

      +
    32. +
    33. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    34. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +
      +
      If |keyData| is a {{JsonWebKey}} dictionary:
      +

      Let |jwk| equal |keyData|.

      +
      Otherwise:
      +

      [= exception/Throw =] a {{DataError}}.

      +
      +
    2. +
    3. +

      + If the {{JsonWebKey/d}} field is present and |usages| contains + a value which is not + "`sign`", or, + if the {{JsonWebKey/d}} field is not present and |usages| contains + a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + If the {{JsonWebKey/kty}} field of |jwk| is not + "`EC`", + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`sig`", + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the {{JsonWebKey/key_ops}} field of |jwk| is present, and + is invalid according to the requirements of JSON Web + Key [[JWK]], or it does not contain all of the specified |usages| + values, + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + Let |namedCurve| be a string whose value is equal to the + {{JsonWebKey/crv}} field of |jwk|. +

      +
    14. +
    15. +

      + If |namedCurve| is not equal to the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

      +
    16. +
    17. +
      +
      + If |namedCurve| is equal to "`P-256`", + "`P-384`" or "`P-521`": +
      +
      +
        +
      1. +

        + Let |algNamedCurve| be a string whose initial value is + undefined. +

        +
      2. +
      3. +
        +
        If the {{JsonWebKey/alg}} field is not present:
        +
        + Let |algNamedCurve| be undefined. +
        +
        + If the {{JsonWebKey/alg}} field is equal to the string "ES256": +
        +
        + Let |algNamedCurve| be the string "`P-256`". +
        +
        + If the {{JsonWebKey/alg}} field is equal to the string "ES384": +
        +
        + Let |algNamedCurve| be the string "`P-384`". +
        +
        + If the {{JsonWebKey/alg}} field is equal to the string "ES512": +
        +
        + Let |algNamedCurve| be the string "`P-521`". +
        +
        otherwise:
        +
        + [= exception/throw =] a + {{DataError}}. +
        +
        +
      4. +
      5. +

        + If |algNamedCurve| is defined, and is not equal to + |namedCurve|, [= exception/throw =] a {{DataError}}. +

        +
      6. +
      7. +
        +
        If the {{JsonWebKey/d}} field is present:
        +
        +
          +
        1. +

          + If |jwk| does not meet the requirements of Section + 6.2.2 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

          +
        2. +
        3. +

          + Let |key| be a new {{CryptoKey}} object that represents the + Elliptic Curve private key identified by interpreting + |jwk| according to Section 6.2.2 of JSON Web Algorithms [[JWA]]. +

          +
        4. +
        5. +

          + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to {{KeyType/"private"}}. +

          +
        6. +
        +
        +
        Otherwise:
        +
        +
          +
        1. +

          + If |jwk| does not meet the requirements of Section + 6.2.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

          +
        2. +
        3. +

          + Let |key| be a new {{CryptoKey}} object that represents the + Elliptic Curve public key identified by interpreting + |jwk| according to Section 6.2.1 of JSON Web Algorithms [[JWA]]. +

          +
        4. +
        5. +

          + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to "`public`". +

          +
        6. +
        +
        +
        +
      8. +
      +
      +
      + Otherwise: +
      +
      +
        +
      1. +

        + Perform any [= ECDSA key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |jwk| + and obtaining |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    18. +
    19. +

      + If the key value is not a valid point on the Elliptic Curve + identified by the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. +

      +
    20. +
    21. +

      + Let |algorithm| be a new instance of an {{EcKeyAlgorithm}} object. +

      +
    22. +
    23. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDSA`". +

      +
    24. +
    25. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to |namedCurve|. +

      +
    26. +
    27. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    28. +
    +
    +
    If |format| is {{KeyFormat/"raw"}}:
    +
    +
      +
    1. +

      + If the {{EcKeyImportParams/namedCurve}} + member of |normalizedAlgorithm| is not a + named curve, + then [= exception/throw =] a + {{DataError}}. +

      +
    2. +
    3. +

      + If |usages| contains a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +
      +
      + If |namedCurve| is "`P-256`", + "`P-384`" or "`P-521`": +
      +
      +
        +
      1. +

        + Let |Q| be the elliptic curve point on the curve identified + by the {{EcKeyImportParams/namedCurve}} + member of |normalizedAlgorithm| identified by performing + the conversion steps defined in Section 2.3.4 of [[SEC1]] on |keyData|. +

        +

        + The uncompressed point format MUST be supported. +

        +
      2. +
      3. +

        + If the implementation does not support the compressed point format and + a compressed point is provided, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If a decode error occurs or an identity point is found, + [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + that represents |Q|. +

        +
      8. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= ECDH key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |keyData| + and obtaining |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    6. +
    7. +

      + Let |algorithm| be a new {{EcKeyAlgorithm}} object. +

      +
    8. +
    9. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDSA`". +

      +
    10. +
    11. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to equal the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|. +

      +
    12. +
    13. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    16. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    +
    +
  4. +
  5. +

    + Return |key| +

    +
  6. +
+
+ +
+
Export Key
+ +
    +
  1. +

    + Let |key| be the {{CryptoKey}} to be + exported. +

    +
  2. +
  3. +

    + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

    +
  4. +
  5. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

      +
        +
      • +

        + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `id-ecPublicKey` defined in + [[RFC5480]]. +

          +
        • +
        • +

          + Set the |parameters| field to an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] as follows: +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`", + "`P-384`" or "`P-521`": +
          +
          +

          + Let |keyData| be the + [= byte sequence =] that + represents the Elliptic Curve public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| according to the encoding rules specified in + Section 2.2 of [[RFC5480]] and using the + uncompressed form. and |keyData|. +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`": +
          +
          +

          + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier + `secp256r1` defined in [[RFC5480]] +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-384`": +
          +
          +

          + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier + `secp384r1` defined in [[RFC5480]] +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-521`": +
          +
          +

          + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier + `secp521r1` defined in [[RFC5480]] +

          +
          +
          +
          +
          + Otherwise: +
          +
          +
            +
          1. +

            + Perform any [= ECDSA key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurveOid| and |keyData|. +

            +
          2. +
          3. +

            + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier |namedCurveOid|. +

            +
          4. +
          +
          +
          +
        • +
        +
      • +
      • +

        + Set the |subjectPublicKey| field to |keyData|. +

        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

      +
        +
      • +

        + Set the |version| field to `0`. +

        +
      • +
      • +

        + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

        +
          +
        • +

          + Set the |algorithm| field to the OID + `id-ecPublicKey` defined in + [[RFC5480]]. +

          +
        • +
        • +

          + Set the |parameters| field to an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] as follows: +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`", + "`P-384`" or "`P-521`": +
          +
          +

          + Let |keyData| be the result of DER-encoding + an instance of the `ECPrivateKey` structure defined in + Section 3 of [[RFC5915]] for the Elliptic + Curve private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| and that conforms to the following: +

          +
            +
          • +

            + The |parameters| field is present, and is equivalent + to the |parameters| field of the + |privateKeyAlgorithm| field of this + `PrivateKeyInfo` ASN.1 structure. +

            +
          • +
          • +

            + The |publicKey| field is present and represents the + Elliptic Curve public key associated with the Elliptic Curve + private key represented by the {{CryptoKey/[[handle]]}} internal slot + of |key|. +

            +
          • +
          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`": +
          +
          +

          + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier + `secp256r1` defined in [[RFC5480]] +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-384`": +
          +
          +

          + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier + `secp384r1` defined in [[RFC5480]] +

          +
          +
          + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-521`": +
          +
          +

          + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier + `secp521r1` defined in [[RFC5480]] +

          +
          +
          +
          +
          + Otherwise: +
          +
          +
            +
          1. +

            + Perform any [= ECDSA key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurveOid| and |keyData|. +

            +
          2. +
          3. +

            + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier |namedCurveOid|. +

            +
          4. +
          +
          +
          +
        • +
        +
      • +
      • +

        + Set the |privateKey| field to |keyData|. +

        +
      • +
      +
    4. +
    5. +

      + Let |result| be the result of DER-encoding |data|. +

      +
    6. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +

      + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

      +
    2. +
    3. +

      + Set the `kty` attribute of |jwk| to + "`EC`". +

      +
    4. +
    5. +
      +
      + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-256`", "`P-384`" or + "`P-521`": +
      +
      +
        +
      1. +
        +
        + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-256`": +
        +
        + Set the {{JsonWebKey/crv}} attribute of |jwk| to + "`P-256`" +
        +
        + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-384`": +
        +
        + Set the {{JsonWebKey/crv}} attribute of |jwk| to + "`P-384`" +
        +
        + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-521`": +
        +
        + Set the {{JsonWebKey/crv}} attribute of |jwk| to + "`P-521`" +
        +
        +
      2. +
      3. +

        + Set the {{JsonWebKey/x}} attribute of |jwk| according to the + definition in Section 6.2.1.2 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + Set the {{JsonWebKey/y}} attribute of |jwk| according to the + definition in Section 6.2.1.3 of JSON Web Algorithms [[JWA]]. +

        +
      6. +
      7. +
        +
        + If the {{CryptoKey/[[type]]}} internal slot + of |key| is {{KeyType/"private"}} +
        +
        +

        + Set the {{JsonWebKey/d}} attribute of |jwk| according to + the definition in Section 6.2.2.1 of JSON Web Algorithms [[JWA]]. +

        +
        +
        +
      8. +
      +
      +
      + Otherwise: +
      +
      +
        +
      1. +

        + Perform any [= ECDSA key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurve| and a new value of |jwk|. +

        +
      2. +
      3. +

        + Set the {{JsonWebKey/crv}} attribute of |jwk| to + |namedCurve|. +

        +
      4. +
      +
      +
      +
    6. +
    7. +

      + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

      +
    8. +
    9. +

      + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

      +
    10. +
    11. +

      + Let |result| be |jwk|. +

      +
    12. +
    +
    +
    + If |format| is {{KeyFormat/"raw"}}: +
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +
      +
      + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-256`", "`P-384`" + or "`P-521`": +
      +
      +

      + Let |data| be a [= byte sequence =] representing the Elliptic Curve + point |Q| represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| according to [[SEC1]] 2.3.3 using the uncompressed format. +

      +
      +
      Otherwise:
      +
      +

      + Perform any [= ECDH key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurve| and |data|. +

      +
      +
      +
    4. +
    5. +

      + Let |result| be |data|. +

      +
    6. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    +
    +
  6. +
  7. +

    + Return |result|. +

    +
  8. +
+
+
+
+ +
+

ECDH

+
+

Description

+

+ This describes using Elliptic Curve Diffie-Hellman (ECDH) for key generation and key + agreement, as specified by [[RFC6090]]. +

+

+ Other specifications + may specify the use of additional elliptic curves with ECDH. + To specify an additional elliptic curve a specification must define + the curve name, + ECDH generation steps, + ECDH derivation steps, + ECDH key import steps and + ECDH key export steps. +

+
+
+

Registration

+

+ The [= recognized algorithm name =] for + this algorithm is "`ECDH`". +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperationParametersResult
generateKey{{EcKeyGenParams}}{{CryptoKeyPair}}
deriveBits{{EcdhKeyDeriveParams}}[= byte sequence =]
importKey{{EcKeyImportParams}}{{CryptoKey}}
exportKeyNoneobject
+
+
+

EcdhKeyDeriveParams dictionary

+
+dictionary EcdhKeyDeriveParams : Algorithm {
+  required CryptoKey public;
+};
+          
+

The public member represents the peer's EC public key.

+
+
+

Operations

+ +
+
Generate Key
+ +
    +
  1. +

    + If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

    +
  2. +
  3. +
    +
    + If the {{EcKeyGenParams/namedCurve}} member of + |normalizedAlgorithm| is "`P-256`", "`P-384`" + or "`P-521`": +
    +
    +

    + Generate an Elliptic Curve key pair, as defined in [[RFC6090]] with domain parameters for the curve identified by + the {{EcKeyGenParams/namedCurve}} member of + |normalizedAlgorithm|. +

    +
    +
    + If the {{EcKeyGenParams/namedCurve}} member of + |normalizedAlgorithm| is a value specified in an + applicable specification that + specifies the use of that value with ECDH: +
    +
    +

    + Perform the [= ECDH + generation steps =] specified in that specification, passing in + |normalizedAlgorithm| and resulting in an elliptic curve key pair. +

    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}} +

    +
    +
    +
  4. +
  5. +

    + If performing the operation results in an error, + then [= exception/throw =] a + {{OperationError}}. +

    +
  6. +
  7. +

    + Let |algorithm| be a new + {{EcKeyAlgorithm}} + object. +

    +
  8. +
  9. +

    + Set the {{Algorithm/name}} member of + |algorithm| to "`ECDH`". +

    +
  10. +
  11. +

    + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to equal the + {{namedCurve}} member of + |normalizedAlgorithm|. +

    +
  12. +
  13. +

    + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

    +
  14. +
  15. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

    +
  16. +
  17. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |publicKey| to |algorithm|. +

    +
  18. +
  19. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |publicKey| to true. +

    +
  20. +
  21. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the empty list. +

    +
  22. +
  23. +

    + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

    +
  24. +
  25. +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

    +
  26. +
  27. +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |privateKey| to |algorithm|. +

    +
  28. +
  29. +

    + Set the {{CryptoKey/[[extractable]]}} internal + slot of |privateKey| to |extractable|. +

    +
  30. +
  31. +

    + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the + [= usage intersection =] of + |usages| and `[ "deriveKey", "deriveBits" ]`. +

    +
  32. +
  33. +

    + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

    +
  34. +
  35. +

    + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

    +
  36. +
  37. +

    + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

    +
  38. +
  39. +

    + Return |result|. +

    +
  40. +
+
+ +
+
Derive Bits
+ +
    +
  1. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  2. +
  3. +

    + Let |publicKey| be the + {{EcdhKeyDeriveParams/public}} member of + |normalizedAlgorithm|. +

    +
  4. +
  5. +

    + If the {{CryptoKey/[[type]]}} internal slot of + |publicKey| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  6. +
  7. +

    + If the {{KeyAlgorithm/name}} attribute of + the {{CryptoKey/[[algorithm]]}} internal slot of + |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the {{CryptoKey/[[algorithm]]}} internal slot of + |key|, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  8. +
  9. +

    + If the {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} internal slot of + |publicKey| is not equal to the {{EcKeyAlgorithm/namedCurve}} property of the {{CryptoKey/[[algorithm]]}} internal slot of + |key|, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  10. +
  11. +
    +
    + If the {{EcKeyAlgorithm/namedCurve}} property of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| is "`P-256`", "`P-384`" + or "`P-521`": +
    +
    +
      +
    1. +

      + Perform the ECDH primitive specified in [[RFC6090]] Section + 4 with |key| as the EC private key |d| and the EC public + key represented by the {{CryptoKey/[[handle]]}} + internal slot of |publicKey| as the EC public key. +

      +
    2. +
    3. +

      + Let |secret| be a [= byte sequence =] containing + the result of applying the field element to + octet string conversion defined in Section + 6.2 of [[RFC6090]] + to the output of the ECDH primitive. +

      +
    4. +
    +
    +
    + If the {{EcKeyAlgorithm/namedCurve}} property of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| is a value specified in an + applicable specification that + specifies the use of that value with ECDH: +
    +
    +

    + Perform the [= ECDH + derivation steps =] specified in that specification, passing in + |key| and |publicKey| and resulting in |secret|. +

    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}} +

    +
    +
    + +
  12. +
  13. +

    + If performing the operation results in an error, + then [= exception/throw =] a + {{OperationError}}. +

    +
  14. +
  15. +
    +
    If |length| is null:
    +
    Return |secret|
    +
    Otherwise:
    +
    +
    +
    + If the [= length in bits =] of |secret| is less than + |length|: +
    +
    + [= exception/throw =] an + {{OperationError}}. +
    +
    Otherwise:
    +
    + Return a [= byte sequence containing =] the first |length| bits of |secret|. +
    +
    +
    +
    +
  16. +
+
+ +
+
Import Key
+ +
    +
  1. +

    Let |keyData| be the key data to be imported.

    +
  2. +
  3. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData| +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `id-ecPublicKey` + object identifier defined in [[RFC5480]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is absent, + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + Let |params| be the `parameters` field of the + `algorithm` AlgorithmIdentifier field of |spki|. +

      +
    12. +
    13. +

      + If |params| is not an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] that specifies a + `namedCurve`, then [= exception/throw =] a {{DataError}}. +

      +
    14. +
    15. +

      + Let |namedCurve| be a string whose initial value is + undefined. +

      +
    16. +
    17. +
      +
      + If |params| is equivalent to the `secp256r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-256`". +

      +
      +
      + If |params| is equivalent to the `secp384r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-384`". +

      +
      +
      + If |params| is equivalent to the `secp521r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| "`P-521`". +

      +
      +
      +
    18. +
    19. +
      +
      If |namedCurve| is not undefined:
      +
      +
        +
      1. +

        + Let |publicKey| be the Elliptic Curve public key identified by + performing the conversion steps defined in Section 2.3.4 of [[SEC1]] to the `subjectPublicKey` field of + |spki|. +

        +

        + The uncompressed point format MUST be supported. +

        +
      2. +
      3. +

        + If the implementation does not support the compressed point format and + a compressed point is provided, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If a decode error occurs or an identity point is found, + [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + that represents |publicKey|. +

        +
      8. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= ECDH key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |spki| + and obtaining |namedCurve| and |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    20. +
    21. +

      + If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

      +
    22. +
    23. +

      + If the key value is not a valid point on the Elliptic Curve + identified by the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. +

      +
    24. +
    25. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

      +
    26. +
    27. +

      + Let |algorithm| be a new {{EcKeyAlgorithm}}. +

      +
    28. +
    29. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDH`". +

      +
    30. +
    31. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to |namedCurve|. +

      +
    32. +
    33. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    34. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurs while parsing, + [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `id-ecPublicKey` object identifier + defined in [[RFC5480]], + [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is not present, + [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + Let |params| be the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo|. +

      +
    12. +
    13. +

      + If |params| is not an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] that specifies a + `namedCurve`, then [= exception/throw =] a {{DataError}}. +

      +
    14. +
    15. +

      + Let |namedCurve| be a string whose initial value is + undefined. +

      +
    16. +
    17. +
      +
      + If |params| is equivalent to the `secp256r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| to "`P-256`". +

      +
      +
      + If |params| is equivalent to the `secp384r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| to "`P-384`". +

      +
      +
      + If |params| is equivalent to the `secp521r1` + object identifier defined in [[RFC5480]]: +
      +
      +

      + Set |namedCurve| to "`P-521`". +

      +
      +
      +
    18. +
    19. +
      +
      If |namedCurve| is not undefined:
      +
      +
        +
      1. +

        + Let |ecPrivateKey| be the result of performing the + [= parse an ASN.1 structure =] + algorithm, with |data| as the `privateKey` field + of |privateKeyInfo|, |structure| as the ASN.1 + `ECPrivateKey` structure specified in Section 3 of + [[RFC5915]], and |exactData| set to true. +

        +
      2. +
      3. +

        + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If the `parameters` field of |ecPrivateKey| is + present, and is not an instance of the `namedCurve` ASN.1 + type defined in [[RFC5480]], or does not contain + the same object identifier as the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo|, + [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + that represents the Elliptic Curve private key identified by + performing the conversion steps defined in Section 3 of [[RFC5915]] using |ecPrivateKey|. +

        +
      8. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= ECDH key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |privateKeyInfo| + and obtaining |namedCurve| and |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    20. +
    21. +

      + If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

      +
    22. +
    23. +

      + If the key value is not a valid point on the Elliptic Curve + identified by the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. +

      +
    24. +
    25. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to {{KeyType/"private"}}. +

      +
    26. +
    27. +

      + Let |algorithm| be a new {{EcKeyAlgorithm}}. +

      +
    28. +
    29. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDH`". +

      +
    30. +
    31. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to |namedCurve|. +

      +
    32. +
    33. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    34. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +
      +
      If |keyData| is a {{JsonWebKey}} dictionary:
      +

      Let |jwk| equal |keyData|.

      +
      Otherwise:
      +

      [= exception/Throw =] a {{DataError}}.

      +
      +
    2. +
    3. +

      + If the {{JsonWebKey/d}} field is present and if |usages| + contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + If the {{JsonWebKey/d}} field is not present and if |usages| is not + empty + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    6. +
    7. +

      + If the {{JsonWebKey/kty}} field of |jwk| is + not "`EC`", + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present + and is not equal to "`enc`" then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + If the {{JsonWebKey/key_ops}} field of |jwk| is present, and + is invalid according to the requirements of JSON Web + Key [[JWK]], or it does not contain all of the specified |usages| + values, then [= exception/throw =] a {{DataError}}. +

      +
    12. +
    13. +

      + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

      +
    14. +
    15. +

      + Let |namedCurve| be a string whose value is equal to the + {{JsonWebKey/crv}} field of |jwk|. +

      +
    16. +
    17. +

      + If |namedCurve| is not equal to the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. +

      +
    18. +
    19. +
      +
      + If |namedCurve| is "`P-256`", + "`P-384`" or "`P-521`": +
      +
      +
      +
      If the {{JsonWebKey/d}} field is present:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of Section + 6.2.2 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |key| be a new {{CryptoKey}} object that represents the + Elliptic Curve private key identified by interpreting + |jwk| according to Section 6.2.2 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to {{KeyType/"private"}}. +

        +
      6. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of Section + 6.2.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |key| be a new {{CryptoKey}} object that represents the + Elliptic Curve public key identified by interpreting + |jwk| according to Section 6.2.1 of JSON Web Algorithms [[JWA]]. +

        +
      4. +
      5. +

        + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to "`public`". +

        +
      6. +
      +
      +
      +
      +
      Otherwise
      +
      +
        +
      1. +

        + Perform any [= ECDH key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |jwk| + and obtaining |key|. +

        +
      2. +
      3. +

        + If an error occurred or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    20. +
    21. +

      + If the key value is not a valid point on the Elliptic Curve + identified by the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. +

      +
    22. +
    23. +

      + Let |algorithm| be a new instance of an {{EcKeyAlgorithm}} object. +

      +
    24. +
    25. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDH`". +

      +
    26. +
    27. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to |namedCurve|. +

      +
    28. +
    29. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    30. +
    +
    +
    If |format| is {{KeyFormat/"raw"}}:
    +
    +
      +
    1. +

      + If the {{EcKeyImportParams/namedCurve}} + member of |normalizedAlgorithm| is not a + named curve, + then [= exception/throw =] a + {{DataError}}. +

      +
    2. +
    3. +

      + If |usages| is not the empty list, + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +
      +
      + If |namedCurve| is "`P-256`", + "`P-384`" or "`P-521`": +
      +
      +
        +
      1. +

        + Let |Q| be the Elliptic Curve public key on the curve identified + by the {{EcKeyImportParams/namedCurve}} + member of |normalizedAlgorithm| identified by performing + the conversion steps defined in Section 2.3.4 of [[SEC1]] to |keyData|. +

        +

        + The uncompressed point format MUST be supported. +

        +
      2. +
      3. +

        + If the implementation does not support the compressed point format and + a compressed point is provided, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If a decode error occurs or an identity point is found, + [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + that represents |Q|. +

        +
      8. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + Perform any [= ECDH key import steps | key import steps =] defined by + other applicable + specifications, passing |format|, |keyData| + and obtaining |key|. +

        +
      2. +
      3. +

        + If an error occured or there are no + applicable + specifications, + [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      +
    6. +
    7. +

      + Let |algorithm| be a new {{EcKeyAlgorithm}} object. +

      +
    8. +
    9. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`ECDH`". +

      +
    10. +
    11. +

      + Set the {{EcKeyAlgorithm/namedCurve}} + attribute of |algorithm| to equal the {{EcKeyImportParams/namedCurve}} member of + |normalizedAlgorithm|. +

      +
    12. +
    13. +

      + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

      +
    16. +
    +
    +
    +
  4. +
  5. +

    + Return |key| +

    +
  6. +
+
-
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData| -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-ecPublicKey` - object identifier defined in [[RFC5480]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is absent, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |params| be the `parameters` field of the - `algorithm` AlgorithmIdentifier field of |spki|. -

      -
    12. -
    13. -

      - If |params| is not an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] that specifies a - `namedCurve`, then [= exception/throw =] a {{DataError}}. -

      -
    14. -
    15. -

      - Let |namedCurve| be a string whose initial value is - undefined. -

      -
    16. -
    17. -
      -
      - If |params| is equivalent to the `secp256r1` - object identifier defined in [[RFC5480]]: -
      -
      -

      - Set |namedCurve| "`P-256`". -

      -
      -
      - If |params| is equivalent to the `secp384r1` - object identifier defined in [[RFC5480]]: -
      -
      -

      - Set |namedCurve| "`P-384`". -

      -
      -
      - If |params| is equivalent to the `secp521r1` - object identifier defined in [[RFC5480]]: -
      -
      -

      - Set |namedCurve| "`P-521`". -

      -
      -
      -
    18. -
    19. -
      -
      If |namedCurve| is not undefined:
      -
      -
        -
      1. -

        - Let |publicKey| be the Elliptic Curve public key identified by - performing the conversion steps defined in Section 2.3.4 of [[SEC1]] using the `subjectPublicKey` - field of |spki|. -

        -

        - The uncompressed point format MUST be supported. -

        -
      2. -
      3. -

        - If the implementation does not support the compressed point format and - a compressed point is provided, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If a decode error occurs or an identity point is found, - [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} - that represents |publicKey|. -

        -
      8. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= ECDSA key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |spki| - and obtaining |namedCurve| and |key|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    20. -
    21. -

      - If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

      -
    22. -
    23. -

      - If the public key value is not a valid point on the Elliptic Curve - identified by the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. -

      -
    24. -
    25. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

      -
    26. -
    27. -

      - Let |algorithm| be a new {{EcKeyAlgorithm}}. -

      -
    28. -
    29. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDSA`". -

      -
    30. -
    31. -

      - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to |namedCurve|. -

      -
    32. -
    33. -

      - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

      -
    34. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-ecPublicKey` object identifier defined in [[RFC5480]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is not present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |params| be the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo|. -

      -
    12. -
    13. -

      - If |params| is not an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] that specifies a - `namedCurve`, then [= exception/throw =] a {{DataError}}. -

      -
    14. -
    15. -

      - Let |namedCurve| be a string whose initial value is - undefined. -

      -
    16. -
    17. -
      -
      - If |params| is equivalent to the `secp256r1` - object identifier defined in [[RFC5480]]: -
      -
      -

      - Set |namedCurve| "`P-256`". -

      -
      -
      - If |params| is equivalent to the `secp384r1` - object identifier defined in [[RFC5480]]: -
      -
      -

      - Set |namedCurve| "`P-384`". -

      -
      -
      - If |params| is equivalent to the `secp521r1` - object identifier defined in [[RFC5480]]: -
      -
      -

      - Set |namedCurve| "`P-521`". -

      -
      -
      -
    18. -
    19. -
      -
      If |namedCurve| is not undefined:
      -
      -
        -
      1. -

        - Let |ecPrivateKey| be the result of performing the [= parse an ASN.1 structure =] - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `ECPrivateKey` structure specified in Section 3 of [[RFC5915]], and |exactData| set to true. -

        -
      2. -
      3. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If the `parameters` field of |ecPrivateKey| is - present, and is not an instance of the `namedCurve` ASN.1 - type defined in [[RFC5480]], or does not contain - the same object identifier as the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo|, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} - that represents the Elliptic Curve private key identified by - performing the conversion steps defined in Section 3 of [[RFC5915]] using |ecPrivateKey|. -

        -
      8. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= ECDSA key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |privateKeyInfo| - and obtaining |namedCurve| and |key|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    20. -
    21. -

      - If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

      -
    22. -
    23. -

      - If the private key value is not a valid point on the Elliptic Curve - identified by the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. -

      -
    24. -
    25. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to {{KeyType/"private"}} -

      -
    26. -
    27. -

      - Let |algorithm| be a new {{EcKeyAlgorithm}}. -

      -
    28. -
    29. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDSA`". -

      -
    30. -
    31. -

      - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to |namedCurve|. -

      -
    32. -
    33. -

      - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

      -
    34. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/Throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field is present and |usages| contains - a value which is not - "`sign`", or, - if the {{JsonWebKey/d}} field is not present and |usages| contains - a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not - "`EC`", - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`sig`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - Let |namedCurve| be a string whose value is equal to the - {{JsonWebKey/crv}} field of |jwk|. -

      -
    14. -
    15. -

      - If |namedCurve| is not equal to the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

      -
    16. -
    17. -
      -
      - If |namedCurve| is equal to "`P-256`", - "`P-384`" or "`P-521`": -
      -
      -
        -
      1. -

        - Let |algNamedCurve| be a string whose initial value is - undefined. -

        -
      2. -
      3. -
        -
        If the {{JsonWebKey/alg}} field is not present:
        -
        - Let |algNamedCurve| be undefined. -
        -
        - If the {{JsonWebKey/alg}} field is equal to the string "ES256": -
        -
        - Let |algNamedCurve| be the string "`P-256`". -
        -
        - If the {{JsonWebKey/alg}} field is equal to the string "ES384": -
        -
        - Let |algNamedCurve| be the string "`P-384`". -
        -
        - If the {{JsonWebKey/alg}} field is equal to the string "ES512": -
        -
        - Let |algNamedCurve| be the string "`P-521`". -
        -
        otherwise:
        -
        - [= exception/throw =] a - {{DataError}}. -
        -
        -
      4. -
      5. -

        - If |algNamedCurve| is defined, and is not equal to - |namedCurve|, [= exception/throw =] a {{DataError}}. -

        -
      6. -
      7. -
        -
        If the {{JsonWebKey/d}} field is present:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of Section - 6.2.2 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Elliptic Curve private key identified by interpreting - |jwk| according to Section 6.2.2 of JSON Web Algorithms [[JWA]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to {{KeyType/"private"}}. -

          -
        6. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of Section - 6.2.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Elliptic Curve public key identified by interpreting - |jwk| according to Section 6.2.1 of JSON Web Algorithms [[JWA]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to "`public`". -

          -
        6. -
        -
        -
        -
      8. -
      -
      -
      - Otherwise: -
      -
      -
        -
      1. -

        - Perform any [= ECDSA key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |jwk| - and obtaining |key|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    18. -
    19. -

      - If the key value is not a valid point on the Elliptic Curve - identified by the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. -

      -
    20. -
    21. -

      - Let |algorithm| be a new instance of an {{EcKeyAlgorithm}} object. -

      -
    22. -
    23. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDSA`". -

      -
    24. -
    25. -

      - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to |namedCurve|. -

      -
    26. -
    27. -

      - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

      -
    28. -
    -
    -
    If |format| is {{KeyFormat/"raw"}}:
    -
    -
      -
    1. -

      - If the {{EcKeyImportParams/namedCurve}} - member of |normalizedAlgorithm| is not a - named curve, - then [= exception/throw =] a - {{DataError}}. -

      -
    2. -
    3. -

      - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -
      -
      - If |namedCurve| is "`P-256`", - "`P-384`" or "`P-521`": -
      -
      -
        -
      1. -

        - Let |Q| be the elliptic curve point on the curve identified - by the {{EcKeyImportParams/namedCurve}} - member of |normalizedAlgorithm| identified by performing - the conversion steps defined in Section 2.3.4 of [[SEC1]] on |keyData|. -

        -

        - The uncompressed point format MUST be supported. -

        -
      2. -
      3. -

        - If the implementation does not support the compressed point format and - a compressed point is provided, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If a decode error occurs or an identity point is found, - [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} - that represents |Q|. -

        -
      8. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - Perform any [= ECDH key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |keyData| - and obtaining |key|. -

        -
      2. -
      3. -

        - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      -
    6. -
    7. -

      - Let |algorithm| be a new {{EcKeyAlgorithm}} object. -

      -
    8. -
    9. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDSA`". -

      -
    10. -
    11. -

      - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to equal the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|. -

      -
    12. -
    13. -

      - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

      -
    16. -
    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  4. -
  5. -

    - Return |key| -

    -
  6. -
-
+
+
Export Key
-
Export Key
-
-
    -
  1. -

    - Let |key| be the {{CryptoKey}} to be - exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `id-ecPublicKey` defined in - [[RFC5480]]. -

          -
        • -
        • -

          - Set the |parameters| field to an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] as follows: -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`", - "`P-384`" or "`P-521`": -
          -
          -

          - Let |keyData| be the - [= byte sequence =] that - represents the Elliptic Curve public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| according to the encoding rules specified in - Section 2.2 of [[RFC5480]] and using the - uncompressed form. and |keyData|. -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`": -
          -
          -

          - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier - `secp256r1` defined in [[RFC5480]] -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-384`": -
          -
          -

          - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier - `secp384r1` defined in [[RFC5480]] -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-521`": -
          -
          -

          - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier - `secp521r1` defined in [[RFC5480]] -

          -
          -
          -
          -
          - Otherwise: -
          -
          -
            -
          1. -

            - Perform any [= ECDSA key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurveOid| and |keyData|. -

            -
          2. -
          3. -

            - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier |namedCurveOid|. -

            -
          4. -
          -
          -
          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to |keyData|. -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| field to the OID - `id-ecPublicKey` defined in - [[RFC5480]]. -

          -
        • -
        • -

          - Set the |parameters| field to an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] as follows: -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`", - "`P-384`" or "`P-521`": -
          -
          -

          - Let |keyData| be the result of DER-encoding - an instance of the `ECPrivateKey` structure defined in - Section 3 of [[RFC5915]] for the Elliptic - Curve private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| and that conforms to the following: -

          -
            -
          • -

            - The |parameters| field is present, and is equivalent - to the |parameters| field of the - |privateKeyAlgorithm| field of this - `PrivateKeyInfo` ASN.1 structure. -

            -
          • -
          • -

            - The |publicKey| field is present and represents the - Elliptic Curve public key associated with the Elliptic Curve - private key represented by the {{CryptoKey/[[handle]]}} internal slot - of |key|. -

            -
          • -
          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`": -
          -
          -

          - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier - `secp256r1` defined in [[RFC5480]] -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-384`": -
          -
          -

          - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier - `secp384r1` defined in [[RFC5480]] -

          -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-521`": -
          -
          -

          - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier - `secp521r1` defined in [[RFC5480]] -

          -
          -
          -
          -
          - Otherwise: -
          -
          -
            -
          1. -

            - Perform any [= ECDSA key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurveOid| and |keyData|. -

            -
          2. -
          3. -

            - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier |namedCurveOid|. -

            -
          4. -
          -
          -
          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to |keyData|. -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be the result of DER-encoding |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

      -
    2. -
    3. -

      - Set the `kty` attribute of |jwk| to - "`EC`". -

      -
    4. -
    5. -
      -
      - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-256`", "`P-384`" or - "`P-521`": -
      -
      -
        -
      1. -
        -
        - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-256`": -
        -
        - Set the {{JsonWebKey/crv}} attribute of |jwk| to - "`P-256`" -
        -
        - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-384`": -
        -
        - Set the {{JsonWebKey/crv}} attribute of |jwk| to - "`P-384`" -
        -
        - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-521`": -
        -
        - Set the {{JsonWebKey/crv}} attribute of |jwk| to - "`P-521`" -
        -
        -
      2. -
      3. -

        - Set the {{JsonWebKey/x}} attribute of |jwk| according to the - definition in Section 6.2.1.2 of JSON Web Algorithms [[JWA]]. -

        -
      4. -
      5. -

        - Set the {{JsonWebKey/y}} attribute of |jwk| according to the - definition in Section 6.2.1.3 of JSON Web Algorithms [[JWA]]. -

        -
      6. -
      7. -
        -
        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is {{KeyType/"private"}} -
        -
        -

        - Set the {{JsonWebKey/d}} attribute of |jwk| according to - the definition in Section 6.2.2.1 of JSON Web Algorithms [[JWA]]. -

        -
        -
        -
      8. -
      -
      -
      - Otherwise: -
      -
      -
        -
      1. -

        - Perform any [= ECDSA key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurve| and a new value of |jwk|. -

        -
      2. -
      3. -

        +

          +
        1. +

          + Let |key| be the {{CryptoKey}} to be + exported. +

          +
        2. +
        3. +

          + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

          +
        4. +
        5. +
          +
          If |format| is {{KeyFormat/"spki"}}:
          +
          +
            +
          1. +

            + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

            +
          2. +
          3. +

            + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

            +
              +
            • +

              + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

              +
                +
              • +

                + Set the |algorithm| field to the OID + `id-ecPublicKey` defined in + [[RFC5480]]. +

                +
              • +
              • +

                + Set the |parameters| field to an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] as follows: +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`", + "`P-384`" or "`P-521`": +
                +
                +

                + Let |keyData| be the [= byte sequence =] that + represents the Elliptic Curve public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| according to the encoding rules specified in + Section 2.3.3 of [[SEC1]] and using the + uncompressed form. +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`": +
                +
                +

                + Set |parameters| to the |namedCurve| choice + with value equal to the object identifier + `secp256r1` defined in [[RFC5480]] +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-384`": +
                +
                +

                + Set |parameters| to the |namedCurve| choice + with value equal to the object identifier + `secp384r1` defined in [[RFC5480]] +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-521`": +
                +
                +

                + Set |parameters| to the |namedCurve| choice + with value equal to the object identifier + `secp521r1` defined in [[RFC5480]] +

                +
                +
                +
                +
                + Otherwise: +
                +
                +
                  +
                1. +

                  + Perform any [= ECDH key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurveOid| and |keyData|. +

                  +
                2. +
                3. +

                  + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier |namedCurveOid|. +

                  +
                4. +
                +
                +
                +
              • +
              +
            • +
            • +

              + Set the |subjectPublicKey| field to |keyData| +

              +
            • +
            +
          4. +
          +
          +
          If |format| is {{KeyFormat/"pkcs8"}}:
          +
          +
            +
          1. +

            + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

            +
          2. +
          3. +

            + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

            +
              +
            • +

              + Set the |version| field to `0`. +

              +
            • +
            • +

              + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

              +
                +
              • +

                + Set the |algorithm| field to the OID + `id-ecPublicKey` defined in + [[RFC5480]]. +

                +
              • +
              • +

                + Set the |parameters| field to an instance of the + `ECParameters` ASN.1 type defined in + [[RFC5480]] as follows: +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`", + "`P-384`" or "`P-521`": +
                +
                +

                + Let |keyData| be the result of DER-encoding + an instance of the `ECPrivateKey` structure defined in + Section 3 of [[RFC5915]] for the Elliptic + Curve private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| and that conforms to the following: +

                +
                  +
                • +

                  + The |parameters| field is present, and is equivalent + to the |parameters| field of the + |privateKeyAlgorithm| field of this + `PrivateKeyInfo` ASN.1 structure. +

                  +
                • +
                • +

                  + The |publicKey| field is present and represents the + Elliptic Curve public key associated with the Elliptic Curve + private key represented by the {{CryptoKey/[[handle]]}} internal slot + of |key|. +

                  +
                • +
                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-256`": +
                +
                +

                + Set |parameters| to the |namedCurve| choice + with value equal to the object identifier + `secp256r1` defined in [[RFC5480]] +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-384`": +
                +
                +

                + Set |parameters| to the |namedCurve| choice + with value equal to the object identifier + `secp384r1` defined in [[RFC5480]] +

                +
                +
                + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} + internal slot of |key| is "`P-521`": +
                +
                +

                + Set |parameters| to the |namedCurve| choice + with value equal to the object identifier + `secp521r1` defined in [[RFC5480]] +

                +
                +
                +
                +
                + Otherwise: +
                +
                +
                  +
                1. +

                  + Perform any [= ECDH key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurveOid| and |keyData|. +

                  +
                2. +
                3. +

                  + Set |parameters| to the `namedCurve` choice + with value equal to the object identifier |namedCurveOid|. +

                  +
                4. +
                +
                +
                +
              • +
              +
            • +
            • +

              + Set the |privateKey| field to |keyData|. +

              +
            • +
            +
          4. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +

            + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

            +
          2. +
          3. +

            + Set the `kty` attribute of |jwk| to + "`EC`". +

            +
          4. +
          5. +
            +
            + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-256`", "`P-384`" + or "`P-521`": +
            +
            +
              +
            1. +
              +
              + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-256`": +
              +
              Set the {{JsonWebKey/crv}} attribute of |jwk| to - |namedCurve|. -

              -
            2. -
            -
            -
            -
          6. -
          7. -

            - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

            -
          8. -
          9. -

            - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

            -
          10. -
          11. -

            - Let |result| be |jwk|. -

            -
          12. -
          -
          -
          - If |format| is {{KeyFormat/"raw"}}: -
          -
          -
            -
          1. -

            - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

            -
          2. -
          3. -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-256`", "`P-384`" - or "`P-521`": -
            -
            -

            - Let |data| be a [= byte sequence =] representing the Elliptic Curve - point |Q| represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| according to [[SEC1]] 2.3.3 using the uncompressed format. -

            -
            -
            Otherwise:
            -
            -

            - Perform any [= ECDH key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurve| and |data|. -

            -
            -
            -
          4. -
          5. -

            - Let |result| be |data|. -

            -
          6. -
          -
          -
          Otherwise:
          -
          -

          - [= exception/throw =] a - {{NotSupportedError}}. -

          -
          -
          -
        6. -
        7. -

          - Return |result|. -

          -
        8. -
        -
      -
      + "`P-256`" +
    +
    + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-384`": +
    +
    + Set the {{JsonWebKey/crv}} attribute of |jwk| to + "`P-384`" +
    +
    + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-521`": +
    +
    + Set the {{JsonWebKey/crv}} attribute of |jwk| to + "`P-521`" +
    +
    +
  6. +
  7. +

    + Set the {{JsonWebKey/x}} attribute of |jwk| according to the + definition in Section 6.2.1.2 of JSON Web Algorithms [[JWA]]. +

    +
  8. +
  9. +

    + Set the {{JsonWebKey/y}} attribute of |jwk| according to the + definition in Section 6.2.1.3 of JSON Web Algorithms [[JWA]]. +

    +
  10. +
  11. +
    +
    + If the {{CryptoKey/[[type]]}} internal slot + of |key| is {{KeyType/"private"}} +
    +
    +

    + Set the {{JsonWebKey/d}} attribute of |jwk| according to the + definition in Section 6.2.2.1 of JSON Web Algorithms [[JWA]]. +

    +
    +
    +
  12. +
+
+
+ Otherwise: +
+
+
    +
  1. +

    + Perform any [= ECDH key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurve| and a new value of |jwk|. +

    +
  2. +
  3. +

    + Set the {{JsonWebKey/crv}} attribute of |jwk| to + |namedCurve|. +

    +
  4. +
+
+ + +
  • +

    + Set the `key_ops` attribute of |jwk| to the + {{CryptoKey/usages}} attribute of |key|. +

    +
  • +
  • +

    + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

    +
  • +
  • +

    + Let |result| be |jwk|. +

    +
  • + + +
    + If |format| is {{KeyFormat/"raw"}}: +
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +
      +
      + If the {{EcKeyAlgorithm/namedCurve}} + attribute of the {{CryptoKey/[[algorithm]]}} internal slot + of |key| is "`P-256`", "`P-384`" + or "`P-521`": +
      +
      +

      + Let |data| be the [= byte sequence =] that + represents the Elliptic Curve public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| according to the encoding rules specified in + Section 2.3.3 of [[SEC1]] and using the + uncompressed form. +

      +
      +
      Otherwise:
      +
      +

      + Perform any [= ECDH key export steps | key export steps =] + defined by other applicable + specifications, passing |format| and the + {{EcKeyAlgorithm/namedCurve}} attribute of + the {{CryptoKey/[[algorithm]]}} + internal slot of |key| + and obtaining |namedCurve| and |data|. +

      +
      +
      +
    4. +
    5. +

      + Let |result| be |data|. +

      +
    6. +
    +
    + + +
  • +

    + Return |result|. +

    +
  • + +
    -
    -

    ECDH

    -
    +
    +

    Ed25519

    +

    Description

    - This describes using Elliptic Curve Diffie-Hellman (ECDH) for key generation and key - agreement, as specified by [[RFC6090]]. -

    -

    - Other specifications - may specify the use of additional elliptic curves with ECDH. - To specify an additional elliptic curve a specification must define - the curve name, - ECDH generation steps, - ECDH derivation steps, - ECDH key import steps and - ECDH key export steps. + The "`Ed25519`" algorithm identifier is used to perform signing + and verification using the Ed25519 algorithm specified in + [[RFC8032]].

    -
    +

    Registration

    The [= recognized algorithm name =] for - this algorithm is "`ECDH`". + this algorithm is "`Ed25519`".

    @@ -8734,18 +10312,23 @@

    Registration

    - - - + + + - - - + + + + + + + + - + @@ -8756,1529 +10339,846 @@

    Registration

    generateKey{{EcKeyGenParams}}{{CryptoKeyPair}}signNone[= byte sequence =]
    deriveBits{{EcdhKeyDeriveParams}}[= byte sequence =]verifyNoneboolean
    generateKeyNone{{CryptoKeyPair}}
    importKey{{EcKeyImportParams}}None {{CryptoKey}}
    -
    -

    EcdhKeyDeriveParams dictionary

    -
    -dictionary EcdhKeyDeriveParams : Algorithm {
    -  required CryptoKey public;
    -};
    -          
    -

    The public member represents the peer's EC public key.

    -
    -
    + +

    Operations

    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -
      -
      - If the {{EcKeyGenParams/namedCurve}} member of - |normalizedAlgorithm| is "`P-256`", "`P-384`" - or "`P-521`": -
      -
      -

      - Generate an Elliptic Curve key pair, as defined in [[RFC6090]] with domain parameters for the curve identified by - the {{EcKeyGenParams/namedCurve}} member of - |normalizedAlgorithm|. -

      -
      -
      - If the {{EcKeyGenParams/namedCurve}} member of - |normalizedAlgorithm| is a value specified in an - applicable specification that - specifies the use of that value with ECDH: -
      -
      -

      - Perform the [= ECDH - generation steps =] specified in that specification, passing in - |normalizedAlgorithm| and resulting in an elliptic curve key pair. -

      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}} -

      -
      -
      -
    4. -
    5. -

      - If performing the operation results in an error, - then [= exception/throw =] a - {{OperationError}}. -

      -
    6. -
    7. -

      - Let |algorithm| be a new - {{EcKeyAlgorithm}} - object. -

      -
    8. -
    9. -

      - Set the {{Algorithm/name}} member of - |algorithm| to "`ECDH`". -

      -
    10. -
    11. -

      - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to equal the - {{namedCurve}} member of - |normalizedAlgorithm|. -

      -
    12. -
    13. -

      - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |publicKey| to |algorithm|. -

      -
    18. -
    19. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |publicKey| to true. -

      -
    20. -
    21. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the empty list. -

      -
    22. -
    23. -

      - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

      -
    24. -
    25. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

      -
    26. -
    27. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |privateKey| to |algorithm|. -

      -
    28. -
    29. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |privateKey| to |extractable|. -

      -
    30. -
    31. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the - [= usage intersection =] of - |usages| and `[ "deriveKey", "deriveBits" ]`. -

      -
    32. -
    33. -

      - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

      -
    34. -
    35. -

      - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

      -
    36. -
    37. -

      - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

      -
    38. -
    39. + +
      +
      Sign
      + +
        +
      1. +

        + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

        +
      2. +
      3. +

        + Let |result| be the result of performing the Ed25519 + signing process, as specified in [[RFC8032]], + Section 5.1.6, with |message| as |M|, + using the Ed25519 private key associated with |key|. +

        +

        - Return |result|. + Some implementations may (wish to) generate randomized signatures + as per draft-irtf-cfrg-det-sigs-with-noise + instead of deterministic signatures as per [[RFC8032]].

        -
      4. -
      -
    -
    Derive Bits
    -
    -
      -
    1. - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. + See WICG/webcrypto-secure-curves issue 28.

      -
    2. -
    3. + +
    4. +
    5. +

      + Return |result|. +

      +
    6. +
    +
    + +
    +
    Verify
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"public"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the key data of |key| represents an invalid point or a small-order element + on the Elliptic Curve of Ed25519, return `false`. +

      +

      - Let |publicKey| be the - {{EcdhKeyDeriveParams/public}} member of - |normalizedAlgorithm|. + Not all implementations perform this check.

      -
    4. -
    5. - If the {{CryptoKey/[[type]]}} internal slot of - |publicKey| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. + See WICG/webcrypto-secure-curves issue 27.

      -
    6. -
    7. + +
    8. +
    9. +

      + If the point R, encoded in the first half of |signature|, + represents an invalid point or a small-order element + on the Elliptic Curve of Ed25519, return `false`. +

      +

      - If the {{KeyAlgorithm/name}} attribute of - the {{CryptoKey/[[algorithm]]}} internal slot of - |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the {{CryptoKey/[[algorithm]]}} internal slot of - |key|, then [= exception/throw =] an {{InvalidAccessError}}. + Not all implementations perform this check.

      -
    10. -
    11. - If the {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} internal slot of - |publicKey| is not equal to the {{EcKeyAlgorithm/namedCurve}} property of the {{CryptoKey/[[algorithm]]}} internal slot of - |key|, then [= exception/throw =] an {{InvalidAccessError}}. + See WICG/webcrypto-secure-curves issue 27.

      -
    12. -
    13. -
      -
      - If the {{EcKeyAlgorithm/namedCurve}} property of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| is "`P-256`", "`P-384`" - or "`P-521`": -
      -
      -
        -
      1. -

        - Perform the ECDH primitive specified in [[RFC6090]] Section - 4 with |key| as the EC private key |d| and the EC public - key represented by the {{CryptoKey/[[handle]]}} - internal slot of |publicKey| as the EC public key. -

        -
      2. -
      3. -

        - Let |secret| be a [= byte sequence =] containing - the result of applying the field element to - octet string conversion defined in Section - 6.2 of [[RFC6090]] - to the output of the ECDH primitive. -

        -
      4. -
      -
      -
      - If the {{EcKeyAlgorithm/namedCurve}} property of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| is a value specified in an - applicable specification that - specifies the use of that value with ECDH: -
      -
      -

      - Perform the [= ECDH - derivation steps =] specified in that specification, passing in - |key| and |publicKey| and resulting in |secret|. -

      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}} -

      -
      -
      + +
    14. +
    15. +

      + Perform the Ed25519 verification steps, as specified in [[RFC8032]], + Section 5.1.7, using the cofactorless (unbatched) equation, + `[S]B = R + [k]A'`, on the |signature|, with |message| as |M|, + using the Ed25519 public key associated with |key|. +

      +
    16. +
    17. +

      + Let |result| be a boolean with the value `true` if the signature is valid + and the value `false` otherwise. +

      +
    18. +
    19. +

      + Return |result|. +

      +
    20. +
    +
    - -
  • -

    - If performing the operation results in an error, - then [= exception/throw =] a - {{OperationError}}. -

    -
  • -
  • -
    -
    If |length| is null:
    -
    Return |secret|
    -
    Otherwise:
    -
    -
    -
    - If the [= length in bits =] of |secret| is less than - |length|: -
    -
    - [= exception/throw =] an - {{OperationError}}. -
    -
    Otherwise:
    -
    - Return a [= byte sequence containing =] the first |length| bits of |secret|. -
    -
    -
    -
    -
  • - - +
    +
    Generate Key
    + +
      +
    1. +

      + If |usages| contains a value which is not + one of "`sign`" or "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Generate an Ed25519 key pair, as defined in [[RFC8032]], section 5.1.5. +

      +
    4. +
    5. +

      + Let |algorithm| be a new {{KeyAlgorithm}} object. +

      +
    6. +
    7. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed25519`". +

      +
    8. +
    9. +

      + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

      +
    10. +
    11. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

      +
    12. +
    13. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |publicKey| to |algorithm|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |publicKey| to true. +

      +
    16. +
    17. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the [= usage intersection =] + of |usages| and `[ "verify" ]`. +

      +
    18. +
    19. +

      + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

      +
    20. +
    21. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

      +
    22. +
    23. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |privateKey| to |algorithm|. +

      +
    24. +
    25. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |privateKey| to |extractable|. +

      +
    26. +
    27. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the [= usage intersection =] + of |usages| and `[ "sign" ]`. +

      +
    28. +
    29. +

      + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

      +
    30. +
    31. +

      + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

      +
    32. +
    33. +

      + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

      +
    34. +
    35. +

      + Return |result|. +

      +
    36. +
    +
    + +
    +
    Import Key
    + +
      +
    1. +

      Let |keyData| be the key data to be imported.

      +
    2. +
    3. +
      +
      If |format| is {{KeyFormat/"spki"}}:
      +
      +
        +
      1. +

        + If |usages| contains a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData|. +

        +
      4. +
      5. +

        + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `id-Ed25519` + object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

        +
      8. +
      9. +

        + If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is present, + then [= exception/throw =] a + {{DataError}}. +

        +
      10. +
      11. +

        + Let |publicKey| be the Ed25519 public key identified by + the `subjectPublicKey` field of |spki|. +

        +
      12. +
      13. +

        + Let |key| be a new {{CryptoKey}} + that represents |publicKey|. +

        +
      14. +
      15. +

        + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

        +
      16. +
      17. +

        + Let |algorithm| be a new {{KeyAlgorithm}}. +

        +
      18. +
      19. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed25519`". +

        +
      20. +
      21. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      22. +
      +
      +
      If |format| is {{KeyFormat/"pkcs8"}}:
      +
      +
        +
      1. +

        + If |usages| contains a value which is not + "`sign`" + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

        +
      4. +
      5. +

        + If an error occurs while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `id-Ed25519` object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

        +
      8. +
      9. +

        + If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is present, + then [= exception/throw =] a + {{DataError}}. +

        +
      10. +
      11. +

        + Let |curvePrivateKey| be the result of performing the + [= parse an ASN.1 structure =] + algorithm, with |data| as the `privateKey` field + of |privateKeyInfo|, |structure| as the ASN.1 + `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. +

        +
      12. +
      13. +

        + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      14. +
      15. +

        + Let |key| be a new {{CryptoKey}} + that represents the Ed25519 private key identified by |curvePrivateKey|. +

        +
      16. +
      17. +

        + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to {{KeyType/"private"}} +

        +
      18. +
      19. +

        + Let |algorithm| be a new {{KeyAlgorithm}}. +

        +
      20. +
      21. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed25519`". +

        +
      22. +
      23. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      24. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +
        +
        If |keyData| is a {{JsonWebKey}} dictionary:
        +

        Let |jwk| equal |keyData|.

        +
        Otherwise:
        +

        [= exception/Throw =] a {{DataError}}.

        +
        +
      2. +
      3. +

        + If the {{JsonWebKey/d}} field is present and |usages| contains + a value which is not + "`sign`", or, + if the {{JsonWebKey/d}} field is not present and |usages| contains + a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      4. +
      5. +

        + If the {{JsonWebKey/kty}} field of |jwk| is not + "`OKP`", + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + If the {{JsonWebKey/crv}} field of |jwk| is not + "`Ed25519`", + then [= exception/throw =] a + {{DataError}}. +

        +
      8. +
      9. +

        + If the {{JsonWebKey/alg}} field of |jwk| is present and is + not "`Ed25519`" or "`EdDSA`", + then [= exception/throw =] a + {{DataError}}. +

        +
      10. +
      11. +

        + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`sig`", + then [= exception/throw =] a + {{DataError}}. +

        +
      12. +
      13. +

        + If the {{JsonWebKey/key_ops}} field of |jwk| is present, and + is invalid according to the requirements of JSON Web + Key [[JWK]], or it does not contain all of the specified |usages| + values, + then [= exception/throw =] a + {{DataError}}. +

        +
      14. +
      15. +

        + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

        +
      16. +
      17. +
        +
        If the {{JsonWebKey/d}} field is present:
        +
        +
          +
        1. +

          + If |jwk| does not meet the requirements of + the JWK private key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

          +
        2. +
        3. +

          + Let |key| be a new {{CryptoKey}} object that represents the + Ed25519 private key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

          +
        4. +
        5. +

          + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to {{KeyType/"private"}}. +

          +
        6. +
        +
        +
        Otherwise:
        +
        +
          +
        1. +

          + If |jwk| does not meet the requirements of + the JWK public key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

          +
        2. +
        3. +

          + Let |key| be a new {{CryptoKey}} object that represents the + Ed25519 public key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

          +
        4. +
        5. +

          + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to {{KeyType/"public"}}. +

          +
        6. +
        +
        +
        +
      18. +
      19. +

        + Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. +

        +
      20. +
      21. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed25519`". +

        +
      22. +
      23. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      24. +
      +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + If |usages| contains a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + Let |algorithm| be a new {{KeyAlgorithm}} object. +

        +
      4. +
      5. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed25519`". +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + representing the key data provided in |keyData|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

        +
      10. +
      11. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      12. +
      +
      +
      Otherwise:
      +
      +

      + [= exception/throw =] a + {{NotSupportedError}}. +

      +
      +
      +
    4. +
    5. +

      + Return |key| +

      +
    6. +
    +
    -
    Import Key
    -
    -
      -
    1. -

      Let |keyData| be the key data to be imported.

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData| -

        -
      4. -
      5. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-ecPublicKey` - object identifier defined in [[RFC5480]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is absent, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |params| be the `parameters` field of the - `algorithm` AlgorithmIdentifier field of |spki|. -

        -
      12. -
      13. -

        - If |params| is not an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] that specifies a - `namedCurve`, then [= exception/throw =] a {{DataError}}. -

        -
      14. -
      15. -

        - Let |namedCurve| be a string whose initial value is - undefined. -

        -
      16. -
      17. -
        -
        - If |params| is equivalent to the `secp256r1` - object identifier defined in [[RFC5480]]: -
        -
        -

        - Set |namedCurve| "`P-256`". -

        -
        -
        - If |params| is equivalent to the `secp384r1` - object identifier defined in [[RFC5480]]: -
        -
        -

        - Set |namedCurve| "`P-384`". -

        -
        -
        - If |params| is equivalent to the `secp521r1` - object identifier defined in [[RFC5480]]: -
        -
        -

        - Set |namedCurve| "`P-521`". -

        -
        -
        -
      18. -
      19. -
        -
        If |namedCurve| is not undefined:
        -
        -
          -
        1. -

          - Let |publicKey| be the Elliptic Curve public key identified by - performing the conversion steps defined in Section 2.3.4 of [[SEC1]] to the `subjectPublicKey` field of - |spki|. -

          -

          - The uncompressed point format MUST be supported. -

          -
        2. -
        3. -

          - If the implementation does not support the compressed point format and - a compressed point is provided, - [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        5. -

          - If a decode error occurs or an identity point is found, - [= exception/throw =] a - {{DataError}}. -

          -
        6. -
        7. -

          - Let |key| be a new {{CryptoKey}} - that represents |publicKey|. -

          -
        8. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - Perform any [= ECDH key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |spki| - and obtaining |namedCurve| and |key|. -

          -
        2. -
        3. -

          - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        -
        -
        -
      20. -
      21. -

        - If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

        -
      22. -
      23. -

        - If the key value is not a valid point on the Elliptic Curve - identified by the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. -

        -
      24. -
      25. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

        -
      26. -
      27. -

        - Let |algorithm| be a new {{EcKeyAlgorithm}}. -

        -
      28. -
      29. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDH`". -

        -
      30. -
      31. -

        - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to |namedCurve|. -

        -
      32. -
      33. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      34. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurs while parsing, - [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-ecPublicKey` object identifier - defined in [[RFC5480]], - [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is not present, - [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |params| be the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo|. -

        -
      12. -
      13. -

        - If |params| is not an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] that specifies a - `namedCurve`, then [= exception/throw =] a {{DataError}}. -

        -
      14. -
      15. -

        - Let |namedCurve| be a string whose initial value is - undefined. -

        -
      16. -
      17. -
        -
        - If |params| is equivalent to the `secp256r1` - object identifier defined in [[RFC5480]]: -
        -
        -

        - Set |namedCurve| to "`P-256`". -

        -
        -
        - If |params| is equivalent to the `secp384r1` - object identifier defined in [[RFC5480]]: -
        -
        -

        - Set |namedCurve| to "`P-384`". -

        -
        -
        - If |params| is equivalent to the `secp521r1` - object identifier defined in [[RFC5480]]: -
        -
        -

        - Set |namedCurve| to "`P-521`". -

        -
        -
        -
      18. -
      19. -
        -
        If |namedCurve| is not undefined:
        -
        -
          -
        1. -

          - Let |ecPrivateKey| be the result of performing the - [= parse an ASN.1 structure =] - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `ECPrivateKey` structure specified in Section 3 of - [[RFC5915]], and |exactData| set to true. -

          -
        2. -
        3. -

          - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        5. -

          - If the `parameters` field of |ecPrivateKey| is - present, and is not an instance of the `namedCurve` ASN.1 - type defined in [[RFC5480]], or does not contain - the same object identifier as the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo|, - [= exception/throw =] a - {{DataError}}. -

          -
        6. -
        7. -

          - Let |key| be a new {{CryptoKey}} - that represents the Elliptic Curve private key identified by - performing the conversion steps defined in Section 3 of [[RFC5915]] using |ecPrivateKey|. -

          -
        8. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - Perform any [= ECDH key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |privateKeyInfo| - and obtaining |namedCurve| and |key|. -

          -
        2. -
        3. -

          - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        -
        -
        -
      20. -
      21. -

        - If |namedCurve| is defined, and not equal to the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

        -
      22. -
      23. -

        - If the key value is not a valid point on the Elliptic Curve - identified by the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. -

        -
      24. -
      25. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to {{KeyType/"private"}}. -

        -
      26. -
      27. -

        - Let |algorithm| be a new {{EcKeyAlgorithm}}. -

        -
      28. -
      29. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDH`". -

        -
      30. -
      31. -

        - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to |namedCurve|. -

        -
      32. -
      33. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      34. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/d}} field is present and if |usages| - contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      4. -
      5. -

        - If the {{JsonWebKey/d}} field is not present and if |usages| is not - empty - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      6. -
      7. -

        - If the {{JsonWebKey/kty}} field of |jwk| is - not "`EC`", - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present - and is not equal to "`enc`" then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, then [= exception/throw =] a {{DataError}}. -

        -
      12. -
      13. -

        - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - Let |namedCurve| be a string whose value is equal to the - {{JsonWebKey/crv}} field of |jwk|. -

        -
      16. -
      17. -

        - If |namedCurve| is not equal to the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|, [= exception/throw =] a {{DataError}}. -

        -
      18. -
      19. -
        -
        - If |namedCurve| is "`P-256`", - "`P-384`" or "`P-521`": -
        -
        -
        -
        If the {{JsonWebKey/d}} field is present:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of Section - 6.2.2 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Elliptic Curve private key identified by interpreting - |jwk| according to Section 6.2.2 of JSON Web Algorithms [[JWA]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to {{KeyType/"private"}}. -

          -
        6. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of Section - 6.2.1 of JSON Web Algorithms [[JWA]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Elliptic Curve public key identified by interpreting - |jwk| according to Section 6.2.1 of JSON Web Algorithms [[JWA]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to "`public`". -

          -
        6. -
        -
        -
        -
        -
        Otherwise
        -
        -
          -
        1. -

          - Perform any [= ECDH key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |jwk| - and obtaining |key|. -

          -
        2. -
        3. -

          - If an error occurred or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        -
        -
        -
      20. -
      21. -

        - If the key value is not a valid point on the Elliptic Curve - identified by the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm| [= exception/throw =] a {{DataError}}. -

        -
      22. -
      23. -

        - Let |algorithm| be a new instance of an {{EcKeyAlgorithm}} object. -

        -
      24. -
      25. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDH`". -

        -
      26. -
      27. -

        - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to |namedCurve|. -

        -
      28. -
      29. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      30. -
      -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - If the {{EcKeyImportParams/namedCurve}} - member of |normalizedAlgorithm| is not a - named curve, - then [= exception/throw =] a - {{DataError}}. -

        -
      2. -
      3. -

        - If |usages| is not the empty list, - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      4. -
      5. -
        -
        - If |namedCurve| is "`P-256`", - "`P-384`" or "`P-521`": -
        -
        -
          -
        1. -

          - Let |Q| be the Elliptic Curve public key on the curve identified - by the {{EcKeyImportParams/namedCurve}} - member of |normalizedAlgorithm| identified by performing - the conversion steps defined in Section 2.3.4 of [[SEC1]] to |keyData|. -

          -

          - The uncompressed point format MUST be supported. -

          -
        2. -
        3. -

          - If the implementation does not support the compressed point format and - a compressed point is provided, - [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        5. -

          - If a decode error occurs or an identity point is found, - [= exception/throw =] a - {{DataError}}. -

          -
        6. -
        7. -

          - Let |key| be a new {{CryptoKey}} - that represents |Q|. -

          -
        8. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - Perform any [= ECDH key import steps | key import steps =] defined by - other applicable - specifications, passing |format|, |keyData| - and obtaining |key|. -

          -
        2. -
        3. -

          - If an error occured or there are no - applicable - specifications, - [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        -
        -
        -
      6. -
      7. -

        - Let |algorithm| be a new {{EcKeyAlgorithm}} object. -

        -
      8. -
      9. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`ECDH`". -

        -
      10. -
      11. -

        - Set the {{EcKeyAlgorithm/namedCurve}} - attribute of |algorithm| to equal the {{EcKeyImportParams/namedCurve}} member of - |normalizedAlgorithm|. -

        -
      12. -
      13. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

        -
      14. -
      15. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      16. -
      -
      -
      -
    4. -
    5. -

      - Return |key| -

      -
    6. -
    -
    +
    +
    Export Key
    -
    Export Key
    -
    -
      -
    1. -

      - Let |key| be the {{CryptoKey}} to be - exported. -

      -
    2. -
    3. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

        -
      2. -
      3. -

        - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

        -
          -
        • -

          - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

          -
            -
          • -

            - Set the |algorithm| field to the OID - `id-ecPublicKey` defined in - [[RFC5480]]. -

            -
          • -
          • -

            - Set the |parameters| field to an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] as follows: -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`", - "`P-384`" or "`P-521`": -
            -
            -

            - Let |keyData| be the [= byte sequence =] that - represents the Elliptic Curve public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| according to the encoding rules specified in - Section 2.3.3 of [[SEC1]] and using the - uncompressed form. -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`": -
            -
            -

            - Set |parameters| to the |namedCurve| choice - with value equal to the object identifier - `secp256r1` defined in [[RFC5480]] -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-384`": -
            -
            -

            - Set |parameters| to the |namedCurve| choice - with value equal to the object identifier - `secp384r1` defined in [[RFC5480]] -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-521`": -
            -
            -

            - Set |parameters| to the |namedCurve| choice - with value equal to the object identifier - `secp521r1` defined in [[RFC5480]] -

            -
            -
            -
            -
            - Otherwise: -
            -
            -
              -
            1. -

              - Perform any [= ECDH key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurveOid| and |keyData|. -

              -
            2. -
            3. -

              - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier |namedCurveOid|. -

              -
            4. -
            -
            -
            -
          • -
          -
        • -
        • -

          - Set the |subjectPublicKey| field to |keyData| -

          -
        • -
        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

        -
      2. -
      3. -

        - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

        -
          -
        • -

          - Set the |version| field to `0`. -

          -
        • -
        • -

          - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

          -
            -
          • -

            - Set the |algorithm| field to the OID - `id-ecPublicKey` defined in - [[RFC5480]]. -

            -
          • -
          • -

            - Set the |parameters| field to an instance of the - `ECParameters` ASN.1 type defined in - [[RFC5480]] as follows: -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`", - "`P-384`" or "`P-521`": -
            -
            -

            - Let |keyData| be the result of DER-encoding - an instance of the `ECPrivateKey` structure defined in - Section 3 of [[RFC5915]] for the Elliptic - Curve private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| and that conforms to the following: -

            -
              -
            • -

              - The |parameters| field is present, and is equivalent - to the |parameters| field of the - |privateKeyAlgorithm| field of this - `PrivateKeyInfo` ASN.1 structure. -

              -
            • -
            • -

              - The |publicKey| field is present and represents the - Elliptic Curve public key associated with the Elliptic Curve - private key represented by the {{CryptoKey/[[handle]]}} internal slot - of |key|. -

              -
            • -
            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-256`": -
            -
            -

            - Set |parameters| to the |namedCurve| choice - with value equal to the object identifier - `secp256r1` defined in [[RFC5480]] -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-384`": -
            -
            -

            - Set |parameters| to the |namedCurve| choice - with value equal to the object identifier - `secp384r1` defined in [[RFC5480]] -

            -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} - internal slot of |key| is "`P-521`": -
            -
            -

            - Set |parameters| to the |namedCurve| choice - with value equal to the object identifier - `secp521r1` defined in [[RFC5480]] -

            -
            -
            -
            -
            - Otherwise: -
            -
            -
              -
            1. -

              - Perform any [= ECDH key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurveOid| and |keyData|. -

              -
            2. -
            3. -

              - Set |parameters| to the `namedCurve` choice - with value equal to the object identifier |namedCurveOid|. -

              -
            4. -
            -
            -
            -
          • -
          -
        • -
        • -

          - Set the |privateKey| field to |keyData|. -

          -
        • -
        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to - "`EC`". -

        -
      4. -
      5. -
        -
        - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-256`", "`P-384`" - or "`P-521`": -
        -
        -
          -
        1. -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-256`": -
          -
          - Set the {{JsonWebKey/crv}} attribute of |jwk| to - "`P-256`" -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-384`": -
          -
          - Set the {{JsonWebKey/crv}} attribute of |jwk| to - "`P-384`" -
          -
          - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-521`": -
          -
          - Set the {{JsonWebKey/crv}} attribute of |jwk| to - "`P-521`" -
          -
          -
        2. -
        3. -

          - Set the {{JsonWebKey/x}} attribute of |jwk| according to the - definition in Section 6.2.1.2 of JSON Web Algorithms [[JWA]]. -

          -
        4. -
        5. -

          - Set the {{JsonWebKey/y}} attribute of |jwk| according to the - definition in Section 6.2.1.3 of JSON Web Algorithms [[JWA]]. -

          -
        6. -
        7. -
          -
          - If the {{CryptoKey/[[type]]}} internal slot - of |key| is {{KeyType/"private"}} -
          -
          -

          - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 6.2.2.1 of JSON Web Algorithms [[JWA]]. -

          -
          -
          -
        8. -
        -
        -
        - Otherwise: -
        -
        -
          -
        1. -

          - Perform any [= ECDH key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurve| and a new value of |jwk|. -

          -
        2. -
        3. -

          - Set the {{JsonWebKey/crv}} attribute of |jwk| to - |namedCurve|. -

          -
        4. -
        -
        -
        -
      6. -
      7. -

        - Set the `key_ops` attribute of |jwk| to the - {{CryptoKey/usages}} attribute of |key|. -

        -
      8. -
      9. -

        - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

        -
      10. -
      11. -

        - Let |result| be |jwk|. -

        -
      12. -
      -
      -
      - If |format| is {{KeyFormat/"raw"}}: -
      -
      -
        -
      1. -

        +

          +
        1. +

          + Let |key| be the {{CryptoKey}} to be + exported. +

          +
        2. +
        3. +

          + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

          +
        4. +
        5. +
          +
          If |format| is {{KeyFormat/"spki"}}:
          +
          +
            +
          1. +

            + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

            +
          2. +
          3. +

            + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

            +
              +
            • +

              + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

              +
                +
              • +

                + Set the |algorithm| object identifier to the + `id-Ed25519` OID defined in [[RFC8410]]. +

                +
              • +
              +
            • +
            • +

              + Set the |subjectPublicKey| field to |keyData|. +

              +
            • +
            +
          4. +
          5. +

            + Let |result| be the result of DER-encoding |data|. +

            +
          6. +
          +
          +
          If |format| is {{KeyFormat/"pkcs8"}}:
          +
          +
            +
          1. +

            + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

            +
          2. +
          3. +

            + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

            +
              +
            • +

              + Set the |version| field to `0`. +

              +
            • +
            • +

              + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

              +
                +
              • +

                + Set the |algorithm| object identifier to the + `id-Ed25519` OID defined in [[RFC8410]]. +

                +
              • +
              +
            • +
            • +

              + Set the |privateKey| field to the result of DER-encoding + a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the + Ed25519 private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

              +
            • +
            +
          4. +
          5. +

            + Let |result| be the result of DER-encoding |data|. +

            +
          6. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +

            + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

            +
          2. +
          3. +

            + Set the `kty` attribute of |jwk| to + "`OKP`". +

            +
          4. +
          5. +

            + Set the `alg` attribute of |jwk| to + "`Ed25519`". +

            +
          6. +
          7. +

            + Set the `crv` attribute of |jwk| to + "`Ed25519`". +

            +
          8. +
          9. +

            + Set the {{JsonWebKey/x}} attribute of |jwk| according to the + definition in Section 2 of [[RFC8037]]. +

            +
          10. +
          11. +
            +
            If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

            -
          12. -
          13. -
            -
            - If the {{EcKeyAlgorithm/namedCurve}} - attribute of the {{CryptoKey/[[algorithm]]}} internal slot - of |key| is "`P-256`", "`P-384`" - or "`P-521`": -
            -
            -

            - Let |data| be the [= byte sequence =] that - represents the Elliptic Curve public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| according to the encoding rules specified in - Section 2.3.3 of [[SEC1]] and using the - uncompressed form. -

            -
            -
            Otherwise:
            -
            -

            - Perform any [= ECDH key export steps | key export steps =] - defined by other applicable - specifications, passing |format| and the - {{EcKeyAlgorithm/namedCurve}} attribute of - the {{CryptoKey/[[algorithm]]}} - internal slot of |key| - and obtaining |namedCurve| and |data|. -

            -
            -
            -
          14. -
          15. -

            - Let |result| be |data|. -

            -
          16. -
          -
          -
          -
        6. -
        7. -

          - Return |result|. -

          -
        8. -
        -
      -
      + of |key| is {{KeyType/"private"}} + +
      + Set the {{JsonWebKey/d}} attribute of |jwk| according to the + definition in Section 2 of [[RFC8037]]. +
      + +
    6. +
    7. +

      + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

      +
    8. +
    9. +

      + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

      +
    10. +
    11. +

      + Let |result| be |jwk|. +

      +
    12. +
    +
    +
    + If |format| is {{KeyFormat/"raw"}}: +
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be a [= byte sequence =] representing the Ed25519 + public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

      +
    4. +
    5. +

      + Let |result| be |data|. +

      +
    6. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    + + +
  • +

    + Return |result|. +

    +
  • + +
    -
    -

    Ed25519

    -
    +
    +

    X25519

    +

    Description

    - The "`Ed25519`" algorithm identifier is used to perform signing - and verification using the Ed25519 algorithm specified in - [[RFC8032]]. + The "`X25519`" algorithm identifier is used to perform + key agreement using the X25519 algorithm specified in + [[RFC7748]].

    -
    +

    Registration

    The [= recognized algorithm name =] for - this algorithm is "`Ed25519`". + this algorithm is "`X25519`".

    @@ -10290,15 +11190,10 @@

    Registration

    - - + + - - - - - @@ -10318,841 +11213,810 @@

    Registration

    signNonederiveBits{{EcdhKeyDeriveParams}} [= byte sequence =]
    verifyNoneboolean
    generateKey None
    -
    -

    Operations

    -
    -
    Sign
    -
    - When signing, the following algorithm should be used: -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |result| be the result of performing the Ed25519 - signing process, as specified in [[RFC8032]], - Section 5.1.6, with |message| as |M|, - using the Ed25519 private key associated with |key|. -

      -
      -

      - Some implementations may (wish to) generate randomized signatures - as per draft-irtf-cfrg-det-sigs-with-noise - instead of deterministic signatures as per [[RFC8032]]. -

      -

      - See WICG/webcrypto-secure-curves issue 28. -

      -
      -
    4. -
    5. -

      - Return |result|. -

      -
    6. -
    -
    -
    Verify
    -
    - When verifying, the following algorithm should be used: -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"public"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - If the key data of |key| represents an invalid point or a small-order element - on the Elliptic Curve of Ed25519, return `false`. -

      -
      -

      - Not all implementations perform this check. -

      -

      - See WICG/webcrypto-secure-curves issue 27. -

      -
      -
    4. -
    5. -

      - If the point R, encoded in the first half of |signature|, - represents an invalid point or a small-order element - on the Elliptic Curve of Ed25519, return `false`. -

      -
      -

      - Not all implementations perform this check. -

      -

      - See WICG/webcrypto-secure-curves issue 27. -

      -
      -
    6. -
    7. -

      - Perform the Ed25519 verification steps, as specified in [[RFC8032]], - Section 5.1.7, using the cofactorless (unbatched) equation, - `[S]B = R + [k]A'`, on the |signature|, with |message| as |M|, - using the Ed25519 public key associated with |key|. -

      -
    8. -
    9. -

      - Let |result| be a boolean with the value `true` if the signature is valid - and the value `false` otherwise. -

      -
    10. -
    11. -

      - Return |result|. -

      -
    12. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - one of "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Generate an Ed25519 key pair, as defined in [[RFC8032]], section 5.1.5. -

      -
    4. -
    5. -

      - Let |algorithm| be a new {{KeyAlgorithm}} object. -

      -
    6. -
    7. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

      -
    8. -
    9. -

      - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

      -
    10. -
    11. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

      -
    12. -
    13. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |publicKey| to |algorithm|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |publicKey| to true. -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the [= usage intersection =] - of |usages| and `[ "verify" ]`. -

      -
    18. -
    19. -

      - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

      -
    20. -
    21. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

      -
    22. -
    23. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |privateKey| to |algorithm|. -

      -
    24. -
    25. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |privateKey| to |extractable|. -

      -
    26. -
    27. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the [= usage intersection =] - of |usages| and `[ "sign" ]`. -

      -
    28. -
    29. -

      - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

      -
    30. -
    31. -

      - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

      -
    32. -
    33. -

      - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

      -
    34. -
    35. -

      - Return |result|. -

      -
    36. -
    -
    +
    +

    Operations

    + +
    +
    Derive Bits
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |publicKey| be the + {{EcdhKeyDeriveParams/public}} member of + |normalizedAlgorithm|. +

      +
    4. +
    5. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |publicKey| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    6. +
    7. +

      + If the {{KeyAlgorithm/name}} attribute of + the {{CryptoKey/[[algorithm]]}} internal slot of + |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the {{CryptoKey/[[algorithm]]}} internal slot of + |key|, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    8. +
    9. +

      + Let |secret| be the result of performing the X25519 function specified in + [[RFC7748]] Section 5 with |key| as the X25519 private key |k| + and the X25519 public key represented by the {{CryptoKey/[[handle]]}} + internal slot of |publicKey| as the X25519 public key |u|. +

      +
    10. +
    11. +

      + If |secret| is the all-zero value, + then [= exception/throw =] a {{OperationError}}. + This check must be performed in constant-time, as per [[RFC7748]] Section 6.1. +

      +
    12. +
    13. +
      +
      If |length| is null:
      +
      Return |secret|
      +
      Otherwise:
      +
      +
      +
      + If the length of |secret| in bits is less than + |length|: +
      +
      + [= exception/throw =] an + {{OperationError}}. +
      +
      Otherwise:
      +
      + Return a [= byte sequence containing =] the first |length| bits of |secret|. +
      +
      +
      +
      +
    14. +
    +
    + +
    +
    Generate Key
    + +
      +
    1. +

      + If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Generate an X25519 key pair, with the private key being 32 random bytes, + and the public key being `X25519(a, 9)`, + as defined in [[RFC7748]], section 6.1. +

      +
    4. +
    5. +

      + Let |algorithm| be a new {{KeyAlgorithm}} object. +

      +
    6. +
    7. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X25519`". +

      +
    8. +
    9. +

      + Let |publicKey| be a new {{CryptoKey}} + representing the public key of the generated key pair. +

      +
    10. +
    11. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |publicKey| to "`public`" +

      +
    12. +
    13. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |publicKey| to |algorithm|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |publicKey| to true. +

      +
    16. +
    17. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |publicKey| to be the empty list. +

      +
    18. +
    19. +

      + Let |privateKey| be a new {{CryptoKey}} + representing the private key of the generated key pair. +

      +
    20. +
    21. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |privateKey| to {{KeyType/"private"}} +

      +
    22. +
    23. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |privateKey| to |algorithm|. +

      +
    24. +
    25. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |privateKey| to |extractable|. +

      +
    26. +
    27. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |privateKey| to be the + [= usage intersection =] of + |usages| and `[ "deriveKey", "deriveBits" ]`. +

      +
    28. +
    29. +

      + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

      +
    30. +
    31. +

      + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

      +
    32. +
    33. +

      + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

      +
    34. +
    35. +

      + Return |result|. +

      +
    36. +
    +
    + +
    +
    Import Key
    + +
      +
    1. +

      Let |keyData| be the key data to be imported.

      +
    2. +
    3. +
      +
      If |format| is {{KeyFormat/"spki"}}:
      +
      +
        +
      1. +

        + If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + Let |spki| be the result of running the + [= parse a subjectPublicKeyInfo =] + algorithm over |keyData|. +

        +
      4. +
      5. +

        + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `id-X25519` + object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

        +
      8. +
      9. +

        + If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is present, + then [= exception/throw =] a + {{DataError}}. +

        +
      10. +
      11. +

        + Let |publicKey| be the X25519 public key identified by + the `subjectPublicKey` field of |spki|. +

        +
      12. +
      13. +

        + Let |key| be a new {{CryptoKey}} + that represents |publicKey|. +

        +
      14. +
      15. +

        + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

        +
      16. +
      17. +

        + Let |algorithm| be a new {{KeyAlgorithm}}. +

        +
      18. +
      19. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X25519`". +

        +
      20. +
      21. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      22. +
      +
      +
      If |format| is {{KeyFormat/"pkcs8"}}:
      +
      +
        +
      1. +

        + If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + Let |privateKeyInfo| be the result of running the + [= parse a privateKeyInfo =] + algorithm over |keyData|. +

        +
      4. +
      5. +

        + If an error occurs while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `id-X25519` object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

        +
      8. +
      9. +

        + If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is present, + then [= exception/throw =] a + {{DataError}}. +

        +
      10. +
      11. +

        + Let |curvePrivateKey| be the result of performing the + [= parse an ASN.1 structure =] + algorithm, with |data| as the `privateKey` field + of |privateKeyInfo|, |structure| as the ASN.1 + `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. +

        +
      12. +
      13. +

        + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

        +
      14. +
      15. +

        + Let |key| be a new {{CryptoKey}} + that represents the X25519 private key identified by |curvePrivateKey|. +

        +
      16. +
      17. +

        + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to {{KeyType/"private"}} +

        +
      18. +
      19. +

        + Let |algorithm| be a new {{KeyAlgorithm}}. +

        +
      20. +
      21. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X25519`". +

        +
      22. +
      23. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      24. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +
        +
        If |keyData| is a {{JsonWebKey}} dictionary:
        +

        Let |jwk| equal |keyData|.

        +
        Otherwise:
        +

        [= exception/Throw =] a {{DataError}}.

        +
        +
      2. +
      3. +

        + If the {{JsonWebKey/d}} field is present and if |usages| + contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      4. +
      5. +

        + If the {{JsonWebKey/d}} field is not present and if |usages| is not + empty + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      6. +
      7. +

        + If the {{JsonWebKey/kty}} field of |jwk| is not + "`OKP`", + then [= exception/throw =] a + {{DataError}}. +

        +
      8. +
      9. +

        + If the {{JsonWebKey/crv}} field of |jwk| is not + "`X25519`", + then [= exception/throw =] a + {{DataError}}. +

        +
      10. +
      11. +

        + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present + and is not equal to "`enc`" then [= exception/throw =] a + {{DataError}}. +

        +
      12. +
      13. +

        + If the {{JsonWebKey/key_ops}} field of |jwk| is present, and + is invalid according to the requirements of JSON Web + Key [[JWK]], or it does not contain all of the specified |usages| + values, + then [= exception/throw =] a + {{DataError}}. +

        +
      14. +
      15. +

        + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

        +
      16. +
      17. +
        +
        If the {{JsonWebKey/d}} field is present:
        +
        +
          +
        1. +

          + If |jwk| does not meet the requirements of + the JWK private key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

          +
        2. +
        3. +

          + Let |key| be a new {{CryptoKey}} object that represents the + X25519 private key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

          +
        4. +
        5. +

          + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to {{KeyType/"private"}}. +

          +
        6. +
        +
        +
        Otherwise:
        +
        +
          +
        1. +

          + If |jwk| does not meet the requirements of + the JWK public key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

          +
        2. +
        3. +

          + Let |key| be a new {{CryptoKey}} object that represents the + X25519 public key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

          +
        4. +
        5. +

          + Set the {{CryptoKey/[[type]]}} + internal slot of |Key| to {{KeyType/"public"}}. +

          +
        6. +
        +
        +
        +
      18. +
      19. +

        + Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. +

        +
      20. +
      21. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X25519`". +

        +
      22. +
      23. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      24. +
      +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + Let |algorithm| be a new {{KeyAlgorithm}} object. +

        +
      4. +
      5. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X25519`". +

        +
      6. +
      7. +

        + Let |key| be a new {{CryptoKey}} + representing the key data provided in |keyData|. +

        +
      8. +
      9. +

        + Set the {{CryptoKey/[[type]]}} internal slot + of |key| to "`public`" +

        +
      10. +
      11. +

        + Set the {{CryptoKey/[[algorithm]]}} + internal slot of |key| to |algorithm|. +

        +
      12. +
      +
      +
      Otherwise:
      +
      +

      + [= exception/throw =] a + {{NotSupportedError}}. +

      +
      +
      +
    4. +
    5. +

      + Return |key| +

      +
    6. +
    +
    -
    Import Key
    -
    -
      -
    1. -

      Let |keyData| be the key data to be imported.

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-Ed25519` - object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |publicKey| be the Ed25519 public key identified by - the `subjectPublicKey` field of |spki|. -

        -
      12. -
      13. -

        - Let |key| be a new {{CryptoKey}} - that represents |publicKey|. -

        -
      14. -
      15. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

        -
      16. -
      17. -

        - Let |algorithm| be a new {{KeyAlgorithm}}. -

        -
      18. -
      19. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

        -
      20. -
      21. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      22. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        - If |usages| contains a value which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-Ed25519` object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |curvePrivateKey| be the result of performing the - [= parse an ASN.1 structure =] - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. -

        -
      12. -
      13. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - Let |key| be a new {{CryptoKey}} - that represents the Ed25519 private key identified by |curvePrivateKey|. -

        -
      16. -
      17. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to {{KeyType/"private"}} -

        -
      18. -
      19. -

        - Let |algorithm| be a new {{KeyAlgorithm}}. -

        -
      20. -
      21. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

        -
      22. -
      23. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      24. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/d}} field is present and |usages| contains - a value which is not - "`sign`", or, - if the {{JsonWebKey/d}} field is not present and |usages| contains - a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      4. -
      5. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the {{JsonWebKey/crv}} field of |jwk| is not - "`Ed25519`", - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the {{JsonWebKey/alg}} field of |jwk| is present and is - not "`Ed25519`" or "`EdDSA`", - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`sig`", - then [= exception/throw =] a - {{DataError}}. -

        -
      12. -
      13. -

        - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

        -
      16. -
      17. -
        -
        If the {{JsonWebKey/d}} field is present:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Ed25519 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to {{KeyType/"private"}}. -

          -
        6. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Ed25519 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to {{KeyType/"public"}}. -

          -
        6. -
        -
        -
        -
      18. -
      19. -

        - Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -

        -
      20. -
      21. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

        -
      22. -
      23. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      24. -
      -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |algorithm| be a new {{KeyAlgorithm}} object. -

        -
      4. -
      5. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} - representing the key data provided in |keyData|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

        -
      10. -
      11. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      12. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    4. -
    5. -

      - Return |key| -

      -
    6. -
    -
    +
    +
    Export Key
    -
    Export Key
    -
    -
      -
    1. -

      - Let |key| be the {{CryptoKey}} to be - exported. -

      -
    2. -
    3. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

        -
      2. -
      3. -

        - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

        -
          -
        • -

          - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

          -
            -
          • -

            - Set the |algorithm| object identifier to the - `id-Ed25519` OID defined in [[RFC8410]]. -

            -
          • -
          -
        • -
        • -

          - Set the |subjectPublicKey| field to |keyData|. -

          -
        • -
        -
      4. -
      5. -

        - Let |result| be the result of DER-encoding |data|. -

        -
      6. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        +

          +
        1. +

          + Let |key| be the {{CryptoKey}} to be + exported. +

          +
        2. +
        3. +

          + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

          +
        4. +
        5. +
          +
          If |format| is {{KeyFormat/"spki"}}:
          +
          +
            +
          1. +

            + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

            +
          2. +
          3. +

            + Let |data| be an instance of the `SubjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

            +
              +
            • +

              + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

              +
                +
              • +

                + Set the |algorithm| object identifier to the + `id-X25519` OID defined in [[RFC8410]]. +

                +
              • +
              +
            • +
            • +

              + Set the |subjectPublicKey| field to |keyData|. +

              +
            • +
            +
          4. +
          5. +

            + Let |result| be the result of DER-encoding |data|. +

            +
          6. +
          +
          +
          If |format| is {{KeyFormat/"pkcs8"}}:
          +
          +
            +
          1. +

            + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

            +
          2. +
          3. +

            + Let |data| be an instance of the `PrivateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

            +
              +
            • +

              + Set the |version| field to `0`. +

              +
            • +
            • +

              + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

              +
                +
              • +

                + Set the |algorithm| object identifier to the + `id-X25519` OID defined in [[RFC8410]]. +

                +
              • +
              +
            • +
            • +

              + Set the |privateKey| field to the result of DER-encoding + a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the + X25519 private key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key| +

              +
            • +
            +
          4. +
          5. +

            + Let |result| be the result of DER-encoding |data|. +

            +
          6. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +

            + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

            +
          2. +
          3. +

            + Set the `kty` attribute of |jwk| to + "`OKP`". +

            +
          4. +
          5. +

            + Set the `crv` attribute of |jwk| to + "`X25519`". +

            +
          6. +
          7. +

            + Set the {{JsonWebKey/x}} attribute of |jwk| according to the + definition in Section 2 of [[RFC8037]]. +

            +
          8. +
          9. +
            +
            If the {{CryptoKey/[[type]]}} internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

            -
          10. -
          11. -

            - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

            -
              -
            • -

              - Set the |version| field to `0`. -

              -
            • -
            • -

              - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

              -
                -
              • -

                - Set the |algorithm| object identifier to the - `id-Ed25519` OID defined in [[RFC8410]]. -

                -
              • -
              -
            • -
            • -

              - Set the |privateKey| field to the result of DER-encoding - a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the - Ed25519 private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

              -
            • -
            -
          12. -
          13. -

            - Let |result| be the result of DER-encoding |data|. -

            -
          14. -
          -
          -
          If |format| is {{KeyFormat/"jwk"}}:
          -
          -
            -
          1. -

            - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

            -
          2. -
          3. -

            - Set the `kty` attribute of |jwk| to - "`OKP`". -

            -
          4. -
          5. -

            - Set the `alg` attribute of |jwk| to - "`Ed25519`". -

            -
          6. -
          7. -

            - Set the `crv` attribute of |jwk| to - "`Ed25519`". -

            -
          8. -
          9. -

            - Set the {{JsonWebKey/x}} attribute of |jwk| according to the + of |key| is {{KeyType/"private"}} + +

            + Set the {{JsonWebKey/d}} attribute of |jwk| according to the definition in Section 2 of [[RFC8037]]. -

            -
          10. -
          11. -
            -
            - If the {{CryptoKey/[[type]]}} internal slot - of |key| is {{KeyType/"private"}} -
            -
            - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
            -
            -
          12. -
          13. -

            - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

            -
          14. -
          15. -

            - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

            -
          16. -
          17. -

            - Let |result| be |jwk|. -

            -
          18. -
          -
          -
          - If |format| is {{KeyFormat/"raw"}}: -
          -
          -
            -
          1. -

            - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

            -
          2. -
          3. -

            - Let |data| be a [= byte sequence =] representing the Ed25519 - public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

            -
          4. -
          5. -

            - Let |result| be |data|. -

            -
          6. -
          -
          -
          Otherwise:
          -
          -

          - [= exception/throw =] a - {{NotSupportedError}}. -

          -
          -
          -
        6. -
        7. -

          - Return |result|. -

          -
        8. -
        -
      -
      +
    +
    + +
  • +

    + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

    +
  • +
  • +

    + Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

    +
  • +
  • +

    + Let |result| be |jwk|. +

    +
  • + + +
    + If |format| is {{KeyFormat/"raw"}}: +
    +
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |data| be a [= byte sequence =] representing the X25519 + public key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

      +
    4. +
    5. +

      + Let |result| be |data|. +

      +
    6. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    + + +
  • +

    + Return |result|. +

    +
  • + +
    -
    -

    X25519

    -
    +
    +

    AES-CTR

    +

    Description

    - The "`X25519`" algorithm identifier is used to perform - key agreement using the X25519 algorithm specified in - [[RFC7748]]. + The "`AES-CTR`" algorithm identifier is used to perform + encryption and decryption using AES in Counter mode, + as described in [[NIST-SP800-38A]].

    -
    +

    Registration

    The [= recognized algorithm name =] for - this algorithm is "`X25519`". + this algorithm is "`AES-CTR`".

    @@ -11164,14 +12028,19 @@

    Registration

    - - + + + + + + + - - + + @@ -11183,810 +12052,558 @@

    Registration

    + + + + +
    deriveBits{{EcdhKeyDeriveParams}}encrypt{{AesCtrParams}}[= byte sequence =]
    decrypt{{AesCtrParams}} [= byte sequence =]
    generateKeyNone{{CryptoKeyPair}}{{AesKeyGenParams}}{{CryptoKey}}
    importKey None object
    get key length{{AesDerivedKeyParams}}Integer
    -
    +
    +

    AesCtrParams dictionary

    +
    +dictionary AesCtrParams : Algorithm {
    +  required BufferSource counter;
    +  required [EnforceRange] octet length;
    +};
    +          
    +

    The counter member contains the initial value of the counter block. {{AesCtrParams/counter}} MUST be 16 bytes (the AES block size). The counter bits are the rightmost length + bits of the counter block. The rest of the counter block is for + the nonce. The counter bits are incremented using the standard + incrementing function specified in NIST SP 800-38A Appendix B.1: + the counter bits are interpreted as a big-endian integer and + incremented by one.

    +

    The length member contains the length, in bits, of the rightmost part of the counter block that is incremented.

    +
    +
    +

    AesKeyAlgorithm dictionary

    +
    +dictionary AesKeyAlgorithm : KeyAlgorithm {
    +  required unsigned short length;
    +};
    +          
    +

    The length member represents the length, in bits, of the key.

    +
    +
    +

    AesKeyGenParams dictionary

    +
    +dictionary AesKeyGenParams : Algorithm {
    +  required [EnforceRange] unsigned short length;
    +};
    +          
    +

    The length member represents the length, in bits, of the key.

    +
    +
    +

    AesDerivedKeyParams dictionary

    +
    +dictionary AesDerivedKeyParams : Algorithm {
    +  required [EnforceRange] unsigned short length;
    +};
    +          
    +

    The length member represents the length, in bits, of the key.

    +
    + +

    Operations

    -
    -
    Derive Bits
    -
    -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - Let |publicKey| be the - {{EcdhKeyDeriveParams/public}} member of - |normalizedAlgorithm|. -

      -
    4. -
    5. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |publicKey| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    6. -
    7. -

      - If the {{KeyAlgorithm/name}} attribute of - the {{CryptoKey/[[algorithm]]}} internal slot of - |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the {{CryptoKey/[[algorithm]]}} internal slot of - |key|, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    8. -
    9. -

      - Let |secret| be the result of performing the X25519 function specified in - [[RFC7748]] Section 5 with |key| as the X25519 private key |k| - and the X25519 public key represented by the {{CryptoKey/[[handle]]}} - internal slot of |publicKey| as the X25519 public key |u|. -

      -
    10. -
    11. -

      - If |secret| is the all-zero value, - then [= exception/throw =] a {{OperationError}}. - This check must be performed in constant-time, as per [[RFC7748]] Section 6.1. -

      -
    12. -
    13. -
      -
      If |length| is null:
      -
      Return |secret|
      -
      Otherwise:
      -
      -
      -
      - If the length of |secret| in bits is less than - |length|: -
      -
      - [= exception/throw =] an - {{OperationError}}. -
      -
      Otherwise:
      -
      - Return a [= byte sequence containing =] the first |length| bits of |secret|. -
      -
      -
      -
      -
    14. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Generate an X25519 key pair, with the private key being 32 random bytes, - and the public key being `X25519(a, 9)`, - as defined in [[RFC7748]], section 6.1. -

      -
    4. -
    5. -

      - Let |algorithm| be a new {{KeyAlgorithm}} object. -

      -
    6. -
    7. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

      -
    8. -
    9. -

      - Let |publicKey| be a new {{CryptoKey}} - representing the public key of the generated key pair. -

      -
    10. -
    11. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |publicKey| to "`public`" -

      -
    12. -
    13. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |publicKey| to |algorithm|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |publicKey| to true. -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |publicKey| to be the empty list. -

      -
    18. -
    19. -

      - Let |privateKey| be a new {{CryptoKey}} - representing the private key of the generated key pair. -

      -
    20. -
    21. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |privateKey| to {{KeyType/"private"}} -

      -
    22. -
    23. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |privateKey| to |algorithm|. -

      -
    24. -
    25. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |privateKey| to |extractable|. -

      -
    26. -
    27. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |privateKey| to be the - [= usage intersection =] of - |usages| and `[ "deriveKey", "deriveBits" ]`. -

      -
    28. -
    29. -

      - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

      -
    30. -
    31. -

      - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

      -
    32. -
    33. -

      - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

      -
    34. -
    35. -

      - Return |result|. -

      -
    36. -
    -
    -
    Import Key
    -
    -
      -
    1. -

      Let |keyData| be the key data to be imported.

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |spki| be the result of running the - [= parse a subjectPublicKeyInfo =] - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-X25519` - object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |publicKey| be the X25519 public key identified by - the `subjectPublicKey` field of |spki|. -

        -
      12. -
      13. -

        - Let |key| be a new {{CryptoKey}} - that represents |publicKey|. -

        -
      14. -
      15. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

        -
      16. -
      17. -

        - Let |algorithm| be a new {{KeyAlgorithm}}. -

        -
      18. -
      19. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

        -
      20. -
      21. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      22. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |privateKeyInfo| be the result of running the - [= parse a privateKeyInfo =] - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-X25519` object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |curvePrivateKey| be the result of performing the - [= parse an ASN.1 structure =] - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. -

        -
      12. -
      13. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - Let |key| be a new {{CryptoKey}} - that represents the X25519 private key identified by |curvePrivateKey|. -

        -
      16. -
      17. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to {{KeyType/"private"}} -

        -
      18. -
      19. -

        - Let |algorithm| be a new {{KeyAlgorithm}}. -

        -
      20. -
      21. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

        -
      22. -
      23. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      24. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/d}} field is present and if |usages| - contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      4. -
      5. -

        - If the {{JsonWebKey/d}} field is not present and if |usages| is not - empty - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      6. -
      7. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the {{JsonWebKey/crv}} field of |jwk| is not - "`X25519`", - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present - and is not equal to "`enc`" then [= exception/throw =] a - {{DataError}}. -

        -
      12. -
      13. -

        - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

        -
      16. -
      17. -
        -
        If the {{JsonWebKey/d}} field is present:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - X25519 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to {{KeyType/"private"}}. -

          -
        6. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - X25519 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

          -
        4. -
        5. -

          - Set the {{CryptoKey/[[type]]}} - internal slot of |Key| to {{KeyType/"public"}}. -

          -
        6. -
        -
        -
        -
      18. -
      19. -

        - Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -

        -
      20. -
      21. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

        -
      22. -
      23. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      24. -
      -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |algorithm| be a new {{KeyAlgorithm}} object. -

        -
      4. -
      5. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

        -
      6. -
      7. -

        - Let |key| be a new {{CryptoKey}} - representing the key data provided in |keyData|. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[type]]}} internal slot - of |key| to "`public`" -

        -
      10. -
      11. -

        - Set the {{CryptoKey/[[algorithm]]}} - internal slot of |key| to |algorithm|. -

        -
      12. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    4. -
    5. -

      - Return |key| -

      -
    6. -
    -
    +
    +
    Encrypt
    + +
      +
    1. +

      + If the {{AesCtrParams/counter}} member of + |normalizedAlgorithm| does not have + a [= byte sequence/length =] of 16 bytes, + then [= exception/throw =] an + {{OperationError}}. +

      +
    2. +
    3. +

      + If the {{AesCtrParams/length}} member of + |normalizedAlgorithm| is zero or is greater + than 128, + then [= exception/throw =] an + {{OperationError}}. +

      +
    4. +
    5. +

      + Let |ciphertext| be the result of performing the CTR Encryption + operation described in Section 6.5 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCtrParams/counter}} member of + |normalizedAlgorithm| as the initial value of the counter block, the + {{AesCtrParams/length}} member of + |normalizedAlgorithm| as the input parameter |m| to the + standard counter block incrementing function defined in Appendix B.1 of + [[NIST-SP800-38A]] and + |plaintext| as the input plaintext. +

      +
    6. +
    7. +

      + Return |ciphertext|. +

      +
    8. +
    +
    + +
    +
    Decrypt
    + +
      +
    1. +

      + If the {{AesCtrParams/counter}} member of + |normalizedAlgorithm| does not have + a [= byte sequence/length =] of 16 bytes, + then [= exception/throw =] an + {{OperationError}}. +

      +
    2. +
    3. +

      + If the {{AesCtrParams/length}} member of + |normalizedAlgorithm| is zero or is greater + than 128, + then [= exception/throw =] an + {{OperationError}}. +

      +
    4. +
    5. +

      + Let |plaintext| be the result of performing the CTR Decryption + operation described in Section 6.5 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCtrParams/counter}} member of + |normalizedAlgorithm| as the initial value of the counter block, the + {{AesCtrParams/length}} member of + |normalizedAlgorithm| as the input parameter |m| to the + standard counter block incrementing function defined in Appendix B.1 of + [[NIST-SP800-38A]] and + |ciphertext| as the input ciphertext. +

      +
    6. +
    7. +

      + Return |plaintext|. +

      +
    8. +
    +
    + +
    +
    Generate Key
    + +
      +
    1. +

      + If |usages| contains any entry which is not + one of "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + If the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm| is not equal to one of + 128, 192 or 256, + then [= exception/throw =] an + {{OperationError}}. +

      +
    4. + +
    5. +

      + Generate an AES key of length + equal to the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

      +
    6. +
    7. +

      + If the key generation step fails, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |key| be a new + {{CryptoKey}} object representing the + generated AES key. +

      +
    10. +
    11. +

      + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

      +
    12. +
    13. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-CTR`". +

      +
    14. +
    15. +

      + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to equal the + {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

      +
    16. +
    17. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

      +
    18. +
    19. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

      +
    20. +
    21. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |key| to be |extractable|. +

      +
    22. +
    23. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |key| to be |usages|. +

      +
    24. +
    25. +

      + Return |key|. +

      +
    26. +
    +
    + +
    +
    Import Key
    + +
      +
    1. +

      + If |usages| contains an entry which is not + one of "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + Let |data| be |keyData|. +

        +
      2. +
      3. +

        + If the [= length in bits =] of |data| is not 128, 192 or 256 + then [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +
        +
        If |keyData| is a {{JsonWebKey}} dictionary:
        +

        Let |jwk| equal |keyData|.

        +
        Otherwise:
        +

        [= exception/Throw =] a {{DataError}}.

        +
        +
      2. +
      3. +

        + If the {{JsonWebKey/kty}} field of |jwk| is not + "`oct`", + then [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If |jwk| does not meet the requirements of + Section 6.4 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |data| be the [= byte sequence =] obtained by decoding the + {{JsonWebKey/k}} field of |jwk|. +

        +
      8. +
      9. +
        +
        If the [= length in bits =] of |data| is 128:
        +
        + If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A128CTR`", then [= exception/throw =] a {{DataError}}. +
        +
        If the [= length in bits =] of |data| is 192:
        +
        + If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A192CTR`", then [= exception/throw =] a {{DataError}}. +
        +
        If the [= length in bits =] of |data| is 256:
        +
        + If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A256CTR`", then [= exception/throw =] a {{DataError}}. +
        +
        Otherwise:
        +
        + [= exception/throw =] a + {{DataError}}.
        +
        +
      10. +
      11. +

        + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`enc`", + then [= exception/throw =] a + {{DataError}}. +

        +
      12. +
      13. +

        + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

        +
      14. +
      15. +

        + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

        +
      16. +
      +
      +
      Otherwise:
      +
      + [= exception/throw =] a + {{NotSupportedError}}. +
      +
      +
    4. +
    5. +

      + Let |key| be a new {{CryptoKey}} object representing an AES key with + value |data|. +

      +
    6. +
    7. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

      +
    8. +
    9. +

      + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

      +
    10. +
    11. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-CTR`". +

      +
    12. +
    13. +

      + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to the length, in bits, of |data|. +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

      +
    16. +
    17. +

      + Return |key|. +

      +
    18. +
    +
    + +
    +
    Export Key
    -
    Export Key
    -
    -
      -
    1. -

      - Let |key| be the {{CryptoKey}} to be - exported. -

      -
    2. -
    3. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

        -
      2. -
      3. -

        - Let |data| be an instance of the `SubjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

        -
          -
        • -

          - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

          -
            -
          • -

            - Set the |algorithm| object identifier to the - `id-X25519` OID defined in [[RFC8410]]. -

            -
          • -
          -
        • -
        • -

          - Set the |subjectPublicKey| field to |keyData|. -

          -
        • -
        -
      4. -
      5. -

        - Let |result| be the result of DER-encoding |data|. -

        -
      6. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

        -
      2. -
      3. -

        - Let |data| be an instance of the `PrivateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

        -
          -
        • -

          - Set the |version| field to `0`. -

          -
        • -
        • -

          - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

          -
            -
          • -

            - Set the |algorithm| object identifier to the - `id-X25519` OID defined in [[RFC8410]]. -

            -
          • -
          -
        • -
        • -

          - Set the |privateKey| field to the result of DER-encoding - a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the - X25519 private key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key| -

          -
        • -
        -
      4. -
      5. -

        - Let |result| be the result of DER-encoding |data|. -

        -
      6. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to - "`OKP`". -

        -
      4. -
      5. -

        - Set the `crv` attribute of |jwk| to - "`X25519`". -

        -
      6. -
      7. -

        - Set the {{JsonWebKey/x}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -

        -
      8. -
      9. -
        -
        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is {{KeyType/"private"}} -
        -
        - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
        -
        -
      10. -
      11. -

        - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

        -
      12. -
      13. -

        - Set the `ext` attribute of |jwk| to the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

        -
      14. -
      15. -

        - Let |result| be |jwk|. -

        -
      16. -
      -
      -
      - If |format| is {{KeyFormat/"raw"}}: -
      -
      -
        -
      1. -

        - If the {{CryptoKey/[[type]]}} internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -

        -
      2. -
      3. -

        - Let |data| be a [= byte sequence =] representing the X25519 - public key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

        -
      4. -
      5. -

        - Let |result| be |data|. -

        -
      6. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    6. -
    7. -

      - Return |result|. -

      -
    8. -
    -
    -
    +
      +
    1. +

      + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + Let |data| be a [= byte sequence =] containing + the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

        +
      2. +
      3. +

        + Let |result| be |data|. +

        +
      4. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +

        + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

        +
      2. +
      3. +

        + Set the `kty` attribute of |jwk| to the + string "`oct`". +

        +
      4. +
      5. +

        + Set the {{JsonWebKey/k}} attribute of |jwk| to be a string + containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. +

        +
      6. +
      7. +
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 128:
        +
        Set the `alg` attribute of |jwk| to + the string "`A128CTR`".
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 192:
        +
        Set the `alg` attribute of |jwk| to + the string "`A192CTR`".
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 256:
        +
        Set the `alg` attribute of |jwk| to + the string "`A256CTR`".
        +
        +
      8. +
      9. +

        + Set the `key_ops` attribute of |jwk| to equal the + {{CryptoKey/[[usages]]}} internal slot of + |key|. +

        +
      10. +
      11. +

        + Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

        +
      12. +
      13. +

        + Let |result| be |jwk|. +

        +
      14. +
      +
      +
      Otherwise:
      +
      +

      + [= exception/throw =] a + {{NotSupportedError}}. +

      +
      +
      +
    4. +
    5. +

      + Return |result|. +

      +
    6. +
    +
    + +
    +
    Get key length
    + +
      +
    1. +

      + If the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, + then [= exception/throw =] a + {{OperationError}}. +

      +
    2. +
    3. +

      + Return the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm|. +

      +
    4. +
    +
    -
    -

    AES-CTR

    -
    +
    +

    AES-CBC

    +

    Description

    - The "`AES-CTR`" algorithm identifier is used to perform - encryption and decryption using AES in Counter mode, + The "`AES-CBC`" algorithm identifier is used to perform + encryption and decryption using AES in Cipher Block Chaining mode, as described in [[NIST-SP800-38A]].

    +

    + When operating in CBC mode, messages that are not exact multiples + of the AES block size (16 bytes) can be padded under a variety of + padding schemes. In the Web Crypto API, the only padding mode that + is supported is that of PKCS#7, as described by + Section 10.3, step 2, of [[RFC2315]]. +

    -
    +

    Registration

    The [= recognized algorithm name =] for - this algorithm is "`AES-CTR`". + this algorithm is "`AES-CBC`".

    @@ -11998,1087 +12615,520 @@

    Registration

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    encrypt{{AesCtrParams}}[= byte sequence =]
    decrypt{{AesCtrParams}}[= byte sequence =]
    generateKey{{AesKeyGenParams}}{{CryptoKey}}
    importKeyNone{{CryptoKey}}
    exportKeyNoneobject
    get key length{{AesDerivedKeyParams}}Integer
    -
    - -
    -

    AesCtrParams dictionary

    -
    -dictionary AesCtrParams : Algorithm {
    -  required BufferSource counter;
    -  required [EnforceRange] octet length;
    -};
    -          
    -

    The counter member contains the initial value of the counter block. {{AesCtrParams/counter}} MUST be 16 bytes (the AES block size). The counter bits are the rightmost length - bits of the counter block. The rest of the counter block is for - the nonce. The counter bits are incremented using the standard - incrementing function specified in NIST SP 800-38A Appendix B.1: - the counter bits are interpreted as a big-endian integer and - incremented by one.

    -

    The length member contains the length, in bits, of the rightmost part of the counter block that is incremented.

    -
    -
    -

    AesKeyAlgorithm dictionary

    -
    -dictionary AesKeyAlgorithm : KeyAlgorithm {
    -  required unsigned short length;
    -};
    -          
    -

    The length member represents the length, in bits, of the key.

    -
    -
    -

    AesKeyGenParams dictionary

    -
    -dictionary AesKeyGenParams : Algorithm {
    -  required [EnforceRange] unsigned short length;
    -};
    -          
    -

    The length member represents the length, in bits, of the key.

    + encrypt + {{AesCbcParams}} + [= byte sequence =] + + + decrypt + {{AesCbcParams}} + [= byte sequence =] + + + generateKey + {{AesKeyGenParams}} + {{CryptoKey}} + + + importKey + None + {{CryptoKey}} + + + exportKey + None + object + + + get key length + {{AesDerivedKeyParams}} + Integer + + +
    -
    -

    AesDerivedKeyParams dictionary

    +
    +

    AesCbcParams dictionary

    -dictionary AesDerivedKeyParams : Algorithm {
    -  required [EnforceRange] unsigned short length;
    +dictionary AesCbcParams : Algorithm {
    +  required BufferSource iv;
     };
               
    -

    The length member represents the length, in bits, of the key.

    +

    The iv member represents the initialization vector. It MUST be 16 bytes.

    - -
    +

    Operations

    -
    -
    Encrypt
    -
    -
      -
    1. -

      - If the {{AesCtrParams/counter}} member of - |normalizedAlgorithm| does not have - a [= byte sequence/length =] of 16 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - If the {{AesCtrParams/length}} member of - |normalizedAlgorithm| is zero or is greater - than 128, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. -
    5. -

      - Let |ciphertext| be the result of performing the CTR Encryption - operation described in Section 6.5 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCtrParams/counter}} member of - |normalizedAlgorithm| as the initial value of the counter block, the - {{AesCtrParams/length}} member of - |normalizedAlgorithm| as the input parameter |m| to the - standard counter block incrementing function defined in Appendix B.1 of - [[NIST-SP800-38A]] and - |plaintext| as the input plaintext. -

      -
    6. -
    7. -

      - Return |ciphertext|. -

      -
    8. -
    -
    -
    Decrypt
    -
    -
      -
    1. -

      - If the {{AesCtrParams/counter}} member of - |normalizedAlgorithm| does not have - a [= byte sequence/length =] of 16 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - If the {{AesCtrParams/length}} member of - |normalizedAlgorithm| is zero or is greater - than 128, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. -
    5. -

      - Let |plaintext| be the result of performing the CTR Decryption - operation described in Section 6.5 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCtrParams/counter}} member of - |normalizedAlgorithm| as the initial value of the counter block, the - {{AesCtrParams/length}} member of - |normalizedAlgorithm| as the input parameter |m| to the - standard counter block incrementing function defined in Appendix B.1 of - [[NIST-SP800-38A]] and - |ciphertext| as the input ciphertext. -

      -
    6. -
    7. -

      - Return |plaintext|. -

      -
    8. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains any entry which is not - one of "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - If the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm| is not equal to one of - 128, 192 or 256, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. -
    5. -

      - Generate an AES key of length - equal to the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

      -
    6. -
    7. -

      - If the key generation step fails, - then [= exception/throw =] an - {{OperationError}}. -

      -
    8. -
    9. -

      - Let |key| be a new - {{CryptoKey}} object representing the - generated AES key. -

      -
    10. -
    11. -

      - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

      -
    12. -
    13. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-CTR`". -

      -
    14. -
    15. -

      - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to equal the - {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    18. -
    19. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    20. -
    21. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |key| to be |extractable|. -

      -
    22. -
    23. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |key| to be |usages|. -

      -
    24. -
    25. -

      - Return |key|. -

      -
    26. -
    -
    -
    Import Key
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - one of "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be |keyData|. -

        -
      2. -
      3. -

        - If the [= length in bits =] of |data| is not 128, 192 or 256 - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`oct`", - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If |jwk| does not meet the requirements of - Section 6.4 of JSON Web Algorithms [[JWA]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |data| be the [= byte sequence =] obtained by decoding the - {{JsonWebKey/k}} field of |jwk|. -

        -
      8. -
      9. -
        -
        If the [= length in bits =] of |data| is 128:
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A128CTR`", then [= exception/throw =] a {{DataError}}. -
        -
        If the [= length in bits =] of |data| is 192:
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A192CTR`", then [= exception/throw =] a {{DataError}}. -
        -
        If the [= length in bits =] of |data| is 256:
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A256CTR`", then [= exception/throw =] a {{DataError}}. -
        -
        Otherwise:
        -
        - [= exception/throw =] a - {{DataError}}.
        -
        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`enc`", - then [= exception/throw =] a - {{DataError}}. -

        -
      12. -
      13. -

        - If the {{JsonWebKey/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 [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

        -
      16. -
      -
      -
      Otherwise:
      -
      - [= exception/throw =] a - {{NotSupportedError}}. -
      -
      -
    4. -
    5. -

      - Let |key| be a new {{CryptoKey}} object representing an AES key with - value |data|. -

      -
    6. -
    7. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    8. -
    9. -

      - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

      -
    10. -
    11. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-CTR`". -

      -
    12. -
    13. -

      - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to the length, in bits, of |data|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    16. -
    17. -

      - Return |key|. -

      -
    18. -
    -
    -
    Export Key
    -
    -
      -
    1. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be a [= byte sequence =] containing - the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

        -
      2. -
      3. -

        - Let |result| be |data|. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to the - string "`oct`". -

        -
      4. -
      5. -

        - Set the {{JsonWebKey/k}} attribute of |jwk| to be a string - containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. -

        -
      6. -
      7. -
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 128:
        -
        Set the `alg` attribute of |jwk| to - the string "`A128CTR`".
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 192:
        -
        Set the `alg` attribute of |jwk| to - the string "`A192CTR`".
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 256:
        -
        Set the `alg` attribute of |jwk| to - the string "`A256CTR`".
        -
        -
      8. -
      9. -

        - Set the `key_ops` attribute of |jwk| to equal the - {{CryptoKey/[[usages]]}} internal slot of - |key|. -

        -
      10. -
      11. -

        - Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

        -
      12. -
      13. -

        - Let |result| be |jwk|. -

        -
      14. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    4. -
    5. -

      - Return |result|. -

      -
    6. -
    -
    -
    Get key length
    -
    -
      -
    1. -

      - If the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, - then [= exception/throw =] a - {{OperationError}}. -

      -
    2. -
    3. -

      - Return the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm|. -

      -
    4. -
    -
    -
    -
    -
    +
    +
    Encrypt
    + +
      +
    1. +

      + If the {{AesCbcParams/iv}} member of + |normalizedAlgorithm| does not have + a [= byte sequence/length =] of 16 bytes, + then [= exception/throw =] an + {{OperationError}}. +

      +
    2. +
    3. +

      + Let |paddedPlaintext| be the result of adding padding octets to + |plaintext| + according to the procedure defined in Section 10.3 + of [[RFC2315]], step 2, with a value of + |k| of 16. +

      +
    4. +
    5. +

      + Let |ciphertext| be the result of performing the CBC Encryption + operation described in Section 6.2 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCbcParams/iv}} member of |normalizedAlgorithm| as + the |IV| input parameter and |paddedPlaintext| + as the input plaintext. +

      +
    6. +
    7. +

      + Return |ciphertext|. +

      +
    8. +
    +
    + +
    +
    Decrypt
    + +
      +
    1. +

      + If the {{AesCbcParams/iv}} member of + |normalizedAlgorithm| does not have + a [= byte sequence/length =] of 16 bytes, + then [= exception/throw =] an + {{OperationError}}. +

      +
    2. +
    3. +

      + Let |paddedPlaintext| be the result of performing the CBC Decryption + operation described in Section 6.2 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCbcParams/iv}} member of |normalizedAlgorithm| as + the |IV| input parameter and + |ciphertext| as the input ciphertext. +

      +
    4. +
    5. +

      + Let |p| be the value of the last octet of |paddedPlaintext|. +

      +
    6. +
    7. +

      + If |p| is zero or greater than 16, or if any of the last |p| + octets of |paddedPlaintext| have a value which is not |p|, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |plaintext| be the result of removing |p| octets from + the end of |paddedPlaintext|. +

      +
    10. +
    11. +

      + Return |plaintext|. +

      +
    12. +
    +
    + +
    +
    Generate Key
    + +
      +
    1. +

      + If |usages| contains any entry which is not + one of "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + If the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm| is not equal to one of + 128, 192 or 256, + then [= exception/throw =] an + {{OperationError}}. +

      +
    4. + +
    5. +

      + Generate an AES key of length + equal to the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

      +
    6. +
    7. +

      + If the key generation step fails, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |key| be a new + {{CryptoKey}} object representing the + generated AES key. +

      +
    10. +
    11. +

      + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

      +
    12. +
    13. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-CBC`". +

      +
    14. +
    15. +

      + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to equal the + {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

      +
    16. +
    17. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

      +
    18. +
    19. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

      +
    20. +
    21. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |key| to be |extractable|. +

      +
    22. +
    23. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |key| to be |usages|. +

      +
    24. +
    25. +

      + Return |key|. +

      +
    26. +
    +
    -
    -

    AES-CBC

    -
    -

    Description

    -

    - The "`AES-CBC`" algorithm identifier is used to perform - encryption and decryption using AES in Cipher Block Chaining mode, - as described in [[NIST-SP800-38A]]. -

    -

    - When operating in CBC mode, messages that are not exact multiples - of the AES block size (16 bytes) can be padded under a variety of - padding schemes. In the Web Crypto API, the only padding mode that - is supported is that of PKCS#7, as described by - Section 10.3, step 2, of [[RFC2315]]. -

    -
    -
    -

    Registration

    -

    - The [= recognized algorithm name =] for - this algorithm is "`AES-CBC`". -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OperationParametersResult
    encrypt{{AesCbcParams}}[= byte sequence =]
    decrypt{{AesCbcParams}}[= byte sequence =]
    generateKey{{AesKeyGenParams}}{{CryptoKey}}
    importKeyNone{{CryptoKey}}
    exportKeyNoneobject
    get key length{{AesDerivedKeyParams}}Integer
    -
    -
    -

    AesCbcParams dictionary

    -
    -dictionary AesCbcParams : Algorithm {
    -  required BufferSource iv;
    -};
    -          
    -

    The iv member represents the initialization vector. It MUST be 16 bytes.

    -
    -
    -

    Operations

    -
    -
    Encrypt
    -
    -
      -
    1. -

      - If the {{AesCbcParams/iv}} member of - |normalizedAlgorithm| does not have - a [= byte sequence/length =] of 16 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - Let |paddedPlaintext| be the result of adding padding octets to - |plaintext| - according to the procedure defined in Section 10.3 - of [[RFC2315]], step 2, with a value of - |k| of 16. -

      -
    4. -
    5. -

      - Let |ciphertext| be the result of performing the CBC Encryption - operation described in Section 6.2 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCbcParams/iv}} member of |normalizedAlgorithm| as - the |IV| input parameter and |paddedPlaintext| - as the input plaintext. -

      -
    6. -
    7. -

      - Return |ciphertext|. -

      -
    8. -
    -
    -
    Decrypt
    -
    -
      -
    1. -

      - If the {{AesCbcParams/iv}} member of - |normalizedAlgorithm| does not have - a [= byte sequence/length =] of 16 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - Let |paddedPlaintext| be the result of performing the CBC Decryption - operation described in Section 6.2 of [[NIST-SP800-38A]] using AES as the block cipher, the {{AesCbcParams/iv}} member of |normalizedAlgorithm| as - the |IV| input parameter and - |ciphertext| as the input ciphertext. -

      -
    4. -
    5. -

      - Let |p| be the value of the last octet of |paddedPlaintext|. -

      -
    6. -
    7. -

      - If |p| is zero or greater than 16, or if any of the last |p| - octets of |paddedPlaintext| have a value which is not |p|, - then [= exception/throw =] an - {{OperationError}}. -

      -
    8. -
    9. -

      - Let |plaintext| be the result of removing |p| octets from - the end of |paddedPlaintext|. -

      -
    10. -
    11. -

      - Return |plaintext|. -

      -
    12. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains any entry which is not - one of "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - If the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm| is not equal to one of - 128, 192 or 256, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. +
      +
      Import Key
      -
    5. -

      - Generate an AES key of length - equal to the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

      -
    6. -
    7. -

      - If the key generation step fails, - then [= exception/throw =] an - {{OperationError}}. -

      -
    8. -
    9. -

      - Let |key| be a new - {{CryptoKey}} object representing the - generated AES key. -

      -
    10. -
    11. -

      - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

      -
    12. -
    13. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-CBC`". -

      -
    14. -
    15. -

      - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to equal the - {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    18. -
    19. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    20. -
    21. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |key| to be |extractable|. -

      -
    22. -
    23. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |key| to be |usages|. -

      -
    24. -
    25. -

      - Return |key|. -

      -
    26. -
    -
    -
    Import Key
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - one of "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be |keyData|. -

        -
      2. -
      3. -

        - If the [= length in bits =] of |data| is not 128, 192 or 256 - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`oct`", - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If |jwk| does not meet the requirements of - Section 6.4 of JSON Web Algorithms [[JWA]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |data| be the [= byte sequence =] obtained by decoding the - {{JsonWebKey/k}} field of |jwk|. -

        -
      8. -
      9. -
        -
        If the [= length in bits =] of |data| is 128:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A128CBC`", - then [= exception/throw =] a - {{DataError}}.
        -
        If the [= length in bits =] of |data| is 192:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A192CBC`", - then [= exception/throw =] a - {{DataError}}.
        -
        If the [= length in bits =] of |data| is 256:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A256CBC`", - then [= exception/throw =] a - {{DataError}}.
        -
        Otherwise:
        -
        - [= exception/throw =] a - {{DataError}}. -
        -
        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`enc`", +

          +
        1. +

          + If |usages| contains an entry which is not + one of "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

          +
        2. +
        3. +
          +
          If |format| is {{KeyFormat/"raw"}}:
          +
          +
            +
          1. +

            + Let |data| be |keyData|. +

            +
          2. +
          3. +

            + If the [= length in bits =] of |data| is not 128, 192 or 256 + then [= exception/throw =] a + {{DataError}}. +

            +
          4. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +
            +
            If |keyData| is a {{JsonWebKey}} dictionary:
            +

            Let |jwk| equal |keyData|.

            +
            Otherwise:
            +

            [= exception/Throw =] a {{DataError}}.

            +
            +
          2. +
          3. +

            + If the {{JsonWebKey/kty}} field of |jwk| is not + "`oct`", + then [= exception/throw =] a + {{DataError}}. +

            +
          4. +
          5. +

            + If |jwk| does not meet the requirements of + Section 6.4 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

            +
          6. +
          7. +

            + Let |data| be the [= byte sequence =] obtained by decoding the + {{JsonWebKey/k}} field of |jwk|. +

            +
          8. +
          9. +
            +
            If the [= length in bits =] of |data| is 128:
            +
            If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A128CBC`", then [= exception/throw =] a - {{DataError}}. -

            -
          10. -
          11. -

            - If the {{JsonWebKey/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, + {{DataError}}.

          +
          If the [= length in bits =] of |data| is 192:
          +
          If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A192CBC`", then [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        5. -

          - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, + {{DataError}}.

      +
      If the [= length in bits =] of |data| is 256:
      +
      If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A256CBC`", then [= exception/throw =] a + {{DataError}}.
      +
      Otherwise:
      +
      + [= exception/throw =] a {{DataError}}. -

      -
    4. -
    -
    -
    Otherwise:
    -
    +
    +
    + +
  • +

    + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`enc`", + then [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +

    + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +

    + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

    +
  • + + +
    Otherwise:
    +
    + [= exception/throw =] a + {{NotSupportedError}} +
    + + +
  • +

    + Let |key| be a new {{CryptoKey}} + object representing an AES key with value |data|. +

    +
  • +
  • +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

    +
  • +
  • +

    + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

    +
  • +
  • +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-CBC`". +

    +
  • +
  • +

    + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to the length, in bits, of |data|. +

    +
  • +
  • +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

    +
  • +
  • +

    + Return |key|. +

    +
  • + +
    + +
    +
    Export Key
    + +
      +
    1. +

      + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + Let |data| be a [= byte sequence =] containing + the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

        +
      2. +
      3. +

        + Let |result| be |data|. +

        +
      4. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +

        Let |jwk| be a new {{JsonWebKey}} dictionary.

        +
      2. +
      3. +

        + Set the `kty` attribute of |jwk| to the + string "`oct`". +

        +
      4. +
      5. +

        + Set the {{JsonWebKey/k}} attribute of |jwk| to be a string + containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. +

        +
      6. +
      7. +
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 128:
        +
        Set the `alg` attribute of |jwk| to + the string "`A128CBC`".
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 192:
        +
        Set the `alg` attribute of |jwk| to + the string "`A192CBC`".
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 256:
        +
        Set the `alg` attribute of |jwk| to + the string "`A256CBC`".
        +
        +
      8. +
      9. +

        + Set the `key_ops` attribute of |jwk| to equal the + {{CryptoKey/usages}} attribute of |key|. +

        +
      10. +
      11. +

        + Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

        +
      12. +
      13. +

        + Let |result| be |jwk|. +

        +
      14. +
      +
      +
      Otherwise:
      +
      +

      [= exception/throw =] a - {{NotSupportedError}} -

      -
      -
    4. -
    5. -

      - Let |key| be a new {{CryptoKey}} - object representing an AES key with value |data|. -

      -
    6. -
    7. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    8. -
    9. -

      - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

      -
    10. -
    11. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-CBC`". -

      -
    12. -
    13. -

      - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to the length, in bits, of |data|. -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    16. -
    17. -

      - Return |key|. -

      -
    18. -
    - -
    Export Key
    -
    -
      -
    1. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be a [= byte sequence =] containing - the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

        -
      2. -
      3. -

        - Let |result| be |data|. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        Let |jwk| be a new {{JsonWebKey}} dictionary.

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to the - string "`oct`". -

        -
      4. -
      5. -

        - Set the {{JsonWebKey/k}} attribute of |jwk| to be a string - containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. -

        -
      6. -
      7. -
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 128:
        -
        Set the `alg` attribute of |jwk| to - the string "`A128CBC`".
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 192:
        -
        Set the `alg` attribute of |jwk| to - the string "`A192CBC`".
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 256:
        -
        Set the `alg` attribute of |jwk| to - the string "`A256CBC`".
        -
        -
      8. -
      9. -

        - Set the `key_ops` attribute of |jwk| to equal the - {{CryptoKey/usages}} attribute of |key|. -

        -
      10. -
      11. -

        - Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

        -
      12. -
      13. -

        - Let |result| be |jwk|. -

        -
      14. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    4. -
    5. -

      - Return |result|. -

      -
    6. -
    -
    -
    Get key length
    -
    -
      -
    1. -

      - If the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - Return the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm|. -

      -
    4. -
    -
    - + {{NotSupportedError}}. +

    + + + +
  • +

    + Return |result|. +

    +
  • + +
    + +
    +
    Get key length
    + +
      +
    1. +

      + If the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, + then [= exception/throw =] an + {{OperationError}}. +

      +
    2. +
    3. +

      + Return the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm|. +

      +
    4. +
    +
    @@ -13155,560 +13205,570 @@

    AesGcmParams dictionary

    Operations

    -
    -
    Encrypt
    -
    -
      -
    1. -

      - If |plaintext| has a [= byte sequence/length =] - greater than 2^39 - 256 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - If the {{AesGcmParams/iv}} member of - |normalizedAlgorithm| has a [= byte sequence/length =] - greater than 2^64 - 1 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. -
    5. -

      - If the {{AesGcmParams/additionalData}} member - of |normalizedAlgorithm| is present and has a - [= byte sequence/length =] - greater than 2^64 - 1 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    6. -
    7. -
      -
      If the {{AesGcmParams/tagLength}} member of - |normalizedAlgorithm| is not present:
      -
      Let |tagLength| be 128.
      -
      If the {{AesGcmParams/tagLength}} member of - |normalizedAlgorithm| is one of 32, 64, 96, 104, 112, 120 or 128:
      -
      Let |tagLength| be equal to the - {{AesGcmParams/tagLength}} member of - |normalizedAlgorithm|
      -
      Otherwise:
      -
      - [= exception/throw =] an - {{OperationError}}. -
      -
      -
    8. -
    9. -

      - Let |additionalData| be the {{AesGcmParams/additionalData}} member of - |normalizedAlgorithm| if present or an empty [= byte sequence =] - otherwise. -

      -
    10. -
    11. -

      - Let |C| and |T| be the outputs that result from performing - the Authenticated Encryption Function described in Section 7.1 of - [[NIST-SP800-38D]] using AES as the block cipher, the {{AesGcmParams/iv}} member of |normalizedAlgorithm| as - the |IV| input parameter, - |additionalData| as the |A| input parameter, - |tagLength| as the |t| pre-requisite and - |plaintext| as the input plaintext. -

      -
    12. -
    13. -

      - Let |ciphertext| be equal to |C| | |T|, - where '|' denotes concatenation. -

      -
    14. -
    15. -

      - Return |ciphertext|. -

      -
    16. -
    -
    -
    Decrypt
    -
    -
      -
    1. -
      -
      If the {{AesGcmParams/tagLength}} member of - |normalizedAlgorithm| is not present:
      -
      Let |tagLength| be 128.
      -
      If the {{AesGcmParams/tagLength}} member of - |normalizedAlgorithm| is one of 32, 64, 96, 104, 112, 120 or 128:
      -
      Let |tagLength| be equal to the - {{AesGcmParams/tagLength}} member of - |normalizedAlgorithm|
      -
      Otherwise:
      -
      - [= exception/throw =] an - {{OperationError}}. -
      -
      -
    2. -
    3. -

      - If |ciphertext| has a [= length in bits =] less than |tagLength|, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. -
    5. -

      - If the {{AesGcmParams/iv}} member of - |normalizedAlgorithm| has a [= byte sequence/length =] - greater than 2^64 - 1 bytes, - then [= exception/throw =] an - {{OperationError}}. -

      -
    6. -
    7. -

      - If the {{AesGcmParams/additionalData}} member - of |normalizedAlgorithm| is present and has a - [= byte sequence/length =] - greater than 2^64 - 1 bytes, - then [= exception/throw =] an + +

      +
      Encrypt
      + +
        +
      1. +

        + If |plaintext| has a [= byte sequence/length =] + greater than 2^39 - 256 bytes, + then [= exception/throw =] an + {{OperationError}}. +

        +
      2. +
      3. +

        + If the {{AesGcmParams/iv}} member of + |normalizedAlgorithm| has a [= byte sequence/length =] + greater than 2^64 - 1 bytes, + then [= exception/throw =] an + {{OperationError}}. +

        +
      4. +
      5. +

        + If the {{AesGcmParams/additionalData}} member + of |normalizedAlgorithm| is present and has a + [= byte sequence/length =] + greater than 2^64 - 1 bytes, + then [= exception/throw =] an + {{OperationError}}. +

        +
      6. +
      7. +
        +
        If the {{AesGcmParams/tagLength}} member of + |normalizedAlgorithm| is not present:
        +
        Let |tagLength| be 128.
        +
        If the {{AesGcmParams/tagLength}} member of + |normalizedAlgorithm| is one of 32, 64, 96, 104, 112, 120 or 128:
        +
        Let |tagLength| be equal to the + {{AesGcmParams/tagLength}} member of + |normalizedAlgorithm|
        +
        Otherwise:
        +
        + [= exception/throw =] an {{OperationError}}. -

        -
      8. -
      9. -

        - Let |tag| be the last |tagLength| bits of - |ciphertext|. -

        -
      10. -
      11. -

        - Let |actualCiphertext| be the result of removing the last |tagLength| bits - from |ciphertext|. -

        -
      12. -
      13. -

        - Let |additionalData| be the {{AesGcmParams/additionalData}} member of - |normalizedAlgorithm| if present or an empty [= byte sequence =] - otherwise. -

        -
      14. -
      15. -

        - Perform the Authenticated Decryption Function described in Section 7.2 of - [[NIST-SP800-38D]] using AES as the block cipher, - the {{AesGcmParams/iv}} member of |normalizedAlgorithm| as - the |IV| input parameter, - |additionalData| as the |A| input parameter, - |tagLength| as the |t| pre-requisite, - |actualCiphertext| as the input ciphertext, |C| and |tag| as - the authentication tag, |T|. -

        -
        -
        If the result of the algorithm is the indication of inauthenticity, - "|FAIL|":
        -
        - [= exception/throw =] an - {{OperationError}} -
        -
        Otherwise:
        -
        Let |plaintext| be the output |P| of the Authenticated - Decryption Function.
        -
        -
      16. -
      17. -

        - Return |plaintext|. -

        -
      18. -
      -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains any entry which is not - one of "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - If the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm| is not equal to one of - 128, 192 or 256, - then [= exception/throw =] an +

    +
    + +
  • +

    + Let |additionalData| be the {{AesGcmParams/additionalData}} member of + |normalizedAlgorithm| if present or an empty [= byte sequence =] + otherwise. +

    +
  • +
  • +

    + Let |C| and |T| be the outputs that result from performing + the Authenticated Encryption Function described in Section 7.1 of + [[NIST-SP800-38D]] using AES as the block cipher, the {{AesGcmParams/iv}} member of |normalizedAlgorithm| as + the |IV| input parameter, + |additionalData| as the |A| input parameter, + |tagLength| as the |t| pre-requisite and + |plaintext| as the input plaintext. +

    +
  • +
  • +

    + Let |ciphertext| be equal to |C| | |T|, + where '|' denotes concatenation. +

    +
  • +
  • +

    + Return |ciphertext|. +

    +
  • + +
    + +
    +
    Decrypt
    + +
      +
    1. +
      +
      If the {{AesGcmParams/tagLength}} member of + |normalizedAlgorithm| is not present:
      +
      Let |tagLength| be 128.
      +
      If the {{AesGcmParams/tagLength}} member of + |normalizedAlgorithm| is one of 32, 64, 96, 104, 112, 120 or 128:
      +
      Let |tagLength| be equal to the + {{AesGcmParams/tagLength}} member of + |normalizedAlgorithm|
      +
      Otherwise:
      +
      + [= exception/throw =] an {{OperationError}}. -

      -
    2. + + + +
    3. +

      + If |ciphertext| has a [= length in bits =] less than |tagLength|, + then [= exception/throw =] an + {{OperationError}}. +

      +
    4. +
    5. +

      + If the {{AesGcmParams/iv}} member of + |normalizedAlgorithm| has a [= byte sequence/length =] + greater than 2^64 - 1 bytes, + then [= exception/throw =] an + {{OperationError}}. +

      +
    6. +
    7. +

      + If the {{AesGcmParams/additionalData}} member + of |normalizedAlgorithm| is present and has a + [= byte sequence/length =] + greater than 2^64 - 1 bytes, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |tag| be the last |tagLength| bits of + |ciphertext|. +

      +
    10. +
    11. +

      + Let |actualCiphertext| be the result of removing the last |tagLength| bits + from |ciphertext|. +

      +
    12. +
    13. +

      + Let |additionalData| be the {{AesGcmParams/additionalData}} member of + |normalizedAlgorithm| if present or an empty [= byte sequence =] + otherwise. +

      +
    14. +
    15. +

      + Perform the Authenticated Decryption Function described in Section 7.2 of + [[NIST-SP800-38D]] using AES as the block cipher, + the {{AesGcmParams/iv}} member of |normalizedAlgorithm| as + the |IV| input parameter, + |additionalData| as the |A| input parameter, + |tagLength| as the |t| pre-requisite, + |actualCiphertext| as the input ciphertext, |C| and |tag| as + the authentication tag, |T|. +

      +
      +
      If the result of the algorithm is the indication of inauthenticity, + "|FAIL|":
      +
      + [= exception/throw =] an + {{OperationError}} +
      +
      Otherwise:
      +
      Let |plaintext| be the output |P| of the Authenticated + Decryption Function.
      +
      +
    16. +
    17. +

      + Return |plaintext|. +

      +
    18. +
    +
    + +
    +
    Generate Key
    + +
      +
    1. +

      + If |usages| contains any entry which is not + one of "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + If the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm| is not equal to one of + 128, 192 or 256, + then [= exception/throw =] an + {{OperationError}}. +

      +
    4. + +
    5. +

      + Generate an AES key of length + equal to the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

      +
    6. +
    7. +

      + If the key generation step fails, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |key| be a new + {{CryptoKey}} object representing the + generated AES key. +

      +
    10. +
    11. +

      + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

      +
    12. +
    13. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-GCM`". +

      +
    14. +
    15. +

      + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to equal the + {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

      +
    16. +
    17. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

      +
    18. +
    19. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

      +
    20. +
    21. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |key| to be |extractable|. +

      +
    22. +
    23. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |key| to be |usages|. +

      +
    24. +
    25. +

      + Return |key|. +

      +
    26. +
    +
    -
  • -

    - Generate an AES key of length - equal to the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

    -
  • -
  • -

    - If the key generation step fails, - then [= exception/throw =] an - {{OperationError}}. -

    -
  • -
  • -

    - Let |key| be a new - {{CryptoKey}} object representing the - generated AES key. -

    -
  • -
  • -

    - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

    -
  • -
  • -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-GCM`". -

    -
  • -
  • -

    - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to equal the - {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

    -
  • -
  • -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

    -
  • -
  • -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

    -
  • -
  • -

    - Set the {{CryptoKey/[[extractable]]}} internal - slot of |key| to be |extractable|. -

    -
  • -
  • -

    - Set the {{CryptoKey/[[usages]]}} internal slot of - |key| to be |usages|. -

    -
  • -
  • -

    - Return |key|. -

    -
  • - - -
    Import Key
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - one of "`encrypt`", "`decrypt`", - "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be |keyData|. -

        -
      2. -
      3. -

        - If the [= length in bits =] of |data| is not 128, 192 or 256 - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`oct`", - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If |jwk| does not meet the requirements of - Section 6.4 of JSON Web Algorithms [[JWA]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |data| be the [= byte sequence =] obtained by decoding the - {{JsonWebKey/k}} field of |jwk|. -

        -
      8. -
      9. -
        -
        If the [= length in bits =] of |data| is 128:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A128GCM`", - then [= exception/throw =] a - {{DataError}}.
        -
        If the [= length in bits =] of |data| is 192:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A192GCM`", - then [= exception/throw =] a - {{DataError}}.
        -
        If the [= length in bits =] of |data| is 256:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A256GCM`", - then [= exception/throw =] a - {{DataError}}.
        -
        Otherwise:
        -
        - [= exception/throw =] a - {{DataError}}. -
        -
        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`enc`", +

        +
        Import Key
        + +
          +
        1. +

          + If |usages| contains an entry which is not + one of "`encrypt`", "`decrypt`", + "`wrapKey`" or "`unwrapKey`", + then [= exception/throw =] a + {{SyntaxError}}. +

          +
        2. +
        3. +
          +
          If |format| is {{KeyFormat/"raw"}}:
          +
          +
            +
          1. +

            + Let |data| be |keyData|. +

            +
          2. +
          3. +

            + If the [= length in bits =] of |data| is not 128, 192 or 256 + then [= exception/throw =] a + {{DataError}}. +

            +
          4. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +
            +
            If |keyData| is a {{JsonWebKey}} dictionary:
            +

            Let |jwk| equal |keyData|.

            +
            Otherwise:
            +

            [= exception/Throw =] a {{DataError}}.

            +
            +
          2. +
          3. +

            + If the {{JsonWebKey/kty}} field of |jwk| is not + "`oct`", + then [= exception/throw =] a + {{DataError}}. +

            +
          4. +
          5. +

            + If |jwk| does not meet the requirements of + Section 6.4 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

            +
          6. +
          7. +

            + Let |data| be the [= byte sequence =] obtained by decoding the + {{JsonWebKey/k}} field of |jwk|. +

            +
          8. +
          9. +
            +
            If the [= length in bits =] of |data| is 128:
            +
            If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A128GCM`", then [= exception/throw =] a - {{DataError}}. -

            -
          10. -
          11. -

            - If the {{JsonWebKey/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, + {{DataError}}.

          +
          If the [= length in bits =] of |data| is 192:
          +
          If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A192GCM`", then [= exception/throw =] a - {{DataError}}. -

          -
        4. -
        5. -

          - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, + {{DataError}}.

      +
      If the [= length in bits =] of |data| is 256:
      +
      If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A256GCM`", then [= exception/throw =] a + {{DataError}}.
      +
      Otherwise:
      +
      + [= exception/throw =] a {{DataError}}. -

      -
    4. -
    -
    -
    Otherwise:
    -
    - [= exception/throw =] a - {{NotSupportedError}}. -
    - - -
  • -

    - Let |key| be a new {{CryptoKey}} - object representing an AES key with value |data|. -

    -
  • -
  • -

    - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

    -
  • -
  • -

    - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

    -
  • -
  • -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-GCM`". -

    -
  • -
  • -

    - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to the length, in bits, of |data|. -

    -
  • -
  • -

    - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

    -
  • -
  • -

    - Return |key|. -

    -
  • - - -
    Export Key
    -
    -
      -
    1. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be a [= byte sequence =] containing - the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

        -
      2. -
      3. -

        - Let |result| be |data|. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to the - string "`oct`". -

        -
      4. -
      5. -

        - Set the {{JsonWebKey/k}} attribute of |jwk| to be a string - containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. -

        -
      6. -
      7. -
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 128:
        -
        Set the `alg` attribute of |jwk| to - the string "`A128GCM`".
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 192:
        -
        Set the `alg` attribute of |jwk| to - the string "`A192GCM`".
        -
        If the {{AesKeyAlgorithm/length}} attribute of - |key| is 256:
        -
        Set the `alg` attribute of |jwk| to - the string "`A256GCM`".
        -
        -
      8. -
      9. -

        - Set the `key_ops` attribute of |jwk| to equal the - {{CryptoKey/usages}} attribute of - |key|. -

        -
      10. -
      11. -

        - Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

        -
      12. -
      13. -

        - Let |result| be |jwk|. -

        -
      14. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    4. -
    5. -

      - Return |result|. -

      -
    6. -
    -
    -
    Get key length
    -
    -
      -
    1. -

      - If the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -

      - Return the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm|. -

      -
    4. -
    -
    - + + + +
  • +

    + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`enc`", + then [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +

    + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +

    + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

    +
  • + + +
    Otherwise:
    +
    + [= exception/throw =] a + {{NotSupportedError}}. +
    + + +
  • +

    + Let |key| be a new {{CryptoKey}} + object representing an AES key with value |data|. +

    +
  • +
  • +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

    +
  • +
  • +

    + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

    +
  • +
  • +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-GCM`". +

    +
  • +
  • +

    + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to the length, in bits, of |data|. +

    +
  • +
  • +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

    +
  • +
  • +

    + Return |key|. +

    +
  • + +
    + +
    +
    Export Key
    + +
      +
    1. +

      + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + Let |data| be a [= byte sequence =] containing + the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

        +
      2. +
      3. +

        + Let |result| be |data|. +

        +
      4. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +

        + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

        +
      2. +
      3. +

        + Set the `kty` attribute of |jwk| to the + string "`oct`". +

        +
      4. +
      5. +

        + Set the {{JsonWebKey/k}} attribute of |jwk| to be a string + containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. +

        +
      6. +
      7. +
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 128:
        +
        Set the `alg` attribute of |jwk| to + the string "`A128GCM`".
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 192:
        +
        Set the `alg` attribute of |jwk| to + the string "`A192GCM`".
        +
        If the {{AesKeyAlgorithm/length}} attribute of + |key| is 256:
        +
        Set the `alg` attribute of |jwk| to + the string "`A256GCM`".
        +
        +
      8. +
      9. +

        + Set the `key_ops` attribute of |jwk| to equal the + {{CryptoKey/usages}} attribute of + |key|. +

        +
      10. +
      11. +

        + Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

        +
      12. +
      13. +

        + Let |result| be |jwk|. +

        +
      14. +
      +
      +
      Otherwise:
      +
      +

      + [= exception/throw =] a + {{NotSupportedError}}. +

      +
      +
      +
    4. +
    5. +

      + Return |result|. +

      +
    6. +
    +
    + +
    +
    Get key length
    + +
      +
    1. +

      + If the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +

      + Return the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm|. +

      +
    4. +
    +
    @@ -13772,428 +13832,438 @@

    Registration

    Operations

    -
    -
    Wrap Key
    -
    -
      -
    1. -

      - If |plaintext| is not a multiple of 64 bits in length, - then [= exception/throw =] an - {{OperationError}}. -

      -
    2. -
    3. -

      - Let |ciphertext| be the result of performing the Key Wrap - operation described in Section 2.2.1 of [[RFC3394]] - with |plaintext| as the plaintext to be wrapped and using the default - Initial Value defined in Section 2.2.3.1 of the same document. -

      -
    4. -
    5. -

      - Return |ciphertext|. -

      -
    6. -
    -
    -
    Unwrap Key
    -
    -
      -
    1. -

      - Let |plaintext| be the result of performing the Key Unwrap - operation described in Section 2.2.2 of [[RFC3394]] with - |ciphertext| as the input ciphertext and using the default Initial - Value defined in Section 2.2.3.1 of the same document. -

      -
    2. -
    3. -

      - If the Key Unwrap operation returns an error, - then [= exception/throw =] an - {{OperationError}}. -

      -
    4. -
    5. -

      - Return |plaintext|. -

      -
    6. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains any entry which is not one of - "`wrapKey`" or "`unwrapKey`", then [= exception/throw =] a {{SyntaxError}}. -

      -
    2. -
    3. -

      - If the {{AesKeyGenParams/length}} property of - |normalizedAlgorithm| is not equal to one of 128, 192 or 256, then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -

      - Generate an AES key of length - equal to the {{AesKeyGenParams/length}} member of - |normalizedAlgorithm|. -

      -
    6. -
    7. -

      - If the key generation step fails, - then [= exception/throw =] an - {{OperationError}}. -

      -
    8. -
    9. -

      - Let |key| be a new - {{CryptoKey}} object representing the - generated AES key. -

      -
    10. -
    11. -

      - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

      -
    12. -
    13. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-KW`". -

      -
    14. -
    15. -

      - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to equal the - {{AesKeyGenParams/length}} property of - |normalizedAlgorithm|. -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    18. -
    19. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    20. -
    21. -

      - Set the {{CryptoKey/[[extractable]]}} internal - slot of |key| to be |extractable|. -

      -
    22. -
    23. -

      - Set the {{CryptoKey/[[usages]]}} internal slot of - |key| to be |usages|. -

      -
    24. -
    25. -

      - Return |key|. -

      -
    26. -
    -
    -
    Import Key
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - one of "`wrapKey`" or "`unwrapKey`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be |keyData|. -

        -
      2. -
      3. -

        - If the [= length in bits =] of |data| is not 128, 192 or 256 - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`oct`", - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If |jwk| does not meet the requirements of - Section 6.4 of JSON Web Algorithms [[JWA]], - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - Let |data| be the [= byte sequence =] obtained by decoding the - {{JsonWebKey/k}} field of |jwk|. -

        -
      8. -
      9. -
        -
        If the [= length in bits =] of |data| is 128:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A128KW`", - then [= exception/throw =] a - {{DataError}}.
        -
        If the [= length in bits =] of |data| is 192:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A192KW`", - then [= exception/throw =] a - {{DataError}}.
        -
        If the [= length in bits =] of |data| is 256:
        -
        If the {{JsonWebKey/alg}} field of |jwk| is present, and is - not "`A256KW`", - then [= exception/throw =] a - {{DataError}}.
        -
        Otherwise:
        -
        - [= exception/throw =] a - {{DataError}}. -
        -
        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`enc`", - then [= exception/throw =] a - {{DataError}}. -

        -
      12. -
      13. -

        - If the {{JsonWebKey/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 [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}.

        -
      16. -
      -
      -
      Otherwise:
      -
      +
      +
      Wrap Key
      + +
        +
      1. +

        + If |plaintext| is not a multiple of 64 bits in length, + then [= exception/throw =] an + {{OperationError}}. +

        +
      2. +
      3. +

        + Let |ciphertext| be the result of performing the Key Wrap + operation described in Section 2.2.1 of [[RFC3394]] + with |plaintext| as the plaintext to be wrapped and using the default + Initial Value defined in Section 2.2.3.1 of the same document. +

        +
      4. +
      5. +

        + Return |ciphertext|. +

        +
      6. +
      +
      + +
      +
      Unwrap Key
      + +
        +
      1. +

        + Let |plaintext| be the result of performing the Key Unwrap + operation described in Section 2.2.2 of [[RFC3394]] with + |ciphertext| as the input ciphertext and using the default Initial + Value defined in Section 2.2.3.1 of the same document. +

        +
      2. +
      3. +

        + If the Key Unwrap operation returns an error, + then [= exception/throw =] an + {{OperationError}}. +

        +
      4. +
      5. +

        + Return |plaintext|. +

        +
      6. +
      +
      + +
      +
      Generate Key
      + +
        +
      1. +

        + If |usages| contains any entry which is not one of + "`wrapKey`" or "`unwrapKey`", then [= exception/throw =] a {{SyntaxError}}. +

        +
      2. +
      3. +

        + If the {{AesKeyGenParams/length}} property of + |normalizedAlgorithm| is not equal to one of 128, 192 or 256, then [= exception/throw =] an {{OperationError}}. +

        +
      4. +
      5. +

        + Generate an AES key of length + equal to the {{AesKeyGenParams/length}} member of + |normalizedAlgorithm|. +

        +
      6. +
      7. +

        + If the key generation step fails, + then [= exception/throw =] an + {{OperationError}}. +

        +
      8. +
      9. +

        + Let |key| be a new + {{CryptoKey}} object representing the + generated AES key. +

        +
      10. +
      11. +

        + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

        +
      12. +
      13. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-KW`". +

        +
      14. +
      15. +

        + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to equal the + {{AesKeyGenParams/length}} property of + |normalizedAlgorithm|. +

        +
      16. +
      17. +

        + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

        +
      18. +
      19. +

        + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

        +
      20. +
      21. +

        + Set the {{CryptoKey/[[extractable]]}} internal + slot of |key| to be |extractable|. +

        +
      22. +
      23. +

        + Set the {{CryptoKey/[[usages]]}} internal slot of + |key| to be |usages|. +

        +
      24. +
      25. +

        + Return |key|. +

        +
      26. +
      +
      + +
      +
      Import Key
      + +
        +
      1. +

        + If |usages| contains an entry which is not + one of "`wrapKey`" or "`unwrapKey`", + + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +
        +
        If |format| is {{KeyFormat/"raw"}}:
        +
        +
          +
        1. +

          + Let |data| be |keyData|. +

          +
        2. +
        3. +

          + If the [= length in bits =] of |data| is not 128, 192 or 256 + then [= exception/throw =] a + {{DataError}}. +

          +
        4. +
        +
        +
        If |format| is {{KeyFormat/"jwk"}}:
        +
        +
          +
        1. +
          +
          If |keyData| is a {{JsonWebKey}} dictionary:
          +

          Let |jwk| equal |keyData|.

          +
          Otherwise:
          +

          [= exception/Throw =] a {{DataError}}.

          +
          +
        2. +
        3. +

          + If the {{JsonWebKey/kty}} field of |jwk| is not + "`oct`", + then [= exception/throw =] a + {{DataError}}. +

          +
        4. +
        5. +

          + If |jwk| does not meet the requirements of + Section 6.4 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

          +
        6. +
        7. +

          + Let |data| be the [= byte sequence =] obtained by decoding the + {{JsonWebKey/k}} field of |jwk|. +

          +
        8. +
        9. +
          +
          If the [= length in bits =] of |data| is 128:
          +
          If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A128KW`", + then [= exception/throw =] a + {{DataError}}.
          +
          If the [= length in bits =] of |data| is 192:
          +
          If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A192KW`", + then [= exception/throw =] a + {{DataError}}.
          +
          If the [= length in bits =] of |data| is 256:
          +
          If the {{JsonWebKey/alg}} field of |jwk| is present, and is + not "`A256KW`", + then [= exception/throw =] a + {{DataError}}.
          +
          Otherwise:
          +
          + [= exception/throw =] a + {{DataError}}. +
          +
          +
        10. +
        11. +

          + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`enc`", + then [= exception/throw =] a + {{DataError}}. +

          +
        12. +
        13. +

          + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

          +
        14. +
        15. +

          + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}.

          +
        16. +
        +
        +
        Otherwise:
        +
        + [= exception/throw =] a + {{NotSupportedError}}. +
        +
        +
      4. +
      5. +

        + Let |key| be a new {{CryptoKey}} + representing an AES key with value |data|. +

        +
      6. +
      7. +

        + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

        +
      8. +
      9. +

        + Let |algorithm| be a new + {{AesKeyAlgorithm}}. +

        +
      10. +
      11. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`AES-KW`". +

        +
      12. +
      13. +

        + Set the {{AesKeyAlgorithm/length}} attribute of + |algorithm| to the length, in bits, of |data|. +

        +
      14. +
      15. +

        + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

        +
      16. +
      17. +

        + Return |key|. +

        +
      18. +
      +
      + +
      +
      Export Key
      + +
        +
      1. +

        + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

        +
      2. +
      3. +
        +
        If |format| is {{KeyFormat/"raw"}}:
        +
        +
          +
        1. +

          + Let |data| be a [= byte sequence =] containing + the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

          +
        2. +
        3. +

          + Let |result| be |data|. +

          +
        4. +
        +
        +
        If |format| is {{KeyFormat/"jwk"}}:
        +
        +
          +
        1. +

          + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

          +
        2. +
        3. +

          + Set the `kty` attribute of |jwk| to the + string "`oct`". +

          +
        4. +
        5. +

          + Set the {{JsonWebKey/k}} attribute of |jwk| to be a string + containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. +

          +
        6. +
        7. +
          +
          If the {{AesKeyAlgorithm/length}} attribute of + |key| is 128:
          +
          Set the `alg` attribute of |jwk| to + the string "`A128KW`".
          +
          If the {{AesKeyAlgorithm/length}} attribute of + |key| is 192:
          +
          Set the `alg` attribute of |jwk| to + the string "`A192KW`".
          +
          If the {{AesKeyAlgorithm/length}} attribute of + |key| is 256:
          +
          Set the `alg` attribute of |jwk| to + the string "`A256KW`".
          +
          +
        8. +
        9. +

          + Set the `key_ops` attribute of |jwk| to equal the + {{CryptoKey/usages}} attribute of |key|. +

          +
        10. +
        11. +

          + Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

          +
        12. +
        13. +

          + Let |result| be |jwk|. +

          +
        14. +
        +
        +
        Otherwise:
        +
        +

        [= exception/throw =] a {{NotSupportedError}}. -

        -
        -
      4. -
      5. -

        - Let |key| be a new {{CryptoKey}} - representing an AES key with value |data|. -

        -
      6. -
      7. -

        - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

        -
      8. -
      9. -

        - Let |algorithm| be a new - {{AesKeyAlgorithm}}. -

        -
      10. -
      11. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`AES-KW`". -

        -
      12. -
      13. -

        - Set the {{AesKeyAlgorithm/length}} attribute of - |algorithm| to the length, in bits, of |data|. -

        -
      14. -
      15. -

        - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

        -
      16. -
      17. -

        - Return |key|. -

        -
      18. -
      -
      -
      Export Key
      -
      -
        -
      1. -

        - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

        -
      2. -
      3. -
        -
        If |format| is {{KeyFormat/"raw"}}:
        -
        -
          -
        1. -

          - Let |data| be a [= byte sequence =] containing - the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

          -
        2. -
        3. -

          - Let |result| be |data|. -

          -
        4. -
        -
        -
        If |format| is {{KeyFormat/"jwk"}}:
        -
        -
          -
        1. -

          - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

          -
        2. -
        3. -

          - Set the `kty` attribute of |jwk| to the - string "`oct`". -

          -
        4. -
        5. -

          - Set the {{JsonWebKey/k}} attribute of |jwk| to be a string - containing the raw octets of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. -

          -
        6. -
        7. -
          -
          If the {{AesKeyAlgorithm/length}} attribute of - |key| is 128:
          -
          Set the `alg` attribute of |jwk| to - the string "`A128KW`".
          -
          If the {{AesKeyAlgorithm/length}} attribute of - |key| is 192:
          -
          Set the `alg` attribute of |jwk| to - the string "`A192KW`".
          -
          If the {{AesKeyAlgorithm/length}} attribute of - |key| is 256:
          -
          Set the `alg` attribute of |jwk| to - the string "`A256KW`".
          -
          -
        8. -
        9. -

          - Set the `key_ops` attribute of |jwk| to equal the - {{CryptoKey/usages}} attribute of |key|. -

          -
        10. -
        11. -

          - Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

          -
        12. -
        13. -

          - Let |result| be |jwk|. -

          -
        14. -
        -
        -
        Otherwise:
        -
        -

        - [= exception/throw =] a - {{NotSupportedError}}. -

        -
        -
        -
      4. -
      5. -

        - Return |result|. -

        -
      6. -
      -
      -
      Get key length
      -
      -
        -
      1. -

        - If the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, then [= exception/throw =] an {{OperationError}}. -

        -
      2. -
      3. -

        - Return the {{AesDerivedKeyParams/length}} member of - |normalizedDerivedKeyAlgorithm|. -

        -
      4. -
      -
      -
      +

      +
    +
    + +
  • +

    + Return |result|. +

    +
  • + +
    + +
    +
    Get key length
    + +
      +
    1. +

      + If the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm| is not 128, 192 or 256, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +

      + Return the {{AesDerivedKeyParams/length}} member of + |normalizedDerivedKeyAlgorithm|. +

      +
    4. +
    +
    @@ -14298,632 +14368,643 @@

    HmacKeyGenParams dictionary

    Operations

    -
    -
    Sign
    -
    -
      -
    1. -

      - Let |mac| be the result of performing the MAC Generation operation - described in Section 4 of [[FIPS-198-1]] using - the key represented by the {{CryptoKey/[[handle]]}} - internal slot of |key|, the hash function identified by the {{HmacKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| and |message| as the input data |text|. -

      -
    2. -
    3. -

      - Return |mac|. -

      -
    4. -
    -
    -
    Verify
    -
    -
      -
    1. -

      - Let |mac| be the result of performing the MAC Generation operation - described in Section 4 of [[FIPS-198-1]] using - the key represented by the {{CryptoKey/[[handle]]}} - internal slot of |key|, the hash function identified by the {{HmacKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of - |key| and |message| as the input data |text|. -

      -
    2. -
    3. -

      - Return true if |mac| is equal to |signature| and false - otherwise. -

      -
    4. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains any entry which is not "`sign`" or - "`verify`", then [= exception/throw =] a {{SyntaxError}}. -

      -
    2. -
    3. -
      -
      - If the {{HmacKeyGenParams/length}} member of - |normalizedAlgorithm| is not present: -
      -
      - Let |length| be the block size in bits of the hash function - identified by the {{HmacKeyGenParams/hash}} member - of |normalizedAlgorithm|. -
      -
      - Otherwise, if the {{HmacKeyGenParams/length}} - member of |normalizedAlgorithm| is non-zero: -
      -
      - Let |length| be equal to the - {{HmacKeyGenParams/length}} - member of |normalizedAlgorithm|. -
      -
      Otherwise:
      -
      - [= exception/throw =] an - {{OperationError}}. -
      -
      -
    4. - -
    5. -

      - Generate a key of length |length| bits. -

      -
    6. -
    7. -

      - If the key generation step fails, - then [= exception/throw =] an - {{OperationError}}. -

      -
    8. -
    9. -

      - Let |key| be a new - {{CryptoKey}} object representing the - generated key. -

      -
    10. -
    11. -

      - Let |algorithm| be a new - {{HmacKeyAlgorithm}}. -

      -
    12. -
    13. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`HMAC`". -

      -
    14. -
    15. -

      - Set the {{HmacKeyAlgorithm/length}} attribute of - |algorithm| to |length|. -

      -
    16. -
    17. -

      - Let |hash| be a new - {{KeyAlgorithm}}. -

      -
    18. -
    19. -

      - Set the {{KeyAlgorithm/name}} attribute of - |hash| to equal the {{Algorithm/name}} - member of the {{HmacKeyGenParams/hash}} + +

      +
      Sign
      + +
        +
      1. +

        + Let |mac| be the result of performing the MAC Generation operation + described in Section 4 of [[FIPS-198-1]] using + the key represented by the {{CryptoKey/[[handle]]}} + internal slot of |key|, the hash function identified by the {{HmacKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| and |message| as the input data |text|. +

        +
      2. +
      3. +

        + Return |mac|. +

        +
      4. +
      +
      + +
      +
      Verify
      + +
        +
      1. +

        + Let |mac| be the result of performing the MAC Generation operation + described in Section 4 of [[FIPS-198-1]] using + the key represented by the {{CryptoKey/[[handle]]}} + internal slot of |key|, the hash function identified by the {{HmacKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| and |message| as the input data |text|. +

        +
      2. +
      3. +

        + Return true if |mac| is equal to |signature| and false + otherwise. +

        +
      4. +
      +
      + +
      +
      Generate Key
      + +
        +
      1. +

        + If |usages| contains any entry which is not "`sign`" or + "`verify`", then [= exception/throw =] a {{SyntaxError}}. +

        +
      2. +
      3. +
        +
        + If the {{HmacKeyGenParams/length}} member of + |normalizedAlgorithm| is not present: +
        +
        + Let |length| be the block size in bits of the hash function + identified by the {{HmacKeyGenParams/hash}} member + of |normalizedAlgorithm|. +
        +
        + Otherwise, if the {{HmacKeyGenParams/length}} + member of |normalizedAlgorithm| is non-zero: +
        +
        + Let |length| be equal to the + {{HmacKeyGenParams/length}} member of |normalizedAlgorithm|. -

        -
      4. -
      5. -

        - Set the {{HmacKeyAlgorithm/hash}} attribute - of |algorithm| to |hash|. -

        -
      6. -
      7. -

        - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

        -
      8. -
      9. -

        - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

        -
      10. -
      11. -

        - Set the {{CryptoKey/[[extractable]]}} internal - slot of |key| to be |extractable|. -

        -
      12. -
      13. -

        - Set the {{CryptoKey/[[usages]]}} internal slot of - |key| to be |usages|. -

        -
      14. -
      15. -

        - Return |key|. -

        -
      16. -
      -
    -
    Import Key
    -
    -
      -
    1. -

      Let |keyData| be the key data to be imported.

      -
    2. -
    3. -

      - If |usages| contains an entry which is not - "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - Let |hash| be a new {{KeyAlgorithm}}. -

      -
    6. -
    7. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |data| be |keyData|. -

        -
      2. -
      3. -

        - Set |hash| to equal the {{HmacImportParams/hash}} - member of |normalizedAlgorithm|. -

        -
      4. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`oct`", - then [= exception/throw =] a - {{DataError}}. -

        -
      4. -
      5. -

        - If |jwk| does not meet the requirements of - Section 6.4 of JSON Web Algorithms [[JWA]], +

      +
      Otherwise:
      +
      + [= exception/throw =] an + {{OperationError}}. +
      +
      +
    8. + +
    9. +

      + Generate a key of length |length| bits. +

      +
    10. +
    11. +

      + If the key generation step fails, + then [= exception/throw =] an + {{OperationError}}. +

      +
    12. +
    13. +

      + Let |key| be a new + {{CryptoKey}} object representing the + generated key. +

      +
    14. +
    15. +

      + Let |algorithm| be a new + {{HmacKeyAlgorithm}}. +

      +
    16. +
    17. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`HMAC`". +

      +
    18. +
    19. +

      + Set the {{HmacKeyAlgorithm/length}} attribute of + |algorithm| to |length|. +

      +
    20. +
    21. +

      + Let |hash| be a new + {{KeyAlgorithm}}. +

      +
    22. +
    23. +

      + Set the {{KeyAlgorithm/name}} attribute of + |hash| to equal the {{Algorithm/name}} + member of the {{HmacKeyGenParams/hash}} + member of |normalizedAlgorithm|. +

      +
    24. +
    25. +

      + Set the {{HmacKeyAlgorithm/hash}} attribute + of |algorithm| to |hash|. +

      +
    26. +
    27. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

      +
    28. +
    29. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

      +
    30. +
    31. +

      + Set the {{CryptoKey/[[extractable]]}} internal + slot of |key| to be |extractable|. +

      +
    32. +
    33. +

      + Set the {{CryptoKey/[[usages]]}} internal slot of + |key| to be |usages|. +

      +
    34. +
    35. +

      + Return |key|. +

      +
    36. +
    +
    + +
    +
    Import Key
    + +
      +
    1. +

      Let |keyData| be the key data to be imported.

      +
    2. +
    3. +

      + If |usages| contains an entry which is not + "`sign`" or "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + Let |hash| be a new {{KeyAlgorithm}}. +

      +
    6. +
    7. +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + Let |data| be |keyData|. +

        +
      2. +
      3. +

        + Set |hash| to equal the {{HmacImportParams/hash}} + member of |normalizedAlgorithm|. +

        +
      4. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +
        +
        If |keyData| is a {{JsonWebKey}} dictionary:
        +

        Let |jwk| equal |keyData|.

        +
        Otherwise:
        +

        [= exception/Throw =] a {{DataError}}.

        +
        +
      2. +
      3. +

        + If the {{JsonWebKey/kty}} field of |jwk| is not + "`oct`", + then [= exception/throw =] a + {{DataError}}. +

        +
      4. +
      5. +

        + If |jwk| does not meet the requirements of + Section 6.4 of JSON Web Algorithms [[JWA]], + then [= exception/throw =] a + {{DataError}}. +

        +
      6. +
      7. +

        + Let |data| be the [= byte sequence =] obtained by decoding the + {{JsonWebKey/k}} field of |jwk|. +

        +
      8. +
      9. +

        + Set the |hash| to equal the {{HmacImportParams/hash}} member of + |normalizedAlgorithm|. +

        +
      10. +
      11. +
        +
        + If the {{KeyAlgorithm/name}} attribute + of |hash| is + "`SHA-1`": +
        +
        + If the {{JsonWebKey/alg}} field of |jwk| is present + and is not "`HS1`", then [= exception/throw =] a {{DataError}}. -

        -
      12. -
      13. -

        - Let |data| be the [= byte sequence =] obtained by decoding the - {{JsonWebKey/k}} field of |jwk|. -

        -
      14. -
      15. -

        - Set the |hash| to equal the {{HmacImportParams/hash}} member of - |normalizedAlgorithm|. -

        -
      16. -
      17. -
        -
        - If the {{KeyAlgorithm/name}} attribute - of |hash| is - "`SHA-1`": -
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present - and is not "`HS1`", - then [= exception/throw =] a - {{DataError}}. -
        -
        - If the {{KeyAlgorithm/name}} attribute - of |hash| is - "`SHA-256`": -
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present - and is not "`HS256`", - then [= exception/throw =] a - {{DataError}}. -
        -
        - If the {{KeyAlgorithm/name}} attribute - of |hash| is - "`SHA-384`": -
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present - and is not "`HS384`", - then [= exception/throw =] a - {{DataError}}. -
        -
        - If the {{KeyAlgorithm/name}} attribute - of |hash| is - "`SHA-512`": -
        -
        - If the {{JsonWebKey/alg}} field of |jwk| is present - and is not "`HS512`", - then [= exception/throw =] a - {{DataError}}. -
        -
        - Otherwise, if the {{KeyAlgorithm/name}} attribute - of |hash| is defined in - another applicable - specification: -
        -
        - Perform any [= HMAC key import steps | key - import steps =] defined by - other applicable - specifications, passing |format|, |jwk| - and |hash| - and obtaining |hash|. -
        -
        -
      18. -
      19. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`sign`", +

      +
      + If the {{KeyAlgorithm/name}} attribute + of |hash| is + "`SHA-256`": +
      +
      + If the {{JsonWebKey/alg}} field of |jwk| is present + and is not "`HS256`", then [= exception/throw =] a {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/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, + +

      + If the {{KeyAlgorithm/name}} attribute + of |hash| is + "`SHA-384`": +
      +
      + If the {{JsonWebKey/alg}} field of |jwk| is present + and is not "`HS384`", then [= exception/throw =] a {{DataError}}. -

      -
    10. -
    11. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, + +

      + If the {{KeyAlgorithm/name}} attribute + of |hash| is + "`SHA-512`": +
      +
      + If the {{JsonWebKey/alg}} field of |jwk| is present + and is not "`HS512`", then [= exception/throw =] a {{DataError}}. -

      -
    12. -
    - -
    Otherwise:
    -
    +
    +
    + Otherwise, if the {{KeyAlgorithm/name}} attribute + of |hash| is defined in + another applicable + specification: +
    +
    + Perform any [= HMAC key import steps | key + import steps =] defined by + other applicable + specifications, passing |format|, |jwk| + and |hash| + and obtaining |hash|. +
    + + +
  • +

    + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`sign`", + then [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +

    + If the {{JsonWebKey/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 [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +

    + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

    +
  • + + +
    Otherwise:
    +
    + [= exception/throw =] a + {{NotSupportedError}}. +
    + + +
  • +

    + Let |length| be the [= length in bits =] of + |data|. +

    +
  • +
  • +

    + If |length| is zero + then [= exception/throw =] a + {{DataError}}. +

    +
  • +
  • +
    +
    + If the {{HmacImportParams/length}} member of + |normalizedAlgorithm| is present: +
    +
    +
    +
    + If the {{HmacImportParams/length}} member of + |normalizedAlgorithm| is greater than |length|: +
    +
    + [= exception/throw =] a + {{DataError}}. +
    +
    + If the {{HmacImportParams/length}} member of + |normalizedAlgorithm|, is less than or equal to + |length| minus eight: +
    +
    + [= exception/throw =] a + {{DataError}}. +
    +
    + Otherwise: +
    +
    + Set |length| equal to the {{HmacImportParams/length}} + member of |normalizedAlgorithm|. +
    +
    +
    +
    +
  • +
  • +

    + Let |key| be a new {{CryptoKey}} + object representing an HMAC key with the first |length| + bits of |data|. +

    +
  • +
  • +

    + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

    +
  • +
  • +

    + Let |algorithm| be a new + {{HmacKeyAlgorithm}}. +

    +
  • +
  • +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`HMAC`". +

    +
  • +
  • +

    + Set the {{HmacKeyAlgorithm/length}} attribute of + |algorithm| to |length|. +

    +
  • +
  • +

    + Set the {{HmacKeyAlgorithm/hash}} attribute of + |algorithm| to |hash|. +

    +
  • +
  • +

    + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

    +
  • +
  • +

    + Return |key|. +

    +
  • + +
    + +
    +
    Export Key
    + +
      +
    1. +

      + If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +

      + Let |bits| be the raw bits of the key represented by the {{CryptoKey/[[handle]]}} internal slot of + |key|. +

      +
    4. +
    5. +

      + Let |data| be a [= byte sequence containing =] |bits|. +

      +
    6. +
    7. +
      +
      If |format| is {{KeyFormat/"raw"}}:
      +
      +
        +
      1. +

        + Let |result| be |data|. +

        +
      2. +
      +
      +
      If |format| is {{KeyFormat/"jwk"}}:
      +
      +
        +
      1. +

        + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

        +
      2. +
      3. +

        + Set the `kty` attribute of |jwk| to the + string "`oct`". +

        +
      4. +
      5. +

        + Set the {{JsonWebKey/k}} attribute of |jwk| to be a string + containing |data|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. +

        +
      6. +
      7. +

        + Let |algorithm| be the {{CryptoKey/[[algorithm]]}} internal slot of + |key|. +

        +
      8. +
      9. +

        + Let |hash| be the + {{HmacKeyAlgorithm/hash}} attribute of + |algorithm|. +

        +
      10. + +
      11. +
        +
        If the {{KeyAlgorithm/name}} attribute of + |hash| is "`SHA-1`":
        +
        Set the `alg` attribute of |jwk| to + the string "`HS1`".
        +
        If the {{KeyAlgorithm/name}} attribute of + |hash| is "`SHA-256`":
        +
        Set the `alg` attribute of |jwk| to + the string "`HS256`".
        +
        If the {{KeyAlgorithm/name}} attribute of + |hash| is "`SHA-384`":
        +
        Set the `alg` attribute of |jwk| to + the string "`HS384`".
        +
        If the {{KeyAlgorithm/name}} attribute of + |hash| is "`SHA-512`":
        +
        Set the `alg` attribute of |jwk| to + the string "`HS512`".
        +
        + Otherwise, the {{KeyAlgorithm/name}} attribute + of |hash| is defined in + another applicable + specification: +
        +
        +
          +
        1. +

          + Perform any [= HMAC key export steps | key export steps =] defined by + other applicable + specifications, passing |format| and |key| + and obtaining |alg|. +

          +
        2. +
        3. +

          + Set the `alg` attribute of |jwk| to + |alg|. +

          +
        4. +
        +
        +
        +
      12. +
      13. +

        + Set the `key_ops` attribute of |jwk| to equal the + {{CryptoKey/usages}} attribute of |key|. +

        +
      14. +
      15. +

        + Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot + of |key|. +

        +
      16. +
      17. +

        + Let |result| be |jwk|. +

        +
      18. +
      +
      +
      Otherwise:
      +
      +

      [= exception/throw =] a {{NotSupportedError}}. -

      -
      -
    8. -
    9. -

      - Let |length| be the [= length in bits =] of - |data|. -

      -
    10. -
    11. -

      - If |length| is zero - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -
      -
      - If the {{HmacImportParams/length}} member of - |normalizedAlgorithm| is present: -
      -
      -
      -
      - If the {{HmacImportParams/length}} member of - |normalizedAlgorithm| is greater than |length|: -
      -
      - [= exception/throw =] a - {{DataError}}. -
      -
      - If the {{HmacImportParams/length}} member of - |normalizedAlgorithm|, is less than or equal to - |length| minus eight: -
      -
      - [= exception/throw =] a - {{DataError}}. -
      -
      - Otherwise: -
      -
      - Set |length| equal to the {{HmacImportParams/length}} - member of |normalizedAlgorithm|. -
      -
      -
      -
      -
    14. -
    15. -

      - Let |key| be a new {{CryptoKey}} - object representing an HMAC key with the first |length| - bits of |data|. -

      -
    16. -
    17. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    18. -
    19. -

      - Let |algorithm| be a new - {{HmacKeyAlgorithm}}. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`HMAC`". -

      -
    22. -
    23. -

      - Set the {{HmacKeyAlgorithm/length}} attribute of - |algorithm| to |length|. -

      -
    24. -
    25. -

      - Set the {{HmacKeyAlgorithm/hash}} attribute of - |algorithm| to |hash|. -

      -
    26. -
    27. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    28. -
    29. -

      - Return |key|. -

      -
    30. -
    - -
    Export Key
    -
    -
      -
    1. -

      - If the underlying cryptographic key material represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -

      - Let |bits| be the raw bits of the key represented by the {{CryptoKey/[[handle]]}} internal slot of - |key|. -

      -
    4. -
    5. -

      - Let |data| be a [= byte sequence containing =] |bits|. -

      -
    6. -
    7. -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - Let |result| be |data|. -

        -
      2. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to the - string "`oct`". -

        -
      4. -
      5. -

        - Set the {{JsonWebKey/k}} attribute of |jwk| to be a string - containing |data|, encoded according to Section 6.4 of JSON Web Algorithms [[JWA]]. -

        -
      6. -
      7. -

        - Let |algorithm| be the {{CryptoKey/[[algorithm]]}} internal slot of - |key|. -

        -
      8. -
      9. -

        - Let |hash| be the - {{HmacKeyAlgorithm/hash}} attribute of - |algorithm|. -

        -
      10. - -
      11. -
        -
        If the {{KeyAlgorithm/name}} attribute of - |hash| is "`SHA-1`":
        -
        Set the `alg` attribute of |jwk| to - the string "`HS1`".
        -
        If the {{KeyAlgorithm/name}} attribute of - |hash| is "`SHA-256`":
        -
        Set the `alg` attribute of |jwk| to - the string "`HS256`".
        -
        If the {{KeyAlgorithm/name}} attribute of - |hash| is "`SHA-384`":
        -
        Set the `alg` attribute of |jwk| to - the string "`HS384`".
        -
        If the {{KeyAlgorithm/name}} attribute of - |hash| is "`SHA-512`":
        -
        Set the `alg` attribute of |jwk| to - the string "`HS512`".
        -
        - Otherwise, the {{KeyAlgorithm/name}} attribute - of |hash| is defined in - another applicable - specification: -
        -
        -
          -
        1. -

          - Perform any [= HMAC key export steps | key export steps =] defined by - other applicable - specifications, passing |format| and |key| - and obtaining |alg|. -

          -
        2. -
        3. -

          - Set the `alg` attribute of |jwk| to - |alg|. -

          -
        4. -
        -
        -
        -
      12. -
      13. -

        - Set the `key_ops` attribute of |jwk| to equal the - {{CryptoKey/usages}} attribute of |key|. -

        -
      14. -
      15. -

        - Set the `ext` attribute of |jwk| to equal the {{CryptoKey/[[extractable]]}} internal slot - of |key|. -

        -
      16. -
      17. -

        - Let |result| be |jwk|. -

        -
      18. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    8. -
    9. -

      - Return |result|. -

      -
    10. -
    -
    -
    Get key length
    -
    -
      -
    1. -
      -
      - If the {{HmacImportParams/length}} member of - |normalizedDerivedKeyAlgorithm| is not present: -
      -
      -

      - Let |length| be the block size in bits of the hash function - identified by the {{HmacImportParams/hash}} member - of |normalizedDerivedKeyAlgorithm|. -

      -
      -
      - Otherwise, if the {{HmacImportParams/length}} - member of |normalizedDerivedKeyAlgorithm| is non-zero: -
      -
      - Let |length| be equal to the - {{HmacImportParams/length}} - member of |normalizedDerivedKeyAlgorithm|. -
      -
      Otherwise:
      -
      - [= exception/throw =] a - {{TypeError}}. -
      -
      -
    2. -
    3. -

      - Return |length|. -

      -
    4. -
    -
    - +

    + + + +
  • +

    + Return |result|. +

    +
  • + +
    + +
    +
    Get key length
    + +
      +
    1. +
      +
      + If the {{HmacImportParams/length}} member of + |normalizedDerivedKeyAlgorithm| is not present: +
      +
      +

      + Let |length| be the block size in bits of the hash function + identified by the {{HmacImportParams/hash}} member + of |normalizedDerivedKeyAlgorithm|. +

      +
      +
      + Otherwise, if the {{HmacImportParams/length}} + member of |normalizedDerivedKeyAlgorithm| is non-zero: +
      +
      + Let |length| be equal to the + {{HmacImportParams/length}} + member of |normalizedDerivedKeyAlgorithm|. +
      +
      Otherwise:
      +
      + [= exception/throw =] a + {{TypeError}}. +
      +
      +
    2. +
    3. +

      + Return |length|. +

      +
    4. +
    +

    -
    + +

    SHA

    Description

    @@ -14960,286 +15041,290 @@

    Registration

    Operations

    -
    -
    Digest
    -
    -
      -
    1. -
      -
      - If the {{Algorithm/name}} member of - |normalizedAlgorithm| is a cases-sensitive string match for - "`SHA-1`": -
      -
      - Let |result| be the result of performing the SHA-1 hash function - defined in Section 6.1 of [[FIPS-180-4]] using - |message| as the input message, |M|. -
      -
      - If the {{Algorithm/name}} member of - |normalizedAlgorithm| is a cases-sensitive string match for - "`SHA-256`": -
      -
      - Let |result| be the result of performing the SHA-256 hash function - defined in Section 6.2 of [[FIPS-180-4]] using - |message| as the input message, |M|. -
      -
      - If the {{Algorithm/name}} member of - |normalizedAlgorithm| is a cases-sensitive string match for - "`SHA-384`": -
      -
      - Let |result| be the result of performing the SHA-384 hash function - defined in Section 6.5 of [[FIPS-180-4]] using - |message| as the input message, |M|. -
      -
      - If the {{Algorithm/name}} member of - |normalizedAlgorithm| is a cases-sensitive string match for - "`SHA-512`": -
      -
      - Let |result| be the result of performing the SHA-512 hash function - defined in Section 6.4 of [[FIPS-180-4]] using - |message| as the input message, |M|. -
      -
      -
    2. -
    3. -

      - If performing the operation results in an error, then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -

      - Return |result|. -

      -
    6. -
    -
    -
    + +
    +
    Digest
    + +
      +
    1. +
      +
      + If the {{Algorithm/name}} member of + |normalizedAlgorithm| is a cases-sensitive string match for + "`SHA-1`": +
      +
      + Let |result| be the result of performing the SHA-1 hash function + defined in Section 6.1 of [[FIPS-180-4]] using + |message| as the input message, |M|. +
      +
      + If the {{Algorithm/name}} member of + |normalizedAlgorithm| is a cases-sensitive string match for + "`SHA-256`": +
      +
      + Let |result| be the result of performing the SHA-256 hash function + defined in Section 6.2 of [[FIPS-180-4]] using + |message| as the input message, |M|. +
      +
      + If the {{Algorithm/name}} member of + |normalizedAlgorithm| is a cases-sensitive string match for + "`SHA-384`": +
      +
      + Let |result| be the result of performing the SHA-384 hash function + defined in Section 6.5 of [[FIPS-180-4]] using + |message| as the input message, |M|. +
      +
      + If the {{Algorithm/name}} member of + |normalizedAlgorithm| is a cases-sensitive string match for + "`SHA-512`": +
      +
      + Let |result| be the result of performing the SHA-512 hash function + defined in Section 6.4 of [[FIPS-180-4]] using + |message| as the input message, |M|. +
      +
      +
    2. +
    3. +

      + If performing the operation results in an error, then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + Return |result|. +

      +
    6. +
    +
    -
    -

    HKDF

    -
    -

    Description

    -

    - The "`HKDF`" algorithm identifier is used to - perform key derivation using the extraction-then-expansion approach described in - [[RFC5869]] and - using the SHA hash functions defined in this specification. -

    -

    - Other specifications - may specify the use of additional hash algorithms with HKDF. - Such specifications must define the digest operation for the additional hash algorithms. -

    -
    -
    -

    Registration

    -

    - The [= recognized algorithm name =] - for this algorithm is "`HKDF`". -

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    OperationParametersResult
    deriveBits{{HkdfParams}}[= byte sequence =]
    importKeyNone{{CryptoKey}}
    Get key lengthNonenull
    -
    -
    -

    HkdfParams dictionary

    -
    -dictionary HkdfParams : Algorithm {
    -  required HashAlgorithmIdentifier hash;
    -  required BufferSource salt;
    -  required BufferSource info;
    -};
    -          
    -

    The hash member represents the algorithm to use with HMAC (e.g.: SHA-256).

    -

    The salt member represents the salt used in the extract step.

    -

    The info member represents application specific context for the derived keying material.

    -
    -
    -

    Operations

    -
    -
    Derive Bits
    -
    -
      -
    1. -

      - If |length| is null or is not a multiple of 8, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -

      - Let |keyDerivationKey| be the secret represented by the {{CryptoKey/[[handle]]}} internal slot of |key|. -

      -
    4. -
    5. -

      - Let |result| be the result of performing the HKDF extract and then - the HKDF expand step described in Section 2 of - [[RFC5869]] using: -

      -
        -
      • -

        - the {{HkdfParams/hash}} member of - |normalizedAlgorithm| as |Hash|, -

        -
      • -
      • -

        - |keyDerivationKey| as the input keying material, - |IKM|, -

        -
      • -
      • -

        - the {{HkdfParams/salt}} member of - |normalizedAlgorithm| as |salt|, -

        -
      • -
      • -

        - the {{HkdfParams/info}} member of - |normalizedAlgorithm| as |info|, -

        -
      • -
      • -

        - |length| divided by 8 as the value of |L|, -

        -
      • -
      -
    6. -
    7. -

      - If the key derivation operation fails, - then [= exception/throw =] an - {{OperationError}}. -

      -
    8. -
    9. -

      - Return |result|. -

      -
    10. -
    -
    -
    Import key
    -
    -
      -
    1. -

      Let |keyData| be the key data to be imported.

      -
    2. -
    3. -
      -
      - If |format| is {{KeyFormat/"raw"}}: -
      -
      -
        -
      1. -

        - If |usages| contains a value that is not - "`deriveKey`" or "`deriveBits`", - - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - If |extractable| is not `false`, - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      4. -
      5. -

        - Let |key| be a new {{CryptoKey}} - representing the key data provided in |keyData|. -

        -
      6. -
      7. -

        - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

        -
      8. -
      9. -

        - Let |algorithm| be a new - {{KeyAlgorithm}} object. -

        -
      10. -
      11. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`HKDF`". -

        -
      12. -
      13. -

        - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

        -
      14. -
      15. -

        - Return |key|. -

        -
      16. -
      -
      -
      Otherwise:
      -
      - [= exception/throw =] a - {{NotSupportedError}}. -
      -
      -
    4. -
    -
    -
    Get key length
    -
    -
      -
    1. -

      - Return null. -

      -
    2. -
    -
    -
    +
    +

    HKDF

    +
    +

    Description

    +

    + The "`HKDF`" algorithm identifier is used to + perform key derivation using the extraction-then-expansion approach described in + [[RFC5869]] and + using the SHA hash functions defined in this specification. +

    +

    + Other specifications + may specify the use of additional hash algorithms with HKDF. + Such specifications must define the digest operation for the additional hash algorithms. +

    +
    +
    +

    Registration

    +

    + The [= recognized algorithm name =] + for this algorithm is "`HKDF`". +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    OperationParametersResult
    deriveBits{{HkdfParams}}[= byte sequence =]
    importKeyNone{{CryptoKey}}
    Get key lengthNonenull
    +
    +
    +

    HkdfParams dictionary

    +
    +dictionary HkdfParams : Algorithm {
    +  required HashAlgorithmIdentifier hash;
    +  required BufferSource salt;
    +  required BufferSource info;
    +};
    +          
    +

    The hash member represents the algorithm to use with HMAC (e.g.: SHA-256).

    +

    The salt member represents the salt used in the extract step.

    +

    The info member represents application specific context for the derived keying material.

    +
    +
    +

    Operations

    + +
    +
    Derive Bits
    + +
      +
    1. +

      + If |length| is null or is not a multiple of 8, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +

      + Let |keyDerivationKey| be the secret represented by the {{CryptoKey/[[handle]]}} internal slot of |key|. +

      +
    4. +
    5. +

      + Let |result| be the result of performing the HKDF extract and then + the HKDF expand step described in Section 2 of + [[RFC5869]] using: +

      +
        +
      • +

        + the {{HkdfParams/hash}} member of + |normalizedAlgorithm| as |Hash|, +

        +
      • +
      • +

        + |keyDerivationKey| as the input keying material, + |IKM|, +

        +
      • +
      • +

        + the {{HkdfParams/salt}} member of + |normalizedAlgorithm| as |salt|, +

        +
      • +
      • +

        + the {{HkdfParams/info}} member of + |normalizedAlgorithm| as |info|, +

        +
      • +
      • +

        + |length| divided by 8 as the value of |L|, +

        +
      • +
      +
    6. +
    7. +

      + If the key derivation operation fails, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Return |result|. +

      +
    10. +
    +
    + +
    +
    Import key
    + +
      +
    1. +

      Let |keyData| be the key data to be imported.

      +
    2. +
    3. +
      +
      + If |format| is {{KeyFormat/"raw"}}: +
      +
      +
        +
      1. +

        + If |usages| contains a value that is not + "`deriveKey`" or "`deriveBits`", + + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      2. +
      3. +

        + If |extractable| is not `false`, + then [= exception/throw =] a + {{SyntaxError}}. +

        +
      4. +
      5. +

        + Let |key| be a new {{CryptoKey}} + representing the key data provided in |keyData|. +

        +
      6. +
      7. +

        + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

        +
      8. +
      9. +

        + Let |algorithm| be a new + {{KeyAlgorithm}} object. +

        +
      10. +
      11. +

        + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`HKDF`". +

        +
      12. +
      13. +

        + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

        +
      14. +
      15. +

        + Return |key|. +

        +
      16. +
      +
      +
      Otherwise:
      +
      + [= exception/throw =] a + {{NotSupportedError}}. +
      +
      +
    4. +
    +
    + +
    +
    Get key length
    + +
      +
    1. +

      + Return null. +

      +
    2. +
    +
    @@ -15307,130 +15392,134 @@

    Pbkdf2Params dictionary

    Operations

    -
    -
    Derive Bits
    -
    -
      -
    1. -

      - If |length| is null or is not a multiple of 8, then [= exception/throw =] an {{OperationError}}. -

      -
    2. -
    3. -

      - If the {{Pbkdf2Params/iterations}} member of |normalizedAlgorithm| is zero, - then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -

      - If |length| is zero, return an empty [= byte sequence =]. -

      -
    6. -
    7. -

      - Let |prf| be the MAC Generation function described in Section 4 of - [[FIPS-198-1]] using the hash function - described by the {{Pbkdf2Params/hash}} member of - |normalizedAlgorithm|. -

      -
    8. -
    9. -

      - Let |result| be the result of performing the PBKDF2 operation defined - in Section 5.2 of [[RFC8018]] using |prf| as the - pseudo-random function, |PRF|, the password represented by the {{CryptoKey/[[handle]]}} internal slot of |key| - as the password, |P|, - the {{Pbkdf2Params/salt}} attribute of - |normalizedAlgorithm| as the salt, |S|, the value of the {{Pbkdf2Params/iterations}} attribute of - |normalizedAlgorithm| as the iteration count, |c|, and - |length| divided by 8 as the intended key length, |dkLen|. -

      -
    10. -
    11. -

      - If the key derivation operation fails, - then [= exception/throw =] an - {{OperationError}}. -

      -
    12. -
    13. -

      - Return |result|. -

      -
    14. -
    -
    -
    Import key
    -
    -
      -
    1. -

      - If |format| is not {{KeyFormat/"raw"}}, [= exception/throw =] a {{NotSupportedError}} -

      -
    2. -
    3. -

      - If |usages| contains a value that is not - "`deriveKey`" or "`deriveBits`", then - [= exception/throw =] a {{SyntaxError}}. -

      -
    4. -
    5. -

      - If |extractable| is not `false`, - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    6. -
    7. -

      - Let |key| be a new {{CryptoKey}} - representing |keyData|. -

      -
    8. -
    9. -

      - Set the {{CryptoKey/[[type]]}} internal slot of - |key| to {{KeyType/"secret"}}. -

      -
    10. -
    11. -

      - Let |algorithm| be a new {{KeyAlgorithm}} - object. -

      -
    12. -
    13. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`PBKDF2`". -

      -
    14. -
    15. -

      - Set the {{CryptoKey/[[algorithm]]}} internal - slot of |key| to |algorithm|. -

      -
    16. -
    17. -

      - Return |key|. -

      -
    18. -
    -
    -
    Get key length
    -
    -
      -
    1. -

      - Return null. -

      -
    2. -
    -
    -
    + +
    +
    Derive Bits
    + +
      +
    1. +

      + If |length| is null or is not a multiple of 8, then [= exception/throw =] an {{OperationError}}. +

      +
    2. +
    3. +

      + If the {{Pbkdf2Params/iterations}} member of |normalizedAlgorithm| is zero, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + If |length| is zero, return an empty [= byte sequence =]. +

      +
    6. +
    7. +

      + Let |prf| be the MAC Generation function described in Section 4 of + [[FIPS-198-1]] using the hash function + described by the {{Pbkdf2Params/hash}} member of + |normalizedAlgorithm|. +

      +
    8. +
    9. +

      + Let |result| be the result of performing the PBKDF2 operation defined + in Section 5.2 of [[RFC8018]] using |prf| as the + pseudo-random function, |PRF|, the password represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + as the password, |P|, + the {{Pbkdf2Params/salt}} attribute of + |normalizedAlgorithm| as the salt, |S|, the value of the {{Pbkdf2Params/iterations}} attribute of + |normalizedAlgorithm| as the iteration count, |c|, and + |length| divided by 8 as the intended key length, |dkLen|. +

      +
    10. +
    11. +

      + If the key derivation operation fails, + then [= exception/throw =] an + {{OperationError}}. +

      +
    12. +
    13. +

      + Return |result|. +

      +
    14. +
    +
    + +
    +
    Import key
    + +
      +
    1. +

      + If |format| is not {{KeyFormat/"raw"}}, [= exception/throw =] a {{NotSupportedError}} +

      +
    2. +
    3. +

      + If |usages| contains a value that is not + "`deriveKey`" or "`deriveBits`", then + [= exception/throw =] a {{SyntaxError}}. +

      +
    4. +
    5. +

      + If |extractable| is not `false`, + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    6. +
    7. +

      + Let |key| be a new {{CryptoKey}} + representing |keyData|. +

      +
    8. +
    9. +

      + Set the {{CryptoKey/[[type]]}} internal slot of + |key| to {{KeyType/"secret"}}. +

      +
    10. +
    11. +

      + Let |algorithm| be a new {{KeyAlgorithm}} + object. +

      +
    12. +
    13. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`PBKDF2`". +

      +
    14. +
    15. +

      + Set the {{CryptoKey/[[algorithm]]}} internal + slot of |key| to |algorithm|. +

      +
    16. +
    17. +

      + Return |key|. +

      +
    18. +
    +
    + +
    +
    Get key length
    + +
      +
    1. +

      + Return null. +

      +
    2. +
    +