Skip to content

vectorized encrypt API#385

Merged
kazuho merged 4 commits into
masterfrom
kazuho/vectorized
May 4, 2022
Merged

vectorized encrypt API#385
kazuho merged 4 commits into
masterfrom
kazuho/vectorized

Conversation

@kazuho

@kazuho kazuho commented May 1, 2022

Copy link
Copy Markdown
Member

At the moment, the encrypt API provided by picotls only receives one ptl_iovec_t, which in turn produces an AEAD record. This leads to inefficiency when multiple fragments of data has to be sent concatenated.

To give an example, HTTP/2 implementations typically split HTTP response into small chunks, prepending HTTP/2 frame headers to each of those chunks, before they pass them to the TLS stack. At the moment, HTTP/2 implementations have to either:

  • a) build a flat image that has the HTTP/2 frame headers and chunks of response being concatenated, or
  • b) call ptls_send for encrypting the HTTP/2 frame header, then make a separate call for encrypting the response chunk.

a is inefficient when the implementation already has the response buffered in memory, because an extra copy would be required to concatenate the HTTP/2 frame header and the chunk of the response. b is inefficient due to generating a tiny TLS record that contains only the HTTP/2 frame header, not to mention the privacy aspect of leaking information through how things are chunked.

To address this problem, this pull request attempts to introduce a variant of ptls_send function that accepts a vector of buffers as input.

At the moment, this PR also replaces the init -> update -> final API at the AEAD layer with a new vectorized API as well. The rationale is that vectorized APIs are expected to provide better performance (as they can be integrated tighter to the encrypting code, see #384). But we can probably keep the existing ones deprecated.

…small, vectorized makes more sense for speed.
@kazuho kazuho mentioned this pull request May 1, 2022
4 tasks

@huitema huitema left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I first saw these API changes as part of the fastls PR review.

If we change the API, we need to update the picotls_bcrypt library, which uses the previous API. The current init/update/final set of function can be used to implement do_encrypt_v, except for the parameter ptls_iovec_t aad -- the structure BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO used for AEAD defines the "aad" parameter as

  PUCHAR    pbAuthData;
  ULONG     cbAuthData;

If the aad is in fact presented as a vector, it will have to be serialized, which is not great but is also not too complicated.

How do you want to do that? I guess I could prepare a PR against your PR...

@kazuho

kazuho commented May 1, 2022

Copy link
Copy Markdown
Member Author

@huitema Thank you for your quick response.

The current init/update/final set of function can be used to implement do_encrypt_v, except for the parameter ptls_iovec_t aad

I do not have a strong opinion here, let's go back to using two arguments.

How do you want to do that? I guess I could prepare a PR against your PR...

That would be fantastic. Thank you in advance.

Do you have an opinion regarding if we should keep existing init -> update -> final API?

@huitema

huitema commented May 1, 2022

Copy link
Copy Markdown
Collaborator

I checked the picoquic sources. The code only uses ptls_aead_encrypt. So I do not directly use the init -> update -> final.

On the other hand, if an implementation already provides the init -> update -> final functions, the encrypt_v function can be implemented as init -> loop(update) -> final. That would be generic code.

@kazuho

kazuho commented May 1, 2022

Copy link
Copy Markdown
Member Author

On the other hand, if an implementation already provides the init -> update -> final functions, the encrypt_v function can be implemented as init -> loop(update) -> final. That would be generic code.

This SGTM.

Please let me know if you want me to work on that before you'd be working on the bcrypt side (thank you as always). I'd also be totally fine if you could do everything and open a PR to this PR.

@huitema

huitema commented May 1, 2022

Copy link
Copy Markdown
Collaborator

Do you plan to reverse the change to the aad data representation from (value, length) to ptls_iovec_t? That's one of the incompatible changes in the API. Do I have to implement that change in the PR, or should I wait for it to be reversed?

Comment thread lib/cifra/aes-common.h Outdated
@kazuho

kazuho commented May 1, 2022

Copy link
Copy Markdown
Member Author

@huitema In ea42ef7, I've reverted all the changes modulo the introduction of the encrypt_v callback.

There is now a helper called ptls_aead__do_encrypt_v that you can use in the existing crypto engines that implement the init, update, final callbacks, see

ctx->super.do_encrypt_v = ptls_aead__do_encrypt_v;
.

Do these work for you on the bcrypt-side?

@huitema
huitema marked this pull request as ready for review May 2, 2022 04:01
@huitema

huitema commented May 2, 2022

Copy link
Copy Markdown
Collaborator

Please see PR #386, which fixes the bcrypt implementation of encrypt_v.

@kazuho
kazuho marked this pull request as draft May 4, 2022 02:33
@kazuho
kazuho marked this pull request as ready for review May 4, 2022 02:35
@kazuho

kazuho commented May 4, 2022

Copy link
Copy Markdown
Member Author

It would be a good idea to expose an API (ptls_sendv) that allows an user to specify vectorized input. But that can happen as a separate PR.

This PR is in good shape and the TLS (over TCP) side already utilizes the new API. Content-type and the record payload is supplied to the AEAD layer using the new encrypt_v callback.

@kazuho
kazuho merged commit 2c0c0c3 into master May 4, 2022
This was referenced May 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants