--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/Overview-CR.html Thu Nov 06 14:53:14 2014 -0800
@@ -0,0 +1,17996 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Web Cryptography API</title>
+
+ <link rel="stylesheet" href="webcrypto.css" type="text/css" />
+ <script src="section-links.js" type="application/ecmascript"></script>
+ <script src="dfn.js" type="application/ecmascript"></script>
+ <!--[if IE]>
+ <style type='text/css'>
+ .ignore {
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
+ filter: alpha(opacity=50);
+ }
+ </style>
+ <![endif]-->
+
+
+ <link rel="stylesheet" href="//www.w3.org/StyleSheets/TR/W3C-CR" type="text/css" /></head>
+
+ <body>
+ <div class="head"><div><a href="http://www.w3.org/"><img src="//www.w3.org/Icons/w3c_home" width="72" height="48" alt="W3C" /></a></div><h1>Web Cryptography API</h1><h2>W3C Candidate Recommendation <em>NaN @@ rypt</em></h2><dl><dt>This Version:</dt><dd><a href="http://www.w3.org/TR/WebCryptoAPI/">http://www.w3.org/TR/WebCryptoAPI/</a></dd><dt>Latest Published Version:</dt><dd><a href="http://www.w3.org/TR/WebCryptoAPI/">http://www.w3.org/TR/WebCryptoAPI/</a></dd><dt>Latest Editor’s Draft:</dt><dd><a href="http://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html">http://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html</a></dd><dt>Previous Version(s):</dt><dd><a href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/0fe9b34c13fb/spec/Overview.html">https://dvcs.w3.org/hg/webcrypto-api/raw-file/0fe9b34c13fb/spec/Overview.html</a></dd><dt>Editors:</dt><dd><a href="http://www.google.com/">Ryan Sleevi</a>, Google, Inc. <sleevi@google.com></dd><dd><a href="http://www.netflix.com/">Mark Watson</a>, Netflix <watsonm@netflix.com></dd><dt>Participate:</dt><dd><p>Send feedback to <a href="mailto:public-webcrypto@w3.org?subject=%5BWebCryptoAPI%5D">public-webcrypto@w3.org</a> (<a href="http://lists.w3.org/Archives/Public/public-webcrypto/">archives</a>), or <a href="https://www.w3.org/Bugs/Public/enter_bug.cgi?product=Web%20Cryptography&component=Web%20Cryptography%20API%20Document">file a bug</a>
+ (see <a href="https://www.w3.org/Bugs/Public/buglist.cgi?product=Web%20Cryptography&component=Web%20Cryptography%20API%20Document&resolution=---">existing bugs</a>).</p></dd></dl><p class="copyright"><a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © rypt <a href="http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href="http://www.ercim.org/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply.</p></div><hr />
+
+ <div class="section">
+ <h2>Abstract</h2>
+ <p>
+ This specification describes a JavaScript API for performing basic
+ cryptographic operations in web applications, such as hashing,
+ signature generation and verification, and encryption and decryption.
+ Additionally, it describes an API for applications to generate and/or
+ manage the keying material necessary to perform these operations.
+ Uses for this API range from user or service authentication, document
+ or code signing, and the confidentiality and integrity of
+ communications.
+ </p>
+
+
+ </div>
+
+ <div class="section">
+ <h2>Status of this Document</h2>
+ <p><em>
+ This section describes the status of this document at the time of
+ its publication. Other documents may supersede this document. A list
+ of current W3C publications and the latest revision of this technical
+ report can be found in the <a href="http://www.w3.org/TR/">W3C technical
+ reports index</a> at http://www.w3.org/TR/.
+ </em></p><p>
+ This document is the NaN @@ rypt <b>Candidate Recommendation</b> of the
+ <cite>Web Cryptography API</cite> specification.
+
+ Please send comments about this document to
+ <a href="mailto:public-webcrypto-comments@w3.org">public-webcrypto-comments@w3.org</a>
+ (<a href="http://lists.w3.org/Archives/Public/public-webcrypto-comments/">archived</a>).
+ </p>
+
+ <p>
+ This document is produced by the <a href="http://www.w3.org/2012/webcrypto">Web Cryptography
+ <acronym title="Working Group">WG</acronym></a> of the <acronym title="World Wide Web Consortium">W3C</acronym>.
+ </p>
+
+ <p class="XXX">
+ Implementors should be aware that this specification is not stable.
+ <strong>Implementors who are not taking part in the discussions are likely to find the
+ specification changing out from under them in incompatible ways.</strong> Vendors interested
+ in implementing this specification before it eventually reaches the Candidate Recommendation
+ stage should join the mailing lists that follow and take part in the discussions.
+ </p>
+ <p>
+ The Web Cryptography Working Group invites discussion and feedback on this draft document by
+ web developers, companies, standardization bodies or forums interested in deployment of secure
+ services with web applications. Specifically, Web Cryptography Working Group is looking for
+ feedback on:
+ </p>
+ <ul>
+ <li>developer convenience for managing keys and algorithms;</li>
+ <li>comments on open issues the WG is currently dealing with, highlighted in this working draft;</li>
+ <li>potential missing functionalities to deploy secure web applications.</li>
+ </ul>
+ <p>
+ Previous discussion of this specification has taken place on three other
+ mailing lists: <a href="mailto:whatwg@whatwg.org">whatwg@whatwg.org</a>
+ (<a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/031741.html">archive</a>)
+ , <a href="mailto:public-websecurity@w3.org">public-websecurity@w3.org</a>
+ (<a href="http://lists.w3.org/Archives/Public/public-web-security/2011Jun/0000.html">archive</a>), and
+ <a href="mailto:public-identity@w3.org">public-identity@w3.org</a> (<a href="http://www.w3.org/Search/Mail/Public/search?type-index=public-identity&index-type=t&keywords=DOMCrypt&search=Search">archive</a>).
+ Ongoing discussion will be on the <a href="mailto:public-webcrypto@w3.org">public-webcrypto@w3.org</a>
+ mailing list.
+ </p>
+
+ <p>
+ Web content and browser developers are encouraged to review this draft. Please send comments
+ to <a href="mailto:public-webcrypto-comments@w3.org">public-webcrypto-comments@w3.org</a>,
+ the <acronym title="World Wide Web Consortium">W3C</acronym>'s public email list for issues
+ related to Web Cryptography. <a href="http://lists.w3.org/Archives/Public/public-webcrypto-comments/">Archives</a> of the
+ public list and <a href="http://lists.w3.org/Archives/Public/public-webcrypto/">archives</a>
+ of the member's-only list are available.
+ </p>
+ <p>
+ Changes made to this document can be found in the
+ <a href="https://dvcs.w3.org/hg/webcrypto-api/file/tip/spec/">W3C public Mercurial server</a>.
+ </p>
+
+ <p>
+ Publication as a Candidate Recommendation does not imply endorsement by the
+ W3C Membership. This is a draft document and may be updated, replaced
+ or obsoleted by other documents at any time. It is inappropriate to cite
+ this document as other than work in progress.
+ </p><p>
+ This document was produced by a group operating under the
+ <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February
+ 2004 W3C Patent Policy</a>. W3C maintains a
+ <a href="http://www.w3.org/2004/01/pp-impl/54174/status">public list of
+ any patent disclosures</a> made in connection with the deliverables of
+ the group; that page also includes instructions for disclosing a patent.
+ An individual who has actual knowledge of a patent which the individual
+ believes contains
+ <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential
+ Claim(s)</a> must disclose the information in accordance with
+ <a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section
+ 6 of the W3C Patent Policy</a>.
+ </p>
+ </div>
+
+ <div id="toc">
+ <h2>Table of Contents</h2>
+ <div class="toc"><ul><li><a href="#introduction">1. Introduction</a></li><li><a href="#use-cases">2. Use Cases</a><ul><li><a href="#multifactor-authentication">2.1. Multi-factor Authentication</a></li><li><a href="#protected-document">2.2. Protected Document Exchange</a></li><li><a href="#cloud-storage">2.3. Cloud Storage</a></li><li><a href="#document-signing">2.4. Document Signing</a></li><li><a href="#data-integrity-protection">2.5. Data Integrity Protection</a></li><li><a href="#secure-messaging">2.6. Secure Messaging</a></li><li><a href="#jose">2.7. Javascript Object Signing and Encryption (JOSE)</a></li></ul></li><li><a href="#conformance">3. Conformance</a><ul><li><a href="#extensibility">3.1. Extensibility</a></li></ul></li><li><a href="#scope">4. Scope</a><ul><li><a href="#scope-abstraction">4.1. Level of abstraction</a></li><li><a href="#scope-algorithms">4.2. Cryptographic algorithms</a></li><li><a href="#scope-operations">4.3. Operations</a></li><li><a href="#scope-out-of-scope">4.4. Out of scope</a></li></ul></li><li><a href="#concepts">5. Concepts</a><ul><li><a href="#concepts-underlying-implementation">5.1. Underlying Cryptographic Implementation</a></li><li><a href="#concepts-key-storage">5.2. Key Storage</a></li></ul></li><li><a href="#security">6. Security considerations</a><ul><li><a href="#security-implementers">6.1. Security considerations for implementers</a></li><li><a href="#security-developers">6.2. Security considerations for authors</a></li><li><a href="#security-users">6.3. Security considerations for users</a></li></ul></li><li><a href="#privacy">7. Privacy considerations</a></li><li><a href="#dependencies">8. Dependencies</a></li><li><a href="#terminology">9. Terminology</a></li><li><a href="#crypto-interface">10. Crypto interface</a><ul><li><a href="#Crypto-description">10.1. Description</a></li><li><a href="#Crypto-interface-methods">10.2. Methods and Parameters</a><ul><li><a href="#Crypto-method-getRandomValues">10.2.1. The getRandomValues method</a></li></ul></li><li><a href="#Crypto-interface-attributes">10.3. Attributes</a><ul><li><a href="#Crypto-attribute-subtle">10.3.1. The subtle attribute</a></li></ul></li></ul></li><li><a href="#algorithm-dictionary">11. Algorithm dictionary</a><ul><li><a href="#algorithm-dictionary-members">11.1. Algorithm Dictionary Members</a></li></ul></li><li><a href="#key-algorithm-dictionary">12. KeyAlgorithm dictionary</a><ul><li><a href="#key-algorithm-dictionary-description">12.1. Description</a></li><li><a href="#key-algorithm-dictionary-members">12.2. KeyAlgorithm dictionary members</a></li></ul></li><li><a href="#cryptokey-interface">13. CryptoKey interface</a><ul><li><a href="#cryptokey-interface-description">13.1. Description</a></li><li><a href="#cryptokey-interface-types">13.2. Key interface data types</a></li><li><a href="#cryptokey-interface-internal-slots">13.3. CryptoKey internal slots</a></li><li><a href="#cryptokey-interface-members">13.4. CryptoKey interface members</a></li><li><a href="#cryptokey-interface-clone">13.5. Structured clone algorithm</a></li></ul></li><li><a href="#subtlecrypto-interface">14. SubtleCrypto interface</a><ul><li><a href="#subtlecrypto-interface-description">14.1. Description</a></li><li><a href="#subtlecrypto-interface-datatypes">14.2. Data Types</a></li><li><a href="#subtlecrypto-interface-methods">14.3. Methods and Parameters</a><ul><li><a href="#SubtleCrypto-method-encrypt">14.3.1. The encrypt method</a></li><li><a href="#SubtleCrypto-method-decrypt">14.3.2. The decrypt method</a></li><li><a href="#SubtleCrypto-method-sign">14.3.3. The sign method</a></li><li><a href="#SubtleCrypto-method-verify">14.3.4. The verify method</a></li><li><a href="#SubtleCrypto-method-digest">14.3.5. The digest method</a></li><li><a href="#SubtleCrypto-method-generateKey">14.3.6. The generateKey method</a></li><li><a href="#SubtleCrypto-method-deriveKey">14.3.7. The deriveKey method</a></li><li><a href="#SubtleCrypto-method-deriveBits">14.3.8. The deriveBits method</a></li><li><a href="#SubtleCrypto-method-importKey">14.3.9. The importKey method</a></li><li><a href="#SubtleCrypto-method-exportKey">14.3.10. The exportKey method</a></li><li><a href="#SubtleCrypto-method-wrapKey">14.3.11. The wrapKey method</a></li><li><a href="#SubtleCrypto-method-unwrapKey">14.3.12. The unwrapKey method</a></li></ul></li><li><a href="#SubtleCrypto-Exceptions">14.4. Exceptions</a></li></ul></li><li><a href="#JsonWebKey-dictionary">15. JsonWebKey dictionary</a></li><li><a href="#big-integer">16. BigInteger</a></li><li><a href="#keypair">17. CryptoKeyPair dictionary</a></li><li><a href="#algorithms">18. Algorithms</a><ul><li><a href="#algorithm-overview">18.1. Overview</a></li><li><a href="#algorithm-concepts">18.2. Concepts</a><ul><li><a href="#algorithm-concepts-naming">18.2.1. Naming</a></li><li><a href="#algorithm-concepts-operations">18.2.2. Supported Operations</a></li><li><a href="#algorithm-concepts-normalization">18.2.3. Normalization</a></li></ul></li><li><a href="#algorithm-conventions">18.3. Specification Conventions</a></li><li><a href="#algorithm-normalizing">18.4. Algorithm Normalization</a><ul><li><a href="#algorithm-normalizing-description">18.4.1. Description</a></li><li><a href="#algorithm-normalizing-internal">18.4.2. Internal State Objects</a></li><li><a href="#algorithm-normalizing-define-an-algorithm">18.4.3. Defining an Algorithm</a></li><li><a href="#algorithm-normalizing-normalize-an-algorithm">18.4.4. Normalizing an algorithm</a></li></ul></li><li><a href="#algorithm-recommendations">18.5. Recommendations</a><ul><li><a href="#algorithm-recommendations-authors">18.5.1. For Authors</a></li><li><a href="#algorithm-recommendations-implementers">18.5.2. For Implementers</a></li></ul></li></ul></li><li><a href="#algorithm-overview">19. Algorithm Overview</a></li><li><a href="#rsassa-pkcs1">20. RSASSA-PKCS1-v1_5</a><ul><li><a href="#rsassa-pkcs1-description">20.1. Description</a></li><li><a href="#rsassa-pkcs1-registration">20.2. Registration</a></li><li><a href="#RsaKeyGenParams-dictionary">20.3. RsaKeyGenParams dictionary</a></li><li><a href="#RsaHashedKeyGenParams-dictionary">20.4. RsaHashedKeyGenParams dictionary</a></li><li><a href="#RsaKeyAlgorithm-dictionary">20.5. RsaKeyAlgorithm dictionary</a></li><li><a href="#RsaHashedKeyAlgorithm-dictionary">20.6. RsaHashedKeyAlgorithm dictionary</a></li><li><a href="#RsaHashedImportParams-dictionary">20.7. RsaHashedImportParams dictionary</a></li><li><a href="#rsassa-pkcs1-operations">20.8. Operations</a></li></ul></li><li><a href="#rsa-pss">21. RSA-PSS</a><ul><li><a href="#rsa-pss-description">21.1. Description</a></li><li><a href="#rsa-pss-registration">21.2. Registration</a></li><li><a href="#RsaPssParams-dictionary">21.3. RsaPssParams dictionary</a></li><li><a href="#rsa-pss-operations">21.4. Operations</a></li></ul></li><li><a href="#rsa-oaep">22. RSA-OAEP</a><ul><li><a href="#rsa-oaep-description">22.1. Description</a></li><li><a href="#rsa-oaep-registration">22.2. Registration</a></li><li><a href="#rsa-oaep-params">22.3. RsaOaepParams dictionary</a></li><li><a href="#rsa-oaep-operations">22.4. Operations</a></li></ul></li><li><a href="#ecdsa">23. ECDSA</a><ul><li><a href="#ecdsa-description">23.1. Description</a></li><li><a href="#ecdsa-registration">23.2. Registration</a></li><li><a href="#EcdsaParams-dictionary">23.3. EcdsaParams dictionary</a></li><li><a href="#EcKeyGenParams-dictionary">23.4. EcKeyGenParams dictionary</a></li><li><a href="#EcKeyAlgorithm-dictionary">23.5. EcKeyAlgorithm dictionary</a></li><li><a href="#EcKeyImportParams-dictionary">23.6. EcKeyImportParams dictionary</a></li><li><a href="#ecdsa-operations">23.7. Operations</a></li></ul></li><li><a href="#ecdh">24. ECDH</a><ul><li><a href="#ecdh-description">24.1. Description</a></li><li><a href="#ecdh-registration">24.2. Registration</a></li><li><a href="#dh-EcdhKeyDeriveParams">24.3. EcdhKeyDeriveParams dictionary</a></li><li><a href="#ecdh-operations">24.4. Operations</a></li></ul></li><li><a href="#aes-ctr">25. AES-CTR</a><ul><li><a href="#aes-ctr-description">25.1. Description</a></li><li><a href="#aes-ctr-registration">25.2. Registration</a></li><li><a href="#aes-ctr-params">25.3. AesCtrParams dictionary</a></li><li><a href="#AesKeyAlgorithm-dictionary">25.4. </a></li><li><a href="#aes-keygen-params">25.5. AesKeyGenParams dictionary</a></li><li><a href="#aes-derivedkey-params">25.6. AesDerivedKeyParams dictionary</a></li><li><a href="#aes-ctr-operations">25.7. Operations</a></li></ul></li><li><a href="#aes-cbc">26. AES-CBC</a><ul><li><a href="#aes-cbc-description">26.1. Description</a></li><li><a href="#aes-cbc-registration">26.2. Registration</a></li><li><a href="#aes-cbc-params">26.3. AesCbcParams dictionary</a></li><li><a href="#aes-cbc-operations">26.4. Operations</a></li></ul></li><li><a href="#aes-cmac">27. AES-CMAC</a><ul><li><a href="#aes-cmac-description">27.1. Description</a></li><li><a href="#aes-cmac-registration">27.2. Registration</a></li><li><a href="#aes-cmac-params">27.3. AesCmacParams dictionary</a></li><li><a href="#aes-cmac-operations">27.4. Operations</a></li></ul></li><li><a href="#aes-gcm">28. AES-GCM</a><ul><li><a href="#aes-gcm-description">28.1. Description</a></li><li><a href="#aes-gcm-registration">28.2. Registration</a></li><li><a href="#aes-gcm-params">28.3. AesGcmParams dictionary</a></li><li><a href="#aes-gcm-operations">28.4. Operations</a></li></ul></li><li><a href="#aes-cfb">29. AES-CFB</a><ul><li><a href="#aes-cfb-description">29.1. Description</a></li><li><a href="#aes-cfb-registration">29.2. Registration</a></li><li><a href="#aes-cfb-params">29.3. AesCfbParams dictionary</a></li><li><a href="#aes-cfb-operations">29.4. Operations</a></li></ul></li><li><a href="#aes-kw">30. AES-KW</a><ul><li><a href="#aes-kw-description">30.1. Description</a></li><li><a href="#aes-kw-registration">30.2. Registration</a></li><li><a href="#aes-kw-operations">30.3. Operations</a></li></ul></li><li><a href="#hmac">31. HMAC</a><ul><li><a href="#hmac-description">31.1. Description</a></li><li><a href="#hmac-registration">31.2. Registration</a></li><li><a href="#hmac-importparams">31.3. HmacImportParams dictionary</a></li><li><a href="#HmacKeyAlgorithm-dictionary">31.4. HmacKeyAlgorithm dictionary</a></li><li><a href="#hmac-keygen-params">31.5. HmacKeyGenParams dictionary</a></li><li><a href="#hmac-operations">31.6. Operations</a></li></ul></li><li><a href="#dh">32. Diffie-Hellman</a><ul><li><a href="#dh-description">32.1. Description</a></li><li><a href="#dh-registration">32.2. Registration</a></li><li><a href="#dh-DhKeyGenParams">32.3. DhKeyGenParams dictionary</a></li><li><a href="#dh-DhKeyAlgorithm">32.4. DhKeyAlgorithm dictionary</a></li><li><a href="#dh-DhKeyDeriveParams">32.5. DhKeyDeriveParams dictionary</a></li><li><a href="#dh-DhImportKeyParams">32.6. DhImportKeyParams dictionary</a></li><li><a href="#dh-operations">32.7. Operations</a></li></ul></li><li><a href="#sha">33. SHA</a><ul><li><a href="#sha-description">33.1. Description</a></li><li><a href="#sha-registration">33.2. Registration</a></li><li><a href="#sha-operations">33.3. Operations</a></li></ul></li><li><a href="#concatkdf">34. Concat KDF</a><ul><li><a href="#concatkdf-description">34.1. Description</a></li><li><a href="#concatkdf-registration">34.2. Registration</a></li><li><a href="#concat-params">34.3. ConcatParams dictionary</a></li><li><a href="#concat-operations">34.4. Operations</a></li></ul></li><li><a href="#hkdf-ctr">35. HKDF-CTR</a><ul><li><a href="#hkdf-ctr-description">35.1. Description</a></li><li><a href="#hkdf-ctr-registration">35.2. Registration</a></li><li><a href="#hkdf-ctr-params">35.3. HkdfCtrParams dictionary</a></li><li><a href="#hkdf2-ctr-operations">35.4. Operations</a></li></ul></li><li><a href="#pbkdf2">36. PBKDF2</a><ul><li><a href="#pbkdf2-description">36.1. Description</a></li><li><a href="#pbkdf2-registration">36.2. Registration</a></li><li><a href="#pbkdf2-params">36.3. Pbkdf2Params dictionary</a></li><li><a href="#pbkdf2-operations">36.4. Operations</a></li></ul></li><li><a href="#examples-section">37. JavaScript Example Code</a><ul><li><a href="#examples-signing">37.1. Generate a signing key pair, sign some data</a></li><li><a href="#examples-symmetric-encryption">37.2. Symmetric Encryption</a></li></ul></li><li><a href="#iana-section">38. IANA Considerations</a><ul><li><a href="#iana-section-jws-jwa">38.1. JSON Web Signature and Encryption Algorithms Registration</a></li><li><a href="#iana-section-jwk">38.2. JSON Web Key Parameters Registration</a></li></ul></li><li><a href="#acknowledgements-section">39. Acknowledgements</a></li><li><a href="#references">40. References</a><ul><li><a href="#normative-references">40.1. Normative References</a></li><li><a href="#informative-references">40.2. Informative References</a></li></ul></li></ul><ul><li><a href="#jwk-mapping">A. Mapping between JSON Web Key / JSON Web Algorithm</a><ul><li><a href="#jwk-mapping-alg">A.1. Algorithm mappings</a></li><li><a href="#jwk-mapping-usage">A.2. Usage mapping</a></li></ul></li><li><a href="#spki-mapping">B. Mapping between Algorithm and SubjectPublicKeyInfo</a></li><li><a href="#pkcs8-mapping">C. Mapping between Algorithm and PKCS#8 PrivateKeyInfo</a></li></ul></div>
+ </div>
+
+ <div id="sections">
+ <div id="introduction" class="section">
+ <h2>1. Introduction</h2>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The Web Cryptography API defines a low-level interface to interacting with cryptographic
+ key material that is managed or exposed by user agents. The API itself is agnostic of
+ the underlying implementation of key storage, but provides a common set of interfaces
+ that allow rich web applications to perform operations such as signature generation and
+ verification, hashing and verification, encryption and decryption, without requiring
+ access to the raw keying material.
+ </p>
+ <p>
+ Cryptographic transformations are exposed via the
+ <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface, which defines a common set
+ of methods and events for dealing with initialization, processing data, and completing
+ the operation to yield the final output. In addition to operations such as signature
+ generation and verification, hashing and verification, and encryption and decryption,
+ the API provides interfaces for key generation, key derivation, key import and export,
+ and key discovery.
+ </p>
+ </div>
+
+ <div id="use-cases" class="section">
+ <h2>2. Use Cases</h2>
+ <p class="norm">This section is non-normative</p>
+ <div id="multifactor-authentication" class="section">
+ <h3>2.1. Multi-factor Authentication</h3>
+ <p>
+ A web application may wish to extend or replace existing username/password based
+ authentication schemes with authentication methods based on proving that the user has
+ access to some secret keying material. Rather than using transport-layer authentication,
+ such as TLS client certificates, the web application may wish to provide a rich user
+ experience by providing authentication within the application itself.
+ </p>
+ <p>
+ Using the Web Cryptography API, such an application could locate suitable client keys,
+ which may have been previously generated via the user agent or pre-provisioned
+ out-of-band by the web application. It could then perform cryptographic operations such
+ as decrypting an authentication challenge followed by signing an authentication response.
+ </p>
+ <p>
+ Further, the authentication data could be further enhanced by binding the authentication
+ to the TLS session that the client is authenticating over, by deriving a key based on
+ properties of the underlying transport.
+ </p>
+ <p>
+ If a user did not already have a key associated with their account, the web application
+ could direct the user agent to either generate a new key or to re-use an existing key of
+ the user's choosing.
+ </p>
+ </div>
+
+ <div id="protected-document" class="section">
+ <h3>2.2. Protected Document Exchange</h3>
+ <p>
+ When exchanging documents that may contain sensitive or personal information, a
+ web application may wish to ensure that only certain users can view the documents, even
+ after they have been securely received, such as over TLS. One way that a web application
+ can do so is by encrypting the documents with a secret key, and then wrapping that key
+ with the public keys associated with authorized users.
+ </p>
+ <p>
+ When a user agent navigates to such a web application, the application may send the
+ encrypted form of the document. The user agent is then instructed to unwrap the encryption
+ key, using the user's private key, and from there, decrypt and display the document.
+ </p>
+ </div>
+
+ <div id="cloud-storage" class="section">
+ <h3>2.3. Cloud Storage</h3>
+ <p>
+ When storing data with remote service providers, users may wish to protect the
+ confidentiality of their documents and data prior to uploading them. The Web
+ Cryptography API allows an application to have a user select a private or secret key,
+ to either derive encryption keys from the selected key or to directly encrypt documents
+ using this key, and then to upload the transformed/encrypted data to the service provider
+ using existing APIs.
+ </p>
+ <p>
+ This use case is similar to the <a href="#protected-document">Protected Document
+ Exchange</a> use case because Cloud Storage can be considered as a user exchanging
+ protected data with himself in the future.
+ </p>
+ </div>
+
+ <div id="document-signing" class="section">
+ <h3>2.4. Document Signing</h3>
+ <p>
+ A web application may wish to accept electronic signatures on documents, in lieu of
+ requiring physical signatures. An authorized signature may use a key that was
+ pre-provisioned out-of-band by the web application, or it may be using a key that the
+ client generated specifically for the web application.
+ </p>
+ <p>
+ The web application must be able to locate any appropriate keys for signatures, then
+ direct the user to perform a signing operation over some data, as proof that they accept
+ the document.
+ </p>
+ </div>
+
+ <div id="data-integrity-protection" class="section">
+ <h3>2.5. Data Integrity Protection</h3>
+ <p>
+ When caching data locally, an application may wish to ensure that this data cannot be
+ modified in an offline attack. In such a case, the server may sign the data that it
+ intends the client to cache, with a private key held by the server. The web application
+ that subsequently uses this cached data may contain a public key that enables it to
+ validate that the cache contents have not been modified by anyone else.
+ </p>
+ </div>
+
+ <div id="secure-messaging" class="section">
+ <h3>2.6. Secure Messaging</h3>
+ <p>
+ In addition to a number of web applications already offering chat based services, the
+ rise of WebSockets and RTCWEB allows a great degree of flexibility in inter-user-agent
+ messaging. While TLS/DTLS may be used to protect messages to web applications, users
+ may wish to directly secure messages using schemes such as off-the-record (OTR) messaging.
+ </p>
+ <p>
+ The Web Cryptography API enables OTR, by allowing key agreement to be performed so that
+ the two parties can negotiate shared encryption keys and message authentication code (MAC)
+ keys, to allow encryption and decryption of messages, and to prevent tampering of
+ messages through the MACs.
+ </p>
+ </div>
+
+ <div id="jose" class="section">
+ <h3>2.7. Javascript Object Signing and Encryption (JOSE)</h3>
+ <p>
+ A web application wishes to make use of the structures and format of
+ messages defined by the IETF Javascript Object Signing and Encryption
+ (JOSE) Working Group. The web application wishes to manipulate public
+ keys encoded in the JSON key format (JWK), messages that have been
+ integrity protected using digital signatures or MACs (JWS), or that
+ have been encrypted (JWE).
+ </p>
+ </div>
+
+ </div>
+
+ <div id="conformance" class="section">
+ <h2>3. Conformance</h2>
+ <p>
+ As well as sections marked as non-normative, all authoring guidelines, diagrams,
+ examples, and notes in this specification are non-normative. Everything else in
+ this specification is normative.
+ </p>
+ <p>
+ The keywords <span class="RFC2119">MUST</span>,
+ <span class="RFC2119">MUST NOT</span>,
+ <span class="RFC2119">REQUIRED</span>,
+ <span class="RFC2119">SHALL</span>,
+ <span class="RFC2119">SHALL NOT</span>,
+ <span class="RFC2119">RECOMMENDED</span>,
+ <span class="RFC2119">MAY</span>,
+ <span class="RFC2119">OPTIONAL</span>,
+ in this specification are to be interpreted as described in
+ <cite><a href="http://www.ietf.org/rfc/rfc2119">Key words for use in RFCs to
+ Indicate Requirement Levels</a></cite> [<a href="#RFC2119">RFC2119</a>].
+ </p>
+ <p>
+ The following conformance classes are defined by this specification:
+ </p>
+ <dl>
+ <dt><dfn id="dfn-conforming-implementation">conforming user agent</dfn></dt>
+ <dd>
+ <p>
+ A user agent is considered to be a
+ <a class="dfnref" href="#dfn-conforming-implementation">conforming user agent</a>
+ if it satisfies all of the <span class="RFC2119">MUST</span>-,
+ <span class="RFC2119">REQUIRED</span>- and <span class="RFC2119">SHALL</span>-level
+ criteria in this specification that apply to implementations. This specification
+ uses both the terms "conforming user agent" and "user agent" to refer to this
+ product class.
+ </p>
+ </dd>
+ </dl>
+ <p>
+ Conformance requirements phrased as algorithms or specific steps may be implemented in any
+ manner, so long as the end result is equivalent. (In particular, the algorithms defined in
+ this specification are intended to be easy to follow, and not intended to be performant.)
+ </p>
+ <p>
+ User agents that use ECMAScript to implement the APIs defined in this specification
+ <span class="RFC2119">MUST</span> implement them in a manner consistent with the
+ ECMAScript Bindings defined in the Web IDL specification [<a href="#WebIDL">WEBIDL</a>]
+ as this specification uses that specification and terminology.
+ </p>
+ <p>
+ Unless otherwise stated, string comparisons are done in a
+ <a href="#case-sensitive">case-sensitive</a> manner. String literals in this specification
+ written in monospace font like <code>"this"</code> do not include the enclosing quotes.
+ </p>
+ <div id="extensibility" class="section">
+ <h3>3.1. Extensibility</h3>
+ <p>
+ Vendor-specific proprietary extensions to this specification are strongly discouraged.
+ Authors must not use such extensions, as doing so reduces interoperability and fragments
+ the user base, allowing only users of specific user agents to access the content in
+ question.
+ </p>
+ <p>
+ If vendor-specific extensions are needed, the members should be prefixed by
+ vendor-specific strings to prevent clashes with future versions of this specification.
+ Extensions must be defined so that the use of extensions neither contradicts nor causes
+ the non-conformance of functionality defined in the specification.
+ </p>
+ <p>
+ When vendor-neutral extensions to this specification are needed, either this
+ specification can be updated accordingly, or an extension specification can be written
+ that overrides the requirements in this specification. When someone applying this
+ specification to their activities decides that they will recognize the requirements of
+ such an extension specification, it becomes an
+ <dfn id="dfn-applicable-specification">applicable specification</dfn> for the purposes
+ of conformance requirements in this specification. Applicable specifications defined
+ by the W3C WebCrypto Working Group are listed in the table below.
+ </p>
+ <p>
+ <table>
+ <tbody>
+ <tr>
+ <td>Specification</td>
+ <td>Reference</td>
+ </tr>
+ </tbody>
+ </table>
+ </p>
+ <div class="note"><div class="noteHeader">Note</div>
+ Readers are advised to consult the errata to this specification for updates to the table
+ above.
+ </div>
+ </div>
+ </div>
+
+ <div id="scope" class="section">
+ <h2>4. Scope</h2>
+ <p class="norm">This section is non-normative.</p>
+ <div class="section" id="scope-abstraction">
+ <h3>4.1. Level of abstraction</h3>
+ <p>
+ The specification attempts to focus on the common functionality and features between
+ various platform-specific or standardized cryptographic APIs, and avoid features and
+ functionality that are specific to one or two implementations. As such this API allows
+ key generation, management, and exchange with a level of abstraction that avoids
+ developers needing to care about the implementation of the underlying key storage. The
+ API is focused specifically around CryptoKey objects, as an abstraction for the
+ underlying raw cryptographic keying material. The intent behind this is to allow an API
+ that is generic enough to allow conforming user agents to expose keys that are stored
+ and managed directly by the user agent, that may be stored or managed using isolated
+ storage APIs such as per-user key stores provided by some operating systems, or within
+ key storage devices such as secure elements, while allowing rich web applications to
+ manipulate the keys and without requiring the web application be aware of the nature of
+ the underlying key storage.
+ </p>
+ </div>
+ <div class="section" id="scope-algorithms">
+ <h3>4.2. Cryptographic algorithms</h3>
+ <p>
+ Because the underlying cryptographic implementations will vary between conforming user
+ agents, and may be subject to local policy, including but not limited to concerns such
+ as government or industry regulation, security best practices, intellectual property
+ concerns, and constrained operational environments, this specification does not dictate
+ a mandatory set of algorithms that <span class="RFC2119">MUST</span> be implemented.
+ Instead, it defines a common set of bindings that can be used in an
+ algorithm-independent manner, a common framework for discovering if a user agent or key
+ handle supports the underlying algorithm, and a set of conformance requirements for the
+ behaviours of individual algorithms, if implemented.
+ </p>
+ </div>
+ <div class="section" id="scope-operations">
+ <h3>4.3. Operations</h3>
+ <p>
+ Although the API does not expose the notion of cryptographic providers or modules, each
+ key is internally bound to a cryptographic provider or module, so web applications can
+ rest assured that the right cryptographic provider or module will be used to perform
+ cryptographic operations involving that key.
+ </p>
+ </div>
+ <div class="section" id="scope-out-of-scope">
+ <h3>4.4. Out of scope</h3>
+ <p>
+ This API, while allowing applications to generate, retrieve, and manipulate keying
+ material, does not specifically address the provisioning of keys in particular types of
+ key storage, such as secure elements or smart cards. This is due to such provisioning
+ operations often being burdened with vendor-specific details that make defining a
+ vendor-agnostic interface an unsuitably unbounded task. Additionally, this API does not
+ deal with or address the discovery of cryptographic modules, as such concepts are
+ dependent upon the underlying user agent and are not concepts that are portable between
+ common operating systems, cryptographic libraries, and implementations.
+ </p>
+ </div>
+ </div>
+
+
+ <div class="section" id="concepts">
+ <h2>5. Concepts</h2>
+ <p class="norm">This section is non-normative.</p>
+ <div class="section" id="concepts-underlying-implementation">
+ <h3>5.1. Underlying Cryptographic Implementation</h3>
+ <p>
+ This specification assumes, but does not require, that conforming user agents do not
+ and will not be directly implementing cryptographic operations within the user agent
+ itself. Historically, many user agents have deferred cryptographic operations, such as
+ those used within TLS, to existing APIs that are available as part of the underlying
+ operating system or to third-party modules that are managed independently of the user
+ agent.
+ </p>
+ <p>
+ The <a href="#dfn-CryptoKey">CryptoKey</a> object represents the bridge between the
+ JavaScript execution environment and these underlying libraries, through the use of the
+ internal slot named [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]. The handle
+ represents an opaque type that is implementation specific, which may not be represented
+ within a JavaScript type, nor is it ever exposed to script authors. In this way, the
+ <a href="#dfn-CryptoKey">CryptoKey</a> object is the conceptual equivalent to the
+ JavaScript executing environment as the
+ [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] is to the underlying cryptographic
+ implementation.
+ </p>
+ <p>
+ These APIs are traditionally built around a notion of cryptographic providers, an
+ abstraction for a specific implementation of a set of algorithms. The operating system
+ or library may come with a default provider, and users are frequently allowed to add
+ additional providers, reconfigure the set of enabled algorithms, or otherwise customize
+ how cryptographic services are provided.
+ </p>
+ <p>
+ While it is assumed that most user agents will be interacting with a cryptographic
+ provider that is implemented purely in software, it is not required by this
+ specification. As a result, the capabilities of some implementations may be limited by
+ the capabilities of the underlying hardware, and, depending on how the user has
+ configured the underlying cryptographic library, this may be entirely opaque to the
+ User Agent.
+ </p>
+ </div>
+ <div class="section" id="concepts-key-storage">
+ <h3>5.2. Key Storage</h3>
+ <p>
+ This specification does not explicitly provide any new storage mechanisms for
+ <a href="#dfn-CryptoKey">CryptoKey</a> objects. Instead, by allowing the
+ <a href="#dfn-CryptoKey">CryptoKey</a> to be used with the structured clone algorithm,
+ any existing or future web storage mechanisms that support storing structured clonable
+ objects can be used to store <a href="#dfn-CryptoKey">CryptoKey</a> objects.
+ </p>
+ <p>
+ In practice, it is expected that most authors will make use of the
+ <a href="#IndexedDB">Indexed Database API</a>, which allows associative storage of
+ key/value pairs, where the key is some string identifier meaningful to the application,
+ and the value is a <a href="#dfn-CryptoKey">CryptoKey</a> object. This allows the
+ storage and retrieval of key material, without ever exposing that key material to the
+ application or the JavaScript environment. Additionally, this allows authors
+ the full flexibility to store any additional metadata with the
+ <a href="#dfn-CryptoKey">CryptoKey</a> itself.
+ </p>
+ </div>
+ </div>
+
+ <div id="security" class="section">
+ <h2>6. Security considerations</h2>
+ <p class="norm">This section is non-normative.</p>
+ <div id="security-implementers" class="section">
+ <h2>6.1. Security considerations for implementers</h2>
+ <p>
+ By not providing an explicit storage mechanism, this specification assumes that
+ <a href="#dfn-CryptoKey">CryptoKey</a> objects are scoped to the current execution
+ environment and any storage mechanisms available to that environment (e.g.
+ <a href="#IndexedDB">Indexed Database API</a>). Application authors rely upon this for
+ the security of their applications; two origins with the same
+ <a href="#dfn-CryptoKey">CryptoKey</a> object have full access to the underlying key,
+ and as such, messages from these applications cannot be distinguished, and messages sent
+ to these applications can be fully recovered. Implementors should ensure that no
+ <a href="#dfn-CryptoKey">CryptoKey</a> objects are shared between two origins unless
+ the author has explicitly chosen to share (e.g., such as through the use of postMessage)
+ </p>
+ <p>
+ A number of algorithms specified within this specification perform computationally
+ intensive work, such as the generation of significantly large prime numbers, or through
+ repeated iterations of a particular operation. As such, hostile applications may attempt
+ to misuse this API and attempt to cause significant amount of work to be performed by
+ an implementation, denying access or services to other applications that are executing.
+ Implementations should take steps to mitigate these risks, such as limiting the amount
+ of operations an implementation performs concurrently, requiring user consent for
+ operations that may be known to be disruptive for the executing environment, or defining
+ device-specific limits on attributes such as key sizes or iteration counts.
+ </p>
+ </div>
+ <div id="security-developers" class="section">
+ <h2>6.2. Security considerations for authors</h2>
+ <p>
+ This specification includes descriptions for a variety of cryptographic operations, some
+ of which have known weaknesses when used inappropriately. Application developers must
+ take care and review appropriate and current cryptographic literature, to understand and
+ mitigate such issues. In general, application developers are <strong>strongly</strong>
+ discouraged from inventing new cryptographic protocols; as with all applications, users
+ of this specification will be best served through the use of existing protocols, of
+ which this specification provides the necessary building blocks to implement.
+ </p>
+ <p>
+ In order to use the APIs defined in this specification to provide any meaningful
+ cryptographic assurances, authors must be familiar with existing threats to web
+ applications, as well as the underlying security model employed. Conceptually, issues
+ such as script injection are the equivalent to remote code execution in other operating
+ environments, and allowing hostile script to be injected may allow for the exfiltration
+ of keys or data. Script injection may come from other applications, for which the
+ judicious use of Content Security Policy may mitigate, or it may come from hostile
+ network intermediaries, for which the use of Transport Layer Security may mitigate.
+ </p>
+ <p>
+ This specification does not define any specific mechanisms for the storage of
+ cryptographic keys. By default, unless specific effort is taken by the author to persist
+ keys, such as through the use of the <a href="#IndexedDB">Indexed Database API</a>, keys
+ created with this API will only be valid for the duration of the current page (e.g.
+ until a navigation event). Authors that wish to use the same key across different pages
+ or multiple browsing sessions must employ existing web storage technologies. Authors
+ should be aware of the security assumptions of these technologies, such as the
+ same-origin security model; that is, any application that shares the same scheme, host,
+ and port have access to the same storage partition, even if other information, such as
+ the path, may differ. Authors may explicitly choose to relax this security through the
+ use of inter-origin sharing, such as <code>postMessage</code>.
+ </p>
+ <p>
+ Authors should be aware that this specification places no normative requirements on
+ implementations as to how the underlying cryptographic key material is stored. The only
+ requirement is that key material is not exposed to script, except through the use of the
+ <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a> and <a href="#dfn-SubtleCrypto-method-wrapKey">wrapKey</a> operations. In particular, it does
+ not guarantee that the underlying cryptographic key material will not be persisted to
+ disk, possibly unencrypted, nor that it will be inaccessible to users or other
+ applications running with the same privileges as the User Agent. Any application or user
+ that has access to the device storage may be able to recover the key material, even
+ through scripts may be prohibited.
+ </p>
+ <p>
+ This specification places no normative requirements on how implementations handle key
+ material once all references to it go away. That is, conforming user agents are not
+ required to zeroize key material, and it may still be accessible on device storage or
+ device memory, even after all references to the <a href="#dfn-CryptoKey">CryptoKey</a>
+ have gone away.
+ </p>
+ <p>
+ Applications may share a <a href="#dfn-CryptoKey">CryptoKey</a> object across security
+ boundaries, such as origins, through the use of the structured clone algorithm and APIs
+ such as <code>postMessage</code>. While access to the underlying cryptographic key
+ material may be restricted, based upon the <a href="#dfn-CryptoKey-extractable">extractable</a>
+ attribute, once a key is shared with a destination origin, the source origin can not
+ later restrict or revoke access to the key. As such, authors must be careful to ensure
+ they trust the destination origin to take the same mitigations against hostile script
+ that the source origin employs. Further, in the event of script injection on the source
+ origin, attackers may post the key to an origin under attacker control. Any time that
+ the user agent visits the attacker's origin, the user agent may be directed to perform
+ cryptographic operations using that key, such as the decryption of existing messages
+ or the creation of new, fraudulent messages.
+ </p>
+ <p>
+ Authors should be aware that users may, at any time, choose to clear the storage
+ associated with an origin, potentially destroying keys. Applications that are meant to
+ provide long-term storage, such as on the server, should consider techniques such as
+ key escrow to prevent such data from being inaccessible. Authors should not presume
+ that keys will be available indefinitely.
+ </p>
+ </div>
+ <div class="section" id="security-users">
+ <h3>6.3. Security considerations for users</h3>
+ <p>
+ Users of applications that employ the APIs defined in this specification should be aware
+ that these applications will have full access to all messages exchanged, regardless of
+ the cryptography employed. That is, for messages that are encrypted, applications that
+ use these APIs will have full access to the decrypted message as well.
+ </p>
+ </div>
+ </div>
+
+ <div id="privacy" class="section">
+ <h2>7. Privacy considerations</h2>
+ <p class="norm">This section is non-normative.</p>
+ <dl>
+ <dt>Fingerprinting</dt>
+ <dd>
+ By exposing additional APIs that reflect capabilities of the underlying platform, this
+ specification may allow malicious applications to determine or distinguish different
+ user agents or devices.
+ </dd>
+ <dt>Super-cookies</dt>
+ <dd>
+ This specification does not provide any means for malicious applications to create
+ identifiers that outlive existing web storage technologies. However, care must be taken
+ when introducing future revisions to this API or additional cryptographic capabilities,
+ such as those that are hardware backed (e.g.: smart cards or Trusted Platform Modules).
+ Considering that such storage is designed to prevent any two users from having the same
+ underlying key data, such APIs may represent a real risk of being used as a permanent
+ identifier against the user's wishes.
+ </dd>
+ </dl>
+ </div>
+
+ <div id="dependencies" class="section">
+ <h3>8. Dependencies</h3>
+ <p>This specification relies on underlying specifications.</p>
+ <dl>
+ <dt>DOM</dt>
+ <dd>
+ <p>
+ A <a href="#dfn-conforming-implementation">conforming user agent</a> MUST support at
+ least the subset of the functionality defined in DOM4 that this specification relies
+ upon; in particular, it MUST support <code>Promises</code> and
+ <dfn id="dfn-DOMException">DOMException</dfn>.
+ [<a href="#DOM4">DOM4</a>]
+ </p>
+ </dd>
+ <dt>HTML</dt>
+ <dd>
+ <p>
+ A <a href="#dfn-conforming-implementation">conforming user agent</a> MUST support at
+ least the subset of the functionality defined in HTML that this specification relies
+ upon; in particular, it MUST support the
+ <a href="#arraybufferview">ArrayBufferView</a> typedef and the
+ <a href="#structured-clone">structured clone</a> algorithm.
+ [<a href="#HTML">HTML</a>]
+ </p>
+ </dd>
+ <dt>Web IDL</dt>
+ <dd>
+ <p>
+ A <a href="#dfn-conforming-implementation">conforming user agent</a> MUST be a
+ conforming implementation of the IDL fragments in this specification, as described in
+ the Web IDL specification. [<a href="#WebIDL">WEBIDL</a>]
+ </p>
+ </dd>
+ </dl>
+ </div>
+
+ <div id="terminology" class="section">
+ <h2>9. Terminology</h2>
+ <p>
+ The terms and algorithms
+ <dfn id="arraybufferview">ArrayBufferView</dfn>, and
+ <dfn id="structured-clone">structured clone</dfn>,
+ are defined by the HTML specification [<a href="#HTML">HTML</a>].
+ </p>
+ <p>
+ The term <dfn id="BufferSource">BufferSource</dfn> is defined in [<cite><a href="#WebIDL">WEBIDL</a></cite>].
+ </p>
+ <p>
+ An <dfn id="dfn-octet-string">octet string</dfn> is an ordered sequence of zero or more
+ integers, each in the range 0 to 255 inclusive.
+ </p>
+ <p>
+ Comparing two strings in a <dfn id="case-sensitive">case-sensitive</dfn>
+ manner means comparing them exactly, code point for code point.
+ </p>
+ <p>
+ Comparing two strings in a <dfn id="case-insensitive">ASCII case-insensitive</dfn> manner
+ means comparing them exactly, code point for code point, except that the codepoints in
+ the range U+0041 .. U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z) and
+ the corresponding codepoints in the range U+0061 .. U+007A
+ (i.e. LATIN SMALL LETTER A to LATIN SMALL LETTER Z) are also considered to match.
+ </p>
+ <p>
+ When this specification says to <dfn id="terminate-the-algorithm">terminate the
+ algorithm</dfn>, the user agent must terminate the algorithm after finishing the step it
+ is on. The algorithm referred to is the set of specification-defined processing steps,
+ rather than the underlying cryptographic algorithm that may be in the midst of processing.
+ </p>
+ <p>
+ When this specification says to <dfn id="concept-parse-an-asn1-structure">parse an ASN.1
+ structure</dfn>, the user agent must perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be a sequence of bytes to be parsed.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>structure</var> be the ASN.1 structure to be parsed.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>exactData</var> be an optional boolean value. If it is not supplied,
+ let it be initialized to <code>true</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Parse <var>data</var> according to the Distinguished Encoding Rules of
+ <a href="#X690">X.690 (11/08)</a>, using <var>structure</var> as the ASN.1 structure
+ to be decoded.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>exactData</var> was specified, and all of the bytes of <var>data</var> were
+ not consumed during the parsing phase, then
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the parsed ASN.1 structure.
+ </p>
+ </li>
+ </ol>
+ <p>
+ When this specification says to <dfn id="concept-parse-a-spki">parse a
+ subjectPublicKeyInfo</dfn>, the user agent must
+ <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>, with
+ <var>data</var> set to the sequence of bytes to be parsed, <var>structure</var> as the
+ ASN.1 structure of subjectPublicKeyInfo, as specified in <a href="#RFC5280">RFC 5280</a>,
+ and <var>exactData</var> set to <code>true</code>.
+ </p>
+ <p>
+ When this specification says to <dfn id="concept-parse-a-privateKeyInfo">parse a
+ PrivateKeyInfo</dfn>, the user agent must <a href="#concept-parse-an-asn1-structure">parse
+ an ASN.1 structure</a> with <var>data</var> set to the sequence of bytes to be parsed,
+ <var>structure</var> as the ASN.1 structure of PrivateKeyInfo, as specified in
+ <a href="#RFC5208">RFC 5208</a>, and <var>exactData</var> set to <code>true</code>.
+ </p>
+ <p>
+ When this specification says to <dfn id="concept-parse-a-jwk">parse a JWK</dfn>, the user
+ agent must run the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the sequence of bytes to be parsed.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>json</var> be the Unicode string that results from interpreting
+ <var>data</var> according to UTF-8.
+ </p>
+ </li>
+ <li>
+ <p>
+ Convert <var>json</var> to UTF-16.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the object literal that results from executing the
+ <code>JSON.parse</code> internal function, with <code>text</code>
+ argument set to a JavaScript String containing <var>json</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be the result of converting <var>result</var> to the IDL dictionary
+ type of <a href="#dfn-JsonWebKey">JsonWebKey</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>key</var> is not defined, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ <p>
+ When this specification says to <dfn id="concept-clone-BufferSource">clone the
+ data</dfn> of a <a href="http://heycam.github.io/webidl/#common-BufferSource">BufferSource</a> object
+ <var>data</var>, the user agent must run the following steps:
+ </p>
+ <dl class="switch">
+ <dt>
+ If <var>data</var> is an <code>ArrayBuffer</code>:
+ </dt>
+ <dd>
+ Return the result of invoking the <code>ArrayBuffer.prototype.slice</code> method on
+ <var>data</var>, with the <var>start</var> value set to the integer 0, and the
+ <var>end</var> value set to the value of the [[ArrayBufferByteLength]] internal slot
+ of <var>data</var>.
+ </dd>
+ <dt>
+ If <var>data</var> is an <code>ArrayBufferView</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>buffer</var> be the value of the [[ViewedArrayBuffer]] internal slot
+ of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>start</var> be the value of the [[ByteOffset]] internal slot of
+ <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>end</var> be the value of the [[ByteLength]] internal slot of
+ <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>relativeEnd</var> be <var>start</var>+<var>end</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of invoking the <code>ArrayBuffer.prototype.slice</code> method
+ on <var>buffer</var>, with the <var>start</var> value set to <var>start</var> and
+ the <var>end</var> value set to <var>relativeEnd</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ The above definition makes heavy use of directly accessing the internal slot values,
+ defined in <a href="#ECMA-262">ECMA262</a>. The motivation for this is to avoid issues
+ that might arise with authors defining custom getters/setters on such objects. However,
+ it has the downside of avoiding the error control statements defined in the
+ <code>%TypedArray%.prototype</code> getters and <code>ArrayBuffer.prototype</code>
+ getters, which would be desirable.
+ </p>
+ <p>
+ It is assumed that the Web IDL conversion rules will perform the necessary type checks,
+ and that as a result of these checks, it is guaranteed that the internal slots will
+ always have valid values for the above algorithm. However, that assumption may not be
+ safe to make.
+ </p>
+ </div>
+ <p>
+ When this specification states to supply the <dfn id="concept-contents-of-arraybuffer">
+ contents of an ArrayBuffer</dfn> named <var>data</var> to an underlying cryptographic
+ implementation, the User Agent shall supply a contiguous sequence of bytes that is equal
+ to the contents of the Data Block value of the [[ArrayBufferData]] internal slot of
+ <var>data</var>, and whose length in bytes is equal to the [[ArrayBufferByteLength]]
+ internal slot of <var>data</var>.
+ </p>
+ <p>
+ When this specification says to calculate the <dfn id="concept-usage-intersection">usage
+ intersection</dfn> of two sequences, <var>a</var> and <var>b</var> the result shall be a
+ sequence containing each <a href="#dfn-RecognizedKeyUsage">recognized key usage value</a>
+ that appears in both <var>a</var> and <var>b</var>, in the order listed in the list of
+ <a href="#dfn-RecognizedKeyUsage">recognized key usage values</a>, where a value is said
+ to appear in a sequence if an element of the sequence exists that is a case-sensitive string
+ match for that value.
+ </p>
+ <p>
+ When this specification says to calculate the <dfn id="concept-normalized-usages">
+ normalized value of a usages list</dfn>, <var>usages</var> the result shall be the
+ <a href="#concept-usage-intersection">usage intersection</a> of <var>usages</var> and a
+ sequence containing all <a href="#dfn-RecognizedKeyUsage">recognized key usage values</a>.
+ </p>
+ <p>
+ When this specification refers to the <dfn id="concept-cached-object">cached ECMAScript
+ object</dfn> associated with an internal slot [[<var>slot</var>]] of <var>object</var>,
+ the user agent must run the following steps:
+ </p>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<var>slot</var>_cached]] internal slot of <var>object</var> is undefined:
+ </dt>
+ <dd>
+ Set the [[<var>slot</var>_cached]] internal slot of <var>object</var> to the result
+ of performing type conversion to an ECMAScript object as defined in
+ [<a href="#WebIDL">WEBIDL</a>] to the contents of the [[<var>slot</var>]]
+ internal slot of <var>object</var>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ Return the contents of the [[<var>slot</var>_cached]] internal slot of <var>object</var>.
+ </li>
+ </ol>
+ </div>
+
+ <div id="crypto-interface" class="section">
+ <h2>10. Crypto interface</h2>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+[NoInterfaceObject]
+interface <dfn id="dfn-GlobalCrypto">GlobalCrypto</dfn> {
+ readonly attribute <a href="#dfn-Crypto">Crypto</a> crypto;
+};
+
+Window implements GlobalCrypto;
+WorkerGlobalScope implements GlobalCrypto;
+
+[Exposed=(Window,Worker)]
+interface <dfn id="dfn-Crypto">Crypto</dfn> {
+ readonly attribute <a href="#dfn-SubtleCrypto">SubtleCrypto</a> subtle;
+ ArrayBufferView <a href="#dfn-Crypto-method-getRandomValues">getRandomValues</a>(ArrayBufferView array);
+};
+ </code></pre></div></div>
+
+ <div id="Crypto-description" class="section">
+ <h3>10.1. Description</h3>
+ <p>
+ The <a href="#dfn-Crypto">Crypto</a> interface represents an interface to
+ general purpose cryptographic functionality including a
+ cryptographically strong pseudo-random number generator seeded with truly random values.
+ </p>
+ <div class="note"><div class="noteHeader">Note</div>
+ Implementations should generate cryptographically random values using
+ well-established cryptographic pseudo-random number generators seeded with high-quality
+ entropy, such as from an operating-system entropy source (e.g., "/dev/urandom"). This
+ specification provides no lower-bound on the information theoretic entropy present in
+ cryptographically random values, but implementations should make a best effort to provide
+ as much entropy as practicable.
+ </div>
+ <div class="note"><div class="noteHeader">Note</div>
+ This interface defines a synchronous method for obtaining cryptographically random
+ values. While some devices and implementations may support truly random cryptographic
+ number generators or provide interfaces that block when there is insufficient entropy,
+ implementations are discouraged from using these sources when implementing
+ getRandomValues, both for performance and to avoid depleting the system of entropy.
+ Instead, these sources should be used to seed a cryptographic pseudo-random number
+ generator that can then return suitable values efficiently.
+ </div>
+ </div>
+ <div id="Crypto-interface-methods" class="section">
+ <h3>10.2. Methods and Parameters</h3>
+ <div id="Crypto-method-getRandomValues" class="section">
+ <h4>10.2.1. The getRandomValues method</h4>
+ <p>
+ The <dfn id="dfn-Crypto-method-getRandomValues"><code>getRandomValues</code></dfn>
+ method generates cryptographically random values. It must act as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ If <var>array</var> is not of an integer type (i.e., Int8Array, Uint8Array,
+ Int16Array, Uint16Array, Int32Array, or Uint32Array), <a href="#concept-throw">throw</a> a
+ <code>TypeMismatchError</code> and
+ <a href="#terminate-the-algorithm">terminate the algorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>byteLength</code> of <var>array</var> is greater than 65536, <a href="#concept-throw">throw</a> a
+ <code>QuotaExceededError</code> and
+ <a href="#terminate-the-algorithm">terminate the algorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Overwrite all elements of <var>array</var> with cryptographically random values of
+ the appropriate type.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>array</var>.
+ </p>
+ </li>
+ </ol>
+ <div class="note"><div class="noteHeader">Note</div>
+ <p>
+ Do not generate keys using the <code>getRandomValues</code> method. Use the
+ <a href="#dfn-SubtleCrypto-method-generateKey"><code>generateKey</code></a> method
+ instead.
+ </p>
+ </div>
+ </div>
+ </div>
+ <div id="Crypto-interface-attributes" class="section">
+ <h3>10.3. Attributes</h3>
+ <div id="Crypto-attribute-subtle" class="section">
+ <h4>10.3.1. The subtle attribute</h4>
+ <p>
+ The <dfn id="dfn-Crypto-attribute-subtle"><code>subtle</code></dfn> attribute provides
+ an instance of the <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface which provides
+ low-level cryptographic primitives and algorithms.
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <div id="algorithm-dictionary" class="section">
+ <h2>11. Algorithm dictionary</h2>
+ <p>
+ The Algorithm object is a dictionary object [<cite><a href="#WebIDL">WEBIDL</a></cite>]
+ which is used to specify an algorithm and any additional parameters required to fully
+ specify the desired operation.
+ </p>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+typedef (object or DOMString) <dfn id="dfn-AlgorithmIdentifier">AlgorithmIdentifier</dfn>;
+
+typedef <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> <dfn id="dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</dfn>;
+
+dictionary <dfn id="dfn-Algorithm">Algorithm</dfn> {
+ required DOMString <a href="#dfn-Algorithm-name">name</a>;
+};
+ </code></pre></div></div>
+ <div id="algorithm-dictionary-members" class="section">
+ <h3>11.1. <a href="#dfn-Algorithm">Algorithm</a> Dictionary Members</h3>
+ <dl>
+ <dt id="dfn-Algorithm-name">
+ <code>name</code>
+ </dt>
+ <dd>
+ The name of the <a href="#algorithms">registered algorithm</a> to use.
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="key-algorithm-dictionary" class="section">
+ <h2>12. KeyAlgorithm dictionary</h2>
+ <p>
+ The KeyAlgorithm dictionary represents information about the contents of a given
+ <a href="#dfn-CryptoKey">CryptoKey</a> object.
+ </p>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-KeyAlgorithm">KeyAlgorithm</dfn> {
+ required DOMString <a href="#dfn-KeyAlgorithm-name">name</a>
+};
+ </code></pre></div></div>
+ <div id="key-algorithm-dictionary-description" class="section">
+ <h3>12.1. Description</h3>
+ <p class="norm">This section is non-normative</p>
+ <p>
+ The <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> dictionary is provided to aid in
+ documenting how fixed, public properties of a <a href="#dfn-CryptoKey">CryptoKey</a>
+ are reflected back to an application. The actual dictionary type is never exposed
+ to applications.
+ </p>
+ </div>
+ <div id="key-algorithm-dictionary-members" class="section">
+ <h3>12.2. KeyAlgorithm dictionary members</h3>
+ <dl>
+ <dt id="dfn-KeyAlgorithm-name">name</dt>
+ <dd>
+ The name of the algorithm used to generate the <a href="#dfn-CryptoKey">CryptoKey</a>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="cryptokey-interface" class="section">
+ <h2>13. CryptoKey interface</h2>
+ <p>
+ The CryptoKey object represents an opaque reference to keying material that is managed by
+ the user agent.
+ </p>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+enum <a href="#dfn-KeyType">KeyType</a> { "public", "private", "secret" };
+
+enum <a href="#dfn-KeyUsage">KeyUsage</a> { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" };
+
+[Exposed=(Window,Worker)]
+interface <dfn id="dfn-CryptoKey">CryptoKey</dfn> {
+ readonly attribute <a href="#dfn-KeyType">KeyType</a> <a href="#dfn-CryptoKey-type">type</a>;
+ readonly attribute boolean <a href="#dfn-CryptoKey-extractable">extractable</a>;
+ readonly attribute object <a href="#dfn-CryptoKey-algorithm">algorithm</a>;
+ readonly attribute object <a href="#dfn-CryptoKey-usages">usages</a>;
+};
+ </code></pre></div></div>
+ <div id="cryptokey-interface-description" class="section">
+ <h3>13.1. Description</h3>
+ <p class="norm">This section is non-normative</p>
+ <p>
+ This specification provides a uniform interface for many different kinds of keying
+ material managed by the user agent. This may include keys that have been generated by
+ the user agent, derived from other keys by the user agent, imported to the user agent
+ through user actions or using this API, pre-provisioned within software or hardware to
+ which the user agent has access or made available to the user agent in other ways. The
+ term key refers broadly to any keying material including actual keys for cryptographic
+ operations and secret values obtained within key derivation or exchange operations.
+ </p>
+ <p>
+ The CryptoKey object is not required to directly interface with the underlying key
+ storage mechanism, and may instead simply be a reference for the user agent to
+ understand how to obtain the keying material when needed, eg. when performing a
+ cryptographic operation.
+ </p>
+ </div>
+
+ <div id="cryptokey-interface-types" class="section">
+ <h3>13.2. Key interface data types</h3>
+ <dl>
+ <dt id="dfn-KeyType"><code>KeyType</code></dt>
+ <dd>
+ The type of a key. The <dfn id="dfn-RecognizedKeyType">recognized key type values</dfn>
+ are <code>"public"</code>, <code>"private"</code> and <code>"secret"</code>.
+ Opaque keying material, including that used for symmetric algorithms, is represented by
+ <code>"secret"</code>, while keys used as part of asymmetric algorithms composed of
+ public/private keypairs will be either <code>"public"</code> or <code>"private"</code>.
+ </dd>
+ <dt id="dfn-KeyUsage"><code>KeyUsage</code></dt>
+ <dd>
+ A type of operation that may be performed using a key. The
+ <dfn id="dfn-RecognizedKeyUsage">recognized key usage values</dfn> are
+ <code>"encrypt"</code>,
+ <code>"decrypt"</code>,
+ <code>"sign"</code>,
+ <code>"verify"</code>,
+ <code>"deriveKey"</code>,
+ <code>"deriveBits"</code>,
+ <code>"wrapKey"</code> and
+ <code>"unwrapKey"</code>.
+ </dd>
+ </dl>
+ </div>
+
+ <div id="cryptokey-interface-internal-slots" class="section">
+ <h3>13.3. CryptoKey internal slots</h3>
+ <p>
+ Every <code>CryptoKey</code> object has a set of internal slots that store information
+ about the key. These slots are not exposed as part of this specification; they
+ represent internal state that an implementation uses to implement this specification.
+ The notational convention used in [<a href="#ES262">ES262</a>] is re-used here; internal
+ slots are identified by names enclosed in double square brackets [[ ]].
+ </p>
+ <p>
+ All <code>CryptoKey</code> objects have internal slots named
+ [[<dfn id="dfn-CryptoKey-slot-type">type</dfn>]],
+ [[<dfn id="dfn-CryptoKey-slot-extractable">extractable</dfn>]],
+ [[<dfn id="dfn-CryptoKey-slot-algorithm">algorithm</dfn>]],
+ [[<dfn id="dfn-CryptoKey-slot-algorithm_cached">algorithm_cached</dfn>]],
+ [[<dfn id="dfn-CryptoKey-slot-usages">usages</dfn>]],
+ [[<dfn id="dfn-CryptoKey-slot-usages_cached">usages_cached</dfn>]], and
+ [[<dfn id="dfn-CryptoKey-slot-handle">handle</dfn>]].
+ </p>
+ <p>
+ The contents of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot shall be, or be derived from, a <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>.
+ The contents of the [[<a href="#dfn-CryptoKey-slot-algorithm">usages</a>]] internal
+ slot shall be of type Sequence<KeyUsage>.
+ </p>
+ <p class="note">
+ The [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] slot is an opaque type that
+ contains whatever data the underlying cryptographic implementation uses to represent a
+ logical key. Different cryptographic implementations may use different types, ranging
+ from opaque identifiers represented as integers, pointer types, or structures that
+ provide identifying information. These handles are never exposed to applications.
+ </p>
+ </div>
+
+ <div id="cryptokey-interface-members" class="section">
+ <h3>13.4. CryptoKey interface members</h3>
+ <dl>
+ <dt id="dfn-CryptoKey-type"><code>type</code></dt>
+ <dd>
+ Reflects the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot,
+ which contains the type of the underlying key.
+ </dd>
+ <dt id="dfn-CryptoKey-extractable"><code>extractable</code></dt>
+ <dd>
+ Reflects the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot, which indicates whether or not the raw keying material may be exported by the
+ application.
+ </dd>
+ <dt id="dfn-CryptoKey-algorithm"><code>algorithm</code></dt>
+ <dd>
+ Returns the <a href="#concept-cached-object">cached ECMAScript object</a>
+ associated with the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot.
+ </dd>
+ <dt id="dfn-CryptoKey-usages"><code>usages</code></dt>
+ <dd>
+ Returns the <a href="#concept-cached-object">cached ECMAScript object</a>
+ associated with the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot,
+ which indicates which cryptographic operations are permissible to be used with this key.
+ </dd>
+ </dl>
+ </div>
+
+ <div id="cryptokey-interface-clone" class="section">
+ <h3>13.5. Structured clone algorithm</h3>
+ <p>
+ When a user agent is required to obtain a <a href="#structured-clone">structured clone</a>
+ of a <a href="#dfn-CryptoKey">CryptoKey</a> object, it must run the following steps.
+ </p>
+ <ol>
+ <li>
+ Let <var>input</var> and <var>memory</var> be the corresponding inputs defined by the
+ <a href="#structured-clone">internal structured cloning algorithm</a>, where
+ <var>input</var> represents a <a href="#dfn-CryptoKey">CryptoKey</a> object to be
+ cloned.
+ </li>
+ <li>
+ Let <var>output</var> be a newly constructed <a href="#dfn-CryptoKey">CryptoKey</a>
+ object.
+ </li>
+ <li>
+ Let the [[<a href="#dfn-CryptoKey-slot-type">type</a>]], <a href="#dfn-CryptoKey-slot-extractable">[[extractable]]</a>, <a href="#dfn-CryptoKey-slot-algorithm">[[algorithm]]</a>, and <a href="#dfn-CryptoKey-slot-usages">[[usages]]</a> internal slots of <var>output</var>
+ be set to the result of invoking the internal structured clone algorithm recursively
+ on the corresponding internal slots of <var>input</var>, with the slot contents as the
+ new "<var>input</var>" argument and <var>memory</var> as the new "<var>memory</var>"
+ argument.
+ </li>
+ <li>
+ Let the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>output</var> refer to the same cryptographic key data represented by the
+ [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>input</var>.
+ </li>
+ </ol>
+ <div class="note"><div class="noteHeader">Note</div>
+ <strong>Implementation Note:</strong> When performing the structured clone algorithm in
+ order to serialize a <code>CryptoKey</code> object, implementations must not allow the
+ object to be deserialized as a different type. This is normatively required by the
+ definition of structured clone, but it merits specific attention, as such
+ deserialization may expose the contents of the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot, which in some
+ implementations may contain cryptographic key data that should not be exposed to
+ applications.
+ </div>
+ </div>
+ </div>
+
+ <div id="subtlecrypto-interface" class="section">
+ <h2>14. SubtleCrypto interface</h2>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+enum <a href="#dfn-KeyFormat"><code>KeyFormat</code></a> { "raw", "spki", "pkcs8", "jwk" };
+
+[Exposed=(Window,Worker)]
+interface <dfn id="dfn-SubtleCrypto">SubtleCrypto</dfn> {
+ Promise<any> <a href="#dfn-SubtleCrypto-method-encrypt">encrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ <a href="#dfn-CryptoKey">CryptoKey</a> key,
+ BufferSource data);
+ Promise<any> <a href="#dfn-SubtleCrypto-method-decrypt">decrypt</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ <a href="#dfn-CryptoKey">CryptoKey</a> key,
+ BufferSource data);
+ Promise<any> <a href="#dfn-SubtleCrypto-method-sign">sign</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ <a href="#dfn-CryptoKey">CryptoKey</a> key,
+ BufferSource data);
+ Promise<any> <a href="#dfn-SubtleCrypto-method-verify">verify</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ <a href="#dfn-CryptoKey">CryptoKey</a> key,
+ BufferSource signature,
+ BufferSource data);
+ Promise<any> <a href="#dfn-SubtleCrypto-method-digest">digest</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ BufferSource data);
+
+ Promise<any> <a href="#dfn-SubtleCrypto-method-generateKey">generateKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ boolean extractable,
+ sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
+ Promise<any> <a href="#dfn-SubtleCrypto-method-deriveKey">deriveKey</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ <a href="#dfn-CryptoKey">CryptoKey</a> baseKey,
+ <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> derivedKeyType,
+ boolean extractable,
+ sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
+ Promise<any> <a href="#dfn-SubtleCrypto-method-deriveBits">deriveBits</a>(<a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ <a href="#dfn-CryptoKey">CryptoKey</a> baseKey,
+ unsigned long length);
+
+ <span class="comment">// TBD: <a href="https://www.w3.org/2012/webcrypto/track/issues/35">ISSUE-35</a></span>
+ Promise<any> <a href="#dfn-SubtleCrypto-method-importKey">importKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
+ (BufferSource or JsonWebKey) keyData,
+ <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> algorithm,
+ boolean extractable,
+ sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
+ Promise<any> <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format, <a href="#dfn-CryptoKey">CryptoKey</a> key);
+
+ Promise<any> <a href="#dfn-SubtleCrypto-method-wrapKey">wrapKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
+ <a href="#dfn-CryptoKey">CryptoKey</a> key,
+ <a href="#dfn-CryptoKey">CryptoKey</a> wrappingKey,
+ <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> wrapAlgorithm);
+ Promise<any> <a href="#dfn-SubtleCrypto-method-unwrapKey">unwrapKey</a>(<a href="#dfn-KeyFormat">KeyFormat</a> format,
+ BufferSource wrappedKey,
+ <a href="#dfn-CryptoKey">CryptoKey</a> unwrappingKey,
+ <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> unwrapAlgorithm,
+ <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> unwrappedKeyAlgorithm,
+ boolean extractable,
+ sequence<<a href="#dfn-KeyUsage">KeyUsage</a>> keyUsages );
+};
+ </code></pre></div></div>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <ul>
+ <li>
+ <a href="https://www.w3.org/2012/webcrypto/track/issues/35">ISSUE-35</a>:
+ The specification for wrapKey/unwrapKey does not specify how authors that do not trust
+ the execution environment may indicate required attributes for keys that are
+ unwrapped. An example is unwrapping a key with a non-extractable key, marking
+ the newly unwrapped key as non extractable, and then further indicating that all
+ keys unwrapped with the newly unwrapped key are also non-extractable.
+ </li>
+ </ul>
+ </div>
+ <div id="subtlecrypto-interface-description" class="section">
+ <h3>14.1. Description</h3>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface provides a set of
+ methods for dealing with low-level cryptographic primitives and algorithms. It is
+ named <code>SubtleCrypto</code> to reflect the fact that many of these algorithms
+ have subtle usage requirements in order to provide the required algorithmic
+ security guarantees.
+ </p>
+ <p>
+ For example, the direct use of an unauthenticated encryption scheme, such as
+ <a href="#aes-ctr">AES in counter mode</a>, gives potential attackers the ability to
+ manipulate bits in the output by manipulating bits in the input, compromising the
+ integrity of the message. However, AES-CTR can be used securely in combination
+ with other cryptographic primitives, such as message authentication codes, to ensure
+ the integrity of the protected message, but only when the message authentication
+ code is constructed over the encrypted message and IV.
+ </p>
+ <p>
+ Developers making use of the SubtleCrypto interface are expected to be aware of the
+ security concerns associated with both the design and implementation of the various
+ algorithms provided. The raw algorithms are provided in order to allow developers
+ maximum flexibility in implementing a variety of protocols and applications, each of
+ which may represent the composition and security parameters in a unique manner that
+ necessitate the use of the raw algorithms.
+ </p>
+ </div>
+
+ <div id="subtlecrypto-interface-datatypes" class="section">
+ <h3>14.2. Data Types</h3>
+ <dl>
+ <dt id="dfn-KeyFormat"><code>KeyFormat</code></dt>
+ <dd>
+ Specifies a serialization format for a key. The <dfn id="dfn-RecognizedKeyFormats">recognized key format values</dfn> are:
+ <dl>
+ <dt><code>"raw"</code></dt>
+ <dd>An unformatted sequence of bytes. Intended for secret keys.</dd>
+ <dt><code>"pkcs8"</code></dt>
+ <dd>The DER encoding of the PrivateKeyInfo structure from <a href="#RFC5208">RFC 5208</a>.</dd>
+ <dt><code>"spki"</code></dt>
+ <dd>The DER encoding of the SubjectPublicKeyInfo structure from <a href="#RFC5280">RFC 5280</a>.</dd>
+ <dt><code>"jwk"</code></dt>
+ <dd>The key is a <a href="#dfn-JsonWebKey">JsonWebKey</a> dictionary encoded as a JavaScript object</dd>
+ </dl>
+ </dd>
+ </dl>
+ </div>
+
+ <div id="subtlecrypto-interface-methods" class="section">
+ <h3>14.3. Methods and Parameters</h3>
+ <div class="note"><div class="noteHeader">Note</div>
+ <p>
+ All errors are reported asynchronously by rejecting the returned
+ Promise. This includes Web IDL type mapping errors.
+ </p>
+ </div>
+ <div id="SubtleCrypto-method-encrypt" class="section">
+ <h4>14.3.1. The encrypt method</h4>
+ <p>
+ The <dfn id="dfn-SubtleCrypto-method-encrypt"><code>encrypt</code></dfn>
+ method returns a new Promise object that will encrypt data using
+ the specified
+ <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
+ the supplied <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act
+ as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var> and <var>key</var> be the
+ <code>algorithm</code> and <code>key</code> parameters
+ passed to the <a href="#dfn-SubtleCrypto-method-encrypt">encrypt</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
+ cloning the data</a> of the <code>data</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-encrypt">encrypt</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"encrypt"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> does not contain an entry that is <code>"encrypt"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>ciphertext</var> be the result of performing the encrypt
+ operation specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>
+ and <var>key</var> and with <var>data</var> as <var>plaintext</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with <var>ciphertext</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-decrypt" class="section">
+ <h4>14.3.2. The decrypt method</h4>
+ <p>
+ The <dfn id="dfn-SubtleCrypto-method-decrypt"><code>decrypt</code></dfn>
+ method returns a new Promise object that will decrypt data using the specified
+ <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with
+ the supplied <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act
+ as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var> and <var>key</var> be the
+ <code>algorithm</code> and <code>key</code>parameters
+ passed to the <a href="#dfn-SubtleCrypto-method-decrypt">decrypt</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
+ cloning the data</a> of the <code>data</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-decrypt">decrypt</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"decrypt"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> does not contain an entry that is <code>"decrypt"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>plaintext</var> be the result of performing the decrypt
+ operation specified by <var>normalizedAlgorithm</var> using <var>key</var>
+ and <var>algorithm</var>
+ and with <var>data</var> as <var>ciphertext</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>plaintext</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-sign" class="section">
+ <h4>14.3.3. The sign method</h4>
+ <p>
+ The <dfn id="dfn-SubtleCrypto-method-sign"><code>sign</code></dfn> method returns a
+ new Promise object that will sign data using the specified <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with the supplied
+ <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var> and <var>key</var> be the
+ <code>algorithm</code> and <code>key</code> parameters
+ passed to the <a href="#dfn-SubtleCrypto-method-sign">sign</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
+ cloning the data</a> of the <code>data</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-sign">sign</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"sign"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> does not contain an entry that is <code>"sign"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the sign operation
+ specified by <var>normalizedAlgorithm</var> using <var>key</var> and
+ <var>algorithm</var> and with <var>data</var> as <var>message</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-verify" class="section">
+ <h4>14.3.4. The verify method</h4>
+ <p>
+ The <dfn id="dfn-SubtleCrypto-method-verify"><code>verify</code></dfn> method returns
+ a new Promise object that will verify data using the specified <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a> with the supplied
+ <a href="#dfn-CryptoKey"><code>CryptoKey</code></a>. It must act as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var> and <var>key</var>
+ be the <code>algorithm</code> and <code>key</code> parameters passed to the
+ <a href="#dfn-SubtleCrypto-method-verify">verify</a> method, respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>signature</var> be the result of <a href="#concept-clone-BufferSource">
+ cloning the data</a> of the <code>signature</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-verify">verify</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"verify"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
+ cloning the data</a> of the <code>data</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-verify">verify</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> does not contain an entry that is <code>"verify"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the verify operation
+ specified by <var>normalizedAlgorithm</var> using <var>key</var>,
+ <var>algorithm</var> and
+ <var>signature</var> and with <var>data</var> as <var>message</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-digest" class="section">
+ <h4>14.3.5. The digest method</h4>
+ <p>
+ The <dfn id="dfn-SubtleCrypto-method-digest"><code>digest</code></dfn> method returns
+ a new Promise object that will digest data using the specified
+ <a href="#dfn-AlgorithmIdentifier"><code>AlgorithmIdentifier</code></a>.
+ It must act as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var> be the <code>algorithm</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-digest">digest</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#concept-clone-BufferSource">
+ cloning the data</a> of the <code>data</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-digest">digest</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"digest"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the digest
+ operation specified by <var>normalizedAlgorithm</var> using
+ <var>algorithm</var>, with <var>data</var>
+ as <var>message</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-generateKey" class="section">
+ <h4>14.3.6. The generateKey method</h4>
+ <p>
+ When invoked, <dfn id="dfn-SubtleCrypto-method-generateKey">
+ <code>generateKey</code></dfn> <span class="RFC2119">MUST</span> perform the
+ following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var>, <var>extractable</var> and <var>usages</var>
+ be the <code>algorithm</code>, <code>extractable</code> and <code>keyUsages</code>
+ parameters passed to the
+ <a href="#dfn-SubtleCrypto-method-generateKey">generateKey</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"generateKey"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of executing the generate key operation
+ specified by <var>normalizedAlgorithm</var> using
+ <var>algorithm</var>, <var>extractable</var> and <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>result</var> is a <a href="#dfn-CryptoKey">CryptoKey</a> object:</dt>
+ <dd>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
+ <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
+ </p>
+ </dd>
+ <dt>If <var>result</var> is a <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a> object:</dt>
+ <dd>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of the
+ <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute of
+ <var>result</var> is the empty sequence, then
+ <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-deriveKey" class="section">
+ <h4>14.3.7. The deriveKey method</h4>
+ <p>
+ When invoked, <dfn id="dfn-SubtleCrypto-method-deriveKey"><code>deriveKey</code></dfn>
+ <span class="RFC2119">MUST</span> perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var>, <var>baseKey</var>, <var>derivedKeyType</var>,
+ <var>extractable</var> and <var>usages</var> be the <code>algorithm</code>,
+ <code>baseKey</code>, <code>derivedKeyType</code>, <code>extractable</code> and
+ <code>keyUsages</code> parameters passed to the <a href="#dfn-SubtleCrypto-method-deriveKey">deriveKey</a> method, respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"deriveBits"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedDerivedKeyAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>derivedKeyType</var> and <code>op</code> set to
+ <code>"importKey"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> does not identify a <a href="#algorithms">registered algorithm</a> that supports the derive bits
+ operation, then <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> does not identify a
+ <a href="#algorithms">registered algorithm</a> that supports the get key length
+ operation, then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>baseKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>baseKey</var> does not contain an entry that is <code>"deriveKey"</code>,
+ then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>length</var> be the result of executing the get key length
+ algorithm specified by <var>normalizedDerivedKeyAlgorithm</var> using
+ <var>derivedKeyType</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>secret</var> be the result of executing the derive bits operation
+ specified by <var>normalizedAlgorithm</var> using
+ <var>key</var>, <var>algorithm</var> and <var>length</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of executing the import key operation
+ specified by <var>normalizedDerivedKeyAlgorithm</var> using <code>"raw"</code> as
+ <var>format</var>, <var>secret</var> as <var>keyData</var>,
+ <var>derivedKeyType</var> as <var>algorithm</var> and using
+ <var>extractable</var> and <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
+ <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-deriveBits" class="section">
+ <h4>14.3.8. The deriveBits method</h4>
+ <p>
+ When invoked, <dfn id="dfn-SubtleCrypto-method-deriveBits"><code>deriveBits</code></dfn>
+ <span class="RFC2119">MUST</span> perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>algorithm</var>, <var>baseKey</var> and <var>length</var>,
+ be the <code>algorithm</code>,
+ <code>baseKey</code> and <code>length</code>
+ parameters passed to the
+ <a href="#dfn-SubtleCrypto-method-deriveBits">deriveBits</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"deriveBits"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>baseKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>baseKey</var> does not contain an entry that is <code>"deriveBits"</code>,
+ then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-ArrayBuffer">ArrayBuffer</a>
+ containing the result of executing the derive bits operation
+ specified by <var>normalizedAlgorithm</var> using <var>baseKey</var>,
+ <var>algorithm</var> and <var>length</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-importKey" class="section">
+ <h4>14.3.9. The <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method</h4>
+ <p>
+ When invoked, the <dfn id="dfn-SubtleCrypto-method-importKey"><code>importKey</code></dfn> method <span class="RFC2119">MUST</span> perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>format</var>, <var>algorithm</var>, <var>extractable</var> and
+ <var>usages</var>, be the <code>format</code>, <code>algorithm</code>,
+ <code>extractable</code> and <code>keyUsages</code> parameters passed to the <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method, respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"importKey"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is equal to the string <code>"raw"</code>,
+ <code>"pkcs8"</code>, or <code>"spki"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <code>keyData</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method is a
+ JsonWebKey dictionary, <a href="#concept-throw">throw</a> a
+ <a href="#dfn-TypeError"><code>TypeError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>keyData</var> be the result of
+ <a href="#concept-clone-BufferSource">cloning the data</a> of the
+ <code>keyData</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If <var>format</var> is equal to the string <code>"jwk"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <code>keyData</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method is not a
+ JsonWebKey dictionary, <a href="#concept-throw">throw</a> a
+ <a href="#dfn-TypeError"><code>TypeError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>keyData</var> be the <code>keyData</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-importKey">importKey</a> method.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the <a href="#dfn-CryptoKey">CryptoKey</a> object that
+ results from performing the import key operation specified by
+ <var>normalizedAlgorithm</var> using <var>keyData</var>,
+ <var>algorithm</var>,
+ <var>format</var>, <var>extractable</var> and <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
+ <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError">SyntaxError</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>result</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal
+ slot of <var>result</var> to the <a href="#concept-normalized-usages">normalized
+ value</a> of <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ <div class="note"><div class="noteHeader">Note</div>
+ <p class="norm">
+ This note is non-normative.
+ </p>
+ <p>
+ For structured key formats, <code>"spki"</code>, <code>"pks8"</code>
+ and <code>"jwk"</code>, fields that are not explicitly referred to in the key
+ import procedures for an algorithm are ignored.
+ </p>
+ </div>
+ </div>
+
+ <div id="SubtleCrypto-method-exportKey" class="section">
+ <h4>14.3.10. The <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a> method</h4>
+ <p>
+ When invoked, the <dfn id="dfn-SubtleCrypto-method-exportKey"><code>exportKey</code></dfn> method <span class="RFC2119">MUST</span> perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>format</var> and <var>key</var> be the <code>format</code> and
+ <code>key</code> parameters passed to the <a href="#dfn-SubtleCrypto-method-exportKey">exportKey</a> method, respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> does not identify a <a href="#algorithms">registered algorithm</a>
+ that supports the export key operation, then <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var> is false, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the export key operation
+ specified by the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> using <var>key</var> and <var>format</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-wrapKey" class="section">
+ <h4>14.3.11. The wrapKey method</h4>
+ <p>
+ When invoked, the <dfn id="dfn-SubtleCrypto-method-wrapKey">wrapKey</dfn> method <span class="RFC2119">MUST</span> perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>format</var>, <var>key</var>, <var>wrappingKey</var> and
+ <var>algorithm</var> be the <code>format</code>, <code>key</code>,
+ <code>wrappingKey</code> and <code>wrapAlgorithm</code> parameters passed to the
+ <a href="#dfn-SubtleCrypto-method-wrapKey">wrapKey</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"wrapKey"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"encrypt"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> does not identify a
+ <a href="#algorithms">registered algorithm</a> that supports the encrypt or wrap
+ key operation, then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>wrappingKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>wrappingKey</var> does not contain an entry that is <code>"wrapKey"</code>,
+ then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the algorithm identified by the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> does not support the export key operation, then <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var> is false, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be the result of performing the export key operation specified
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> using <var>key</var> and <var>format</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is equal to the strings <code>"raw"</code>,
+ <code>"pkcs8"</code>, or <code>"spki"</code>:
+ </dt>
+ <dd>
+ Set <var>bytes</var> be set to <var>key</var>.
+ </dd>
+ <dt>
+ If <var>format</var> is equal to the string <code>"jwk"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Convert <var>key</var> to an ECMAScript Object, as specified in [
+ <a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>json</var> be the result of representing <var>key</var> as a
+ UTF-16 string conforming to the JSON grammar; for example, by executing
+ the <code>JSON.stringify</code> algorithm specified in
+ <a href="#ECMA-262">ECMA262</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>bytes</var> be the byte sequence the results from converting
+ <var>json</var>, a JavaScript String comprised of UTF-16 code points, to
+ UTF-8 code points.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ <div class="note"><div class="noteHeader">Note</div>
+ <p class="norm">
+ This note is non-normative.
+ </p>
+ <p>
+ The key wrapping operations for some algorithms place constraints on the payload
+ size. For example AES-KW requires the payload to be a multiple of 8 bytes in
+ length and RSA-OAEP places a restriction on the length. For key formats that
+ offer flexibility in serialization of a given key (for example JWK),
+ implementations may choose to adapt the serialization to the constraints of
+ the wrapping algorithm. This is why JSON.stringify is not normatively required,
+ as otherwise it would prohibit implementations from introducing added
+ padding.
+ </p>
+ </div>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>normalizedAlgorithm</var> supports the wrap key operation:</dt>
+ <dd>
+ <p>
+ Let <var>result</var> be the result of performing the wrap key operation
+ specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
+ <var>wrappingKey</var> as <var>key</var> and <var>bytes</var> as
+ <var>plaintext</var>.
+ </p>
+ </dd>
+ <dt>Otherwise, if <var>normalizedAlgorithm</var> supports the encrypt operation:</dt>
+ <dd>
+ <p>
+ Let <var>result</var> be the result of performing the encrypt operation
+ specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
+ <var>wrappingKey</var> as <var>key</var> and <var>bytes</var> as
+ <var>plaintext</var>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="SubtleCrypto-method-unwrapKey" class="section">
+ <h4>14.3.12. The unwrapKey method</h4>
+ <p>
+ When invoked, the <dfn id="dfn-SubtleCrypto-method-unwrapKey">unwrapKey</dfn> method
+ <span class="RFC2119">MUST</span> perform the following steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Let <var>format</var>, <var>unwrappingKey</var>,
+ <var>algorithm</var>, <var>unwrappedKeyAlgorithm</var>,
+ <var>extractable</var> and <var>usages</var>,
+ be the <code>format</code>, <code>unwrappingKey</code>,
+ <code>unwrapAlgorithm</code>, <code>unwrappedKeyAlgorithm</code>,
+ <code>extractable</code> and <code>keyUsages</code>
+ parameters passed to the
+ <a href="#dfn-SubtleCrypto-method-unwrapKey">unwrapKey</a> method,
+ respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>wrappedKey</var> be the result of
+ <a href="#concept-clone-BufferSource">cloning the data</a> of the
+ <code>data</code> parameter passed to the
+ <a href="#dfn-SubtleCrypto-method-unwrapKey">unwrapKey</a> method.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"unwrapKey"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, let <var>normalizedAlgorithm</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>algorithm</var> and <code>op</code> set to
+ <code>"decrypt"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>normalizedKeyAlgorithm</var> be the result of <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
+ <code>alg</code> set to <var>unwrappedKeyAlgorithm</var> and <code>op</code> set
+ to <code>"importKey"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred, return a Promise rejected with
+ <var>normalizedKeyAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>promise</var> be a new Promise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>promise</var> and asynchronously perform the remaining steps.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the following steps or referenced procedures say to
+ <a href="#concept-throw">throw</a> an error,
+ reject <var>promise</var> with
+ the returned error and then
+ <a href="#terminate-the-algorithm">terminate the algorithm.</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is not equal to the
+ <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>unwrappingKey</var> then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>unwrappingKey</var> does not contain an entry that is
+ <code>"unwrapKey"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>normalizedAlgorithm</var> supports an unwrap key operation:</dt>
+ <dd>
+ Let <var>key</var> be the result of performing the unwrap key operation
+ specified by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
+ <var>unwrappingKey</var> as <var>key</var> and <var>wrappedKey</var> as
+ <var>ciphertext</var>.
+ </dd>
+ <dt>
+ Otherwise, if <var>normalizedAlgorithm</var> supports a decrypt
+ operation:
+ </dt>
+ <dd>
+ Let <var>key</var> be the result of performing the decrypt operation specified
+ by <var>normalizedAlgorithm</var> using <var>algorithm</var>,
+ <var>unwrappingKey</var> as <var>key</var> and <var>wrappedKey</var> as
+ <var>ciphertext</var>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is equal to the strings <code>"raw"</code>,
+ <code>"pkcs8"</code>, or <code>"spki"</code>:
+ </dt>
+ <dd>
+ Set <var>bytes</var> be set to <var>key</var>.
+ </dd>
+ <dt>
+ If <var>format</var> is equal to the string <code>"jwk"</code>:
+ </dt>
+ <dd>
+ Let <var>bytes</var> be the result of executing the
+ <a href="#concept-parse-a-jwk">parse a JWK</a> algorithm, withe <var>key</var>
+ as the <code>data</code> to be parsed.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the import key operation
+ specified by <var>normalizedKeyAlgorithm</var> using
+ <var>unwrappedKeyAlgorithm</var> as <var>algorithm</var>, <var>format</var>,
+ <var>usages</var>
+ and <var>extractable</var> and with
+ <var>bytes</var> as <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>result</var> is <code>"secret"</code> or <code>"private"</code> and
+ <var>usages</var> is empty, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>result</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal
+ slot of <var>result</var> to the <a href="#concept-normalized-usages">normalized
+ value</a> of <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Resolve <var>promise</var> with
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </div>
+ </div>
+ <div id="SubtleCrypto-Exceptions" class="section">
+ <h3>14.4. Exceptions</h3>
+ <p>
+ The methods of the <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface return errors
+ by rejecting the returned promise with a
+ <a href="#dfn-DOMException">DOMException</a>. The following DOMException types from
+ [<a href="#DOM4">DOM4</a>] are used:
+ </p>
+ <table>
+ <tbody>
+ <tr>
+ <th>Type</th>
+ <th>Message (optional)</th>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-NotSupportedError"><code>NotSupportedError</code></dfn></td>
+ <td>The algorithm is not supported</td>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-SyntaxError"><code>SyntaxError</code></dfn></td>
+ <td>A required parameter was missing or out-of-range</td>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-InvalidStateError"><code>InvalidStateError</code></dfn></td>
+ <td>The requested operation is not valid for the current state of the provided key.</td>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-InvalidAccessError"><code>InvalidAccessError</code></dfn></td>
+ <td>The requested operation is not valid for the provided key</td>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-UnknownError"><code>UnknownError</code></dfn></td>
+ <td>The operation failed for an unknown transient reason (e.g. out of memory)</td>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-DataError"><code>DataError</code></dfn></td>
+ <td>Data provided to an operation does not meet requirements</td>
+ </tr>
+ <tr>
+ <td><dfn id="dfn-OperationError"><code>OperationError</code></dfn></td>
+ <td>The operation failed for an operation-specific reason</td>
+ </tr>
+ </tbody>
+ </table>
+ <p>
+ When this specification says to
+ <dfn id="concept-throw">throw</dfn> an error, the user agent must
+ <a href="http://heycam.github.io/webidl/#dfn-throw">throw</a> an error as described in
+ [<a href="#WebIDL">WEBIDL</a>]. When this occurs in a sub-algorithm,
+ this results in termination of execution of the sub-algorithm and all ancestor algorithms
+ until one is reached that explicitly describes procedures for catching exceptions.
+ </p>
+ </div>
+ </div>
+
+ <div id="JsonWebKey-dictionary" class="section">
+ <h2>15. JsonWebKey dictionary</h2>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaOtherPrimesInfo">RsaOtherPrimesInfo</dfn> {
+ <span class="comment">// The following fields are defined in Section 6.3.2.7 of <a href="#jwa">JSON Web Algorithms</a></span>
+ DOMString r;
+ DOMString d;
+ DOMString t;
+};
+
+dictionary <dfn id="dfn-JsonWebKey">JsonWebKey</dfn> {
+ <span class="comment">// The following fields are defined in Section 3.1 of <a href="#jwk">JSON Web Key</a></span>
+ DOMString kty;
+ DOMString use;
+ sequence<DOMString> key_ops;
+ DOMString alg;
+
+ <span class="comment">// The following fields are defined in <a href="#iana-section-jwk">JSON Web Key Parameters Registration</a></span>
+ boolean ext;
+
+ <span class="comment">// The following fields are defined in Section 6 of <a href="#jwa">JSON Web Algorithms</a></span>
+ DOMString crv;
+ DOMString x;
+ DOMString y;
+ DOMString d;
+ DOMString n;
+ DOMString e;
+ DOMString p;
+ DOMString q;
+ DOMString dp;
+ DOMString dq;
+ DOMString qi;
+ sequence<RsaOtherPrimesInfo> oth;
+ DOMString k;
+};
+ </code></pre></div></div>
+ <div id="JsonWebKey-description">
+ <h3>Description</h3>
+ <p class="norm">The following section is non-normative</p>
+ <p>
+ The <a href="#dfn-JsonWebKey">JsonWebKey</a> dictionary provides a way to represent
+ and exchange cryptographic keys represented by the <a href="#jwk">JSON Web Key</a>
+ structure, while allowing native and efficient use within Web Cryptography API
+ applications.
+ </p>
+ </div>
+ </div>
+
+ <div id="big-integer" class="section">
+ <h2>16. BigInteger</h2>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+typedef Uint8Array <dfn id="dfn-BigInteger">BigInteger</dfn>;
+ </code></pre></div></div>
+ <p>
+ The <a href="#dfn-BigInteger">BigInteger</a> typedef is a <code>Uint8Array</code> that
+ holds an arbitrary magnitude unsigned integer in big-endian order. Values read from
+ the API SHALL have minimal typed array length (that is, at most 7 leading zero bits,
+ except the value 0 which shall have length 8 bits). The API SHALL accept values with
+ any number of leading zero bits, including the empty array, which represents zero.
+ </p>
+
+ <div class="note"><div class="noteHeader">Note</div>
+ <strong>Implementation Note:</strong> Since the integer is unsigned, the highest order bit
+ is NOT a sign bit. Implementors should take care when mapping to big integer
+ implementations that expected signed integers.
+ </div>
+ </div>
+
+ <div id="keypair" class="section">
+ <h2>17. CryptoKeyPair dictionary</h2>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-CryptoKeyPair">CryptoKeyPair</dfn> {
+ <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-CryptoKey-publicKey">publicKey</dfn>;
+ <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-CryptoKey-privateKey">privateKey</dfn>;
+};
+ </code></pre></div></div>
+ <p>
+ The <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a> dictionary represents an
+ asymmetric key pair that is comprised of both public and private keys.
+ </p>
+ </div>
+
+ <div id="algorithms" class="section">
+ <h2>18. Algorithms</h2>
+ <div id="algorithm-overview" class="section">
+ <h3>18.1. Overview</h3>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ In addition to providing a common interface to perform cryptographic operations, by
+ way of the <a href="#dfn-SubtleCrypto">SubtleCrypto</a> interface, this specification
+ also provides descriptions for a variety of algorithms that authors may wish to use and
+ that User Agents may choose to implement. This includes a selection of commonly-deployed
+ symmetric and asymmetric algorithms, key derivation mechanisms, and methods for wrapping
+ and unwrapping keys. Further, this specification defines a process to allow additional
+ specifications to introduce additional cryptographic algorithms.
+ </p>
+ </div>
+
+ <div id="algorithm-concepts" class="section">
+ <h3>18.2. Concepts</h3>
+ <div id="algorithm-concepts-naming" class="section">
+ <h4>18.2.1. Naming</h4>
+ <p>
+ Every cryptographic algorithm defined for use with the Web Cryptography API
+ <span class="RFC2119">MUST</span> have a unique name, referred to as its
+ <dfn id="recognized-algorithm-name">recognized algorithm name</dfn>, such that no
+ other specification defines the same case-sensitive string for use with the
+ Web Cryptography API.
+ </p>
+ </div>
+ <div id="algorithm-concepts-operations" class="section">
+ <h4>18.2.2. Supported Operations</h4>
+ <p>
+ Every cryptographic algorithm defined for use with the Web Cryptography API has a list
+ of <dfn id="supported-operation">supported operations</dfn>, which are a set of
+ sub-algorithms to be invoked by the <a href="#dfn-SubtleCrypto">SubtleCrypto</a>
+ interface in order to perform the desired cryptographic operation. This specification
+ makes use of the following operations:
+ </p>
+ <ul>
+ <li>encrypt</li>
+ <li>decrypt</li>
+ <li>sign</li>
+ <li>verify</li>
+ <li>deriveBits</li>
+ <li>wrapKey</li>
+ <li>unwrapKey</li>
+ <li>generateKey</li>
+ <li>importKey</li>
+ <li>exportKey</li>
+ <li>getLength</li>
+ </ul>
+ <p>
+ If a given algorithm specification does not list a particular operation as supported,
+ or explicitly lists an operation as not-supported, then the User Agent
+ <span class="RFC2119">MUST</span> behave as if the invocation of the sub-algorithm
+ threw a NotSupportedError.
+ </p>
+ </div>
+ <div id="algorithm-concepts-normalization" class="section">
+ <h4>18.2.3. Normalization</h4>
+ <p>
+ Every cryptographic algorithm defined for use with the Web Cryptography API <span class="RFC2119">MUST</span> define, for every <a href="#supported-operation">
+ supported operation</a>, the IDL type to use for <a href="#concept-algorithm-normalization">algorithm normalization</a>, as well as the
+ IDL type or types of the return values of the sub-algorithms.
+ </p>
+ </div>
+ </div>
+
+ <div id="algorithm-conventions" class="section">
+ <h3>18.3. Specification Conventions</h3>
+ <p>
+ Every cryptographic algorithm definition within this specification employs the following
+ specification conventions. A section, titled <em>"Registration"</em>, will include the
+ <a href="#recognized-algorithm-name">recognized algorithm name</a>. Additionally, it
+ includes a table, which will list each of the <a href="#supported-operation">supported
+ operations</a> as rows, identified by the <em>Operation</em> column. The contents of the
+ <em>Parameters</em> column for a given row will contain the IDL type to use for <a href="#concept-algorithm-normalization">algorithm normalization</a> for that operation,
+ and the contents of the <em>Result</em> column for that row indicate the IDL type that
+ results from performing the supported operation.
+ </p>
+ <p>
+ If a conforming User Agent implements an algorithm, it
+ <span class="RFC2119">MUST</span> implement all of the <a href="#supported-operation">
+ supported operations</a> and <span class="RFC2119">MUST</span> return the IDL type
+ specified.
+ </p>
+ <p>
+ Additionally, upon initialization, conforming User Agents must perform the
+ <a href="#concept-define-an-algorithm">define an algorithm</a> steps for each of
+ the supported operations, registering their IDL parameter type as indicated.
+ </p>
+ </div>
+
+ <div id="algorithm-normalizing" class="section">
+ <h3>18.4. Algorithm Normalization</h3>
+ <div id="algorithm-normalizing-description" class="section">
+ <h4>18.4.1. Description</h4>
+ <p class="norm">This section is non-normative</p>
+ <p>
+ The <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> typedef permits
+ algorithms to either be specified as a <a href="#dfn-DOMString">DOMString</a> or an
+ object. The usage of <a href="#dfn-DOMString">DOMString</a> is to permit authors a
+ short-hand for noting algorithms that have no parameters (e.g. SHA-1).
+ The usage of object is to allow an <a href="#dfn-Algorithm">Algorithm</a> (or appropriate subclass) to be specified, which
+ contains all of the associated parameters for an object.
+ </p>
+ <p>
+ Because of this, it's necessary to define the algorithm for converting an <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> into an appropriate dictionary
+ that is usable with this API. This algorithm must be extensible, so as to allow new
+ cryptographic algorithms to be added, and consistent, so that Web IDL type mapping can
+ occur before any control is returned to the calling script, which would potentially
+ allow the mutation of parameters or the script environment.
+ </p>
+ </div>
+
+ <div id="algorithm-normalizing-internal" class="section">
+ <h4>18.4.2. Internal State Objects</h4>
+ <p>
+ This specification makes use of an internal object,
+ [[<dfn id="dfn-supportedAlgorithms">supportedAlgorithms</dfn>]]. This internal object is
+ not exposed to applications.
+ </p>
+ <p>
+ Because this value is not exposed to applications, the exact type is not specified.
+ It is only required to behave as an associative container of key/value pairs, where
+ comparisons of keys are performed in a case-sensitive manner.
+ </p>
+ <p>
+ The initial contents of this internal object are as follows:
+ </p>
+ <ol>
+ <li>
+ <p>
+ For each value, <var>v</var> in the List of <a href="#supported-operation">supported operations</a>, set the <var>v</var> key of
+ the internal object [[<a href="#dfn-supportedAlgorithms">supportedAlgorithms</a>]]
+ to a new associative container.
+ </p>
+ </li>
+ </ol>
+ </div>
+
+ <div id="algorithm-normalizing-define-an-algorithm" class="section">
+ <h4>18.4.3. Defining an Algorithm</h4>
+ <p>
+ The <dfn id="concept-define-an-algorithm">define an algorithm</dfn> algorithm is used
+ by specification authors to indicate how a user agent should normalize arguments for a
+ particular algorithm. Its input is an algorithm name <var>alg</var>, represented as a
+ DOMString, operation name <var>op</var>, represented as a DOMString, and desired IDL
+ dictionary type <var>type</var>. The algorithm behaves as follows:
+ </p>
+ <ol>
+ <li>
+ Let <var>registeredAlgorithms</var> be the associative container stored at the
+ <var>op</var> key of [[<a href="#dfn-supportedAlgorithms">supportedAlgorithms</a>]]..
+ </li>
+ <li>
+ Set the <var>alg</var> key of <var>registeredAlgorithms</var> to the IDL dictionary
+ type <var>type</var>.
+ </li>
+ </ol>
+ </div>
+
+ <div id="algorithm-normalizing-normalize-an-algorithm" class="section">
+ <h4>18.4.4. Normalizing an algorithm</h4>
+ <p>
+ The <dfn id="dfn-normalize-an-algorithm">normalize an algorithm</dfn> algorithm defines
+ a process for coercing inputs to a targeted IDL dictionary type, after Web IDL
+ conversion has occurred. It is designed to be extensible, to allow future specifications
+ to define additional algorithms, as well as safe for use with Promises. Its input is an
+ operation name <var>op</var> and an <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a> <var>alg</var>. Its output is
+ either an IDL dictionary type or an error. It behaves as follows:
+ </p>
+ <dl class="switch">
+ <dt>If <var>alg</var> is an instance of a DOMString:</dt>
+ <dd>
+ <p>
+ Return the result of running the <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a> algorithm, with
+ the <code>alg</code> set to a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>
+ dictionary whose <a href="#dfn-KeyAlgorithm-name">name</a> attribute is
+ <var>alg</var>, and with the <code>op</code> set to <var>op</var>.
+ </p>
+ </dd>
+ <dt>If <var>alg</var> is an object:</dt>
+ <dd>
+ <ol>
+ <li>
+ Let <var>registeredAlgorithms</var> be the associative container stored at the
+ <code>op</code> key of [[<a href="#dfn-supportedAlgorithms">supportedAlgorithms</a>]].
+ </li>
+ <li>
+ Let <var>initialAlg</var> be the result of converting the ECMAScript object
+ represented by <var>alg</var> to the IDL dictionary type <a href="#dfn-Algorithm">Algorithm</a>, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </li>
+ <li>
+ If an error occurred, return the error and terminate this algorithm.
+ </li>
+ <li>
+ Let <var>algName</var> be the value of the <a href="#dfn-Algorithm-name">name</a>
+ attribute of <var>initialAlg</var>.
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>registeredAlgorithms</var> contains a key that is a
+ <a href="#case-insensitive">case-insensitive</a> string match for
+ <var>algName</var>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Set <var>algName</var> to the value of the matching key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>desiredType</var> be the IDL dictionary type stored at
+ <var>algName</var> in <var>registeredAlgorithms</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ Return a new <code>NotSupportedError</code> and terminate this algorithm.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ Let <var>normalizedAlgorithm</var> be the result of converting the ECMAScript
+ object represented by <var>alg</var> to the IDL dictionary type
+ <var>desiredType</var>, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </li>
+ <li>
+ Set the <a href="#dfn-Algorithm-name">name</a> attribute of
+ <var>normalizedAlgorithm</var> to <var>algName</var>.
+ </li>
+ <li>
+ If an error occurred, return the error and terminate this algorithm.
+ </li>
+ <li>
+ Let <var>dictionaries</var> be a list consisting of the IDL dictionary type
+ <var>desiredType</var> and all of <var>desiredType</var>'s inherited dictionaries,
+ in order from least to most derived.
+ </li>
+ <li>
+ <p>
+ For each dictionary <var>dictionary</var> in <var>dictionaries</var>:
+ </p>
+ <ol>
+ <li>
+ <p>
+ For each dictionary member <var>member</var> declared on
+ <var>dictionary</var>, in order:
+ </p>
+ <ol>
+ <li>
+ Let <var>key</var> be the identifier of <var>member</var>.
+ </li>
+ <li>
+ Let <var>idlValue</var> be the value of the dictionary member with
+ key name of <var>key</var> on <var>normalizedAlgorithm</var>.
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>member</var> is of the type
+ <a href="http://heycam.github.io/webidl/#common-BufferSource">BufferSource</a> and is
+ present:
+ </dt>
+ <dd>
+ Set the dictionary member on <var>normalizedAlgorithm</var> with key
+ name <var>key</var> to a <a href="#concept-clone-BufferSource">clone of
+ <var>idlValue</var></a>, replacing the current value.
+ </dd>
+ <dt>
+ If <var>member</var> is of the type
+ <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a>:
+ </dt>
+ <dd>
+ Set the dictionary member on <var>normalizedAlgorithm</var> with key
+ name <var>key</var> to the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>,
+ with the <code>alg</code> set to <var>idlValue</var> and the
+ <code>op</code> set to <code>"digest"</code>.
+ </dd>
+ <dt>
+ If <var>member</var> is of the type
+ <a href="#dfn-AlgorithmIdentifier">AlgorithmIdentifier</a>:
+ </dt>
+ <dd>
+ Set the dictionary member on <var>normalizedAlgorithm</var> with key
+ name <var>key</var> to the result of
+ <a href="#dfn-normalize-an-algorithm">normalizing an algorithm</a>,
+ with the <code>alg</code> set to <var>idlValue</var> and the
+ <code>op</code> set to the operation defined by the specification
+ that definines the algorithm identified by <var>algName</var>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ If an error occurred, return the error and terminate this algorithm.
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Return <var>normalizedAlgorithm</var>.
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+
+ </div>
+
+ <div id="algorithm-recommendations" class="section">
+ <h3>18.5. Recommendations</h3>
+ <p class="norm">This section is non-normative.</p>
+ <div id="algorithm-recommendations-authors" class="section">
+ <h4>18.5.1. For Authors</h4>
+ <p>
+ As this API is meant to be extensible, in order to keep up with future developments
+ within cryptography, there are no algorithms that conforming user agents are required
+ to implement. As such, authors should check to see what algorithms are currently
+ recommended and supported by implementations.
+ </p>
+ <p>
+ As highlighted in the <a href="#security-considerations">Security Considerations</a>,
+ even cryptographic algorithms that might be considered strong for one purpose may be
+ insufficient when used with another purpose. Authors should therefore proceed with
+ extreme caution before inventing new cryptographic protocols.
+ </p>
+ <p>
+ Additionally, this specification includes several algorithms which, in their default
+ usage, can result in cryptographic vulnerabilities. While these concerns may be
+ mitigated, such as through the combination and composition with additional algorithms
+ provided by this specification, authors should proceed with caution and review the
+ relevant cryptographic literature before using a given algorithm. The inclusion of
+ algorithms within this specification is not an indicator of their suitability for any
+ or all purpose, and instead merely serve to provide as a specification for how a
+ conforming User Agent must implement the given algorithm, if it choses to implement
+ the algorithm.
+ </p>
+ </div>
+ <div id="algorithm-recommendations-implementers" class="section">
+ <h4>18.5.2. For Implementers</h4>
+ <p>
+ In order to promote interoperability for developers, this specification includes a
+ list of suggested algorithms. These are considered to be the most widely used
+ algorithms in practice at the time of writing, and therefore provide a good starting
+ point for initial implementations of this specification. The suggested algorithms are:
+ </p>
+ <ul>
+ <li>
+ <a href="#hmac">HMAC</a> using <a href="#alg-sha-1">SHA-1</a>
+ </li>
+ <li>
+ <a href="#hmac">HMAC</a> using <a href="#alg-sha-256">SHA-256</a>
+ </li>
+ <li>
+ <a href="#rsassa-pkcs1">RSASSA-PKCS1-v1_5</a> using
+ <a href="#alg-sha-256">SHA-1</a>
+ </li>
+ <li>
+ <a href="#rsa-pss">RSA-PSS</a> using <a href="#alg-sha-256">SHA-256</a>
+ and MGF1 with <a href="#alg-sha-256">SHA-256</a>.
+ </li>
+ <li>
+ <a href="#rsa-oaep">RSA-OAEP</a> using <a href="#alg-sha-256">SHA-256</a>
+ and MGF1 with <a href="#alg-sha-256">SHA-256</a>.
+ </li>
+ <li>
+ <a href="#ecdsa">ECDSA</a> using <a href="#dfn-NamedCurve-p256">P-256</a>
+ curve and <a href="#alg-sha-256">SHA-256</a>
+ </li>
+ <li><a href="#aes-cbc">AES-CBC</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div id="algorithm-overview" class="section">
+ <h2>19. Algorithm Overview</h2>
+ <p class="norm">The following section is non-normative.</p>
+ <p>
+ The table below contains an overview of the algorithms described within this
+ specification, as well as the set of <a href="#subtlecrypto-interface-methods">subtlecrypto
+ methods</a> the algorithm may be used with. In order for
+ an algorithm to be used with a method the corresponding
+ operation or operations, as defined
+ in the procedures for the method, must be defined in the algorithm specification.
+ Note that this mapping of methods to underlying
+ operations is not one-to-one:
+ <ul>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-encrypt">encrypt</a> method requires the encrypt operation.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-decrypt">decrypt</a> method requires the decrypt operation.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-sign">sign</a> method requires the sign operation.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-verify">decrypt</a> method requires the verify operation.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-generateKey">generateKey</a> method requires the generateKey operation.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-deriveKey">deriveKey</a> method requires the
+ deriveBits operation for the key derivation algorithm and the get length and importKey operations
+ for the derived key algorithm.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-digest">digest</a> method requires the digest operation.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-wrapKey">wrapKey</a> method requires the either
+ the encrypt or wrapKey operation for the wrapping algorithm and the exportKey operation
+ for the wrapped key algorithm.</p>
+ </li>
+ <li>
+ <p>The <a href="#SubtleCrypto-method-unwrapKey">unwrapKey</a> method requires the either
+ the decrypt or unwrapKey operation for the unwrapping algorithm and the importKey operation
+ for the unwrapped key algorithm.</p>
+ </li>
+ </ul>
+ </p>
+ <p class="note">
+ Application developers and script authors should not interpret this table as a
+ recommendation for the use of particular algorithms. Instead, it simply documents what
+ methods areA supported. Authors should refer to the <a href="#security-developers">Security considerations for authors</a> section of this
+ document to better understand the risks and concerns that may arise when using certain
+ algorithms.
+ </p>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ Note: All algorithms listed should be considered as "features at risk",
+ barring implementors adopting them. Their inclusion in the Editor's Draft
+ reflects requests for their inclusion by members of the community, and are
+ included as an exercise to ensure the robustness of the API defined in this
+ specification.
+ </p>
+ <p>
+ As such, the list of algorithms, and the recommendations, may be significantly
+ altered in future revisions.
+ </p>
+ </div>
+ <table>
+ <thead>
+ <tr>
+ <th>Algorithm name</th>
+ <th scope="col">encrypt</th>
+ <th scope="col">decrypt</th>
+ <th scope="col">sign</th>
+ <th scope="col">verify</th>
+ <th scope="col">digest</th>
+ <th scope="col">generateKey</th>
+ <th scope="col">deriveKey</th>
+ <th scope="col">deriveBits</th>
+ <th scope="col">importKey</th>
+ <th scope="col">exportKey</th>
+ <th scope="col">wrapKey</th>
+ <th scope="col">unwrapKey</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><a href="#rsassa-pkcs1">RSASSA-PKCS1-v1_5</a></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#rsa-pss">RSA-PSS</a></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#rsa-oaep">RSA-OAEP</a></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ </tr>
+ <tr>
+ <td><a href="#ecdsa">ECDSA</a></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#ecdh">ECDH</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#aes-ctr">AES-CTR</a></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ </tr>
+ <tr>
+ <td><a href="#aes-cbc">AES-CBC</a></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ </tr>
+ <tr>
+ <td><a href="#aes-cmac">AES-CMAC</a></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#aes-gcm">AES-GCM</a></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ </tr>
+ <tr>
+ <td><a href="#aes-cfb">AES-CFB</a></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ </tr>
+ <tr>
+ <td><a href="#aes-kw">AES-KW</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ </tr>
+ <tr>
+ <td><a href="#hmac">HMAC</a></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#dh">DH</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#sha">SHA-1</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#sha">SHA-256</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#sha">SHA-384</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#sha">SHA-512</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#concatkdf">CONCAT</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#hkdf-ctr">HKDF-CTR</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="#pbkdf2">PBKDF2</a></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td>✔</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="rsassa-pkcs1" class="section">
+ <h3>20. RSASSA-PKCS1-v1_5</h3>
+ <div id="rsassa-pkcs1-description" class="section">
+ <h4>20.1. Description</h4>
+ <p>
+ The <code>"RSASSA-PKCS1-v1_5"</code> algorithm identifier is used to perform
+ signing and verification using the RSASSA-PKCS1-v1_5 algorithm specified in
+ [<cite><a href="#RFC3447">RFC3447</a></cite>] and using the SHA hash functions defined
+ in this specification.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with RSASSA-PKCS1-v1_5. Such
+ specifications myst define the digest operations for the additional hash algorithms and
+ <dfn id="dfn-rsa-ssa-extended-import-steps">key import steps</dfn> and
+ <dfn id="dfn-rsa-ssa-extended-export-steps">key export steps</dfn> for RSASSA-PKCS1-v1_5.
+ </p>
+ </div>
+ <div id="rsassa-pkcs1-registration" class="section">
+ <h4>20.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"RSASSA-PKCS1-v1_5"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>sign</td>
+ <td>None</td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>verify</td>
+ <td>None</td>
+ <td>boolean</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-RsaHashedImportParams">RsaHashedImportParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="RsaKeyGenParams-dictionary" class="section">
+ <h4>20.3. RsaKeyGenParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaKeyGenParams">RsaKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+ <span class="comment">// The length, in bits, of the RSA modulus</span>
+ [EnforceRange] required unsigned long <dfn id="dfn-RsaKeyGenParams-modulusLength">modulusLength</dfn>;
+ <span class="comment">// The RSA public exponent</span>
+ required <a href="#dfn-BigInteger">BigInteger</a> <dfn id="dfn-RsaKeyGenParams-publicExponent">publicExponent</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="RsaHashedKeyGenParams-dictionary" class="section">
+ <h4>20.4. RsaHashedKeyGenParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</dfn> : <a href="#dfn-RsaKeyGenParams">RsaKeyGenParams</a> {
+ <span class="comment">// The hash algorithm to use</span>
+ required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-RsaHashedKeyGenParams-hash">hash</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="RsaKeyAlgorithm-dictionary" class="section">
+ <h4>20.5. RsaKeyAlgorithm dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaKeyAlgorithm">RsaKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
+ <span class="comment">// The length, in bits, of the RSA modulus</span>
+ required unsigned long <dfn id="dfn-RsaKeyAlgorithm-modulusLength">modulusLength</dfn>;
+ <span class="comment">// The RSA public exponent</span>
+ required <a href="#dfn-BigInteger">BigInteger</a> <dfn id="dfn-RsaKeyAlgorithm-publicExponent">publicExponent</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="RsaHashedKeyAlgorithm-dictionary" class="section">
+ <h4>20.6. RsaHashedKeyAlgorithm dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</dfn> : <a href="#dfn-RsaKeyAlgorithm">RsaKeyAlgorithm</a> {
+ <span class="comment">// The hash algorithm that is used with this key</span>
+ required <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> <dfn id="dfn-RsaHashedKeyAlgorithm-hash">hash</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="RsaHashedImportParams-dictionary" class="section">
+ <h4>20.7. RsaHashedImportParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaHashedImportParams">RsaHashedImportParams</dfn> {
+ <span class="comment">// The hash algorithm to use</span>
+ required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-RsaHashedImportParams-hash">hash</dfn>;
+};
+ </code></pre></div></div>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ Should this be folded into RsaHashedKeyGenParams and rely on the optional nature of the
+ dictionary fields?
+ </p>
+ </div>
+ </div>
+ <div id="rsassa-pkcs1-operations" class="section">
+ <h4>20.8. Operations</h4>
+ <dl>
+ <dt>Sign</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the signature generation operation defined in Section 8.2 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ as the signer's private key and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
+ <var>M</var> and using the hash function specified in the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> as the Hash option for the EMSA-PKCS1-v1_5 encoding method.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>signature</var> be the value <var>S</var> that results from
+ performing the operation.
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Verify</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the signature verification operation defined in Section 8.2 of
+ [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the
+ [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> as the signer's RSA public key and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
+ <var>M</var> and the <a href="#concept-contents-of-arraybuffer">contents of
+ <var>signature</var></a> as <var>S</var> and using the hash function specified
+ in the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> as the Hash option for the EMSA-PKCS1-v1_5 encoding method.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a boolean with value true if the
+ result of the operations was "valid signature" and a boolean with value
+ false otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"sign"</code> or <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate an RSA key pair, as defined in [<cite><a href="#RFC3447">RFC3447</a></cite>], with RSA modulus length equal to the
+ <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a> attribute of
+ <var>normalizedAlgorithm</var> and RSA public exponent equal to the
+ <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a> attribute of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If generation of the key pair fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"RSASSA-PKCS1-v1_5"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the
+ <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a>
+ attribute of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the
+ <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a>
+ attribute of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
+ of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaHashedKeyGenParams">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the public key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>publicKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>publicKey</var> to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>publicKey</var> to be the <a href="#concept-usage-intersection">usage
+ intersection</a> of <var>usages</var> and <code>[ "verify" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the private key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>privateKey</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>privateKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>privateKey</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>privateKey</var> to be the <a href="#concept-usage-intersection">usage
+ intersection</a> of <var>usages</var> and <code>[ "sign" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
+ of <var>result</var> to be <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
+ of <var>result</var> to be <var>privateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of converting <var>result</var> to an ECMAScript Object, as
+ defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ TODO: Specify the mapping between key.algorithm.hash and the appropriate Hash
+ functions (and back to OID).
+ </p>
+ </div>
+ </dd>
+
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>spki</var> be the result of running the
+ <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>alg</var> be the <code>algorithm</code> object identifier
+ field of the <code>algorithm</code> AlgorithmIdentifier field of
+ <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
+ OID defined in Section 2.3.1 of <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha1WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha256WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha384WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha512WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-ssa-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>spki</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the
+ <code>subjectPublicKeyInfo</code> field of <var>spki</var>,
+ <var>structure</var> as the <code>RSAPublicKey</code> structure
+ specified in Section A.1.1 of <a href="#RFC3447">RFC 3447</a>, and
+ <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the RSA public key identified by
+ <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"sign"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKeyInfo</var> be the result of running the
+ <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>alg</var> be the <code>algorithm</code> object identifier
+ field of the <code>privateKeyAlgorithm</code>
+ PrivateKeyAlgorithmIdentifier field of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
+ OID defined in Section 2.3.1 of <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha1WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha256WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha384WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>sha512WithRSAEncryption</code> OID defined in Section A.2.4 of
+ <a href="#RFC3279">RFC 3279</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-ssa-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>rsaPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the
+ <code>privateKey</code> field of <var>privateKeyInfo</var>,
+ <var>structure</var> as the <code>RSAPrivateKey</code> structure
+ specified in Section A.1.2 of <a href="#RFC3447">RFC 3447</a>, and
+ <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the RSA private key identified by
+ <var>rsaPrivateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field of <var>jwk</var> is present and
+ <var>usages</var> contains an entry which is not
+ <code>"sign"</code>, or, if the <code>"d"</code> field of <var>jwk</var>
+ is not present and
+ <var>usages</var> contains an entry which is not
+ <code>"verify"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not a
+ case-sensitive string match to <code>"RSA"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not a case-sensitive string match to <code>"sig"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be a be a string whose initial value is
+ undefined.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>"alg"</code> field of <var>jwk</var> is not
+ present:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"RS1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"RS256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"RS384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"RS512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-ssa-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <code>"d"</code> field of <var>jwk</var> is present:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.3.2 of <a href="#jwa">JSON Web
+ Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ RSA private key identified by interpreting <var>jwk</var>
+ according to Section 6.3.2 of <a href="#jwa"> JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.3.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ RSA public key identified by interpreting <var>jwk</var>
+ according to Section 6.3.1 of <a href="#jwa"> JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a> dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"RSASSA-PKCS1-v1_5"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
+ attribute of <var>algorithm</var> to the length, in bits, of the RSA public
+ modulus.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
+ attribute of <var>algorithm</var> to the <a href="#dfn-BigInteger">BigInteger</a>
+ representation of the RSA public exponent.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of
+ <var>algorithm</var> to the <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>Return <var>key</var>.</p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>key</var> be the key to be exported.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code></dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to an
+ <code>AlgorithmIdentifier</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>1.2.840.113549.1.1</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to the ASN.1 type NULL.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>subjectPublicKey</var> field to the result of
+ DER-encoding an <code>RSAPublicKey</code> ASN.1 type, as defined
+ in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.1, that
+ represents the RSA public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#dfn-encode-a-privateKeyInfo"> encoding a privateKeyInfo</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>version</var> field to 0.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKeyAlgorithm</var> field to a
+ <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>1.2.840.113549.1.1</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to the ASN.1 type NULL.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKey</var> field to the result of DER-encoding
+ an <code>RSAPrivateKey</code> ASN.1 type, as defined in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.2, that represents the
+ RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>
+ </p>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <a href="#RFC5208">RFC 5208</a> specifies that the encoding of
+ this field should be <em>BER</em> encoded in Section 5 (as a "for
+ example"). However, to avoid requiring WebCrypto implementations
+ support BER-encoding and BER-decoding, only <em>DER</em> encodings
+ are produced or accepted.
+ </div>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ul>
+ <li>
+ <p>Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.</p>
+ </li>
+ <li>
+ <p>Set the <code>kty</code> attribute of <var>jwk</var> to the string
+ <code>"RSA"</code>.</p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
+ attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>hash</var> is <code>"SHA-1"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RS1"</code>.
+ </p>
+ </dd>
+ <dt>If <var>hash</var> is <code>"SHA-256"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RS256"</code>.
+ </p>
+ </dd>
+ <dt>If <var>hash</var> is <code>"SHA-384"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RS384"</code>.
+ </p>
+ </dd>
+ <dt>If <var>hash</var> is <code>"SHA-512"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RS512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-ssa-extended-export-steps">key
+ export steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>key</var>
+ and obtaining <var>alg</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to <var>alg</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the attributes <code>n</code> and <code>e</code> of <var>jwk</var>
+ according to the corresponding definitions in <a href="#jwa">JSON Web
+ Algorithms</a>, Section 6.3.1.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is <code>"private"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Set the attributes named <code>d</code>, <code>p</code>,
+ <code>q</code>, <code>dp</code>, <code>dq</code>, and
+ <code>qi</code> of <var>jwk</var> according to the
+ corresponding definitions in <a href="#jwa">JSON Web
+ Algorithms</a>, Section 6.3.2.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
+ of <var>key</var> is represented by more than two primes, set
+ the attribute named <code>oth</code> of <var>jwk</var>
+ according to the corresponding definition in <a href="#jwa">JSON Web Algorithms</a>, Section 6.3.2.7
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ul>
+ </dd>
+ <dt>Otherwise</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="rsa-pss" class="section">
+ <h3>21. RSA-PSS</h3>
+ <div id="rsa-pss-description" class="section">
+ <h4>21.1. Description</h4>
+ <p>
+ The <code>"RSA-PSS"</code> algorithm identifier is used to perform signing
+ and verification using the RSASSA-PSS algorithm specified in
+ [<cite><a href="#RFC3447">RFC3447</a></cite>], using the SHA hash functions defined
+ in this specification and the mask generation
+ formula MGF1.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with RSASSA-PSS. Such specifications
+ must define the digest operation for the additional hash algorithms and
+ <dfn id="dfn-rsa-pss-extended-import-steps">key import steps</dfn> and
+ <dfn id="dfn-rsa-pss-extended-export-steps">key export steps</dfn> for RSASSA-PSS.
+ </p>
+ </div>
+ <div id="rsa-pss-registration" class="section">
+ <h4>21.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"RSA-PSS"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>sign</td>
+ <td><a href="#dfn-RsaPssParams">RsaPssParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>verify</td>
+ <td><a href="#dfn-RsaPssParams">RsaPssParams</a></td>
+ <td>boolean</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-RsaHashedImportParams">RsaHashedImportParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="RsaPssParams-dictionary" class="section">
+ <h4>21.3. RsaPssParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaPssParams">RsaPssParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The desired length of the random salt</span>
+[EnforceRange] required unsigned long <dfn id="dfn-RsaPssParams-saltLength">saltLength</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="rsa-pss-operations" class="section">
+ <h4>21.4. Operations</h4>
+ <dl>
+ <dt>Sign</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the signature generation operation defined in Section 8.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ as the signer's private key, <var>K</var>, and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
+ the message to be signed, <var>M</var>, and using the hash function specified
+ by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> as the Hash option, MGF1 (defined in Section B.2.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option and the <a href="#dfn-RsaPssParams-saltLength">saltLength</a> member of
+ <var>normalizedAlgorithm</var> as the salt length option for the
+ EMM-PSS-ENCODE operation.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>signature</var> be a new <code>ArrayBuffer</code> containing the
+ signature, S, that results from performing the operation.
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Verify</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the signature verification operation defined in Section 8.1 of
+ [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by the
+ [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> as the signer's RSA public key and the <a href="#concept-contents-of-arraybuffer">contents of <var>message</var></a> as
+ <var>M</var> and <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>signature</var></a> as <var>S</var> and using the hash function specified
+ by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> as the Hash option, MGF1 (defined in Section B.2.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option and the <a href="#dfn-RsaPssParams-saltLength">saltLength</a> member of
+ <var>normalizedAlgorithm</var> as the salt length option for the
+ EMSA-PSS-VERIFY operation.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a boolean with value true if the
+ result of the operation was "valid signature" and a boolean with value
+ false otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"sign"</code> or <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate an RSA key pair, as defined in [<cite><a href="#RFC3447">RFC3447</a></cite>], with RSA modulus length equal to the
+ <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a> member of
+ <var>normalizedAlgorithm</var> and RSA public exponent equal to the
+ <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"RSA-PSS"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the
+ <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a>
+ member of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the
+ <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a>
+ member of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
+ of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaHashedKeyGenParams">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the public key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>publicKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>publicKey</var> to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>publicKey</var> to be the <a href="#concept-usage-intersection">usage
+ intersection</a> of <var>usages</var> and <code>[ "verify" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the private key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>privateKey</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>privateKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>privateKey</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>privateKey</var> to be the <a href="#concept-usage-intersection">usage
+ intersection</a> of <var>usages</var> and <code>[ "sign" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
+ of <var>result</var> to <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
+ of <var>result</var> to <var>privateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of converting <var>result</var> to an ECMAScript Object,
+ as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"verify"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>spki</var> be the result of running the
+ <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>alg</var> be the <code>algorithm</code> object identifier
+ field of the <code>algorithm</code> AlgorithmIdentifier field of
+ <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the
+ <code>id-RSASSA-PSS</code> OID defined in
+ <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>params</var> be the ASN.1 structure contained within
+ the <code>parameters</code> field of the <code>algorithm</code>
+ AlgorithmIdentifier field of <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not defined, or is not an instance of
+ the <code>RSASSA-PSS-params</code> ASN.1 type defined in
+ <a href="#RFC3447">RFC3447</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
+ within the <code>hashAlgorithm</code> field of <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha256</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha384</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha512</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>spki</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ an instance of the <code>HashAlgorithm</code> ASN.1 type that is
+ identical in content to the <code>hashAlglorithm</code> field of
+ <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the
+ <code>subjectPublicKeyInfo</code> field of <var>spki</var>,
+ <var>structure</var> as the <code>RSAPublicKey</code> structure
+ specified in Section A.1.1 of <a href="#RFC3447">RFC 3447</a>, and
+ <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the RSA public key identified by
+ <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"sign"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKeyInfo</var> be the result of running the
+ <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>alg</var> be the <code>algorithm</code> object identifier
+ field of the <code>privateKeyAlgorithm</code>
+ PrivateKeyAlgorithmIdentifier field of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the <code>id-RSASSA-PSS</code> OID
+ defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>params</var> be the ASN.1 structure contained within
+ the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier
+ field of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not defined, or is not an instance of
+ the <code>RSASSA-PSS-params</code> ASN.1 type defined in
+ <a href="#RFC3447">RFC3447</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
+ within the <code>hashAlgorithm</code> field of <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha256</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha384</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha512</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ an instance of the <code>HashAlgorithm</code> ASN.1 type that is
+ identical in content to the <code>hashAlglorithm</code> field of
+ <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>rsaPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the
+ <code>privateKey</code> field of <var>privateKeyInfo</var>,
+ <var>structure</var> as the <code>RSAPrivateKey</code> structure
+ specified in Section A.1.2 of <a href="#RFC3447">RFC 3447</a>, and
+ <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the RSA private key identified by
+ <var>rsaPrivateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field of <var>jwk</var> is present and
+ <var>usages</var> contains an entry which is not
+ <code>"sign"</code>, or, if the <code>"d"</code> field of <var>jwk</var>
+ is not present and
+ <var>usages</var> contains an entry which is not
+ <code>"verify"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not a
+ case-sensitive string match to <code>"RSA"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not a case-sensitive string match to <code>"sig"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>"alg"</code> field of <var>jwk</var> is not
+ present:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"PS1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"PS256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"PS384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string
+ <code>"PS512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <code>"d"</code> field of <var>jwk</var> is present:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.3.2 of <a href="#jwa">JSON Web
+ Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ RSA private key identified by interpreting <var>jwk</var>
+ according to Section 6.3.2 of <a href="#jwa"> JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.3.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ RSA public key identified by interpreting <var>jwk</var>
+ according to Section 6.3.1 of <a href="#jwa"> JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a> dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"RSA-PSS"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
+ attribute of <var>algorithm</var> to the length, in bits, of the RSA public
+ modulus.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
+ attribute of <var>algorithm</var> to the <a href="#dfn-BigInteger">BigInteger</a>
+ representation of the RSA public exponent.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of
+ <var>algorithm</var> to the <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>
+ </p>
+ </li>
+ <li>
+ <p>Return <var>key</var>.</p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>key</var> be the key to be exported.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code></dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to an
+ <code>AlgorithmIdentifier</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-RSASSA-PSS</code> defined in
+ <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>RSASSA-PSS-params</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>hashAlgorithm</var> field to an instance of
+ the <code>HashAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>hashOid</var> and <var>hashParams</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to <var>hashOid</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field of <var>hashAlgorithm</var>
+ to
+ <var>hashParams</var> if <var>hashParams</var> is not
+ undefined and omit the <var>params</var> field otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <var>maskGenAlgorithm</var> field to an instance
+ of the <code>MaskGenAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
+ 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>HashAlgorithm</code> ASN.1 type that is
+ identical to the <var>hashAlgorithm</var> field.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>saltLength</var> field to the length in
+ octets of the digest algorithm identified by the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
+ of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>subjectPublicKey</var> field to the result of
+ DER-encoding an <code>RSAPublicKey</code> ASN.1 type, as defined
+ in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.1, that
+ represents the RSA public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#dfn-encode-a-privateKeyInfo"> encoding a privateKeyInfo</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>version</var> field to 0.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKeyAlgorithm</var> field to an
+ <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-RSASSA-PSS</code> defined in
+ <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>RSASSA-PSS-params</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>hashAlgorithm</var> field to an instance of
+ the <code>HashAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>hashOid</var> and <var>hashParams</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to <var>hashOid</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field of <var>hashAlgorithm</var>
+ to
+ <var>hashParams</var> if <var>hashParams</var> is not
+ undefined and omit the <var>params</var> field otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <var>maskGenAlgorithm</var> field to an instance
+ of the <code>MaskGenAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
+ 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>HashAlgorithm</code> ASN.1 type that is
+ identical to the <var>hashAlgorithm</var> field.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>saltLength</var> field to the length in
+ octets of the digest algorithm identified by the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
+ of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKey</var> field to the result of DER-encoding
+ an <code>RSAPrivateKey</code> ASN.1 type, as defined in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.2, that represents the
+ RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>
+ </p>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <a href="#RFC5208">RFC 5208</a> specifies that the encoding of
+ this field should be <em>BER</em> encoded in Section 5 (as a "for
+ example"). However, to avoid requiring WebCrypto implementations
+ support BER-encoding and BER-decoding, only <em>DER</em> encodings
+ are produced or accepted.
+ </div>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ul>
+ <li>
+ <p>Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a> dictionary.</p>
+ </li>
+ <li>
+ <p>Set the <code>kty</code> attribute of <var>jwk</var> to the string
+ <code>"RSA"</code>.</p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>hash</var> is <code>"SHA-1"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"PS1"</code>.
+ </p>
+ </dd>
+ <dt>If <var>hash</var> is <code>"SHA-256"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"PS256"</code>.
+ </p>
+ </dd>
+ <dt>If <var>hash</var> is <code>"SHA-384"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"PS384"</code>.
+ </p>
+ </dd>
+ <dt>If <var>hash</var> is <code>"SHA-512"</code>:</dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"PS512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>alg</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to <var>alg</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the attributes <code>n</code> and <code>e</code> of <var>jwk</var>
+ according to the corresponding definitions in <a href="#jwa">JSON Web
+ Algorithms</a>, Section 6.3.1.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is <code>"private"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Set the attributes named <code>d</code>, <code>p</code>,
+ <code>q</code>, <code>dp</code>, <code>dq</code>, and
+ <code>qi</code> of <var>jwk</var> according to the
+ corresponding definitions in <a href="#jwa">JSON Web
+ Algorithms</a>, Section 6.3.2.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
+ of <var>key</var> is represented by more than two primes, set
+ the attribute named <code>oth</code> of <var>jwk</var>
+ according to the corresponding definition in <a href="#jwa">JSON Web Algorithms</a>, Section 6.3.2.7
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ul>
+ </dd>
+ <dt>Otherwise</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="rsa-oaep" class="section">
+ <h3>22. RSA-OAEP</h3>
+ <div id="rsa-oaep-description" class="section">
+ <h4>22.1. Description</h4>
+ <p>
+ The <code>"RSA-OAEP"</code> algorithm identifier is used to perform encryption
+ and decryption ordering to the RSAES-OAEP algorithm specified in
+ [<cite><a href="#RFC3447">RFC3447</a></cite>], using the SHA hash functions defined
+ in this specification and using the mask
+ generation function MGF1.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with RSAES-OAEP. Such specifications
+ must define the digest operation for the additional hash algorithm and
+ <dfn id="dfn-rsa-oaep-extended-import-steps">key import steps</dfn> and
+ <dfn id="dfn-rsa-oaep-extended-export-steps">key export steps</dfn> for RSAES-OAEP.
+ </p>
+ </div>
+ <div id="rsa-oaep-registration" class="section">
+ <h4>22.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"RSA-OAEP"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>encrypt</td>
+ <td><a href="#dfn-RsaOaepParams">RsaOaepParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>decrypt</td>
+ <td><a href="#dfn-RsaOaepParams">RsaOaepParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-RsaHashedImportParams">RsaHashedImportParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="rsa-oaep-params" class="section">
+ <h4>22.3. RsaOaepParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-RsaOaepParams">RsaOaepParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The optional label/application data to associate with the message</span>
+BufferSource <dfn id="dfn-RsaOaepParams-label">label</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="rsa-oaep-operations" class="section">
+ <h4>22.4. Operations</h4>
+ <dl>
+ <dt>Encrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of <var>key</var>
+ is not <code>"public"</code>,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>label</var> be the <a href="#concept-contents-of-arraybuffer">contents of</a> the <a href="#dfn-RsaOaepParams-label">label</a> member of
+ <var>normalizedAlgorithm</var> or the empty octet string if the
+ <a href="#dfn-RsaOaepParams-label">label</a> member of
+ <var>normalizedAlgorithm</var> is not present.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the encryption operation defined in Section 7.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by <var>key</var>
+ as the recipient's RSA public key, the <a href="#concept-contents-of-arraybuffer">contents of <var>plaintext</var></a>
+ as the message to be encrypted, <var>M</var> and <var>label</var>
+ as the label, <var>L</var>, and with the hash
+ function specified by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> as the Hash option and MGF1 (defined in Section B.2.1 of
+ [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>ciphertext</var> be a new <code>ArrayBuffer</code>
+ containing the value <var>C</var> that results from performing the
+ operation.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Decrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of <var>key</var>
+ is not <code>"private"</code>,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>label</var> be the <a href="#concept-contents-of-arraybuffer">contents of</a> the <a href="#dfn-RsaOaepParams-label">label</a> member of
+ <var>normalizedAlgorithm</var> or the empty octet string if the
+ <a href="#dfn-RsaOaepParams-label">label</a> member of
+ <var>normalizedAlgorithm</var> is not present.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the decryption operation defined in Section 7.1 of [<cite><a href="#RFC3447">RFC3447</a></cite>] with the key represented by <var>key</var>
+ as the recipient's RSA private key, the <a href="#concept-contents-of-arraybuffer">contents of <var>ciphertext</var></a>
+ as the ciphertext to be decrypted, C, and <var>label</var>
+ as the label, <var>L</var>, and with the hash
+ function specified by the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> as the Hash option and MGF1 (defined in Section B.2.1 of
+ [<cite><a href="#RFC3447">RFC3447</a></cite>]) as the MGF option.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>plaintext</var> be a new <code>ArrayBuffer</code>
+ containing the value <var>M</var> that results from performing the
+ operation.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate an RSA key pair, as defined in [<cite><a href="#RFC3447">RFC3447</a></cite>], with RSA modulus length equal to the
+ <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a> member of
+ <var>normalizedAlgorithm</var> and RSA public exponent equal to the
+ <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>
+ object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"RSA-OAEP"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the
+ <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaKeyGenParams-modulusLength">modulusLength</a>
+ member of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the
+ <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaKeyGenParams-publicExponent">publicExponent</a>
+ member of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute
+ of <var>algorithm</var> to equal the
+ <a href="#dfn-RsaHashedKeyGenParams">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the public key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>publicKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot of
+ <var>publicKey</var> to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>publicKey</var> to be the
+ <a href="#concept-usage-intersection">usage intersection</a> of
+ <var>usages</var> and <code>[ "encrypt", "wrapKey" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the private key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>privateKey</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>privateKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot of
+ <var>privateKey</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>privateKey</var> to be the
+ <a href="#concept-usage-intersection">usage intersection</a> of
+ <var>usages</var> and <code>[ "decrypt", "unwrapKey" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
+ of <var>result</var> to be <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
+ of <var>result</var> to be <var>privateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of converting <var>result</var> to an ECMAScript Object, as
+ defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"encrypt"</code> or
+ <code>"wrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>spki</var> be the result of running the
+ <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be a string whose initial value is undefined.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>alg</var> be the <code>algorithm</code> object identifier
+ field of the <code>algorithm</code> AlgorithmIdentifier field of
+ <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the <code>id-RSAES-OAEP</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>params</var> be the ASN.1 structure contained within
+ the <code>parameters</code> field of the <code>algorithm</code>
+ AlgorithmIdentifier field of <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not defined, or is not an instance of
+ the <code>RSAES-OAEP-params</code> ASN.1 type defined in
+ <a href="#RFC3447">RFC3447</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
+ within the <code>hashAlgorithm</code> field of <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha256</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha384</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha512</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-oeap-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>spki</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ an instance of the <code>HashAlgorithm</code> ASN.1 type that is
+ identical in content to the <code>hashAlglorithm</code> field of
+ <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the
+ <code>subjectPublicKeyInfo</code> field of <var>spki</var>,
+ <var>structure</var> as the <code>RSAPublicKey</code> structure
+ specified in Section A.1.1 of <a href="#RFC3447">RFC 3447</a>, and
+ <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the RSA public key identified by
+ <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"decrypt"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKeyInfo</var> be the result of running the
+ <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be a string whose initial value is undefined.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>alg</var> be the <code>algorithm</code> object identifier
+ field of the <code>privateKeyAlgorithm</code>
+ PrivateKeyAlgorithmIdentifier field of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>alg</var> is equivalent to the <code>rsaEncryption</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>hash</var> be undefined.
+ </p>
+ </dd>
+ <dt>
+ If <var>alg</var> is equivalent to the <code>id-RSAES-OAEP</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>params</var> be the ASN.1 structure contained within
+ the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier
+ field of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not defined, or is not an instance of
+ the <code>RSAES-OAEP-params</code> ASN.1 type defined in <a href="#RFC3447">RFC3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hashAlg</var> be the AlgorithmIdentifier ASN.1 type
+ within the <code>hashAlgorithm</code> field of
+ <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the <code>id-sha1</code>
+ OID defined in <a href="#RFC3447">RFC 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-1"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the
+ <code>id-sha256</code> OID defined in <a href="#RFC3447">RFC
+ 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the
+ <code>id-sha384</code> OID defined in <a href="#RFC3447">RFC
+ 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <code>algorithm</code> object identifier field of
+ <var>hashAlg</var> is equivalent to the
+ <code>id-sha512</code> OID defined in <a href="#RFC3447">RFC
+ 3447</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>hash</var> to the string <code>"SHA-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-oeap-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>spki</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ equivalent to the OID <code>id-mgf1</code> defined in <a href="#RFC3447">RFC 3447</a>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>maskGenAlgorithm</code> field of <var>params</var> is not
+ an instance of the <code>HashAlgorithm</code> ASN.1 type that is
+ identical in content to the <code>hashAlglorithm</code> field of
+ <var>params</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>rsaPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the
+ <code>privateKey</code> field of <var>privateKeyInfo</var>,
+ <var>structure</var> as the <code>RSAPrivateKey</code> structure
+ specified in Section A.1.2 of <a href="#RFC3447">RFC 3447</a>, and
+ <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the RSA private key identified by
+ <var>rsaPrivateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field of <var>jwk</var> is present and
+ <var>usages</var> contains an entry which is not
+ <code>"decrypt"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field of <var>jwk</var> is not present and
+ <var>usages</var> contains an entry which is not
+ <code>"encrypt"</code> or <code>"wrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not a
+ case-sensitive string match to <code>"RSA"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not a case-sensitive string match to <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <code>alg</code> field of <var>jwk</var> is not present:</dt>
+ <dd>Let <var>hash</var> be undefined.</dd>
+ <dt>
+ If the <code>alg</code> field of <var>jwk</var> is equal to
+ <code>"RSA-OAEP"</code>:
+ </dt>
+ <dd>Let <var>hash</var> be the string <code>"SHA-1"</code>.</dd>
+ <dt>
+ If the <code>alg</code> field of <var>jwk</var> is equal to
+ <code>"RSA-OAEP-256"</code>:
+ </dt>
+ <dd>Let <var>hash</var> be the string <code>"SHA-256"</code>.</dd>
+ <dt>
+ If the <code>alg</code> field of <var>jwk</var> is equal to
+ <code>"RSA-OAEP-384"</code>:
+ </dt>
+ <dd>Let <var>hash</var> be the string <code>"SHA-384"</code>.</dd>
+ <dt>
+ If the <code>alg</code> field of <var>jwk</var> is equal to
+ <code>"RSA-OAEP-512"</code>:
+ </dt>
+ <dd>Let <var>hash</var> be the string <code>"SHA-512"</code>.</dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-oaep-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and obtaining <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl>
+ <dt>
+ If <var>hash</var> is not undefined:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>normalizedHash</var> be the result of
+ <a href="#dfn-normalize-an-algorithm">normalize an algorithm</a>
+ with <code>alg</code> set to <var>hash</var> and <code>op</code> set
+ to <code>digest</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>normalizedHash</var> is not equal to the
+ <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <code>"d"</code> field of <var>jwk</var> is present:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.3.2 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ RSA private key identified by interpreting <var>jwk</var>
+ according to Section 6.3.2 of <a href="#jwa"> JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.3.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ RSA public key identified by interpreting <var>jwk</var>
+ according to Section 6.3.1 of <a href="#jwa"> JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-RsaHashedKeyAlgorithm">RsaHashedKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"RSA-OAEP"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaKeyAlgorithm-modulusLength">modulusLength</a>
+ attribute of <var>algorithm</var> to the length, in bits, of the RSA public
+ modulus.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaKeyAlgorithm-publicExponent">publicExponent</a>
+ attribute of <var>algorithm</var> to the <a href="#dfn-BigInteger">BigInteger</a>
+ representation of the RSA public exponent.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-RsaHashedKeyAlgorithm-hash">hash</a> attribute of
+ <var>algorithm</var> to the <a href="#dfn-RsaHashedImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> to <var>algorithm</var>
+ </p>
+ </li>
+ <li>
+ <p>Return <var>key</var>.</p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>key</var> be the key to be exported.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> a <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code></dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to an
+ <code>AlgorithmIdentifier</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-RSAES-OAEP</code> defined in
+ <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>RSAES-OAEP-params</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>hashAlgorithm</var> field to an instance of
+ the <code>HashAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-pss-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>hashOid</var> and <var>hashParams</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to <var>hashOid</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field of <var>hashAlgorithm</var>
+ to
+ <var>hashParams</var> if <var>hashParams</var> is not
+ undefined and omit the <var>params</var> field otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <var>maskGenAlgorithm</var> field to an instance
+ of the <code>MaskGenAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
+ 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>HashAlgorithm</code> ASN.1 type that is
+ identical to the <var>hashAlgorithm</var> field.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>subjectPublicKey</var> field to the result of
+ DER-encoding an <code>RSAPublicKey</code> ASN.1 type, as defined
+ in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.1, that
+ represents the RSA public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the result of <a href="#dfn-encode-a-privateKeyInfo"> encoding a privateKeyInfo</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>version</var> field to 0.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKeyAlgorithm</var> field to an
+ <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-RSAES-OAEP</code> defined in
+ <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>RSAES-OAEP-params</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>hashAlgorithm</var> field to an instance of
+ the <code>HashAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha1</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha256</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha384</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a>
+ attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to the
+ OID <code>id-sha512</code> defined in <a href="#RFC3447">RFC 3447</a>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-oaep-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>hashOid</var> and <var>hashParams</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier
+ of <var>hashAlgorithm</var> to <var>hashOid</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field of <var>hashAlgorithm</var>
+ to
+ <var>hashParams</var> if <var>hashParams</var> is not
+ undefined and omit the <var>params</var> field otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <var>maskGenAlgorithm</var> field to an instance
+ of the <code>MaskGenAlgorithm</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the OID
+ <code>id-mgf1</code> defined in <a href="#RFC3447">RFC
+ 3447</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>params</var> field to an instance of the
+ <code>HashAlgorithm</code> ASN.1 type that is
+ identical to the <var>hashAlgorithm</var> field.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKey</var> field to the result of DER-encoding
+ an <code>RSAPrivateKey</code> ASN.1 type, as defined in <a href="#RFC3447">RFC 3447</a>, Appendix A.1.2, that represents the
+ RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>
+ </p>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <a href="#RFC5208">RFC 5208</a> specifies that the encoding of
+ this field should be <em>BER</em> encoded in Section 5 (as a "for
+ example"). However, to avoid requiring WebCrypto implementations
+ support BER-encoding and BER-decoding, only <em>DER</em> encodings
+ are produced or accepted.
+ </div>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ul>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the string
+ <code>"RSA"</code>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RSA-OAEP"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RSA-OAEP-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RSA-OAEP-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to the string
+ <code>"RSA-OAEP-512"</code>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-rsa-oaep-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-RsaHashedKeyAlgorithm">hash</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>alg</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to <var>alg</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the attributes <code>n</code> and <code>e</code> of <var>jwk</var>
+ according to the corresponding definitions in <a href="#jwa">JSON Web
+ Algorithms</a>, Section 6.3.1.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is <code>"private"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Set the attributes named <code>d</code>, <code>p</code>,
+ <code>q</code>, <code>dp</code>, <code>dq</code>, and
+ <code>qi</code> of <var>jwk</var> according to the
+ corresponding definitions in <a href="#jwa">JSON Web
+ Algorithms</a>, Section 6.3.2.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying RSA private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
+ of <var>key</var> is represented by more than two primes, set
+ the attribute named <code>oth</code> of <var>jwk</var>
+ according to the corresponding definition in <a href="#jwa">JSON Web Algorithms</a>, Section 6.3.2.7
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ul>
+ </dd>
+ <dt>Otherwise</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="ecdsa" class="section">
+ <h3>23. ECDSA</h3>
+ <div id="ecdsa-description" class="section">
+ <h4>23.1. Description</h4>
+ <p>
+ The <code>"ECDSA"</code> algorithm identifier is used to perform signing
+ and verification using the ECDSA algorithm specified in
+ [<cite><a href="#X9.62">X9.62</a></cite>] and using the SHA hash functions and elliptic
+ curves defined in this specification.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ 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 <a href="#algorithms">registered algorithm</a> that supports the digest operation.
+ To specify an additional elliptic curve a specification must define
+ <dfn id="dfn-ecdsa-extended-namedcurve-values">the curve name</dfn>,
+ <dfn id="dfn-ecdsa-extended-signature-steps">ECDSA signature steps</dfn>,
+ <dfn id="dfn-ecdsa-extended-verification-steps">ECDSA verification steps</dfn>,
+ <dfn id="dfn-ecdsa-extended-generation-steps">ECDSA generation steps</dfn>,
+ <dfn id="dfn-ecdsa-extended-import-steps">ECDSA key import steps</dfn> and
+ <dfn id="dfn-ecdsa-extended-verification-steps">ECDSA key export steps</dfn>.
+ </p>
+ </div>
+ <div id="ecdsa-registration" class="section">
+ <h4>23.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"ECDSA"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>sign</td>
+ <td><a href="#dfn-EcdsaParams">EcdsaParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>verify</td>
+ <td><a href="#dfn-EcdsaParams">EcdsaParams</a></td>
+ <td>boolean</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-EcKeyGenParams">EcKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-EcKeyImportParams">EcKeyImportParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+ <div id="EcdsaParams-dictionary" class="section">
+ <h4>23.3. EcdsaParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-EcdsaParams">EcdsaParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The hash algorithm to use</span>
+required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-EcdsaParams-hash">hash</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="EcKeyGenParams-dictionary" class="section">
+ <h4>23.4. EcKeyGenParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+typedef DOMString <a href="#dfn-NamedCurve">NamedCurve</a>;
+
+dictionary <dfn id="dfn-EcKeyGenParams">EcKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// A named curve</span>
+required <a href="#dfn-NamedCurve">NamedCurve</a> <dfn id="dfn-EcKeyGenParams-namedCurve">namedCurve</dfn>;
+};
+ </code></pre></div></div>
+ <p>
+ The <dfn id="dfn-NamedCurve">NamedCurve</dfn> 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>
+ <dl>
+ <dt id="dfn-NamedCurve-p256"><code>"P-256"</code></dt>
+ <dd>NIST recommended curve P-256, also known as <code>secp256r1</code>.</dd>
+ <dt id="dfn-NamedCurve-p2384"><code>"P-384"</code></dt>
+ <dd>NIST recommended curve P-384, also known as <code>secp384r1</code>.</dd>
+ <dt id="dfn-NamedCurve-p521"><code>"P-521"</code></dt>
+ <dd>NIST recommended curve P-521, also known as <code>secp521r1</code>.</dd>
+ </dl>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a> may define
+ <a href="#dfn-ecdsa-extended-namedcurve-values">additional values</a>.
+ </p>
+ </div>
+ <div id="EcKeyAlgorithm-dictionary" class="section">
+ <h4>23.5. EcKeyAlgorithm dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-EcKeyAlgorithm">EcKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
+<span class="comment">// The named curve that the key uses</span>
+required <a href="#dfn-NamedCurve">NamedCurve</a> <dfn id="dfn-EcKeyAlgorithm-namedCurve">namedCurve</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="EcKeyImportParams-dictionary" class="section">
+ <h4>23.6. EcKeyImportParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-EcKeyImportParams">EcKeyImportParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// A named curve</span>
+required <a href="#dfn-NamedCurve">NamedCurve</a> <dfn id="dfn-EcKeyImportParams-namedCurve">namedCurve</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+
+ <div id="ecdsa-operations" class="section">
+ <h4>23.7. Operations</h4>
+ <dl>
+ <dt>Sign</dt>
+ <dd>
+ When signing, the following algorithm should be used:
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hashAlgorithm</var> be the <a href="#dfn-EcdsaParams-hash">hash</a>
+ member of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>hashAlgorithm</var> does not describe a
+ <a href="#algorithms">registered algorithm</a> that supports the digest
+ operation,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>M</var> be the result of performing the digest operation specified by
+ <var>hashAlgorithm</var> using <var>message</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>d</var> be the ECDSA private key associated with <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the EC domain parameters associated with
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform the ECDSA signing process, as specified in <a href="#X9.62">X9.62</a>,
+ Section 7.3, with <var>M</var> as the message, using <var>params</var> as the
+ EC domain parameters, and with <var>d</var> as the private key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>r</var> and <var>s</var> be the pair of integers resulting from
+ performing the ECDSA signing process.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Convert <var>r</var> to a bitstring and append the sequence of bytes to
+ <var>result</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Convert <var>s</var> to a bitstring and append the sequence of bytes to
+ <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ Otherwise, the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute
+ of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> is a value specified in an
+ <a href="#dfn-applicable-specification">applicable specification</a>:
+ </dt>
+ <dd>
+ <p>
+ Perform the <a href="#dfn-ecdsa-extended-signature-steps">ECDSA signature steps</a>
+ specified in that specification, passing in <var>M</var>, <var>params</var>
+ and <var>d</var> and resulting in <var>result</var>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Verify</dt>
+ <dd>
+ When verifying, the following algorithm should be used:
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hashAlgorithm</var> be the <a href="#dfn-EcdsaParams-hash">hash</a>
+ member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>hashAlgorithm</var> does not describe a
+ <a href="#algorithms">registered algorithm</a> that supports the digest
+ operation,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>M</var> be the result of performing the digest operation specified by
+ <var>hashAlgorithm</var> using <var>message</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>Q</var> be the ECDSA public key associated with <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the EC domain parameters associated with
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Perform the ECDSA verifying process, as specified in <a href="#X9.62">X9.62</a>, Section 7.4, with <var>M</var> as the received
+ message, <var>signature</var> as the received signature and using
+ <var>params</var> as the EC domain parameters, and
+ <var>Q</var> as the public key.
+ </p>
+ </dd>
+ <dt>
+ Otherwise, the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute
+ of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> is a value specified in an
+ <a href="#dfn-applicable-specification">applicable specification</a>:
+ </dt>
+ <dd>
+ <p>
+ Perform the <a href="#dfn-ecdsa-extended-verification-steps">ECDSA verification steps</a>
+ specified in that specification passing in <var>M</var>, <var>signature</var>,
+ <var>params</var> and <var>Q</var> and resulting in an indication of whether
+ or not the purported signature is valid.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a boolean indicating whether or not the purported
+ signature is valid, with <code>true</code> indicating the signature is valid
+ and <code>false</code> indicating it is invalid.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value which is not
+ one of <code>"sign"</code> or <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> is <code>"P-256"</code>, <code>"P-384"</code>
+ or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Generate an Elliptic Curve key pair, as defined in [<a href="#X9.62">X9.62</a>]
+ with domain parameters for the curve identified by
+ the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> is a value specified in an
+ <a href="#dfn-applicable-specification">applicable specification</a>:
+ </dt>
+ <dd>
+ <p>
+ Perform the <a href="#dfn-ecdsa-extended-generation-steps">ECDSA key
+ generation steps</a> specified in that specification, passing in
+ <var>normalizedAlgorithm</var> and resulting in an elliptic curve key pair.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-OperationError"><code>NotSupportedError</code></a>
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If performing the key generation operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>
+ object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDSA"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-EcKeyGenParams">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the public key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>publicKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>publicKey</var> to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>publicKey</var> to be the <a href="#concept-usage-intersection">usage
+ intersection</a> of <var>usages</var> and <code>[ "verify" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the private key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>privateKey</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>privateKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>privateKey</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>privateKey</var> to be the <a href="#concept-usage-intersection">usage
+ intersection</a> of <var>usages</var> and <code>[ "sign" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
+ of <var>result</var> to be <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
+ of <var>result</var> to be <var>privateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of converting <var>result</var> to an ECMAScript Object, as
+ defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value which is not
+ <code>"verify"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>spki</var> be the result of running the
+ <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
+ algorithm over <var>keyData</var>
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var> is
+ not equal to the <code>id-ecPublicKey</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the <code>algorithm</code>
+ AlgorithmIdentifier field of <var>spki</var> is absent,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the <code>parameters</code> field of the
+ <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> that specifies a
+ <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>namedCurve</var> be a string whose initial value is
+ undefined.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp256r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp384r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp521r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-521"</code>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>namedCurve</var> is not undefined:</dt>
+ <dd>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the Elliptic Curve public key identified by
+ performing the conversion steps defined in Section 2.2 of <a href="#RFC5480">RFC 5480</a>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdsa-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>spki</var>
+ and obtaining <var>namedCurve</var> and <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the public key value is not a valid point on the Elliptic Curve
+ identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDSA"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to <var>namedCurve</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value which is not
+ <code>"sign"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKeyInfo</var> be the result of running the
+ <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurs while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithm field of
+ <var>privateKeyInfo</var> is not equal to the
+ <code>id-ecPublicKey</code> object identifier defined in <a href="#RFC5480">RFC 5480</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
+ of <var>privateKeyInfo</var> is not present,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
+ of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> that specifies a
+ <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>namedCurve</var> be a string whose initial value is
+ undefined.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp256r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp384r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp521r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-521"</code>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>namedCurve</var> is not undefined:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>ecPrivateKey</var> be the result of performing the <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the <code>privateKey</code> field
+ of <var>privateKeyInfo</var>, <var>structure</var> as the ASN.1
+ <code>ECPrivateKey</code> structure specified in Section 3 of <a href="#RFC5915">RFC 5915</a>, and <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of <var>ecPrivateKey</var> is
+ present, and is not an instance of the <code>namedCurve</code> ASN.1
+ type defined in <a href="#RFC5480">RFC 5480</a>, or does not contain
+ the same object identifier as the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
+ of <var>privateKeyInfo</var>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the Elliptic Curve private key identified by
+ performing the conversion steps defined in Section 3 of <a href="#RFC5915">RFC 5915</a> using <var>ecPrivateKey</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdsa-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
+ and obtaining <var>namedCurve</var> and <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the private key value is not a valid point on the Elliptic Curve
+ identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDSA"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to <var>namedCurve</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field is present and <var>usages</var> contains
+ a value which is not
+ <code>"sign"</code>, or,
+ if the <code>"d"</code> field is not present and <var>usages</var> contains
+ a value which is not
+ <code>"verify"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ <code>"EC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"sig"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of <a href="#jwk">JSON Web
+ Key</a>, or it does not contain all of the specified <var>usages</var>
+ values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>namedCurve</var> be a string whose value is equal to the
+ <code>"crv"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>namedCurve</var> is not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>namedCurve</var> is equal to <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>algNamedCurve</var> be a string whose initial value is
+ undefined.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <code>"alg"</code> field is not present:</dt>
+ <dd>
+ Let <var>algNamedCurve</var> be undefined.
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string "ES256":
+ </dt>
+ <dd>
+ Let <var>algNamedCurve</var> be the string <code>"P-256"</code>.
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string "ES384":
+ </dt>
+ <dd>
+ Let <var>algNamedCurve</var> be the string <code>"P-384"</code>.
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field is equal to the string "ES521":
+ </dt>
+ <dd>
+ Let <var>algNamedCurve</var> be the string <code>"P-521"</code>.
+ </dd>
+ <dt>otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If <var>algNamedCurve</var> is defined, and is not equal to
+ <var>namedCurve</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <code>"d"</code> field is present:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ Elliptic Curve private key identified by interpreting
+ <var>jwk</var> according to Section 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>Key</var> to <code>"private"</code>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ Elliptic Curve public key identified by interpreting
+ <var>jwk</var> according to Section 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>Key</var> to <code>"public"</code>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdsa-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and obtaining <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the key value is not a valid point on the Elliptic Curve
+ identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new instance of an <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a> object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDSA"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to <var>namedCurve</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>key</var> be the <a href="#dfn-CryptoKey">CryptoKey</a> to be
+ exported.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to an
+ <code>AlgorithmIdentifier</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier to the OID
+ <code>1.2.840.10045.2.1</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>parameters</var> field to an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> as follows:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>keyData</var> be the
+ <a href="#dfn-octet-string">octet string</a> that
+ represents the Elliptic Curve public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> according to the encoding rules specified in
+ Section 2.2 of <a href="#RFC5480">RFC 5480</a> and using the
+ uncompressed form. and <var>keyData</var>.
+ </p>
+ <p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier
+ <code>secp256r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier
+ <code>secp384r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier
+ <code>secp521r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ </dl>
+ </p>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdsa-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier <var>namedCurveOid</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>subjectPublicKey</var> field to <var>keyData</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>privateKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>version</var> field to <code>0</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKeyAlgorithm</var> field to an
+ <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier to the OID
+ <code>1.2.840.10045.2.1</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>parameters</var> field to an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> as follows:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>keyData</var> be the result of DER-encoding
+ an instance of the <code>ECPrivateKey</code> structure defined in
+ Section 3 of <a href="#RFC5915">RFC 5915</a> for the Elliptic
+ Curve private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> and that conforms to the following:
+ </p>
+ <ul>
+ <li>
+ <p>
+ The <var>parameters</var> field is present, and is equivalent
+ to the <var>parameters</var> field of the
+ <var>privateKeyAlgorithm</var> field of this
+ <code>PrivateKeyInfo</code> ASN.1 structure.
+ </p>
+ </li>
+ <li>
+ <p>
+ The <var>publicKey</var> field is present and represents the
+ Elliptic Curve public key associated with the Elliptic Curve
+ private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ <p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier
+ <code>secp256r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier
+ <code>secp384r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier
+ <code>secp521r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ </dl>
+ </p>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdsa-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier <var>namedCurveOid</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKey</var> field to <var>keyData</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to
+ <code>"EC"</code>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code> or
+ <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-256"</code>:
+ </dt>
+ <dd>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <code>"P-256"</code>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-384"</code>:
+ </dt>
+ <dd>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <code>"P-384"</code>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-521"</code>:
+ </dt>
+ <dd>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <code>"P-521"</code>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>x</code> attribute of <var>jwk</var> according to the
+ definition in Section 6.2.1.2 of <a href="#jwa">JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>y</code> attribute of <var>jwk</var> according to the
+ definition in Section 6.2.1.3 of <a href="#jwa">JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is <code>"private"</code>
+ </dt>
+ <dd>
+ <p>
+ Set the <code>d</code> attribute of <var>jwk</var> according to
+ the definition in Section 6.2.2.1 of <a href="#jwa">JSON Web
+ Algorithms</a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdsa-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurve</var> and a new value of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <var>namedCurve</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to the <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="ecdh" class="section">
+ <h3>24. ECDH</h3>
+ <div id="ecdh-description" class="section">
+ <h4>24.1. Description</h4>
+ <p>
+ This describes using Elliptic Curve Diffie-Hellman (ECDH) for key generation and key
+ agreement, as specified by <a href="#X9.63">X9.63</a>.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional elliptic curves with ECDH.
+ To specify an additional elliptic curve a specification must define
+ <dfn id="dfn-ecdh-extended-namedcurve-values">the curve name</dfn>,
+ <dfn id="dfn-ecdh-extended-generation-steps">ECDH generation steps</dfn>,
+ <dfn id="dfn-ecdh-extended-derivation-steps">ECDH derivation steps</dfn>,
+ <dfn id="dfn-ecdh-extended-import-steps">ECDH key import steps</dfn> and
+ <dfn id="dfn-ecdh-extended-verification-steps">ECDH key export steps</dfn>.
+ </p>
+ </div>
+ <div id="ecdh-registration" class="section">
+ <h4>24.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"ECDH"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-EcKeyGenParams">EcKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
+ </tr>
+ <tr>
+ <td>deriveBits</td>
+ <td><a href="#dfn-EcdhKeyDeriveParams">EcdhKeyDeriveParams</a></td>
+ <td><a href="#dfn-octet-string">Octet string</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-EcKeyImportParams">EcKeyImportParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="dh-EcdhKeyDeriveParams" class="section">
+ <h4>24.3. EcdhKeyDeriveParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-EcdhKeyDeriveParams">EcdhKeyDeriveParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The peer's EC public key.</span>
+required <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-EcdhKeyDeriveParams-public">public</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="ecdh-operations" class="section">
+ <h4>24.4. Operations</h4>
+ <dl>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> is <code>"P-256"</code>, <code>"P-384"</code>
+ or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Generate an Elliptic Curve key pair, as defined in [<a href="#X9.63">X9.63</a>] with domain parameters for the curve identified by
+ the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyGenParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> is a value specified in an
+ <a href="#dfn-applicable-specification">applicable specification</a> that
+ specifies the use of that value with ECDH:
+ </dt>
+ <dd>
+ <p>
+ Perform the <a href="#dfn-ecdh-extended-generation-steps">ECDH key
+ generation steps</a> specified in that specification, passing in
+ <var>normalizedAlgorithm</var> and resulting in an elliptic curve key pair.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-OperationError"><code>NotSupportedError</code></a>
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>
+ object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>algorithm</var> to <code>"ECDH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-EcKeyGenParams">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the public key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>publicKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>publicKey</var> to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>publicKey</var> to be the empty list.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing the private key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>privateKey</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>privateKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>privateKey</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>privateKey</var> to be the
+ <a href="#concept-usage-intersection">usage intersection</a> of
+ <var>usages</var> and <code>[ "deriveKey", "deriveBits" ]</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
+ of <var>result</var> to be <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
+ of <var>result</var> to be <var>privateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of converting <var>result</var> to an ECMAScript Object, as
+ defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Derive Bits</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be the
+ <a href="#dfn-EcdhKeyDeriveParams-public">public</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>publicKey</var> is not equal to the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> property of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> property of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code>
+ or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform the ECDH primitive specified in <a href="#X9.63">X9.63</a> Section
+ 5.4.1 with <var>key</var> as the EC private key <var>d</var> and the EC public
+ key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]
+ internal slot of <var>publicKey</var> as the EC public key <var>Q</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>secret</var> be the result of applying the field element to
+ <a href="#dfn-octet-string">octet string</a> conversion defined in Section ? of <a href="#X9.63">X9.63</a>
+ to the output of the ECDH primitive.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> property of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> is a value specified in an
+ <a href="#dfn-applicable-specification">applicable specification</a> that
+ specifies the use of that value with ECDH:
+ </dt>
+ <dd>
+ <p>
+ Perform the <a href="#dfn-ecdh-extended-derivation-steps">ECDH key
+ derivation steps</a> specified in that specification, passing in
+ <var>key</var> and <var>publicKey</var> and resulting in <var>secret</var>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-OperationError"><code>NotSupportedError</code></a>
+ </p>
+ </dd>
+ </dl>
+
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>length</var> is null:</dt>
+ <dd>Return <var>secret</var></dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <dl class="switch">
+ <dt>
+ If the length of <var>secret</var> in bits is less than
+ <var>length</var>:
+ </dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>Return the first <var>length</var> bits of <var>secret</var>.</dd>
+ </dl>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> is not empty
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>spki</var> be the result of running the
+ <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a>
+ algorithm over <var>keyData</var>
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var> is
+ not equal to the <code>id-ecPublicKey</code> or <code>id-ecDH</code>
+ object identifiers defined in <a href="#RFC5480">RFC 5480</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the <code>algorithm</code>
+ AlgorithmIdentifier field of <var>spki</var> is absent,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the <code>parameters</code> field of the
+ <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> that specifies a
+ <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>namedCurve</var> be a string whose initial value is
+ undefined.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp256r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp384r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp521r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> <code>"P-521"</code>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>namedCurve</var> is not undefined:</dt>
+ <dd>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the Elliptic Curve public key identified by
+ performing the conversion steps defined in Section 2.2 of <a href="#RFC5480">RFC 5480</a>.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>spki</var>
+ and obtaining <var>namedCurve</var> and <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key value is not a valid point on the Elliptic Curve
+ identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to <var>namedCurve</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKeyInfo</var> be the result of running the
+ <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurs while parsing,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithm field of
+ <var>privateKeyInfo</var> is not equal to the
+ <code>id-ecPublicKey</code> or <code>id-ecDH</code> object identifiers
+ defined in <a href="#RFC5480">RFC 5480</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
+ of <var>privateKeyInfo</var> is not present,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
+ of <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> that specifies a
+ <code>namedCurve</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>namedCurve</var> be a string whose initial value is
+ undefined.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp256r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> to <code>"P-256"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp384r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> to <code>"P-384"</code>.
+ </p>
+ </dd>
+ <dt>
+ If <var>params</var> is equivalent to the <code>secp521r1</code>
+ object identifier defined in <a href="#RFC5480">RFC 5480</a>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>namedCurve</var> to <code>"P-521"</code>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>namedCurve</var> is not undefined:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>ecPrivateKey</var> be the result of performing the
+ <a href="#concept-parse-an-asn1-structure">parse an ASN.1 structure</a>
+ algorithm, with <var>data</var> as the <code>privateKey</code> field
+ of <var>privateKeyInfo</var>, <var>structure</var> as the ASN.1
+ <code>ECPrivateKey</code> structure specified in Section 3 of
+ <a href="#RFC5915">RFC 5915</a>, and <var>exactData</var> set to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of <var>ecPrivateKey</var> is
+ present, and is not an instance of the <code>namedCurve</code> ASN.1
+ type defined in <a href="#RFC5480">RFC 5480</a>, or does not contain
+ the same object identifier as the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field
+ of <var>privateKeyInfo</var>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents the Elliptic Curve private key identified by
+ performing the conversion steps defined in Section 3 of <a href="#RFC5915">RFC 5915</a> using <var>ecPrivateKey</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>privateKeyInfo</var>
+ and obtaining <var>namedCurve</var> and <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If <var>namedCurve</var> is defined, and not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key value is not a valid point on the Elliptic Curve
+ identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"private"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to <var>namedCurve</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field is present and if <var>usages</var>
+ contains an entry which is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"d"</code> field is present and if <var>usages</var> is not
+ empty
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is
+ to <code>"EC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of <a href="#jwk">JSON Web
+ Key</a>, or it does not contain all of the specified <var>usages</var>
+ values, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>namedCurve</var> be a string whose value is equal to the
+ <code>"crv"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>namedCurve</var> is not equal to the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>, <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>namedCurve</var> is <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <dl class="switch">
+ <dt>If the <code>"d"</code> field is present:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ Elliptic Curve private key identified by interpreting
+ <var>jwk</var> according to Section 6.2.2 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>Key</var> to <code>"private"</code>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of Section
+ 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object that represents the
+ Elliptic Curve public key identified by interpreting
+ <var>jwk</var> according to Section 6.2.1 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]]
+ internal slot of <var>Key</var> to <code>"public"</code>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </dd>
+ <dt>Otherwise</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and obtaining <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the key value is not a valid point on the Elliptic Curve
+ identified by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var> <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new instance of an <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a> object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to <var>namedCurve</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a>
+ member of <var>normalizedAlgorithm</var> is not a
+ <a href="#dfn-NamedCurve">named curve</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>usages</var> is not the empty list,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>extractable</var> is false,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>namedCurve</var> is <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>Q</var> be the elliptic curve point on the curve identified
+ by the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a>
+ member of <var>normalizedAlgorithm</var> identified by interpreting
+ <var>keyData</var> according to <a href="#X9.62">X9.62</a> Annex A.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object that represents <var>Q</var>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>keyData</var>
+ and obtaining <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occured or there are no
+ <a href="#dfn-applicable-specifications">applicable
+ specifications</a>,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-EcKeyAlgorithm">EcKeyAlgorithm</a> object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"ECDH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of <var>algorithm</var> to equal the <a href="#dfn-EcKeyImportParams-namedCurve">namedCurve</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>
+ </p>
+ </li>
+ </ol>
+ </dd>
+
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>key</var> be the <a href="#dfn-CryptoKey">CryptoKey</a> to be
+ exported.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"spki"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to an
+ <code>AlgorithmIdentifier</code> ASN.1 type with the following
+ properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier to the OID
+ <code>1.3.132.112</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>parameters</var> field to an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> as follows:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>keyData</var> be the <a href="#dfn-octet-string">octet string</a> that
+ represents the Elliptic Curve public key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> according to the encoding rules specified in
+ Section 2.2 of <a href="#RFC5480">RFC 5480</a> and using the
+ uncompressed form.
+ </p>
+ <p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <var>namedCurve</var> choice
+ with value equal to the object identifier
+ <code>secp256r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <var>namedCurve</var> choice
+ with value equal to the object identifier
+ <code>secp384r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <var>namedCurve</var> choice
+ with value equal to the object identifier
+ <code>secp521r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ </dl>
+ </p>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier <var>namedCurveOid</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>subjectPublicKey</var> field to <var>keyData</var>
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"pkcs8"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>privateKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>version</var> field to <code>0</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKeyAlgorithm</var> field to an
+ <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 type with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> object identifier to the OID
+ <code>1.3.132.112</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>parameters</var> field to an instance of the
+ <code>ECParameters</code> ASN.1 type defined in
+ <a href="#RFC5480">RFC 5480</a> as follows:
+ </p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>,
+ <code>"P-384"</code> or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>keyData</var> be the result of DER-encoding
+ an instance of the <code>ECPrivateKey</code> structure defined in
+ Section 3 of <a href="#RFC5915">RFC 5915</a> for the Elliptic
+ Curve private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> and that conforms to the following:
+ </p>
+ <ul>
+ <li>
+ <p>
+ The <var>parameters</var> field is present, and is equivalent
+ to the <var>parameters</var> field of the
+ <var>privateKeyAlgorithm</var> field of this
+ <code>PrivateKeyInfo</code> ASN.1 structure.
+ </p>
+ </li>
+ <li>
+ <p>
+ The <var>publicKey</var> field is present and represents the
+ Elliptic Curve public key associated with the Elliptic Curve
+ private key represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ <p>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-256"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <var>namedCurve</var> choice
+ with value equal to the object identifier
+ <code>secp256r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-384"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <var>namedCurve</var> choice
+ with value equal to the object identifier
+ <code>secp384r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var> is <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Set <var>parameters</var> to the <var>namedCurve</var> choice
+ with value equal to the object identifier
+ <code>secp521r1</code> defined in <a href="#RFC5480">RFC
+ 5480</a>
+ </p>
+ </dd>
+ </dl>
+ </p>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurveOid</var> and <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set <var>parameters</var> to the <code>namedCurve</code> choice
+ with value equal to the object identifier <var>namedCurveOid</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKey</var> field to <var>keyData</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to
+ <code>"EC"</code>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code>
+ or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-256"</code>:
+ </dt>
+ <dd>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <code>"P-256"</code>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-384"</code>:
+ </dt>
+ <dd>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <code>"P-384"</code>
+ </dd>
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-521"</code>:
+ </dt>
+ <dd>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <code>"P-521"</code>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>x</code> attribute of <var>jwk</var> according to the
+ definition in Section 6.2.1.2 of <a href="#jwa">JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>y</code> attribute of <var>jwk</var> according to the
+ definition in Section 6.2.1.3 of <a href="#jwa">JSON Web
+ Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is <code>"private"</code>
+ </dt>
+ <dd>
+ <p>
+ Set the <code>d</code> attribute of <var>jwk</var> according to the
+ definition in Section 6.2.2.1 of <a href="#jwa">JSON Web
+ Algorithms</a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurve</var> and a new value of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>crv</code> attribute of <var>jwk</var> to
+ <var>namedCurve</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If <var>format</var> is <code>"raw"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot
+ of <var>key</var> is <code>"P-256"</code>, <code>"P-384"</code>
+ or <code>"P-521"</code>:
+ </dt>
+ <dd>
+ <p>
+ Let <var>data</var> be an <a href="#dfn-octet-string">octet string</a> representing the Elliptic Curve
+ point <var>Q</var> represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var> according to <a href="#X9.62">X9.62</a> Annex A.
+ </p>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ Perform any <a href="#dfn-ecdh-extended-export-steps">key export steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and the
+ <a href="#dfn-EcKeyAlgorithm-namedCurve">namedCurve</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>
+ and obtaining <var>namedCurve</var> and <var>data</var>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="aes-ctr" class="section">
+ <h3>25. AES-CTR</h3>
+ <div id="aes-ctr-description" class="section">
+ <h4>25.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"AES-CTR"</code> algorithm identifier is used to perform
+ encryption and decryption using AES in Counter mode,
+ as described in NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>].
+ </p>
+ </div>
+ <div id="aes-ctr-registration" class="section">
+ <h4>25.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"AES-CTR"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>encrypt</td>
+ <td><a href="#dfn-AesCtrParams">AesCtrParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>decrypt</td>
+ <td><a href="#dfn-AesCtrParams">AesCtrParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="aes-ctr-params" class="section">
+ <h4>25.3. AesCtrParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesCtrParams">AesCtrParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The initial value of the counter block. counter <span class="RFC2119">MUST</span> 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.</span>
+required BufferSource <dfn id="dfn-AesCtrParams-counter">counter</dfn>;
+<span class="comment">// The length, in bits, of the rightmost part of the counter block
+// that is incremented.</span>
+[EnforceRange] required octet <dfn id="dfn-AesCtrParams-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="AesKeyAlgorithm-dictionary" class="section">
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesKeyAlgorithm">AesKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
+<span class="comment">// The length, in bits, of the key.</span>
+required unsigned short <dfn id="dfn-AesKeyAlgorithm-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="aes-keygen-params" class="section">
+ <h4>25.5. AesKeyGenParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesKeyGenParams">AesKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The length, in bits, of the key.</span>
+[EnforceRange] required unsigned short <dfn id="dfn-AesKeyGenParams-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="aes-derivedkey-params" class="section">
+ <h4>25.6. AesDerivedKeyParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesDerivedKeyParams">AesDerivedKeyParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The length, in bits, of the key.</span>
+[EnforceRange] required unsigned short <dfn id="dfn-AesDerivedKeyParams-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+
+ <div id="aes-ctr-operations" class="section">
+ <h4>25.7. Operations</h4>
+ <dl>
+ <dt>Encrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCtrParams-counter">counter</a> member of
+ <var>normalizedAlgorithm</var> does not have length 16
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCtrParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is zero or is greater
+ than 128,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>ciphertext</var> be the result of performing the CTR Encryption
+ operation described in Section 6.5 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCtrParams-counter">counter</a> member of
+ <var>normalizedAlgorithm</var> as the initial value of the counter block, the
+ <a href="#dfn-AesCtrParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> as the input parameter <var>m</var> to the
+ standard counter block incrementing function defined in Appendix B.1 of NIST SP
+ 800-38A [<a href="#SP800-38A">SP800-38A</a>] and <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>plaintext</var></a> as the input plaintext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>ciphertext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Decrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCtrParams-counter">counter</a> member of
+ <var>normalizedAlgorithm</var> does not have length 16
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCtrParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is zero or is greater
+ than 128,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>plaintext</var> be the result of performing the CTR Decryption
+ operation described in Section 6.5 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCtrParams-counter">counter</a> member of
+ <var>normalizedAlgorithm</var> as the initial value of the counter block, the
+ <a href="#dfn-AesCtrParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> as the input parameter <var>m</var> to the
+ standard counter block incrementing function defined in Appendix B.1 of NIST SP
+ 800-38A [<a href="#SP800-38A">SP800-38A</a>] and <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>ciphertext</var></a> as the input ciphertext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>plaintext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is not equal to one of
+ 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+
+ <li>
+ <p>
+ Generate an AES key of length
+ equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated AES key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CTR"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to equal the
+ <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the length in bits of <var>data</var> is not 128, 192 or 256
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>data</var> has length 128 bits:</dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A128CTR"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>If <var>data</var> has length 192 bits:</dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A192CTR"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>If <var>data</var> has length 256 bits:</dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A256CTR"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code> object representing an AES key with
+ value <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CTR"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to the length, in bits, of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 128:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A128CTR"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 192:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A192CTR"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 256:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A256CTR"</code>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="aes-cbc" class="section">
+ <h3>26. AES-CBC</h3>
+ <div id="aes-cbc-description" class="section">
+ <h4>26.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"AES-CBC"</code> algorithm identifier is used to perform
+ encryption and decryption using AES in Cipher Block Chaining mode,
+ as described in NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>].
+ </p>
+ <p>
+ 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 RFC 2315 [<a href="#RFC2315">RFC2315</a>].
+ </p>
+ </div>
+ <div id="aes-cbc-registration" class="section">
+ <h4>26.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"AES-CBC"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>encrypt</td>
+ <td><a href="#dfn-AesCbcParams">AesCbcParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>decrypt</td>
+ <td><a href="#dfn-AesCbcParams">AesCbcParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="aes-cbc-params" class="section">
+ <h4>26.3. AesCbcParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesCbcParams">AesCbcParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The initialization vector. <span class="RFC2119">MUST</span> be 16 bytes.</span>
+required BufferSource <dfn id="dfn-AesCbcParams-iv">iv</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="aes-cbc-operations" class="section">
+ <h4>26.4. Operations</h4>
+ <dl>
+ <dt>Encrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCbcParams-iv">iv</a> member of
+ <var>normalizedAlgorithm</var> does not have length 16
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>paddedPlaintext</var> be the result of adding padding octets to
+ the <a href="#concept-contents-of-arraybuffer">contents of <var>ciphertext</var></a>
+ according to the procedure defined in Section 10.3
+ of RFC 2315 [<a href="#RFC2315">RFC2315</a>], step 2, with a value of
+ <var>k</var> of 16.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>ciphertext</var> be the result of performing the CBC Encryption
+ operation described in Section 6.2 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCbcParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
+ the <var>IV</var> input parameter and <var>paddedPlaintext</var>
+ as the input plaintext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>ciphertext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Decrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCbcParams-iv">iv</a> member of
+ <var>normalizedAlgorithm</var> does not have length 16
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>paddedPlaintext</var> be the result of performing the CBC Decryption
+ operation described in Section 6.2 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCbcParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
+ the <var>IV</var> input parameter and <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>ciphertext</var></a> as the input ciphertext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>p</var> be the value of the last octet of <var>paddedPlaintext</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>p</var> is zero or greater than 16, or if any of the last <var>p</var>
+ octets of <var>paddedPlaintext</var> have a value which is not <var>p</var>,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>plaintext</var> be the result of removing <var>p</var> octets from
+ the end of <var>paddedPlaintext</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>plaintext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is not equal to one of
+ 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+
+ <li>
+ <p>
+ Generate an AES key of length
+ equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated AES key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CBC"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to equal the
+ <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the length in bits of <var>data</var> is not 128, 192 or 256
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ to <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>data</var> has length 128 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A128CBC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 192 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A192CBC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 256 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A256CBC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
+ object representing an AES key with value <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CBC"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to the length, in bits, of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 128:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A128CBC"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 192:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A192CBC"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 256:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A256CBC"</code>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="aes-cmac" class="section">
+ <h3>27. AES-CMAC</h3>
+ <div id="aes-cmac-description" class="section">
+ <h4>27.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"AES-CMAC"</code> algorithm identifier is used to perform
+ message authentication using AES with a cipher-based MAC, as
+ described in NIST SP 800-38B [<a href="#SP800-38B">SP800-38B</a>].
+ </p>
+ </div>
+ <div id="aes-cmac-registration" class="section">
+ <h4>27.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"AES-CMAC"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>sign</td>
+ <td><a href="#dfn-AesCmacParams">AesCmacParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>verify</td>
+ <td><a href="#dfn-AesCmacParams">AesCmacParams</a></td>
+ <td>boolean</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="aes-cmac-params" class="section">
+ <h4>27.3. AesCmacParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesCmacParams">AesCmacParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The length, in bits, of the MAC.</span>
+[EnforceRange] required unsigned short <dfn id="dfn-AesCmacParams-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="aes-cmac-operations" class="section">
+ <h4>27.4. Operations</h4>
+ <dl>
+ <dt>Sign</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>length</var> equal the <a href="#dfn-AesCmacParams-length">length</a>
+ member of <var>normalizedAlgorithm</var>, if present, and 128 otherwise.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>length</var> is zero or greater than 128,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>mac</var> be the result of performing the MAC Generation
+ operation described in Section 6.2 of
+ NIST SP 800-38B [<a href="#SP800-38B">SP800-38B</a>] using AES as the block
+ cipher, <var>length</var> as the value of the MAC length parameter,
+ <var>Tlen</var>, and <var>message</var> as the message, <var>M</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>mac</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Verify</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>length</var> equal the <a href="#dfn-AesCmacParams-length">length</a>
+ member of <var>normalizedAlgorithm</var>, if present, and 128 otherwise.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>length</var> is zero or greater than 128,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>output</var> be the result of performing the MAC Verification
+ operation described in Section 6.3 of
+ NIST SP 800-38B [<a href="#SP800-38B">SP800-38B</a>] using AES as the block
+ cipher, <var>length</var> as the value of the MAC length parameter,
+ <var>Tlen</var>, <var>message</var> as the message, <var>M</var> and
+ <var>signature</var> as the received MAC, <var>T'</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return true if <var>output</var> is VALID and false otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not
+ <code>"sign"</code> or <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is not equal to one of
+ 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate an AES key of length
+ equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated AES key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CMAC"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to equal the
+ <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"sign"</code> or <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the length in bits of <var>data</var> is not 128, 192 or 256
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ to <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>data</var> has length 128 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A128CMAC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 192 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A192CMAC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 256 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A256CMAC"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
+ object representing an AES key with value <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CMAC"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to the length, in bits, of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 128:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A128CMAC"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 192:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A192CMAC"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 256:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A256CMAC"</code>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div id="aes-gcm" class="section">
+ <h3>28. AES-GCM</h3>
+ <div id="aes-gcm-description" class="section">
+ <h4>28.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"AES-GCM"</code> algorithm identifier is used to perform
+ authenticated encryption and decryption using AES in Galois/Counter Mode mode,
+ as described in NIST SP 800-38D [<a href="#SP800-38D">SP800-38D</a>].
+ </p>
+ </div>
+ <div id="aes-gcm-registration" class="section">
+ <h4>28.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"AES-GCM"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>encrypt</td>
+ <td><a href="#dfn-AesGcmParams">AesGcmParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>decrypt</td>
+ <td><a href="#dfn-AesGcmParams">AesGcmParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="aes-gcm-params" class="section">
+ <h4>28.3. AesGcmParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesGcmParams">AesGcmParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The initialization vector to use. May be up to 2^64-1 bytes long.</span>
+required BufferSource <dfn id="dfn-AesGcmParams-iv">iv</dfn>;
+<span class="comment">// The additional authentication data to include.</span>
+BufferSource <dfn id="dfn-AesGcmParams-additionalData">additionalData</dfn>;
+<span class="comment">// The desired length of the authentication tag. May be 0 - 128.</span>
+[EnforceRange] octet <dfn id="dfn-AesGcmParams-tagLength">tagLength</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="aes-gcm-operations" class="section">
+ <h4>28.4. Operations</h4>
+ <dl>
+ <dt>Encrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>plaintext</var> has a length greater than 2^39 - 256
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesGcmParams-iv">iv</a> member of
+ <var>normalizedAlgorithm</var> has a length greater than 2^64 - 1
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member
+ of <var>normalizedAlgorithm</var> is present and has a length
+ greater than 2^64 - 1 bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
+ <var>normalizedAlgorithm</var> is not present:</dt>
+ <dd>Let <var>tagLength</var> be 128.</dd>
+ <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
+ <var>normalizedAlgorithm</var> is one of 32, 64, 96, 104, 112, 120 or 128:</dt>
+ <dd>Let <var>tagLength</var> be equal to the
+ <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
+ <var>normalizedAlgorithm</var></dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>additionalData</var> be <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member of
+ <var>normalizedAlgorithm</var> if present or the empty octet
+ string otherwise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>C</var> and <var>T</var> be the outputs that result from performing
+ the Authenticated Encryption Function described in Section 7.1 of NIST SP
+ 800-38D [<a href="#SP800-38D">SP800-38D</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesGcmParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
+ the <var>IV</var> input parameter, <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>additionalData</var></a> as the <var>A</var> input parameter,
+ <var>tagLength</var> as the <var>t</var> pre-requisite and <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>plaintext</var></a> as the input plaintext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return a new ArrayBuffer containing <var>C</var> | <var>T</var>
+ where '|' denotes concatenation.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Decrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
+ <var>normalizedAlgorithm</var> is not present:</dt>
+ <dd>Let <var>tagLength</var> be 128.</dd>
+ <dt>If the <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
+ <var>normalizedAlgorithm</var> is one of 32, 64, 96, 104, 112, 120 or 128:</dt>
+ <dd>Let <var>tagLength</var> be equal to the
+ <a href="#dfn-AesGcmParams-tagLength">tagLength</a> member of
+ <var>normalizedAlgorithm</var></dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If <var>plaintext</var> has a length less than <var>tagLength</var> bits,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesGcmParams-iv">iv</a> member of
+ <var>normalizedAlgorithm</var> has a length greater than 2^64 - 1
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member
+ of <var>normalizedAlgorithm</var> is present and has a length
+ greater than 2^64 - 1
+ bytes,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>tag</var> be the last <var>tagLength</var> bits of
+ <var>ciphertext</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>actualCiphertext</var> be the result of removing the last <var>tagLength</var> bits
+ from <var>ciphertext</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>additionalData</var> be <a href="#concept-contents-of-arraybuffer">the contents</a> of the <a href="#dfn-AesGcmParams-additionalData">additionalData</a> member of
+ <var>normalizedAlgorithm</var> if present or the empty octet
+ string otherwise.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the Authenticated Decryption Function described in Section 7.2 of NIST
+ SP 800-38D [<a href="#SP800-38D">SP800-38D</a>] using AES as the block cipher,
+ <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesGcmParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
+ the <var>IV</var> input parameter, <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>additionalData</var></a> as the <var>A</var> input parameter,
+ <var>tagLength</var> as the <var>t</var> pre-requisite, <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>actualCiphertext</var></a> as the input ciphertext, <var>C</var> and <a href="#concept-contents-of-arraybuffer">the contents of <var>tag</var></a> as
+ the authentication tag, <var>T</var>.
+ </p>
+ <dl class="switch">
+ <dt>If the result of the algorithm is the indication of inauthenticity,
+ "<var>FAIL</var>":</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>Let <var>plaintext</var> be the output <var>P</var> of the Authenticated
+ Decryption Function.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return a new ArrayBuffer containing <var>plaintext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is not equal to one of
+ 128, 192 or 256,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+
+ <li>
+ <p>
+ Generate an AES key of length
+ equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated AES key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-GCM"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to equal the
+ <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the length in bits of <var>data</var> is not 128, 192 or 256
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>data</var> has length 128 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A128GCM"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 192 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A192GCM"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 256 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A256GCM"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
+ object representing an AES key with value <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-GCM"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to the length, in bits, of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 128:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A128GCM"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 192:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A192GCM"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 256:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A256GCM"</code>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="aes-cfb" class="section">
+ <h3>29. AES-CFB</h3>
+ <div id="aes-cfb-description" class="section">
+ <h4>29.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"AES-CFB-8"</code> algorithm identifier is used to perform
+ encryption and decryption using AES in Cipher Feedback mode, specifically CFB-8,
+ as described in Section 6.3 of NIST SP 800-38A
+ [<a href="#SP800-38A">SP800-38A</a>].
+ </p>
+ </div>
+ <div id="aes-cfb-registration" class="section">
+ <h4>29.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"AES-CFB-8"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>encrypt</td>
+ <td><a href="#dfn-AesCfbParams">AesCfbParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>decrypt</td>
+ <td><a href="#dfn-AesCfbParams">AesCfbParams</a></td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="aes-cfb-params" class="section">
+ <h4>29.3. AesCfbParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-AesCfbParams">AesCfbParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The initialization vector. <span class="RFC2119">MUST</span> be 16 bytes.</span>
+required BufferSource <dfn id="dfn-AesCfbParams-iv">iv</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="aes-cfb-operations" class="section">
+ <h4>29.4. Operations</h4>
+ <dl>
+ <dt>Encrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCfbParams-iv">iv</a> member of
+ <var>normalizedAlgorithm</var> does not have length 16 bytes, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>ciphertext</var> be the result of performing the CFB Encryption
+ operation described in Section 6.3 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCfbParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
+ the <var>IV</var> input parameter, the value 8 as the input parameter
+ <var>s</var>, and <a href="#concept-contents-of-arraybuffer">the contents
+ of<var>plaintext</var></a> as the input plaintext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>ciphertext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Decrypt</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesCfbParams-iv">iv</a> member of
+ <var>normalizedAlgorithm</var> does not have length 16 bytes, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>plaintext</var> be the result of performing the CFB Decryption
+ operation described in Section 6.3 of NIST SP 800-38A [<a href="#SP800-38A">SP800-38A</a>] using AES as the block cipher, <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-AesCfbParams-iv">iv</a> member of <var>normalizedAlgorithm</var> as
+ the <var>IV</var> input parameter, the the value 8 as the input parameter
+ <var>s</var>, and <a href="#concept-contents-of-arraybuffer">the contents of
+ <var>ciphertext</var></a> as the input ciphertext.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>plaintext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not one of
+ <code>"encrypt"</code>, <code>"decrypt"</code>, <code>"wrapKey"</code> or
+ <code>"unwrapKey"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is not equal to one of 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate an AES key of length equal to the <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated AES key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CFB-8"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to equal the
+ <a href="#dfn-AesKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ one of <code>"encrypt"</code>, <code>"decrypt"</code>,
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the length in bits of <var>data</var> is not 128, 192 or 256
+
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>data</var> has length 128 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A128CFB8"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 192 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A192CFB8"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 256 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A256CFB8"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
+ object representing an AES key with value <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-CFB-8"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to the length, in bits, of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to the <a href="#concept-normalized-usages">normalized
+ value</a> of <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 128:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A128CFB8"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 192:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A192CFB8"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 256:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A256CFB8"</code>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesDerivedKeyParams-length">length</a> property of
+ <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> property of
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="aes-kw" class="section">
+ <h3>30. AES-KW</h3>
+ <div id="aes-kw-description" class="section">
+ <h4>30.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"AES-KW"</code> algorithm identifier is used to perform
+ key wrapping using AES, as
+ described in [<a href="#rfc3394">RFC3394</a>].
+ </p>
+ </div>
+ <div id="aes-kw-registration" class="section">
+ <h4>30.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"AES-KW"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>wrapKey</td>
+ <td>None</td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>unwrapKey</td>
+ <td>None</td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-AesDerivedKeyParams">AesDerivedKeyParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="aes-kw-operations" class="section">
+ <h4>30.3. Operations</h4>
+ <dl>
+ <dt>Wrap Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>plaintext</var> is not a multiple of 64 bits in length,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>ciphertext</var> be the result of performing the Key Wrap
+ operation described in Section 2.2.1 of [<a href="#rfc3394">RFC3394</a>]
+ with <var>plaintext</var> as the plaintext to be wrapped and using the default
+ Initial Value defined in Section 2.2.3.1 of the same document.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>ciphertext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Unwrap Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>plaintext</var> be the result of performing the Key Unwrap
+ operation described in Section 2.2.2 of [<a href="#rfc3394">RFC3394</a>] with
+ <var>ciphertext</var> as the input ciphertext and using the default Initial
+ Value defined in Section 2.2.3.1 of the same document.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the Key Unwrap operation returns an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>plaintext</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not one of
+ <code>"wrapKey"</code> or <code>"unwrapKey"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-AesKeyGenParams-length">length</a> property of
+ <var>normalizedAlgorithm</var> is not equal to one of 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated AES key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-KW"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to equal the
+ <a href="#dfn-AesKeyGenParams-length">length</a> property of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ one of <code>"wrapKey"</code> or <code>"unwrapKey"</code>,
+
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the length in bits of <var>data</var> is not 128, 192 or 256
+
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>data</var> has length 128 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A128KW"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 192 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A192KW"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>If <var>data</var> has length 256 bits:</dt>
+ <dd>If the <code>"alg"</code> field of <var>jwk</var> is present, and is
+ not <code>"A256KW"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.</dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"enc"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>. </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a>
+ object representing an AES key with value <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-AesKeyAlgorithm">AesKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"AES-KW"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to the length, in bits, of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 128:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A128KW"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 192:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A192KW"</code>.</dd>
+ <dt>If the <a href="#dfn-AesKeyAlgorithm-length">length</a> attribute of
+ <var>key</var> is 256:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"A256KW"</code>.</dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> is not 128, 192 or 256, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the <a href="#dfn-AesDerivedKeyParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="hmac" class="section">
+ <h3>31. HMAC</h3>
+ <div id="hmac-description" class="section">
+ <h4>31.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>HMAC</code> algorithm calculates and verifies hash-based message
+ authentication codes according to [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>]
+ using the SHA hash functions defined in this specification.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with HMAC. Such specifications
+ must define the digest operation for the additional hash algorithms and
+ <dfn id="dfn-hmac-extended-import-steps">key import steps</dfn> and
+ <dfn id="dfn-hmac-extended-export-steps">key export steps</dfn> for HMAC.
+ </p>
+
+ </div>
+ <div id="hmac-registration" class="section">
+ <h4>31.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"HMAC"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>sign</td>
+ <td>None</td>
+ <td>ArrayBuffer</td>
+ </tr>
+ <tr>
+ <td>verify</td>
+ <td>None</td>
+ <td>boolean</td>
+ </tr>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-HmacKeyGenParams">HmacKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-HmacImportParams">HmacImportParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ <tr>
+ <td>get key length</td>
+ <td><a href="#dfn-HmacImportParams">HmacImportParams</a></td>
+ <td>Integer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="hmac-importparams" class="section">
+ <h4>31.3. HmacImportParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-HmacImportParams">HmacImportParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The inner hash function to use.</span>
+<a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-HmacImportParams-hash">hash</dfn>;
+<span class="comment">// The length (in bits) of the key.</span>
+[EnforceRange] unsigned long <dfn id="dfn-HmacImportParams-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="HmacKeyAlgorithm-dictionary" class="section">
+ <h4>31.4. HmacKeyAlgorithm dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-HmacKeyAlgorithm">HmacKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
+<span class="comment">// The inner hash function to use.</span>
+required KeyAlgorithm <dfn id="dfn-HmacKeyAlgorithm-hash">hash</dfn>;
+<span class="comment">// The length (in bits) of the key.</span>
+required unsigned long <dfn id="dfn-HmacKeyAlgorithm-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="hmac-keygen-params" class="section">
+ <h4>31.5. HmacKeyGenParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-HmacKeyGenParams">HmacKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The inner hash function to use.</span>
+required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-HmacKeyGenParams-hash">hash</dfn>;
+<span class="comment">// The length (in bits) of the key to generate. If unspecified, the
+// recommended length will be used, which is the size of the associated hash function's block
+// size.</span>
+[EnforceRange] unsigned long <dfn id="dfn-HmacKeyGenParams-length">length</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="hmac-operations" class="section">
+ <h4>31.6. Operations</h4>
+ <dl>
+ <dt>Sign</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>mac</var> be the result of performing the MAC Generation operation
+ described in Section 4 of [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using
+ the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]
+ internal slot of <var>key</var>, the hash function identified by the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> and <var>message</var> as the input data <var>text</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>mac</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Verify</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>mac</var> be the result of performing the MAC Generation operation
+ described in Section 4 of [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using
+ the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]]
+ internal slot of <var>key</var>, the hash function identified by the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var> and <var>message</var> as the input data <var>text</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return true if <var>mac</var> is equal to <var>signature</var> and false
+ otherwise.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains any entry which is not <code>"sign"</code> or
+ <code>"verify"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-HmacKeyGenParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is not present:
+ </dt>
+ <dd>
+ Let <var>length</var> be the block size in bits of the hash function
+ identified by the <a href="#dfn-HmacKeyGenParams-hash">hash</a> member
+ of <var>normalizedAlgorithm</var>.
+ </dd>
+ <dt>
+ Otherwise, if the <a href="#dfn-HmacKeyGenParams-length">length</a>
+ member of <var>normalizedAlgorithm</var> is non-zero:
+ </dt>
+ <dd>
+ Let <var>length</var> be equal to the
+ <a href="#dfn-HmacKeyGenParams-length">length</a>
+ member of <var>normalizedAlgorithm</var>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </dd>
+ </dl>
+ </li>
+
+ <li>
+ <p>
+ Generate a key of length <var>length</var> bits.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key generation step fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new
+ <a href="#dfn-CryptoKey">CryptoKey</a> object representing the
+ generated key.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-HmacKeyAlgorithm">HmacKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"HMAC"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be a new
+ <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> to equal the <a href="#dfn-Algorithm-name">name</a>
+ member of the <a href="#dfn-HmacKeyGenParams-hash">hash</a>
+ member of <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute
+ of <var>algorithm</var> to <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to be <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <p>
+ If <var>usages</var> contains an entry which is not
+ <code>"sign"</code> or <code>"verify"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> contained in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-HmacImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var> is present:
+ </dt>
+ <dd>
+ Set <var>hash</var> to equal the <a href="#dfn-HmacImportParams-hash">hash</a>
+ member of <var>normalizedAlgorithm</var>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-TypeError"><code>TypeError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be the <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary represented by <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"kty"</code> field of <var>jwk</var> is not
+ <code>"oct"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>jwk</var> does not meet the requirements of
+ Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> obtained by decoding the
+ <code>"k"</code> field of <var>jwk</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-HmacImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var> is present:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Set the <var>hash</var> to equal the <a href="#dfn-HmacImportParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
+ of <var>hash</var> is
+ <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present
+ and is not <code>"HS1"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>
+ If If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
+ of <var>hash</var> is
+ <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present
+ and is not <code>"HS256"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>
+ If If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
+ of <var>hash</var> is
+ <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present
+ and is not <code>"HS384"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>
+ If If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
+ of <var>hash</var> is
+ <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ If the <code>"alg"</code> field of <var>jwk</var> is present
+ and is not <code>"HS512"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>
+ Otherwise, if the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
+ of <var>hash</var> is defined in
+ <a href="#dfn-applicable-specifications">another applicable
+ specification</a>:
+ </dt>
+ <dd>
+ Perform any <a href="#dfn-hmac-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and <var>hash</var>
+ and obtaining <var>hash</var>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <code>alg</code> field of <var>jwk</var> is not present,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <code>"alg"</code> field of <var>jwk</var> is
+ <code>"HS1"</code>:
+ </dt>
+ <dd>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> to <code>"SHA-1"</code>.
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field of <var>jwk</var> is
+ to <code>"HS256"</code>:
+ </dt>
+ <dd>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> to <code>"SHA-256"</code>.
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field of <var>jwk</var> is
+ <code>"HS384"</code>:
+ </dt>
+ <dd>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> to <code>"SHA-384"</code>.
+ </dd>
+ <dt>
+ If the <code>"alg"</code> field of <var>jwk</var> is
+ <code>"HS512"</code>:
+ </dt>
+ <dd>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> to <code>"SHA-512"</code>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ Perform any <a href="#dfn-hmac-extended-import-steps">key
+ import steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var>, <var>jwk</var>
+ and undefined
+ and obtaining <var>hash</var>.
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If the <code>"use"</code> field of <var>jwk</var> is present, and is
+ not <code>"sign"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"key_ops"</code> field of <var>jwk</var> is present, and
+ is invalid according to the requirements of
+ <a href="#jwk">JSON Web Key</a> or
+ does not contain all of the specified <var>usages</var> values,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>"ext"</code> field of <var>jwk</var> is present and
+ has the value false and <var>extractable</var> is true,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>length</var> be equivalent to the length, in octets, of
+ <var>data</var>, multiplied by 8.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>length</var> is zero
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-HmacImportParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is present:
+ </dt>
+ <dd>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-HmacImportParams-length">length</a> member of
+ <var>normalizedAlgorithm</var> is greater than <var>length</var>:
+ </dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>
+ If the <a href="#dfn-HmacImportParams-length">length</a> member of
+ <var>normalizedAlgorithm</var>, is less than or equal to
+ <var>length</var> minus eight:
+ </dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-DataError"><code>DataError</code></a>.
+ </dd>
+ <dt>
+ Otherwise:
+ </dt>
+ <dd>
+ Set <var>length</var> equal to the <a href="#dfn-HmacImportParams-length">
+ length</a> member of <var>normalizedAlgorithm</var>.
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <code><a href="#dfn-CryptoKey">CryptoKey</a></code>
+ object representing an HMAC key with the first <var>length</var>
+ bits of <var>data</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-HmacKeyAlgorithm">HmacKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"HMAC"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-HmacKeyAlgorithm-length">length</a> attribute of
+ <var>algorithm</var> to <var>length</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of
+ <var>algorithm</var> to <var>hash</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>If <var>format</var> is <code>"raw"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>data</var> be the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>If <var>format</var> is <code>"jwk"</code>:</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>jwk</var> be a new <a href="#dfn-JsonWebKey">JsonWebKey</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>kty</code> attribute of <var>jwk</var> to the
+ string <code>"oct"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>k</code> attribute of <var>jwk</var> to be a string
+ containing the raw octets of the key represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>, encoded according to Section 6.4 of <a href="#jwa">JSON Web Algorithms</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>hash</var> be the
+ <a href="#dfn-HmacKeyAlgorithm-hash">hash</a> attribute of
+ <var>algorithm</var>.
+ </p>
+ </li>
+
+ <li>
+ <dl class="switch">
+ <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> is <code>"SHA-1"</code>:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"HS1"</code>.</dd>
+ <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> is <code>"SHA-256"</code>:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"HS256"</code>.</dd>
+ <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> is <code>"SHA-384"</code>:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"HS384"</code>.</dd>
+ <dt>If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>hash</var> is <code>"SHA-512"</code>:</dt>
+ <dd>Set the <code>alg</code> attribute of <var>jwk</var> to
+ the string <code>"HS512"</code>.</dd>
+ <dt>
+ Otherwise, the <a href="#dfn-KeyAlgorithm-name">name</a> attribute
+ of <var>hash</var> is defined in
+ <a href="#dfn-applicable-specifications">another applicable
+ specification</a>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Perform any <a href="#dfn-hmac-extended-export-steps">key
+ export steps</a> defined by
+ <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>format</var> and <var>key</var>
+ and obtaining <var>alg</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>alg</code> attribute of <var>jwk</var> to
+ <var>alg</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Set the <code>key_ops</code> attribute of <var>jwk</var> to equal the
+ <a href="#dfn-CryptoKey-usages">usages</a> attribute of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <code>ext</code> attribute of <var>jwk</var> to equal the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of converting <var>jwk</var>
+ to an ECMAScript Object, as defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </p>
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get key length</dt>
+ <dd>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-HmacIMportParams-length">length</a> member of
+ <var>normalizedDerivedKeyAlgorithm</var> is not present:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the <a href="#dfn-HmacImportParams-hash">hash</a> member
+ of <var>normalizedDerivedKeyAlgorithm</var> is not present,
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-TypeError"><code>TypeError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>length</var> be the block size in bytes of the hash function
+ identified by the <a href="#dfn-HmacImportParams-hash">hash</a> member
+ of <var>normalizedDerivedKeyAlgorithm</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ Otherwise, if the <a href="#dfn-HmacImportParams-length">length</a>
+ member of <var>normalizedDerivedKeyAlgorithm</var> is non-zero:
+ </dt>
+ <dd>
+ Let <var>length</var> be equal to the
+ <a href="#dfn-HmacImportParams-length">length</a>
+ member of <var>normalizedDerivedKeyAlgorithm</var>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-TypeError"><code>TypeError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>length</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div id="dh" class="section">
+ <h3>32. Diffie-Hellman</h3>
+ <div id="dh-description" class="section">
+ <h4>32.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ This describes using Diffie-Hellman for key generation and key agreement, as specified
+ by <a href="#PKCS3">PKCS #3</a>.
+ </p>
+ </div>
+ <div id="dh-registration" class="section">
+ <h4>32.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"DH"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>generateKey</td>
+ <td><a href="#dfn-DhKeyGenParams">DhKeyGenParams</a></td>
+ <td><a href="#dfn-CryptoKeyPair">CryptoKeyPair</a></td>
+ </tr>
+ <tr>
+ <td>deriveBits</td>
+ <td><a href="#dfn-DhKeyDeriveParams">DhKeyDeriveParams</a></td>
+ <td><a href="#dfn-octet-string">Octet string</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td><a href="#dfn-DhImportKeyParams">DhImportKeyParams</a></td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>exportKey</td>
+ <td>None</td>
+ <td>object</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="dh-DhKeyGenParams" class="section">
+ <h4>32.3. DhKeyGenParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-DhKeyGenParams">DhKeyGenParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The prime p.</span>
+required BigInteger <dfn id="dfn-DhKeyGenParams-prime">prime</dfn>;
+<span class="comment">// The base g.</span>
+required BigInteger <dfn id="dfn-DhKeyGenParams-generator">generator</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="dh-DhKeyAlgorithm" class="section">
+ <h4>32.4. DhKeyAlgorithm dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-DhKeyAlgorithm">DhKeyAlgorithm</dfn> : <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> {
+<span class="comment">// The prime p.</span>
+required BigInteger <dfn id="dfn-DhKeyAlgorithm-prime">prime</dfn>;
+<span class="comment">// The base g.</span>
+required BigInteger <dfn id="dfn-DhKeyAlgorithm-generator">generator</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="dh-DhKeyDeriveParams" class="section">
+ <h4>32.5. DhKeyDeriveParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-DhKeyDeriveParams">DhKeyDeriveParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The peer's public value.</span>
+required <a href="#dfn-CryptoKey">CryptoKey</a> <dfn id="dfn-DhKeyDeriveParams-public">public</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="dh-DhImportKeyParams" class="section">
+ <h4>32.6. DhImportKeyParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-DhImportKeyParams">DhImportKeyParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The prime p.</span>
+required BigInteger <dfn id="dfn-DhImportKeyParams-prime">prime</dfn>;
+<span class="comment">// The base g.</span>
+required BigInteger <dfn id="dfn-DhImportKeyParams-generator">generator</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="dh-operations" class="section">
+ <h4>32.7. Operations</h4>
+ <dl>
+ <dt>Generate Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value which is not
+ one of <code>"deriveKey"</code> or <code>"deriveBits"</code>,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate a Diffie-Hellman key pair, as defined in Section 7 of
+ [<a href="#PKCS3">PKCS #3</a>], with prime, <var>p</var>, and base,
+ <var>g</var>, as specified in the
+ <a href="#dfn-DhKeyGenParams-prime">prime</a> and
+ <a href="#dfn-DhKeyGenParams-generator">generator</a> properties of
+ <var>normalizedAlgorithm</var>, respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>
+ object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>algorithm</var> to <code>"DH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-DhKeyGenParams-prime">prime</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a>
+ attribute of <var>algorithm</var> to equal the
+ <a href="#dfn-DhKeyGenParams-generator">generator</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the public key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> to <code>"public"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>publicKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>publicKey</var> to true.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>publicKey</var> to be the empty list.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKey</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the private key of the generated key pair.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>privateKey</var> to <code>"private"</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>privateKey</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>privateKey</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>privateKey</var> to be <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <a href="#dfn-CryptoKeyPair">CryptoKeyPair</a>
+ dictionary.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-publicKey">publicKey</a> attribute
+ of <var>result</var> to be <var>publicKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-CryptoKeyPair-privateKey">privateKey</a> attribute
+ of <var>result</var> to be <var>privateKey</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return the result of converting <var>result</var> to an ECMAScript Object, as
+ defined by [<a href="#WebIDL">WEBIDL</a>].
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Derive Bits</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>publicKey</var> be the
+ <a href="#dfn-DhKeyDeriveParams-public">public</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>publicKey</var> is not <code>"DH"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>publicKey</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>publicKey</var> is not equal to the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of the
+ [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>publicKey</var> is not equal to the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal slot of
+ <var>key</var>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Perform the Diffie-Hellman Phase II algorithm as specified in Section 8 of [<a href="#PKCS3">PKCS #3</a>] with <var>key</var> as the DH private value
+ <var>x</var> and the Diffie-Hellman public value represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of the <a href="#dfn-DhKeyDeriveParams-public">public</a> member of
+ <var>normalizedAlgorithm</var> as the other's public value <var>PV'</var>.
+ </p>
+ <dl class="switch">
+ <dt>If performing the operation results in an error:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ Let <var>secret</var> be the output of the DH Phase II, <var>SK</var>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the length of <var>secret</var> in bits is less than
+ <var>length</var>:
+ </dt>
+ <dd>
+ <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>Return the first <var>length</var> bits of <var>secret</var>.</dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import Key</dt>
+ <dd>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is <code>"raw"</code>:
+ </dt>
+ <dd>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ Raw import of private values is presently not supported.
+ </p>
+ </div>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> is not empty
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>extractable</var> is false,
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>PV</var> be the integer which results from interpreting the
+ octets of <var>keyData</var> as an unsigned big integer with most
+ significant octet first.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing a Diffie-Hellman public key with public value <var>PV</var>
+ and with prime, <var>p</var> and base, <var>g</var> equal to the <a href="#dfn-DhImportKeyParams-prime">prime</a> and <a href="#dfn-DhImportKeyParams-generator">generator</a> properties of
+ <var>normalizedAlgorithm</var> respectively.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"public"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-Algorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"DH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
+ <var>algorithm</var> to equal the <a href="#dfn-DhImportKeyParams-prime">prime</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of
+ <var>algorithm</var> to equal the <a href="#dfn-DhImportKeyParams-generator">generator</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If <var>format</var> is <code>"spki"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> is not empty
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>spki</var> be the result of running the <a href="#concept-parse-a-spki">parse a subjectPublicKeyInfo</a> algorithm
+ over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var> is not
+ equivalent to the <code>dhKeyAgreement</code> OID defined in Section 9 of
+ [<a href="#PKCS3">PKCS #3</a>], then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the <code>algorithm</code>
+ AlgorithmIdentifier field of <var>spki</var> is absent, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the <code>parameters</code> field of the
+ <code>algorithm</code> AlgorithmIdentifier field of <var>spki</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not an instance of the <code>DHParameter</code>
+ ASN.1 type defined in Section 9 of <a href="#PKCS3">PKCS #3</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the Diffie-Hellman public key obtained by parsing the
+ <code>subjectPublicKey</code> field of <var>spki</var> as an ASN.1
+ INTEGER.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"public"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>algorithm</var> to <code>"DH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
+ <var>algorithm</var> to a new <code>BigInteger</code> equal to the
+ <a href="#dfn-octet-string">octet string</a> encoding of the <code>prime</code> field of
+ <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of
+ <var>algorithm</var> to a new <code>BigInteger</code> equal to the
+ <a href="#dfn-octet-string">octet string</a> encoding of the <code>base</code> field of
+ <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If <var>format</var> is <code>"pkcs8"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value which is not one of
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>privateKeyInfo</var> be the result of running the
+ <a href="#concept-parse-a-privateKeyInfo">parse a privateKeyInfo</a>
+ algorithm over <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If an error occurred while parsing, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>algorithm</code> object identifier field of the
+ <code>algorithm</code> AlgorithmIdentifier field of
+ <var>privateKeyInfo</var> is not equivalent to the
+ <code>dhKeyAgreement</code> OID defined in Section 9 of [<a href="#PKCS3">PKCS #3</a>], then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field of
+ <var>privateKeyInfo</var> is absent, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>params</var> be the <code>parameters</code> field of the
+ <code>privateKeyAlgorithm</code> PrivateKeyAlgorithmIdentifier field of
+ <var>privateKeyInfo</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>params</var> is not an instance of the <code>DHParameter</code>
+ ASN.1 type defined in Section 9 of <a href="#PKCS3">PKCS #3</a>, then <a href="#concept-throw">throw</a> a <a href="#dfn-DataError"><code>DataError</code></a>.
+ </p>
+ </li>
+ <li>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the Diffie-Hellman private key obtained by parsing the
+ <code>privateKey</code> field of <var>privateKeyInfo</var> as an ASN.1
+ INTEGER.
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"private"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-DhKeyAlgorithm">DhKeyAlgorithm</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>algorithm</var> to <code>"DH"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
+ <var>algorithm</var> to a new <code>BigInteger</code> equal to the
+ <a href="#dfn-octet-string">octet string</a> encoding of the <code>prime</code> field of
+ <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-DhKeyAlgorithm-generator">generator</a> attribute of
+ <var>algorithm</var> to a new <code>BigInteger</code> equal to the
+ <a href="#dfn-octet-string">octet string</a> encoding of the <code>base</code> field of
+ <var>params</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </dd>
+ <dt>Export Key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the underlying cryptographic key material represented by the [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ cannot be accessed, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is <code>"raw"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is <code>"public"</code>:
+ </dt>
+ <dd>
+ Let <var>data</var> be the Public Value, <var>PV</var>, associated
+ with <var>key</var> as specified in Section 7 of [<a href="#PKCS3">PKCS #3</a>].
+ </dd>
+ <dt>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is <code>"private"</code>:
+ </dt>
+ <dd>
+ Let <var>data</var> be the <a href="#dfn-octet-string">octet string</a> that represents the private
+ value <var>x</var> associated with <var>key</var> as a big integer,
+ most significant octet first.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If <var>format</var> is <code>"spki"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"public"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>subjectPublicKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithmIdentifier</var> field to an
+ <code>AlgorithmIdentifier</code> ASN.1 structure with the
+ following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the
+ <code>dhKeyAgreement</code> OID defined in Section 9 of <a href="#PKCS3">PKCS #3</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>parameters</var> field to an instance of the
+ <code>DHParams</code> ASN.1 structure defined in Section 9 of
+ <a href="#PKCS3">PKCS #3</a> with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>prime</var> field to an ASN.1 INTEGER that is
+ equivalent to the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>base</var> field to an ASN.1 INTEGER that is
+ equivalent to the <a href="#dfn-DhKeyAlgorithm-generator">generator</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>subjectPublicKey</var> to an ASN.1 INTEGER that
+ corresponds to the Diffie-Hellman public value represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of
+ <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>
+ If <var>format</var> is <code>"pkcs8"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot
+ of <var>key</var> is not <code>"private"</code>, then <a href="#concept-throw">throw</a> an <a href="#dfn-InvalidAccessError"><code>InvalidAccessError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>data</var> be an instance of the <code>privateKeyInfo</code>
+ ASN.1 structure defined in <a href="#RFC5280">RFC 5280</a>
+ with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>privateKeyAlgorithm</var> field to a
+ <code>PrivateKeyAlgorithmIdentifier</code> ASN.1 structure with
+ the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>algorithm</var> field to the
+ <code>dhKeyAgreement</code> OID defined in Section 9 of <a href="#PKCS3">PKCS #3</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>parameters</var> field to an instance of the
+ <code>DHParams</code> ASN.1 structure defined in Section 9 of
+ <a href="#PKCS3">PKCS #3</a> with the following properties:
+ </p>
+ <ul>
+ <li>
+ <p>
+ Set the <var>prime</var> field to an ASN.1 INTEGER that is
+ equivalent to the <a href="#dfn-DhKeyAlgorithm-prime">prime</a> attribute of
+ the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <var>base</var> field to an ASN.1 INTEGER that is
+ equivalent to the <a href="#dfn-DhKeyAlgorithm-generator">generator</a>
+ attribute of the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]]
+ internal slot of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Set the <var>privateKey</var> field to an ASN.1 INTEGER that
+ corresponds to the Diffie-Hellman private value represented by
+ [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot
+ of <var>key</var>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be a new <code>ArrayBuffer</code> containing
+ <var>data</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div id="sha" class="section">
+ <h3>33. SHA</h3>
+ <div id="sha-description" class="section">
+ <h4>33.1. Description</h4>
+ <p>
+ This describes the SHA-1 and SHA-2 families, as specified by
+ [<a href="#FIPS180-4">FIPS PUB 180-4</a>].
+ </p>
+ </div>
+ <div id="sha-registration" class="section">
+ <h4>33.2. Registration</h4>
+ <p>
+ The following algorithms are added as <a href="#recognized-algorithm-name">
+ recognized algorithm names</a>:
+ </p>
+ <dl>
+ <dt id="alg-sha-1"><code>"SHA-1"</code></dt>
+ <dd>The SHA-1 algorithm as specified in Section 6.1</dd>
+ <dt id="alg-sha-256"><code>"SHA-256"</code></dt>
+ <dd>The SHA-256 algorithm as specified in Section 6.2</dd>
+ <dt id="alg-sha-384"><code>"SHA-384"</code></dt>
+ <dd>The SHA-384 algorithm as specified in Section 6.5</dd>
+ <dt id="alg-sha-512"><code>"SHA-512"</code></dt>
+ <dd>The SHA-512 algorithm as specified in Section 6.4</dd>
+ </dl>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>digest</td>
+ <td>None</td>
+ <td>ArrayBuffer</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="sha-operations" class="section">
+ <h4>33.3. Operations</h4>
+ <dl>
+ <dt>Digest</dt>
+ <dd>
+ <ol>
+ <li>
+ <dl class="switch">
+ <dt>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is a cases-sensitive string match for
+ <code>"SHA-1"</code>:
+ </dt>
+ <dd>
+ Let <var>result</var> be the result of performing the SHA-1 hash function
+ defined in Section 6.1 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
+ <var>message</var> as the input message, <var>M</var>.
+ </dd>
+ <dt>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is a cases-sensitive string match for
+ <code>"SHA-256"</code>:
+ </dt>
+ <dd>
+ Let <var>result</var> be the result of performing the SHA-256 hash function
+ defined in Section 6.2 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
+ <var>message</var> as the input message, <var>M</var>.
+ </dd>
+ <dt>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is a cases-sensitive string match for
+ <code>"SHA-384"</code>:
+ </dt>
+ <dd>
+ Let <var>result</var> be the result of performing the SHA-384 hash function
+ defined in Section 6.5 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
+ <var>message</var> as the input message, <var>M</var>.
+ </dd>
+ <dt>
+ If the <a href="#dfn-Algorithm-name">name</a> member of
+ <var>normalizedAlgorithm</var> is a cases-sensitive string match for
+ <code>"SHA-512"</code>:
+ </dt>
+ <dd>
+ Let <var>result</var> be the result of performing the SHA-1 hash function
+ defined in Section 6.4 of [<a href="#FIPS180-4">FIPS PUB 180-4</a>] using
+ <var>message</var> as the input message, <var>M</var>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ <p>
+ If performing the operation results in an error, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return a new ArrayBuffer containing <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div id="concatkdf" class="section">
+ <h3>34. Concat KDF</h3>
+ <div id="concatkdf-description" class="section">
+ <h4>34.1. Description</h4>
+ <p>
+ The <code>"CONCAT"</code> algorithm identifier is used to perform key derivation
+ using the key derivation algorithm defined in Section 5.8.1 of NIST SP 800-56A
+ [<a href="#SP800-56A">SP800-56A</a>] using the SHA hash functions defined
+ in this specification.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with Concat KDF. Such specifications
+ must define digest operations for the additional hash algorithms and
+ <dfn id="dfn-concat-extended-import-steps">key import steps</dfn> for Concat KDF.
+ </p>
+ </div>
+ <div id="concatkdf-registration" class="section">
+ <h4>34.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"CONCAT"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>deriveBits</td>
+ <td><a href="#dfn-ConcatParams">ConcatParams</a></td>
+ <td><a href="#dfn-octet-string">Octet string</a></td>
+ </tr>
+ <tr>
+ <td>Import key</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>Get key length</td>
+ <td>None</td>
+ <td>Integer or null</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="concat-params" class="section">
+ <h4>34.3. ConcatParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-ConcatParams">ConcatParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The digest method to use to derive the keying material.</span>
+<a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-ConcatParams-hash">hash</dfn>;
+
+<span class="comment">// A bit string corresponding to the AlgorithmId field of the OtherInfo parameter.</span>
+<span class="comment">// The AlgorithmId indicates how the derived keying material will be parsed and for which</span>
+<span class="comment">// algorithm(s) the derived secret keying material will be used.</span>
+required BufferSource <dfn id="dfn-ConcatParams-algorithmId">algorithmId</dfn>;
+<span class="comment">// A bit string that corresponds to the PartyUInfo field of the OtherInfo parameter.</span>
+required BufferSource <dfn id="dfn-ConcatParams-partyUInfo">partyUInfo</dfn>;
+<span class="comment">// A bit string that corresponds to the PartyVInfo field of the OtherInfo parameter.</span>
+required BufferSource <dfn id="dfn-ConcatParams-partyVInfo">partyVInfo</dfn>;
+<span class="comment">// An optional bit string that corresponds to the SuppPubInfo field of the OtherInfo parameter.</span>
+BufferSource <dfn id="dfn-ConcatParams-publicInfo">publicInfo</dfn>;
+<span class="comment">// An optional bit string that corresponds to the SuppPrivInfo field of the OtherInfo parameter.</span>
+BufferSource <dfn id="dfn-ConcatParams-privateInfo">privateInfo</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="concat-operations" class="section">
+ <h4>34.4. Operations</h4>
+ <dl>
+ <dt>Derive Bits</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Let <var>secret</var> be the result of performing the Concatenation Key
+ Derivation Function defined in Section 5.8.1 of
+ [<a href="#SP800-56A">SP800-56A</a>] with <var>length</var> as
+ <var>keydatalen</var>, the hash function identified by the
+ <a href="#dfn-ConcatParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var> as <var>H</var>, the
+ <a href="#dfn-ConcatParams-algorithmId">algorithmId</a> member of
+ <var>normalizedAlgorithm</var> as <var>AlgorithmID</var>, the
+ <a href="#dfn-ConcatParams-partyUInfo">partyUInfo</a> member of
+ <var>normalizedAlgorithm</var> as <var>PartyUInfo</var>, the
+ <a href="#dfn-ConcatParams-partyVInfo">partyVInfo</a> member of
+ <var>normalizedAlgorithm</var> as <var>PartyVInfo</var>, the
+ <a href="#dfn-ConcatParams-publicInfo">publicInfo</a> member of
+ <var>normalizedAlgorithm</var>, if present, as
+ <var>SuppPubInfo</var> and the
+ <a href="#dfn-ConcatParams-privateInfo">privateInfo</a> member of
+ <var>normalizedAlgorithm</var>, if present, as
+ <var>SuppPrivInfo</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the operation fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>secret</var>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <p>
+ Perform any <a href="#dfn-concat-extended-import-steps">key import steps</a>
+ defined by <a href="#dfn-applicable-specifications">other applicable
+ specifications</a>, passing <var>keyData</var> and obtaining <var>result</var>.
+ <dl class="switch">
+ <dt>
+ If <var>result</var> is a <a href="#dfn-CryptoKey">CryptoKey</a>
+ object
+ </dt>
+ <dd>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </dd>
+ <dt>
+ If <var>result</var> is an error with a name that is not
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
+ </dt>
+ <dd>
+ <p>
+ <a href="#concept-throw">throw</a> <var>result</var>.
+ </p>
+ </dd>
+ </dl>
+ </p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is <code>"raw"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value that is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>,
+
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the key data provided in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"secret"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"CONCAT"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Return null.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div id="hkdf-ctr" class="section">
+ <h3>35. HKDF-CTR</h3>
+ <div id="hkdf-ctr-description" class="section">
+ <h4>35.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"HKDF-CTR"</code> algorithm identifier is used to
+ perform key derivation using the extraction-then-expansion approach described in
+ NIST SP 800-56C[<a href="#SP800-56C">SP800-56C</a>], using HMAC in counter mode, and
+ using the SHA hash functions defined in this specification
+ as described in Section 5.1 of NIST SP 800-108
+ [<a href="#SP800-108">SP800-108</a>].
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with HKDF.
+ Such specifications must define the digest operation for the additional hash algorithms.
+ </p>
+ </div>
+ <div id="hkdf-ctr-registration" class="section">
+ <h4>35.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a>
+ for this algorithm is <code>"HKDF-CTR"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>deriveBits</td>
+ <td><a href="#dfn-HkdfCtrParams">HkdfCtrParams</a></td>
+ <td><a href="#dfn-ArrayBuffer">ArrayBuffer</a></td>
+ </tr>
+ <tr>
+ <td>Import key</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>Get key length</td>
+ <td>None</td>
+ <td>Integer or null</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="hkdf-ctr-params" class="section">
+ <h4>35.3. HkdfCtrParams dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-HkdfCtrParams">HkdfCtrParams</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+<span class="comment">// The algorithm to use with HMAC (e.g.: <a href="#sha-256">SHA-256</a>)</span>
+required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-HkdfCtrParams-hash">hash</dfn>;
+<span class="comment">// A bit string that corresponds to the label that identifies the purpose for the derived keying material.</span>
+required BufferSource <dfn id="dfn-HkdfCtrParams-label">label</dfn>;
+<span class="comment">// A bit string that corresponds to the context of the key derivation, as described in Section 5 of NIST SP 800-108 [<a href="#SP800-108">SP800-108</a>]</span>
+required BufferSource <dfn id="dfn-HkdfCtrParams-context">context</dfn>;
+};
+ </code></pre></div></div>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ The definition of HKDF allows the caller to supply an optional pseudorandom salt
+ value, which is used as the key during the extract phase. If this value is not
+ supplied, an all zero string is used instead. However, support for an explicit
+ salt value is not widely implemented in existing APIs, nor is it required by
+ existing usages of HKDF. Should this be an optional parameter, and if so, what
+ should the behavior be of a user agent that does not support explicit salt
+ values (is it conforming or non-conforming?)
+ </p>
+ </div>
+ </div>
+ <div id="hkdf2-ctr-operations" class="section">
+ <h4>35.4. Operations</h4>
+ <dl>
+ <dt>Derive Bits</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>length</var> is null, then <a href="#concept-throw">throw</a> a <a href="#dfn-TypeError"><code>TypeError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-HkdfCtrParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var> does not describe a <a href="#algorithms">
+ recognized algorithm</a> that supports the digest operation, then
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>extractKey</var> be a key equal to <var>n</var> zero bits where
+ <var>n</var> is the size of the output of the hash function described by the
+ <a href="#dfn-HkdfCtrParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>prf</var> be the MAC Generation function described in Section 4 of
+ [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using the hash function
+ described by the <a href="#dfn-HkdfCtrParams-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>keyDerivationKey</var> be the result of performing <var>prf</var>
+ using <var>extractKey</var> as the key and the secret represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ as the message.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the KDF in counter
+ mode operation described in Section 5.1 of NIST SP 800-108
+ [<a href="#SP800-108">SP800-108</a>] using:
+ </p>
+ <ul>
+ <li>
+ <p>
+ <var>prf</var> as the Pseudo-Random Function, <var>PRF</var>,
+ </p>
+ </li>
+ <li>
+ <p>
+ <var>keyDerivationKey</var> as the Key derivation key,
+ <var>K<sub>I</sub></var>,
+ </p>
+ </li>
+ <li>
+ <p>
+ <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-HkdfCtrParams-label">label</a> member of
+ <var>normalizedAlgorithm</var> as <var>Label</var>,
+ </p>
+ </li>
+ <li>
+ <p>
+ <a href="#concept-contents-of-arraybuffer">the contents of</a> the <a href="#dfn-HkdfCtrParams-label">context</a> member of
+ <var>normalizedAlgorithm</var> as <var>Context</var>,
+ </p>
+ </li>
+ <li>
+ <p>
+ <var>length</var> as the value of <var>L</var>,
+ </p>
+ </li>
+ <li>
+ <p>
+ 32 as the value of <var>r</var>, and
+ </p>
+ </li>
+ <li>
+ <p>
+ the 32-bit little-endian binary encoding of <var>length</var>
+ as the encoded length value [<var>L</var>]<sub>2</sub>.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ If the key derivation operation fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>Let <var>keyData</var> be the key data to be imported.</p>
+ </li>
+ <li>
+ <dl class="switch">
+ <dt>
+ If <var>format</var> is <code>"raw"</code>:
+ </dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value that is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>,
+
+ then <a href="#concept-throw">throw</a> a
+ <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the key data provided in <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"secret"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new
+ <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a> object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"HKDF-CTR"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Otherwise:</dt>
+ <dd>
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>.
+ </dd>
+ </dl>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Return null.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+ <div id="pbkdf2" class="section">
+ <h3>36. PBKDF2</h3>
+ <div id="pbkdf2-description" class="section">
+ <h4>36.1. Description</h4>
+ <p class="norm">This section is non-normative.</p>
+ <p>
+ The <code>"PBKDF2"</code> algorithm identifier is used to
+ perform key derivation using the PKCS#5 password-based key
+ derivation function version 2.0, as defined in
+ [<a href="#rfc2898">RFC2898</a>] using HMAC as the pseudo-random function,
+ using the SHA hash functions defined
+ in this specification.
+ </p>
+ <p>
+ <a href="#dfn-applicable-specification">Other specifications</a>
+ may specify the use of additional hash algorithms with PBKDF2. Such specifications
+ must define the digest operation for the additional hash algorithms.
+ </p>
+ </div>
+ <div id="pbkdf2-registration" class="section">
+ <h4>36.2. Registration</h4>
+ <p>
+ The <a href="#recognized-algorithm-name">recognized algorithm name</a> for
+ this algorithm is <code>"PBKDF2"</code>.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th><a href="#supported-operations">Operation</a></th>
+ <th><a href="#algorithm-specific-params">Parameters</a></th>
+ <th><a href="#algorithm-result">Result</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>generateKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>deriveBits</td>
+ <td><a href="#dfn-Pbkdf2Params">Pbkdf2Params</a></td>
+ <td><a href="#dfn-ArrayBuffer">ArrayBuffer</a></td>
+ </tr>
+ <tr>
+ <td>importKey</td>
+ <td>None</td>
+ <td><a href="#dfn-CryptoKey">CryptoKey</a></td>
+ </tr>
+ <tr>
+ <td>Get key length</td>
+ <td>None</td>
+ <td>Length or null</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="pbkdf2-params" class="section">
+ <h4>36.3. Pbkdf2Params dictionary</h4>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">IDL</span></div><div class="blockContent"><pre class="code"><code class="idl-code">
+dictionary <dfn id="dfn-Pbkdf2Params">Pbkdf2Params</dfn> : <a href="#dfn-Algorithm">Algorithm</a> {
+required BufferSource <dfn id="dfn-Pbkdf2Params-salt">salt</dfn>;
+[EnforceRange] required unsigned long <dfn id="dfn-Pbkdf2Params-iterations">iterations</dfn>;
+required <a href="#dfn-HashAlgorithmIdentifier">HashAlgorithmIdentifier</a> <dfn id="dfn-Pbkdf2Params-hash">hash</dfn>;
+};
+ </code></pre></div></div>
+ </div>
+ <div id="pbkdf2-operations" class="section">
+ <h4>36.4. Operations</h4>
+ <dl>
+ <dt>Derive bits</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>length</var> is null or is not a multiple of 8, then <a href="#concept-throw">throw</a> an <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the <a href="#dfn-Pbkdf2Params-hash">hash</a> member of
+ <var>normalizedAlgorithm</var> does not describe a <a href="#algorithms">
+ recognized algorithm</a> that supports the digest operation, then
+ <a href="#concept-throw">throw</a> a
+ <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>prf</var> be the MAC Generation function described in Section 4 of
+ [<a href="#fips-pub-198-1">FIPS PUB 198-1</a>] using the hash function
+ described by the <a href="#dfn-Pbkdf2Params-hash">hash</a> member of
+ <var>normalizedAlgorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>result</var> be the result of performing the PBKDF2 operation defined
+ in Section 5.2 of [<a href="#rfc2898">RFC2898</a>] using <var>prf</var> as the
+ pseudo-random function, <var>PRF</var>, the password represented by [[<a href="#dfn-CryptoKey-slot-handle">handle</a>]] internal slot of <var>key</var>
+ as the password, <var>P</var>, <a href="#concept-contents-of-arraybuffer">the
+ contents of</a> the <a href="#dfn-Pbkdf2Params-salt">salt</a> attribute of
+ <var>normalizedAlgorithm</var> as the salt, <var>S</var>, the value of the <a href="#dfn-Pbkdf2Params-iterations">iterations</a> attribute of
+ <var>normalizedAlgorithm</var> as the iteration count, <var>c</var>, and
+ <var>length</var> divided by 8 as the intended key length, <var>dkLen</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the key derivation operation fails,
+ then <a href="#concept-throw">throw</a> an
+ <a href="#dfn-OperationError"><code>OperationError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>result</var>
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Generate key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>usages</var> contains a value that is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>, then
+ <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>extractable</var> is true, then <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Generate a new password by prompting the user.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing the provided password as a series of bytes encoded using UTF-8.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"secret"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>
+ object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"PBKDF2"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-extractable">extractable</a>]] internal
+ slot of <var>key</var> to <var>extractable</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-usages">usages</a>]] internal slot of
+ <var>key</var> to the <a href="#concept-normalized-usages">normalized
+ value</a> of <var>usages</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Import key</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ If <var>format</var> is not <code>"raw"</code>, <a href="#concept-throw">throw</a> a <a href="#dfn-NotSupportedError"><code>NotSupportedError</code></a>
+ </p>
+ </li>
+ <li>
+ <p>
+ If <var>usages</var> contains a value that is not
+ <code>"deriveKey"</code> or <code>"deriveBits"</code>, then
+ <a href="#concept-throw">throw</a> a <a href="#dfn-SyntaxError"><code>SyntaxError</code></a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>key</var> be a new <a href="#dfn-CryptoKey">CryptoKey</a> object
+ representing <var>keyData</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-type">type</a>]] internal slot of
+ <var>key</var> to <code>"secret"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Let <var>algorithm</var> be a new <a href="#dfn-KeyAlgorithm">KeyAlgorithm</a>
+ object.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the <a href="#dfn-KeyAlgorithm-name">name</a> attribute of
+ <var>algorithm</var> to <code>"PBKDF2"</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Set the [[<a href="#dfn-CryptoKey-slot-algorithm">algorithm</a>]] internal
+ slot of <var>key</var> to <var>algorithm</var>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Return <var>key</var>.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ <dt>Get length</dt>
+ <dd>
+ <ol>
+ <li>
+ <p>
+ Return null.
+ </p>
+ </li>
+ </ol>
+ </dd>
+ </dl>
+ </div>
+ </div>
+
+
+ <div id="examples-section" class="section">
+ <h2>37. JavaScript Example Code</h2>
+ <div id="examples-signing" class="section">
+ <h3>37.1. Generate a signing key pair, sign some data</h3>
+
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+<span class="comment">// Algorithm Object</span>
+var algorithmKeyGen = {
+ name: "RSASSA-PKCS1-v1_5",
+ <span class="comment">// <a href="#dfn-RsaHashedKeyGenParams">RsaHashedKeyGenParams</a></span>
+ modulusLength: 2048,
+ publicExponent: new Uint8Array([0x01, 0x00, 0x01]), <span class="comment">// Equivalent to 65537</span>
+ hash: {
+ name: "SHA-256"
+ }
+};
+
+var algorithmSign = {
+ name: "RSASSA-PKCS1-v1_5"
+};
+
+window.crypto.subtle.generateKey(algorithmKeyGen, false, ["sign"]).then(
+ function(key) {
+ var dataPart1 = convertPlainTextToArrayBufferView("hello,");
+ var dataPart2 = convertPlainTextToArrayBufferView(" world!");
+ <span class="comment">// TODO: create example utility function that converts text -> ArrayBufferView</span>
+
+ return window.crypto.subtle.sign(algorithmSign, key.privateKey, [dataPart1, dataPar2]);
+ },
+ console.error.bind(console, "Unable to generate a key")
+).then(
+ console.log.bind(console, "The signature is: "),
+ console.error.bind(console, "Unable to sign")
+);
+ </code></pre></div></div>
+ </div>
+ <div id="examples-symmetric-encryption" class="section">
+ <h3>37.2. Symmetric Encryption</h3>
+ <div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+var clearDataArrayBufferView = convertPlainTextToArrayBufferView("Plain Text Data");
+<span class="comment">// TODO: create example utility function that converts text -> ArrayBufferView</span>
+
+var aesAlgorithmKeyGen = {
+ name: "AES-CBC",
+ <span class="comment">// <a href="#dfn-AesKeyGenParams">AesKeyGenParams</a></span>
+ length: 128
+};
+
+var aesAlgorithmEncrypt = {
+ name: "AES-CBC",
+ <span class="comment">// <a href="#dfn-AesCbcParams">AesCbcParams</a></span>
+ iv: window.crypto.getRandomValues(new Uint8Array(16))
+};
+
+<span class="comment">// Create a key generator to produce a one-time-use AES key to encrypt some data</span>
+window.crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ["encrypt"]).then(
+ function(aesKey) {
+ return window.crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey, [ clearDataArrayBufferView ]);
+ }
+).then(console.log.bind(console, "The ciphertext is: "),
+ console.error.bind(console, "Unable to encrypt"));
+ </code></pre></div></div>
+ </div>
+ </div>
+ <div id="iana-section" class="section">
+ <h2>38. IANA Considerations</h2>
+ <div id="iana-section-jws-jwa" class="section">
+ <h3>38.1. JSON Web Signature and Encryption Algorithms Registration</h3>
+ <p>
+ This section registers the following algorithm identifiers in the IANA JSON Web
+ Signature and Encryption Algorithms Registry for use with JSON Web Key. Note that the
+ 'Implementation Requirements' field in the template refers to use with JSON Web
+ Signature and JSON Web Encryption specifically, in which case use of unauthenticated
+ encryption is prohibited.
+ </p>
+ <ul>
+ <li>Algorithm Name: "RS1"</li>
+ <li>Algorithm Description: RSASSA-PKCS1-v1_5 with SHA-1</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "RSA-OAEP-384"</li>
+ <li>Algorithm Description: RSA-OAEP using SHA-384 and MGF1 with SHA-384</li>
+ <li>Algorithm Usage Location(s): "alg"</li>
+ <li>JOSE Implementation Requirements: Optional+</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "RSA-OAEP-512"</li>
+ <li>Algorithm Description: RSA-OAEP using SHA-512 and MGF1 with SHA-512</li>
+ <li>Algorithm Usage Location(s): "alg"</li>
+ <li>JOSE Implementation Requirements: Optional+</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A128CBC"</li>
+ <li>Algorithm Description: AES CBC using 128 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A192CBC"</li>
+ <li>Algorithm Description: AES CBC using 192 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A256CBC"</li>
+ <li>Algorithm Description: AES CBC using 256 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A128CTR"</li>
+ <li>Algorithm Description: AES CTR using 128 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A192CTR"</li>
+ <li>Algorithm Description: AES CTR using 192 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A256CTR"</li>
+ <li>Algorithm Description: AES CTR using 256 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A128CMAC"</li>
+ <li>Algorithm Description: AES CMAC using 128 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A192CMAC"</li>
+ <li>Algorithm Description: AES CMAC using 192 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A256CMAC"</li>
+ <li>Algorithm Description: AES CMAC using 256 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A128CFB8"</li>
+ <li>Algorithm Description: AES CFB-8 using 128 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A192CFB8"</li>
+ <li>Algorithm Description: AES CFB-8 using 192 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "A256CFB8"</li>
+ <li>Algorithm Description: AES CFB-8 using 256 bit key</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ <ul>
+ <li>Algorithm Name: "HS1"</li>
+ <li>Algorithm Description: HMAC using SHA-1</li>
+ <li>Algorithm Usage Location(s): "JWK"</li>
+ <li>JOSE Implementation Requirements: Prohibited</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document ]]</li>
+ </ul>
+ </div>
+ <div id="iana-section-jwk" class="section">
+ <h3>38.2. JSON Web Key Parameters Registration</h3>
+ <ul>
+ <li>Parameter Name: "ext"</li>
+ <li>Parameter Description: Extractable</li>
+ <li>Used with "kty" Value(s): *</li>
+ <li>Parameter Information Class: Public</li>
+ <li>Change Controller: W3C Web Cryptography Working Group</li>
+ <li>Specification Document(s): [[ This Document]]</li>
+ </ul>
+ </div>
+ </div>
+ <div id="acknowledgements-section" class="section">
+ <h2>39. Acknowledgements</h2>
+ <p>
+ The editors would like to thank Adam Barth, Alex Russell, Ali Asad, Arun Ranganathan,
+ Brian Smith, Brian Warner, Channy Yun, Eric Roman, Glenn Adams, Jim Schaad, Kai Engert,
+ Mark Watson, Michael Hutchinson, Michael B. Jones, Nick Van den Bleeken, Richard Barnes,
+ Vijay Bharadwaj, Virginie Galindo, and Wan-Teh Chang for their technical feedback and
+ assistance.
+ </p>
+ <p>
+ Thanks to the W3C Web Cryptography WG, and to participants on the public-webcrypto@w3.org
+ mailing list.
+ </p>
+ <p>
+ The W3C would like to thank the <a href="http://certdata.northropgrumman.com/cybersecurity/presskit_research_co.html">Northrop
+ Grumman Cybersecurity Research Consortium</a> for supporting W3C/MIT.
+ </p>
+ <p>
+ The <a href="#dfn-Crypto-method-getRandomValues"><code>getRandomValues</code></a>
+ method in the <code>Crypto</code> interface was originally proposed by Adam Barth to the
+ <a href="http://wiki.whatwg.org/wiki/Crypto">WHATWG</a>.
+ </p>
+ </div>
+ <div id="references" class="section">
+ <h2>40. References</h2>
+ <div id="normative-references" class="section">
+ <h3>40.1. Normative References</h3>
+ <dl>
+ <dt id="DOM4">DOM4</dt>
+ <dd>
+ <cite><a href="http://dom.spec.whatwg.org/">DOM (Living Standard)</a></cite>,
+ A. Gregor, A. van Kesteren, Ms2ger. WHATWG.
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>This will be updated to W3C DOM4 once Promises are incorporated.</div>
+ </dd>
+ <dt id="ECMA-262">ECMA262</dt>
+ <dd>
+ <cite><a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
+ ECMAScript 5th Edition</a></cite>, A. Wirfs-Brock, P. Lakshman et al.
+ </dd>
+ <dt id="FIPS180-4">FIPS 180-4</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf">
+ FIPS PUB 180-4: Secure Hash Standard</a></cite>, NIST.
+ </dd>
+ <dt id="HTML">HTML</dt>
+ <dd>
+ <cite><a href="http://dev.w3.org/html5/spec/Overview.html">HTML5: A vocabulary and
+ associated APIs for HTML and XHTML (work in progress)</a></cite>, I. Hickson. W3C.
+ </dd>
+ <dt id="PKCS3">PKCS3</dt>
+ <dd>
+ <cite><a href="http://www.rsa.com/rsalabs/node.asp?id=2126">PKCS #3: Diffie-Hellman
+ Key-Agreement Standard</a></cite>, RSA Laboratories.
+ </dd>
+ <dt id="RFC2119">RFC2119</dt>
+ <dd>
+ <cite><a href="http://www.ietf.org/rfc/rfc2119">Key words for use in RFCs to
+ Indicate Requirement Levels</a></cite>, S. Bradner. IETF.
+ </dd>
+ <dt id="RFC3447">RFC3447</dt>
+ <dd>
+ <cite><a href="http://www.ietf.org/rfc/rfc3447">Public-Key Cryptography Standards
+ (PKCS) #1: RSA Cryptography Specifications Version 2.1</a></cite>, J. Jonsson,
+ B. Kaliski. IETF.
+ </dd>
+ <dt id="RFC5208">RFC5208</dt>
+ <dd>
+ <cite><a href="http://www.ietf.org/rfc/rfc5208.txt">Public-Key Cryptography Standards
+ (PKCS) #8: Private-Key Information Syntax Specification Version 1.2</a></cite>,
+ B. Kaliski. IETF.
+ </dd>
+ <dt id="RFC5280">RFC5280</dt>
+ <dd>
+ <cite><a href="http://www.ietf.org/rfc/rfc5280.txt">Internet X.509 Public Key
+ Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a></cite>,
+ D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk. IETF.
+ </dd>
+ <dt id="WebIDL">Web IDL (Second Edition)</dt>
+ <dd>
+ <cite><a href="http://heycam.github.io/webidl/">Web IDL (Second Edition)</a></cite>,
+ C. McCormack.
+ </dd>
+ <dt id="X9.62">X9.62</dt>
+ <dd>
+ <cite>ANS X9.62–2005: Public Key Cryptography for the Financial Services Industry,
+ The Elliptic Curve Digital Signature Algorithm (ECDSA)</cite>, ANSI.
+ </dd>
+ <dt id="X9.63">X9.63</dt>
+ <dd>
+ <cite>ANS X9.63–2001: Public Key Cryptography for the Financial Services Industry,
+ Key Agreement and Key Transport Using Elliptic Curve Cryptography</cite>, ANSI.
+ </dd>
+ <dt id="jwk">JSON Web Key</dt>
+ <dd>
+ <cite><a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-key">JSON Web Key
+ (work in progress)</a></cite>, M. Jones, Microsoft.
+ </dd>
+ <dt id="jwa">JSON Web Algorithms</dt>
+ <dd>
+ <cite><a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms">JSON
+ Web Algorithms (work in progress)</a></cite>, M. Jones, Microsoft.
+ </dd>
+ <dt id="rfc3394">RFC3394</dt>
+ <dd>
+ <cite><a href="http://www.ietf.org/rfc/rfc3394.txt">Advanced Encryption Standard
+ (AES) Key Wrap Algorithm</a></cite>, J. Schaad, R. Housley, IETF.
+ </dd>
+ <dt id="fips-pub-198-1">FIPS PUB 198-1</dt>
+ <dd>
+ <cite>
+ <a href="http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf">
+ The Keyed-Hash Message Authentication Code (HMAC)
+ </a>
+ </cite>,
+ July 2008, NIST.
+ </dd>
+ </dl>
+ </div>
+ <div id="informative-references" class="section">
+ <h3>40.2. Informative References</h3>
+ <dl>
+ <dt id="CDSA">CDSA</dt>
+ <dd>
+ <cite><a href="http://www.opengroup.org/security/cdsa.htm">Common Security: CDSA and
+ CSSM, Version 2 (with corrigenda)</a></cite>, the Open Group.
+ </dd>
+ <dt id="CNG">CNG</dt>
+ <dd>
+ <cite><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx">
+ Cryptography API: Next Generation</a></cite>, Microsoft Corporation.
+ </dd>
+ <dt id="CryptoAPI">CryptoAPI</dt>
+ <dd>
+ <cite><a href="http://msdn.microsoft.com/en-us/library/aa380256.aspx">Cryptography
+ Reference</a></cite>, Microsoft Corporation.
+ </dd>
+ <dt id="draft-TLS-OBC">DRAFT-TLS-OBC</dt>
+ <dd>
+ <cite><a href="http://tools.ietf.org/html/draft-balfanz-tls-obc-01">TLS Origin-Bound
+ Certificates</a></cite>, D. Balfanz, D. Smetters, M. Upadhyay, A. Barth. IETF.
+ </dd>
+ <dt id="FileAPI">FileAPI</dt>
+ <dd>
+ <cite><a href="http://www.w3.org/TR/FileAPI/">File API</a></cite>,
+ A. Ranganathan, J. Sicking. W3C.
+ </dd>
+ <dt id="IndexedDB">Indexed Database API</dt>
+ <dd>
+ <cite><a href="http://www.w3.org/TR/IndexedDB/">Indexed Database API</a></cite>,
+ N. Mehta, J. Sicking, E. Graff, A. Popescu, J. Orlow, J. Bell. W3C.
+ </dd>
+ <dt id="PKCS11">PKCS11</dt>
+ <dd>
+ <cite><a href="http://www.rsa.com/rsalabs/node.asp?id=2133">PKCS #11: Cryptographic
+ Token Interface Standard</a></cite>, RSA Laboratories.
+ </dd>
+ <dt id="RFC2315">RFC 2315</dt>
+ <dd>
+ <cite><a href="http://tools.ietf.org/html/rfc2315">PKCS #7: Cryptographic
+ Message Syntax, Version 1.5</a></cite>, B. Kaliski. RSA Laboratories.
+ </dd>
+ <dt id="RFC2898">RFC 2898</dt>
+ <dd>
+ <cite><a href="http://tools.ietf.org/html/rfc2898">PKCS #5: Password-Based
+ Cryptography Specification, Version 2.0</a></cite>, B. Kaliski. RSA Laboratories
+ </dd>
+ <dt id="RFC5705">RFC 5705</dt>
+ <dd>
+ <cite><a href="http://tools.ietf.org/html/rfc5705">Keying Material Exporters for
+ Transport Layer Security (TLS)</a></cite>, E. Rescorla. IETF.
+ </dd>
+ <dt id="RFC5869">RFC 5869</dt>
+ <dd>
+ <cite><a href="https://tools.ietf.org/html/rfc5869">HMAC-based Extract-and-Expand
+ Key Derivation Function (HKDF)</a></cite>, H. Krawczyk, P. Eronen. IETF.
+ </dd>
+ <dt id="RFC4055">RFC 4055</dt>
+ <dd>
+ <cite><a href="https://tools.ietf.org/html/rfc4055">Additional Algorithms and
+ Identifiers for RSA Cryptography for use in the Internet X.509 Public Key
+ Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a></cite>,
+ J. Schaad, B. Kaliski, R. Housley. IETF.
+ </dd>
+ <dt id="SP800-38A">NIST SP 800-38A</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf">
+ NIST Special Publication 800-38A: Recommendation for Block Cipher
+ Modes of Operation, Methods and Techniques</a></cite>, December 2001, NIST.
+ </dd>
+ <dt id="SP800-38B">NIST SP 800-38B</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf">
+ NIST Special Publication 800-38B: Recommendation for Block Cipher Modes of Operation:
+ The CMAC Mode for Authentication</a></cite>, May 2005, NIST.
+ </dd>
+ <dt id="SP800-38D">NIST SP 800-38D</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf">
+ NIST Special Publication 800-38D: Recommendation for Block Cipher Modes of Operation:
+ Galois/Counter Mode (GCM) and GMAC</a></cite>, November 2007, NIST.
+ </dd>
+ <dt id="SP800-56A">NIST SP 800-56A</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">
+ NIST Special Publication 800-56A: Recommendation for Pair-Wise Key Establishment
+ Schemes Using Discrete Logarithm Cryptography (Revised)</a></cite>, March 2007, NIST.
+ </dd>
+ <dt id="SP800-56C">NIST SP 800-56C</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf">
+ NIST Special Publication 800-56C: Recommendation for Key Derivation through
+ Extraction-then-Expansion</a></cite>, November 2011, NIST.
+ </dd>
+ <dt id="SP800-108">NIST SP 800-108</dt>
+ <dd>
+ <cite><a href="http://csrc.nist.gov/publications/nistpubs/800-108/sp800-108.pdf">
+ NIST Special Publication 800-108: Recommendation for Key Derivation Using
+ Pseudorandom Functions (Revised)</a></cite>, October 2009, NIST.
+ </dd>
+ <dt id="StreamsAPI">StreamsAPI</dt>
+ <dd>
+ <cite><a href="http://dvcs.w3.org/hg/streams-api/raw-file/tip/Overview.htm">Streams
+ API</a> </cite>, F. Moussa. W3C.
+ </dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+
+ <div id="appendices">
+ <div id="jwk-mapping" class="section">
+ <h2>A. Mapping between JSON Web Key / JSON Web Algorithm</h2>
+ <p class="norm">
+ The following section is non-normative. Refer to algorithm-specific sections for the
+ normative requirements of importing and exporting JWK.
+ </p>
+ <div id="jwk-mapping-alg" class="section">
+ <h3>A.1. Algorithm mappings</h3>
+ <table>
+ <thead>
+ <tr>
+ <th scope="col">JSON Web Key</th>
+ <th scope="col">AlgorithmIdentifier</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RS1" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSASSA-PKCS1-v1_5",
+ hash: { name: "SHA-1" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RS256" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSASSA-PKCS1-v1_5",
+ hash: { name: "SHA-256" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RS384" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSASSA-PKCS1-v1_5",
+ hash: { name: "SHA-384" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RS512" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSASSA-PKCS1-v1_5",
+ hash: { name: "SHA-512" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "PS256" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-PSS",
+ hash: { name: "SHA-256" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "PS384" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-PSS",
+ hash: { name: "SHA-384" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "PS512" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-PSS",
+ hash: { name: "SHA-512" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RSA-OAEP" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-OAEP",
+ hash: { name: "SHA-1" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RSA-OAEP-256" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-OAEP",
+ hash: { name: "SHA-256" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RSA-OAEP-384" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-OAEP",
+ hash: { name: "SHA-384" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "RSA",
+ alg: "RSA-OAEP-512" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "RSA-OAEP",
+ hash: { name: "SHA-512" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "EC",
+ alg: "ES256" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "ECDSA",
+ namedCurve: "P-256"
+ hash: { name: "SHA-256" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "EC",
+ alg: "ES384" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "ECDSA",
+ namedCurve: "P-384"
+ hash: { name: "SHA-384" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "EC",
+ alg: "ES512" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "ECDSA",
+ namedCurve: "P-521"
+ hash: { name: "SHA-512" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128CTR" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CTR",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192CTR" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CTR",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256CTR" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CTR",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128CBC" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CBC",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192CBC" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CBC",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256CBC" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CBC",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128KW" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-KW",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192KW" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-KW",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256KW" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-KW",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128GCM" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-GCM",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192GCM" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-GCM",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256GCM" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-GCM",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128GCMKW" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-GCM",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192GCMKW" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-GCM",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256GCMKW" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-GCM",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128CMAC" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CMAC",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192CMAC" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CMAC",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256CMAC" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CMAC",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A128CFB8" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CFB-8",
+ length: 128 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A192CFB8" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CFB-8",
+ length: 192 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "A256CFB8" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "AES-CFB-8",
+ length: 256 }
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "HS1" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "HMAC",
+ hash: { name: "SHA-1" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "HS256" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "HMAC",
+ hash: { name: "SHA-256" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "HS384" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "HMAC",
+ hash: { name: "SHA-384" }
+}
+</code></pre></div></div>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ kty: "oct",
+ alg: "HS512" }
+</code></pre></div></div>
+ </td>
+ <td>
+<div class="block"><div class="blockTitleDiv"><span class="blockTitle">ECMAScript</span></div><div class="blockContent"><pre class="code"><code class="es-code">
+{ name: "HMAC",
+ hash: "SHA-512" }
+</code></pre></div></div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>Should the following be specified.</p>
+ <ul>
+ <li><p>RSASSA-PKCS1-v1_5 with SHA-1</p></li>
+ <li><p>RSA-PSS with SHA-1</p></li>
+ <li><p>ECDSA with SHA-1</p></li>
+ <li>
+ <p>
+ ECDSA where the curve (P-256, P-384, P-521) is not aligned with the hash (SHA-256,
+ SHA-384, SHA-512)
+ </p>
+ </li>
+ </ul>
+ </div>
+ </div>
+ <div id="jwk-mapping-usage" class="section">
+ <h3>A.2. Usage mapping</h3>
+ <table>
+ <thead>
+ <tr>
+ <th scope="col">JWK <code>use</code> value</th>
+ <th scope="col"><a href="#dfn-KeyUsage">KeyUsage</a>s</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>enc</code></td>
+ <td><code>["encrypt", "decrypt", "wrapKey", "unwrapKey"]</code></td>
+ </tr>
+ <tr>
+ <td><code>sig</code></td>
+ <td><code>["sign","verify"]</code></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div id="spki-mapping" class="section">
+ <h2>B. Mapping between Algorithm and SubjectPublicKeyInfo</h2>
+ <p class="norm">
+ The following section is non-normative. Refer to algorithm-specific sections for the
+ normative requirements of importing and exporting SPKI.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th scope="col">Algorithm OID</th>
+ <th scope="col">subjectPublicKey ASN.1 structure</th>
+ <th scope="col">AlgorithmIdentifier</th>
+ <th scope="col">Reference</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>rsaEncryption (1.2.840.113549.1.1.1)</td>
+ <td>RSAPublicKey</td>
+ <td>
+ <code>"RSASSA-PKCS1-v1_5"</code>,
+ <code>"RSA-PSS"</code>, or
+ <code>"RSA-OAEP"</code>
+ </td>
+ <td>
+ <a href="#RFC3279">RFC 3279</a>,
+ <a href="#RFC4055">RFC 4055</a>,
+ <a href="#RFC5756">RFC 5756</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-RSASSA-PSS (1.2.840.113549.1.1.10)</td>
+ <td>RSAPublicKey</td>
+ <td><code>"RSA-PSS"</code></td>
+ <td>
+ <a href="#RFC4055">RFC 4055</a>,
+ <a href="#RFC5756">RFC 5756</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-RSAES-OAEP (1.2.840.113549.1.1.7)</td>
+ <td>RSAPublicKey</td>
+ <td><code>"RSA-OAEP"</code></td>
+ <td>
+ <a href="#RFC4055">RFC 4055</a>,
+ <a href="#RFC5756">RFC 5756</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-ecPublicKey (1.2.840.10045.2.1)</td>
+ <td>ECPoint</td>
+ <td><code>"ECDH"</code> or <code>"ECDSA"</code></td>
+ <td><a href="#RFC5480">RFC 5480</a></td>
+ </tr>
+ <tr>
+ <td>id-ecDH (1.3.132.112)</td>
+ <td>ECPoint</td>
+ <td><code>"ECDH"</code></td>
+ <td><a href="#RFC5480">RFC 5480</a></td>
+ </tr>
+ <tr>
+ <td>id-dsa (1.2.840.10040.4.1)</td>
+ <td>DSAPublicKey</td>
+ <td><code>"DSA"</code></td>
+ <td><a href="#RFC3279">RFC 3279</a></td>
+ </tr>
+ <tr>
+ <td>dhKeyAgreement (1.2.840.113549.1.3.1)</td>
+ <td>INTEGER</td>
+ <td><code>"DH"</code></td>
+ <td><a href="#PKCS3">PKCS #3</a></td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ The handling of "id-RSASSA-PSS" and "id-RSAES-OAEP" are tricky.
+ <a href="#RFC5756">RFC 5756</a> recommends implementations should not include parameters
+ when PSS is used with a subjectPublicKeyInfo, and MUST NOT include parameters when OAEP
+ is used. However, when OAEP is used as part of a key transport (as an AlgorithmIdentifier),
+ implementations MUST include the parameters.
+ </p>
+ <p>
+ The natural conflict is in deciding when a key is being exported as part of a
+ subjectPublicKeyInfo (which is what "spki" implies) and when it's being used as an
+ algorithmIdentifier for transport.
+ </p>
+ </div>
+ </div>
+ <div id="pkcs8-mapping" class="section">
+ <h2>C. Mapping between Algorithm and PKCS#8 PrivateKeyInfo</h2>
+ <p class="norm">
+ The following section is non-normative. Refer to algorithm-specific sections for the
+ normative requirements of importing and exporting PKCS#8 PrivateKeyInfo.
+ </p>
+ <table>
+ <thead>
+ <tr>
+ <th scope="col">privateKeyAlgorithm</th>
+ <th scope="col">privateKey format</th>
+ <th scope="col">AlgorithmIdentifier</th>
+ <th scope="col">Reference</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>rsaEncryption (1.2.840.113549.1.1.1)</td>
+ <td>RSAPrivateKey</td>
+ <td>
+ <code>"RSASSA-PKCS1-v1_5"</code>,
+ <code>"RSA-PSS"</code>, or
+ <code>"RSA-OAEP"</code>
+ </td>
+ <td>
+ <a href="#RFC3447">RFC 3447</a>,
+ <a href="#RFC5958">RFC 5958</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-RSASSA-PSS (1.2.840.113549.1.1.10)</td>
+ <td>RSAPrivateKey</td>
+ <td><code>"RSA-PSS"</code></td>
+ <td>
+ <a href="#RFC3447">RFC 3447</a>,
+ <a href="#RFC4055">RFC 4055</a>,
+ <a href="#RFC5958">RFC 5958</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-RSAES-OAEP (1.2.840.113549.1.1.7)</td>
+ <td>RSAPrivateKey</td>
+ <td><code>"RSA-OAEP"</code></td>
+ <td>
+ <a href="#RFC3447">RFC 3447</a>,
+ <a href="#RFC4055">RFC 4055</a>,
+ <a href="#RFC5958">RFC 5958</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-ecPublicKey (1.2.840.10045.2.1)</td>
+ <td>ECPrivateKey</td>
+ <td><code>"ECDH"</code> or <code>"ECDSA"</code></td>
+ <td>
+ <a href="#RFC5480">RFC 5480</a>,
+ <a href="#RFC5915">RFC 5915</a>,
+ <a href="#RFC5958">RFC 5958</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-ecDH (1.3.132.112)</td>
+ <td>ECPrivateKey</td>
+ <td><code>"ECDH"</code></td>
+ <td>
+ <a href="#RFC5480">RFC 5480</a>,
+ <a href="#RFC5915">RFC 5915</a>,
+ <a href="#RFC5958">RFC 5958</a>
+ </td>
+ </tr>
+ <tr>
+ <td>id-dsa (1.2.840.10040.4.1)</td>
+ <td>INTEGER</td>
+ <td><code>"DSA"</code></td>
+ <td><a href="#RFC5958">RFC 5958</a></td>
+ </tr>
+ <tr>
+ <td>dhKeyAgreement (1.2.840.113549.1.3.1)</td>
+ <td>INTEGER</td>
+ <td><code>"DH"</code></td>
+ <td><a href="#PKCS3">PKCS #3</a></td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="ednote"><div class="ednoteHeader">Editorial note</div>
+ <p>
+ There does not appear to be a normative reference for a DH key being encoded as an
+ INTEGER. Only RFC 5958 seems to mention this.
+ </p>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>