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

Add LMS implementation #4826

Merged
merged 104 commits into from
Oct 14, 2022
Merged

Conversation

RcColes
Copy link
Contributor

@RcColes RcColes commented Aug 2, 2021

Description

This adds the LMS stateful-hash asymmetric signature scheme, based on RFC8554 (https://datatracker.ietf.org/doc/html/rfc8554). It also adds the required LM-OTS implementation.

It's intended as a cut-down implementation, which is focused primarily on firmware asset validation (Though it is suitable for many generic purposes). The main limitation is that only one parameter-set is supported (SHA256_H10), with leads to each private key being able to be used for up to 1024 signatures. Supporting only one parameter-set leads to saving in complexity in memory allocation, and excludes the larger parameter-sets which require complex optimizations in order to be used in constrained memory implementations. The parameter-set with a merkle tree-height of 5 was discounted since 32 messages is likely to be too constrained where keys are embedded in devices and cannot be easily changed.

Status

READY

Requires Backporting

NO

Migrations

NO (only additions to the API, no changes)

@gilles-peskine-arm
Copy link
Contributor

Thank you for contributing this! As this is a substantial amount cryptography code, we'll need to schedule time to review for it.

In the meantime, please fix the CI issues on Travis. Once Travis passes, if you need help with the Jenkins failures, post a comment and we'll help. The Jenkins logs are unfortunately not public, all you can see is a truncated list of names of failing jobs.

@gilles-peskine-arm gilles-peskine-arm added Community component-crypto Crypto primitives and low-level interfaces needs-ci Needs to pass CI tests needs-review Every commit must be reviewed by at least two team members, needs-reviewer This PR needs someone to pick it up for review and removed needs-review Every commit must be reviewed by at least two team members, needs-reviewer This PR needs someone to pick it up for review labels Aug 2, 2021
@gilles-peskine-arm gilles-peskine-arm added the size-l Estimated task size: large (2w+) label Aug 2, 2021
@RcColes RcColes force-pushed the development branch 2 times, most recently from 9b48ede to 0c69087 Compare August 3, 2021 12:15
@RcColes
Copy link
Contributor Author

RcColes commented Aug 4, 2021

Right, I think I've fixed most of the CI failures now. There seem to be some random failures occurring in the windows build which I think are CI-related and therefore should be resolved by a re-run.

The main remaining issue is a trickier one, since it's related to one of the algorithmic disadvantages of LMS. Each LMOTS key is ~1KiB, and using H=10 each LMS key contains 1024 LMOTS private keys for ~1MiB. As far as I can tell, this size can't be allocated on the heap by some of the tests which is causing the remaining failures.

There are a few options to fix this:

  1. We could change the parameter-set to H=5, which has 32 OTS keys per LMS key and hence uses 2^5 times less memory. The downside here is that only 32 signatures can be done with each LMS key, which makes it far less useful, particularly, in firmware validation (since you would reasonably expect more than 32 upgrades).
  2. There are some algorithmic options for generating the OTS keys at each signature. This adds some considerable complexity, which I'm quite concerned about.
  3. We could try to get the tests to be able to allocate more memory. This doesn't actually solve the problem that most embedded devices would fail to allocate a megabyte of space however. There is an argument that we can just expect signing to not be done on the device (and instead be done on a PC which can allocate a megabyte easily), but I'm not sure how reasonable that is. This doesn't cause an issues with verify-only implementations, since the context only allocates the space once a private key is generated.

None of the options is clearly favorable however. I'd be interested in your thoughts on this @gilles-peskine-arm

@gilles-peskine-arm
Copy link
Contributor

gilles-peskine-arm commented Aug 4, 2021

While we don't have a set maximum amount of memory that tests must fit in, we do expect the tests to run on “reasonable” microcontroller boards. A board with 1MB of RAM would definitely be considered reasonable.

There is a facility in the test suite to skip tests that need a large amount of memory: ASSERT_ALLOC_WEAK. It works well when the test needs to allocate that large amount upfront, but not when the problematic allocation comes from a library function. Can you arrange to use that in signature tests? Or, if it doesn't work as is, something like

ret = mbedtls_lms_alloc();
TEST_ASSUME( ret != ERR_OUT_OF_MEMORY );
TEST_ASSERT( ret == 0 );

rather than

TEST_ASSERT( mbedtls_lms_alloc() == 0 );

@RcColes
Copy link
Contributor Author

RcColes commented Aug 4, 2021

Ah yes, returning an OOM error is a good idea, thanks.

@RcColes RcColes force-pushed the development branch 2 times, most recently from 91ca95e to 03e0d60 Compare August 9, 2021 07:48
@RcColes
Copy link
Contributor Author

RcColes commented Aug 10, 2021

Right, I think that's the CI sorted. Might want to re-tag this one as a needs: review

@hanno-becker hanno-becker added needs-review Every commit must be reviewed by at least two team members, and removed needs-ci Needs to pass CI tests labels Aug 10, 2021
@gilles-peskine-arm gilles-peskine-arm added the needs-reviewer This PR needs someone to pick it up for review label Aug 30, 2021
@gilles-peskine-arm gilles-peskine-arm self-requested a review August 30, 2021 10:28
@daverodgman
Copy link
Contributor

@RcColes looks like there are some test failures in the LMS tests

Copy link
Contributor

@gilles-peskine-arm gilles-peskine-arm left a comment

Choose a reason for hiding this comment

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

Thanks for all the updates. This looks good to me except for a remaining typo in the code snippets to reproduce test data. I'm approving, but I'd prefer to fix this.

Especially since CI found something I didn't.

tests/suites/test_suite_lmots.data Outdated Show resolved Hide resolved
The test data was invalid because it had the extra 4-byte prefix for HSS.
Regenerate it (which produces completely new signatures since it is
randomized).

Rearrange the reproduction instructions for the second test case so that it
shows more clearly how to generate a second signature with the same private
key.

Signed-off-by: Gilles Peskine <[email protected]>
Copy link
Contributor

@gilles-peskine-arm gilles-peskine-arm left a comment

Choose a reason for hiding this comment

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

With Raef's agreement I've pushed a fix for my last two comments, including the issue that caused test failures. It should be all good now. At least, it looks good to me.

@gilles-peskine-arm gilles-peskine-arm added needs-review Every commit must be reviewed by at least two team members, and removed needs-work labels Oct 14, 2022
Copy link
Contributor

@gilles-peskine-arm gilles-peskine-arm left a comment

Choose a reason for hiding this comment

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

I am approving this pull request.

I authored three commits at the end, which someone else needs to review.

@RcColes
Copy link
Contributor Author

RcColes commented Oct 14, 2022

I've reviewed Gilles' last 3 commits, and I approve them

Copy link
Contributor

@d3zd3z d3zd3z left a comment

Choose a reason for hiding this comment

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

This looks good to me. My concerns have been addressed. It will probably need something to get CI to pass, though.

@gilles-peskine-arm
Copy link
Contributor

The failure of all_u16-test_m32_o2 on pr-merge on the internal CI was an infrastructure glitch, and that job passed on OpenCI and on pr-head. So the CI is a pass.

@gilles-peskine-arm gilles-peskine-arm added approved Design and code approved - may be waiting for CI or backports and removed needs-review Every commit must be reviewed by at least two team members, labels Oct 14, 2022
@gilles-peskine-arm gilles-peskine-arm merged commit 8874cd5 into Mbed-TLS:development Oct 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Design and code approved - may be waiting for CI or backports component-crypto Crypto primitives and low-level interfaces priority-high High priority - will be reviewed soon size-l Estimated task size: large (2w+)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants