Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support a not in-place api's for protect/unprtect #693

Merged
merged 8 commits into from
Jun 12, 2024

Conversation

pabuhler
Copy link
Member

@pabuhler pabuhler commented Mar 25, 2024

The protect/unprotect api's can now operate both in-place or not in-place, depending on the requirements of the caller.
The length of the out buffer can now be checked to ensure there is sufficient space.
This addresses #322 "provide an new version of protect function that does not corrupt memory" and #569 "Please add a "non inplace" protect and unprotect API"

srtp_driver has been updated so all existing test can be run either in-place or not in-place.

  • Document new api and error codes
  • Update examples to use new api
  • Create separate PR's for all clean up / refactoring commits
  • Follow up with test cleanup and reuse of CHECK macros

@pabuhler pabuhler marked this pull request as draft March 25, 2024 08:47
@pabuhler
Copy link
Member Author

This PR is set to draft state as it is still a work in progress and can potentially be force updated with breaking changes.

crypto/cipher/aes_gcm_nss.c Outdated Show resolved Hide resolved
crypto/cipher/aes_gcm_nss.c Outdated Show resolved Hide resolved
non_null_buf = tagbuf;
non_null_dst_buf = tagbuf;
Copy link
Contributor

Choose a reason for hiding this comment

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

I do not know why the original code allowed the source buffer to be NULL. But now we have a case where the source buffer could be NULL, but the destination buffer might point to valid memory. It appears this line will cause the output to go into the local tagbuf, even if a valid dst was provided. Is that the wanted effect?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, if the src buffer is null, it is an indication that this is being used for authentication only and no data will be encrypted.
The api today does not expect the tag to be written to dst at this point, see #714

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll admit I'm a little confused, but I guess this is an NSS thing more than a libsrtp thing. If there is no source data, what is being authenticated?

Copy link
Member Author

Choose a reason for hiding this comment

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

in this case the entire packet was pass as aad data previously with srtp_aes_gcm_nss_set_aad()

crypto/cipher/aes_icm.c Outdated Show resolved Hide resolved
crypto/cipher/null_cipher.c Show resolved Hide resolved
include/srtp.h Show resolved Hide resolved
test/srtp_driver.c Show resolved Hide resolved
A layer to the srtp driver test is added to be able to run the tests both in-place & not-in-place without duplicating the test.

The not-in-place functions are currently a minimal implementation using a memcpy.
The protect/unprotect api's can now operate both in-place or not in-place, depending on the requirements of the caller.
The length of the out buffer can now be checked to ensure there is sufficient space.

Tests are add to verify validation of the output buffer length.
Also update the minimal code example in README.md to reflect the new
api.
With the new api the full length of dst is now passed in, if it is too small it should fail.
@pabuhler pabuhler marked this pull request as ready for review May 27, 2024 05:32
non_null_buf = tagbuf;
non_null_dst_buf = tagbuf;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'll admit I'm a little confused, but I guess this is an NSS thing more than a libsrtp thing. If there is no source data, what is being authenticated?

memcpy(c->tag, non_null_buf + (*enc_len - c->tag_size), c->tag_size);
*enc_len -= c->tag_size;
memcpy(c->tag, non_null_dst_buf + (*dst_len - c->tag_size), c->tag_size);
*dst_len -= c->tag_size;
Copy link
Contributor

Choose a reason for hiding this comment

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

This sets the length in the formal param dst_len to be whatever it was coming in minus the tag size. What if dst_size was 0 or 1, for example? Since I cannot see any data coming out when the src buffer is NULL, is this just indicating how much buffer would remain if a tag had been produced? (I understand a tag is somehow produced for something and stored in c->tag, but I don't see the relationship with that dst parameter when the src is NULL.)

Copy link
Member Author

Choose a reason for hiding this comment

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

you are right that this is confusing and if we do #714 "consider merging the gcm encrypt and get tag functions of cipher api" once this is merged it will clean all this up alot.

As it is now though, if the call to srtp_aes_gcm_nss_do_crypto() succeeds then dst_len was large enough for the tag and any encrypted data, it then would have been update to be that size. Since currently the tag is not going to be returned from this function it is truncated by tag size. But I agree that a sanity check against tag size would have be good here.

{
srtp_err_status_t status =
srtp_aes_gcm_nss_do_crypto(cv, false, buf, enc_len);
uint8_t tagbuf[16];
Copy link
Contributor

Choose a reason for hiding this comment

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

While no less confusing to me than the encrypt() function, it might be good to replicate much of the comments. That said, it would be good if the comments on encrypt() would speak about which "NULL buffer" (src or dst). The When we get a non-NULL buffer doesn't indicate which buffer.

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess that is an old comment, will update.

This is a safety check to ensure we do not wrap dst len when removing tag size.
All of this code would get much cleaner if the tag could just be returned instead of cached. see cisco#714
@pabuhler pabuhler merged commit 24eec55 into cisco:main Jun 12, 2024
39 checks passed
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