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
KBKDF: add CounterLocation.MiddleFixed #7489
Conversation
I wouldn't be opposed to supporting middle fixed. However, I'd like to look at ways to make the API backwards compatible and we should also expand the tests to use the middle_fixed vectors (they're currently skipped). |
Cool, thanks. I did try the following earlier today. It should retain backwards compatibility, but it's a little crude... perhaps there are better ways of doing this in Python?
|
That would definitely work but it's probably more discoverable to add |
Part of me loves the hack to get a rust-style enum with values, but its
probably a bit too magic :-)
…On Tue, Aug 9, 2022 at 5:55 PM Paul Kehrer ***@***.***> wrote:
That would definitely work but it's probably more discoverable to add
blocation (is that the name in the KBKDF documentation?) as an optional
kwarg to the end. The kwarg approach requires users to either use
kwargs-only calling convention or explicitly pass a backend (None being
the default value though) before the blocation though.
—
Reply to this email directly, view it on GitHub
<#7489 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBEZDRTVXPPRHY37KKDVYLHUBANCNFSM56ACQI3A>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
--
All that is necessary for evil to succeed is for good people to do nothing.
|
Updated to use an optional kwarg at the end: e98c7aa |
NIST SP 800-108 doesn't specify a name for the counter location (or I missed it). It simply states that the length and order is arbitrary and defined by the protocol where the KDF is used (page 12):
However, NIST's own test vectors use Perhaps you'd rather use that name? But snake case? i.e. |
|
"blocation is ignored when location is not" | ||
" CounterLocation.MiddleFixed" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to check that blocation
is within 0..len(fixed or label+context)
?
In its present state, it's allowed to set blocation=-1
or =1000
. This works fine with fixed[blocation:]
and fixed[:blocation]
further below, but not sure how pedantic we should be.
Also not sure if you prefer to require location=BeforeFixed
instead of allowing location=MiddleFixed && blocation=0
, and similarly location=AfterFixed
instead of location=MiddleFixed && blocation=len(fixed or label+context)
.
My personal preference is to do none of these length checks and leave it up to the user, but obviously it's your call.
@@ -51,6 +53,21 @@ def __init__( | |||
if not isinstance(location, CounterLocation): | |||
raise TypeError("location must be of type CounterLocation") | |||
|
|||
if break_location is None and location == CounterLocation.MiddleFixed: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if break_location is None and location == CounterLocation.MiddleFixed: | |
if break_location is None and location is CounterLocation.MiddleFixed: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't completely reviewed this yet, but we should add a changelog entry as well.
- Test CounterLocation.MiddleFixed and blocation=
Thanks, changelog entry added 🚀 |
h.update(fixed) | ||
h.update(counter) | ||
else: | ||
h.update(fixed[: self._break_location]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should validate break location, if it's negative or > len(fixed)
dumb things happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Quite a bit had to change, might be best to review the MR in its entirety again... 😢
tests/hazmat/primitives/utils.py
Outdated
params["fixedinputdata"] = params.pop("databeforectrdata") | ||
params["fixedinputdata"] += params.pop("dataafterctrdata") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
params["fixedinputdata"] = params.pop("databeforectrdata") | |
params["fixedinputdata"] += params.pop("dataafterctrdata") | |
params["fixedinputdata"] = params.pop("databeforectrdata") + params.pop("dataafterctrdata") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I tried this approach, but black
reformats it into:
- params["fixedinputdata"] = params.pop("databeforectrdata")
- params["fixedinputdata"] += params.pop("dataafterctrdata")
+ params["fixedinputdata"] = params.pop(
+ "databeforectrdata"
+ ) + params.pop("dataafterctrdata")
Which I found a little less clear.
Would you still prefer this approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I still prefer that, even if it's a bit stupid :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
@@ -114,17 +135,27 @@ def derive(self, key_material: bytes, prf_output_size: int) -> bytes: | |||
if rounds > pow(2, len(r_bin) * 8) - 1: | |||
raise ValueError("There are too many iterations.") | |||
|
|||
fixed = self._generate_fixed_input() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fine to move outside the loop, the fixed input doesn't change across iterations, except for the counter value.
- Update tests to assert exception is raised when break_location < 0 or > len(fixed) - When asserting for "break_location is ignored when MiddleFixed", use break_location=0 instead of =10, to ensure we don't raise because of break_location > len(fixed) - Assert that the right error messages are returned to the user.
Should be ready for another round of review 🙏 Will refrain from pushing any further changes, unless specifically requested. Cheers |
This looks basically ready, but if we could make |
Thanks for the feedback! TIL about kwarg-only arguments and it's been in Python since 3.0 apparently! Initially I thought you meant to simply move Anyway, PR updated 🚀 |
Thanks @alex and @reaperhulk! Wish more upstreams were this easy to work with 😄 |
Thanks for your work and being patient with all the revisions we asked for!
…On Mon, Aug 15, 2022 at 8:39 AM Jean Paul Galea ***@***.***> wrote:
Thanks @alex <https://github.com/alex> and @reaperhulk
<https://github.com/reaperhulk>!
Wish more upstreams were this easy to work with 😄
—
Reply to this email directly, view it on GitHub
<#7489 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBBSACBIIVW2XZNB3C3VZI27DANCNFSM56ACQI3A>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
All that is necessary for evil to succeed is for good people to do nothing.
|
Hi,
Would you consider adding support for
CounterLocation.MiddleFixed
inKBKDFHMAC
andKBKDFCMAC
?Currently the counter bytes can only be added at the beginning (
CounterLocation.BeforeFixed
) or end (CounterLocation.AfterFixed
) of the input. This patch adds support forCounterLocation.MiddleFixed
, which along withblocation=
, allows the user to specify a particular byte offset where the counter bytes are to be added to input.blocation
is shorthand for "break location".The MR is based off an internal patch that we make use of. It breaks backward compatibility due to the introduction of the new
blocation=
argument. If it's something worth your while, happy to discuss alternative implementations (to remain backward compatible) and help with adding tests and updating documentation.Thank you