WebAssembly / wasi-crypto

WASI Cryptography API Proposal
162 stars 25 forks source link

Add another wasi-crypto witx proposal for signatures and a PoC implementation #8

Closed jedisct1 closed 4 years ago

jedisct1 commented 4 years ago

The implementation could be better and is missing the wasm<->host glue to be usable from WebAssembly, but it can help evaluate if the API is usable and what are its limitations.

Only signatures are implemented. But signatures are quite complicated to design an API for, so this is probably a good starting point for the overall API design.

An "operation" object must be created. For signatures, this is a signature_op object, instantiated with an algorithm name.

Different key types are used for each type of operation, and a key is tied to a context, i.e. an algorithm and a set of parameters.

Additional functions to tweak the context can be added without breaking the current API.

A signature_keypair_builder object, tied to a context, can create a key pair:

Key pairs are opaque handles. The host may not allow secret keys to be exported and/or imported.

Having an intermediary "builder" object allows applications to set up additional parameters required for key generation, importation (ex: password) or reference (ex: HSM credentials).

If allowed, key pairs can be exported, using a specified encoding.

We should define what format MUST and MAY be supported by an implementation for common algorithms.

In particular, we may require PKCS8 to be supported whenever the ASN.1 encoding has been defined for an algorithm.

A public key object can obviously be created from a key pair, and public keys can be imported and exported as well.

The signature process itself goes through the creation of a signature_state object, on which an update function can add to the message being signed.

At any point in time, the sign function of signature_state can be called to compute a signature of all the data received so far. The state is not reset, in order to allow incremental signatures.

Non-deterministic signature systems (ECDSA, RSA padding) do not require applications to specify a nonce. In order to avoid catastrophic security failures, the wasi-crypto implementation is responsible for securely choosing the nonce instead of delegating this to applications.

Signature verification works in a similar way. Data is received via a signature_verification_state object that is tied to a public key, and allows a signature to be verified against the data received so far.

We use quite a lot of different object types here. While it makes the API slightly more verbose than if more generic types had been used, it can make static analysis far more useful.

ueno commented 4 years ago

Just a couple of meta comments for now:

jedisct1 commented 4 years ago

Hi Daiki!

That witx file only covers signatures, so that it is easier to review an entire API focused on one operation.

We can totally try to merge both files, but the end result may look quite confusing, as it will be mixing other operations, with different ways to represent keys. The generated documentation only displays what is proposed by this PR, which is easier to review.

You are right, we should totally extend wasmtime/lucet with the new APIs. But that requires writing a bit of glue for every function, in order to copy and convert data between host and guest memories.

I'm currently working on this in another repository, and experimenting with wig that helps a little bit with the boilerplate. But there is still quite a lot of work to be manually done for each function, and done again every time any change is made to the API.

So, before extending the runtime, we should probably have an API that is not going to change too much, and test the implementation by calling functions directly -- their internal interface is already virtually identical to their WebAssembly interface.

jedisct1 commented 4 years ago

Thanks a lot for the link to Aaron's list of steps to add new APIs to wasmtime.

These instructions are excellent and will soon be very useful!

jedisct1 commented 4 years ago

Having multiple files with the same name is indeed confusing, thanks for pointing this out.

The witx file has been renamed to proposal_signatures.witx.

tniessen commented 4 years ago

Can we still change or replace the proposed API if we have a reference implementation, without having to implement every API revision?

I don't know if it's common practice to provide a PoC implementation this early.

jedisct1 commented 4 years ago

Of course, this is just a proposal and it can be totally changed or replaced.

The example implementation is useful to check the usability of the API and have a better understanding of what it would take to implement it. It is not meant to be a reference implementation.

But as a part of the specification, we will need test vectors and a test suite early. This is also why we need an implementation in addition to the interface description.

jedisct1 commented 4 years ago

Thanks a ton for your review, Daiki! ❤️

Your feedback helped a lot to get a good starting point!

I'm going to merge this, so that it will be easier to directly submit patches against that proposal.

The set of errors we need to define and how to name then, your concern about the usefulness of supporting more than one encoding for signatures, among other things, can be more comfortably discussed in dedicated tickets.

Thanks again for your input! It's exciting to see wasi-crypto make progress!