This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 24410 - Define operation procedures for each algorithm
Summary: Define operation procedures for each algorithm
Status: RESOLVED FIXED
Alias: None
Product: Web Cryptography
Classification: Unclassified
Component: Web Cryptography API Document (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Mark Watson
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-27 17:11 UTC by Mark Watson
Modified: 2014-03-13 02:29 UTC (History)
2 users (show)

See Also:


Attachments

Description Mark Watson 2014-01-27 17:11:18 UTC
The operation procedures for each algorithm are mostly missing.

Superficially, it looks as if there could be a lot of duplication between algorithms. The examples currently present are also unnecessarily verbose, for example, four steps for calculating a hash could be replaced by one: 'Let M be the result of performing the hash operation specified by *hash* on the data in *bytes*. If the hash operation fails, return an empty ArrayBuffer."

I'd like to propose a small refactoring, such that for each algorithm and operation we specify only:
- a reference to the specification of the algorithm itself
- a mapping table, mapping input and output fields in WebCrypto terminology to the input and output fields as defined in the referenced specification

If there is a need to fill the gap between the "perform the underlying cryptographic operation" in the WebCrypto method procedures and the per-algorithm mapping tables then we can include some common text along the lies:

"To *perform an encryption operation* for *normalized algorithm identifier* with input parameters ..., the following steps shall be followed ... '

There may even be some additional common procedures - for example I think all the 'sign' operations start by calculating a hash.
Comment 1 Mark Watson 2014-01-28 00:37:36 UTC
As an example, consider the sign operation for RSASSA-PKCS-v1_5. I'd propose the following:

(1) In the description of the sign method (13.3.3), replace 'perform the underlying cryptographic algorithm specified by ...' with 'perform the signature algorithm specified by ...', where 'perform the signature algorithm' links to ...

(2) In a new sub-section (Procedures), add

'To *perform the signature algorithm* specified by *algorithm*, using *hash*, perform the following steps:
1.  If key does not refer to a key that matches the *required key type* for signature using *algorithm*, terminate the algorithm with an error
2.  Let M be a hash of bytes calculated using *hash*. If the hash algorithm fails, return an empty ArrayBuffer
3.  Let result be the output that results from applying the underlying cryptographic signature algorithm defined for *algorithm* to input data as defined for the *Sign* operation for *algorithm*.
4.  Return result

(3) In the "Sign" section of "RSASSA-PKCS-v1_5", we include a table:

+-------------------+------------------------------+
| Required Key Type | RSASSA-PKCS-v1_5 private key |
+-------------------+------------------------------+
| Specification     | RFC3447 Section 8.2          |
+-------------------+------------------------------+
| Input parameters  | WebCrypto    | RFC3447       |
|                   +--------------+---------------+ 
|                   | key          | K             |
|                   | M            | M             |
+-------------------+--------------+---------------+
| Output            | RFC3447      | WebCrypto     |
|                   +--------------+---------------+
|                   | S            | result        |
+-------------------+--------------+---------------+

[At some point we could make clear that the WebCrypto columns in this mapping refer to the variables defined in the generic procedure sections (2).]
Comment 2 Ryan Sleevi 2014-01-28 08:02:01 UTC
(In reply to Mark Watson from comment #1)
> As an example, consider the sign operation for RSASSA-PKCS-v1_5. I'd propose
> the following:
> 
> (1) In the description of the sign method (13.3.3), replace 'perform the
> underlying cryptographic algorithm specified by ...' with 'perform the
> signature algorithm specified by ...', where 'perform the signature
> algorithm' links to ...
> 
> (2) In a new sub-section (Procedures), add
> 
> 'To *perform the signature algorithm* specified by *algorithm*, using
> *hash*, perform the following steps:
> 1.  If key does not refer to a key that matches the *required key type* for
> signature using *algorithm*, terminate the algorithm with an error
> 2.  Let M be a hash of bytes calculated using *hash*. If the hash algorithm
> fails, return an empty ArrayBuffer
> 3.  Let result be the output that results from applying the underlying
> cryptographic signature algorithm defined for *algorithm* to input data as
> defined for the *Sign* operation for *algorithm*.
> 4.  Return result

Not all signature operations work on a hash. Or may use multiple inputs (eg: PSS's label). Such a generic specification for procedures is not a good fit - it was one of the first things I looked at.

> 
> (3) In the "Sign" section of "RSASSA-PKCS-v1_5", we include a table:
> 
> +-------------------+------------------------------+
> | Required Key Type | RSASSA-PKCS-v1_5 private key |
> +-------------------+------------------------------+
> | Specification     | RFC3447 Section 8.2          |
> +-------------------+------------------------------+
> | Input parameters  | WebCrypto    | RFC3447       |
> |                   +--------------+---------------+ 
> |                   | key          | K             |
> |                   | M            | M             |
> +-------------------+--------------+---------------+
> | Output            | RFC3447      | WebCrypto     |
> |                   +--------------+---------------+
> |                   | S            | result        |
> +-------------------+--------------+---------------+
> 
> [At some point we could make clear that the WebCrypto columns in this
> mapping refer to the variables defined in the generic procedure sections
> (2).]
Comment 3 Mark Watson 2014-01-28 23:13:44 UTC
Adding Ryan's comment from email, to keep the discussion in one place:

As mentioned on the bug, I don't think this will work. Consider PSS's inputs, for example.

For any 'generic' definition of inputs, you're essentially at best saying "Pass the params down to the next layer".

A fair comparison of where "linking to a spec and providing a table" is insufficient is the ECDSA specification - https://dvcs.w3.org/hg/webcrypto-api/raw-file/737e12c5ad33/spec/Overview.html#ecdsa-operations - which deals with integers and bitstrings and thus conversions and ordering is necessary to be specified.

Further complicated by the fact that the signing steps themselves depend on the named curve being used. For example, Curve25519 would *not* reference X9.62 (nor would it be usable for sign/verify), and the ECDHE computation would be different as far as references go (SEC1 vs Curve25519), even if they yield the same external results.

So I agree algorithms need specifications, I agree we should reference as much as possible existing specifications, but I don't think a table-based approach is sufficient.

I also find the reference to RFC3447 (eg: as proposed in the bug) to be confusing with respect of determining how the hash is computed. What if there are additional parameters to the hash that need to be mapped from the algorithm dictionary? What about potential polyfill/extension points? It's insufficient to suggest we provide M as the input, since the first step of RFC 3447, Section 8.2 is to encode, as per section 9.2, which requires defining the hash function.
Comment 4 Mark Watson 2014-01-28 23:22:33 UTC
Regarding the parameters tables, I had imagined that the tables could include forumlas. So we would say, for ECDSA, using X.9.62, for example, we would have:

+-------------------+------------------------------+---------------+
| Output            | X.9.62                       | WebCrypto     |
|                   +------------------------------+---------------+
|                   | BitString(r)||BitString(s)   | result        |
+-------------------+------------------------------+---------------+

Where we would obviously define the 'BitString' conversion function and the || concatenation operation. The point is that each column in the table contains an expression in the terminology of a different specification and we identify the two.

Where there are different specifications to be used in different cases, we would have multiple tables.

Regarding the hashes for signature algorithms, all the signature algorithms in the specification start by calculating a hash, so I thought it reasonable to factor that out. Now I look at X.9.62 I realize there is an error in the existing WebCrypto text, because taking the hash of the message is part of the procedures in Section 7.3 of that document. So, what we have now in the specification calculates a hash of a hash of the message (although it fails to define the input parameter to X.9.62 section 7.3 that identifies the hash function).

Still, calculating a hash can be written as a = hash( b ) instead of four lines of text. Parameter mapping can be defined, with simple manipulations, in mathematical notation instead of verbose text.

At the very least, if we are going to write long procedures, the tables as I have suggested capture the information needed to generate those procedures, so I may well go ahead creating the tables first and we can see if there is a necessity to convert to text.
Comment 5 Mark Watson 2014-01-28 23:41:08 UTC
For clarity, I agree with the point that the hash computation can't be pulled out into generic 'signature' text.

Here is how I would do PSS signature:

+-------------------+----------------------------------------------+
| Required Key Type | RSASSA-PSS private key                       |
+-------------------+----------------------------------------------+
| Specification     | RFC3447 Section 8.1                          |
+-------------------+----------------------------------------------+
| Input parameters  | WebCrypto            | RFC3447               |
|                   +----------------------+-----------------------+ 
|                   | key                  | K                     |
|                   | M                    | M                     |
|                   | algorithm.hash.name  | Hash                  |
|                   | algorithm.saltLength | sLen                  |
|                   | MGF-1                | MGF                   |
+-------------------+----------------------+-----------------------+
| Output            | RFC3447              | WebCrypto             |
|                   +----------------------+-----------------------+
|                   | S                    | result                |
+-------------------+----------------------+-----------------------+

Perhaps the columns should be the other way around.

Revised table for "RSASSA-PKCS-v1_5":

+-------------------+------------------------------+
| Required Key Type | RSASSA-PKCS-v1_5 private key |
+-------------------+------------------------------+
| Specification     | RFC3447 Section 8.2          |
+-------------------+------------------------------+
| Input parameters  | WebCrypto    | RFC3447       |
|                   +--------------+---------------+ 
|                   | key          | K             |
|                   | hash(M)      | M             |
+-------------------+--------------+---------------+
| Output            | RFC3447      | WebCrypto     |
|                   +--------------+---------------+
|                   | S            | result        |
+-------------------+--------------+---------------+

where hash(M) is the result of applying the hash algorithm identified by algorithm.hash to the message M.
Comment 6 Mark Watson 2014-02-07 02:41:27 UTC
https://dvcs.w3.org/hg/webcrypto-api/rev/f1dca326d8a2 for RSA ES and RSA SSA
Comment 7 Mark Watson 2014-02-20 00:57:38 UTC
Bug 24410 - operation descriptions for AES CTR: https://dvcs.w3.org/hg/webcrypto-api/rev/1d45ba72099d
Bug 24410 - operation descriptions for AES CBC: https://dvcs.w3.org/hg/webcrypto-api/rev/50d83a6fae47
Bug 24410 - operation descriptions for AES CFB-8: https://dvcs.w3.org/hg/webcrypto-api/rev/f7a0c1209ddf
Bug 24410 - operation descriptions for AES GCM: https://dvcs.w3.org/hg/webcrypto-api/rev/1ed0fb7da636
Bug 24410 - operation descriptions for AES-CMAC: https://dvcs.w3.org/hg/webcrypto-api/rev/768a11dba263
Bug 24410 - operation descriptions for AES-KW and associated method updates: https://dvcs.w3.org/hg/webcrypto-api/rev/0fee8e979b4f
Comment 8 Mark Watson 2014-02-26 21:05:35 UTC
Changeset fbc6ef272ace for stylistic consistency between algoritithms
Changeset 6973f252d137 for operation descriptions for the HMAC algorithm
Changeset 59edf569342c for operation descriptions for the SHA algorithm
Changeset 5f1f7c04c1de for operation descriptions for Diffie-Hellman
Comment 9 Mark Watson 2014-03-03 19:09:43 UTC
Changeset aa2535681aa5 to align sign and verify operation descriptions with the rest of the specification
Comment 11 Mark Watson 2014-03-13 02:29:58 UTC
Bug 25037 tracks the remaining issue of hanging references to the now removed encode procedures for subjectPublicKeyInfo and privateKeyInfo.