CTR_DRBG: grab a nonce from the entropy source if needed #305
No reviewers
Labels
No labels
api-spec
bug
CLA requested
CLA valid
compliance
DO NOT MERGE
duplicate
enhancement
feature branch
good first issue
HEADER FORMATTING ISSUE
help wanted
Information
invalid
Jira status: AWAITING REVIEW
Jira status: CLOSED
Jira status: DONE
Jira status: IN PROGRESS
Jira status: IN REVIEW
Jira status: OPEN
Jira status: REOPENED
Jira status: RESOLVED
mirrored
mirror internally
needs: backports
needs: ci
needs: design review
needs: preceding PR
needs: review
needs: work
notabug
open for community contribution
Product Backlog
question
ready for merge
security
stale
type: bug
type: enhancement
type: question
web pages
wontfix
writing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-ARMmbed/mbed-crypto!305
Loading…
Reference in a new issue
No description provided.
Delete branch "ctr_drbg-grab_nonce_from_entropy-set_nonce_length"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
CTR_DRBG grabs as many bytes of entropy for the initial seeding as for reseeds. This is not compliant with NIST SP 800-90A when the entropy length is too small to cover both the entropy itself and a nonce, unless the caller passes a nonce in the
customparameter.Fix this by making a second call to the entropy function to grab enough entropy for a random nonce (half the entropy length, per SP 800-90A).
To maximize backward compatibility, do not make a second call to the entropy function if the entropy length is sufficient to cover a nonce. Thus the only combination of boolean compile-time option that leads to making a second call to the entropy function is:
An alternative design choice would be to always grab a nonce whose length is half the entropy length, like the HMAC_DRBG module does. This would be a simpler design but I preferred this solution which only adds a few bytes of code and which has less risk of breaking someone's workflow.
Test run on a merge of this PR and #291 to get coverage of relevant compilation settings that are currently not covered: https://jenkins-internal.mbed.com/job/mbedtls-psa-release-new/592/ → passed except for some Mbed OS jobs which are also failing in this PR.
Some commits in this PR are minor bugs which I've fixed in the backports of #299 (https://github.com/ARMmbed/mbedtls/pull/2894 and https://github.com/ARMmbed/mbedtls/pull/2895):
ctr_drbg.handhmac_drbg.hneeds to be backported, and I did so in the backport PRs which have not been merged yet. The one inctr_drbg.cwas already present in a suitably modified form in the 2.16 backport of #299 and is not applicable to 2.7.The rest of the PR is a behavior change that should not be backported, and some very minor test improvements that do not need to be backported.
Internal ref: IOTCRYPT-180
I would like to ask for clarification of two issues I have pointed out in the comments. In general the PR looks good though.
@ -381,15 +416,33 @@ exit:return( ret );}Becoming static, this no longer needs the
mbedtls_prefix. Is it supposed to be left like this e.g. for maintaining the ABI compatibility even for the internal API?@ -191,0 +216,4 @@TEST_ASSERT( test_offset_idx - last_idx >= byte_strength );exit:mbedtls_ctr_drbg_free( &ctx );test_offset_idxdoesn't seem to be updated anywhere in this test case. Therefore, neither this, nor the last assertion operate on anything depending on the runtime other than the function argument.@ -381,15 +416,33 @@ exit:return( ret );}It's an internal function, so it doesn't need an
mbedtls_xxxprefix, but I think using the prefix makes the code easier to read. For example you can search formbedtls_ctr_drbg_reseed(in the file, or ingit grep) and it'll findmbedtls_ctr_drbg_reseed_internal.@ -191,0 +216,4 @@TEST_ASSERT( test_offset_idx - last_idx >= byte_strength );exit:mbedtls_ctr_drbg_free( &ctx );It's a global variable.
mbedtls_test_entropy_funcupdates it.Looking at the test results, many Mbed OS jobs are failing. This isn't just known bugs or ordinary flakiness of some boards on the CI: all the benchmark jobs are failing on K64F with an error that's directly related to this PR (https://jenkins-internal.mbed.com/job/mbed-crypto-pr/job/PR-305-merge/4/execution/node/3923/log/), and all the CY8CKIT jobs are failing (not just the known issue with IAR) for a reason I don't understand.
Thanks for addressing my comments! I have also reviewed the two new commits. Still looks good.
CI failures:
getting-started-CY8CKIT_062_WIFI_BT-IARfails. This is a known issue that existed before this PR.CY8CKIT_062_WIFI_BTjobs are failing, but only on -merge, not on -head: authcrypt-CY8CKIT_062_WIFI_BT-ARM, authcrypt-CY8CKIT_062_WIFI_BT-ARM, authcrypt-CY8CKIT_062_WIFI_BT-ARM, authcrypt-CY8CKIT_062_WIFI_BT-IAR, authcrypt-CY8CKIT_062_WIFI_BT-IAR, authcrypt-CY8CKIT_062_WIFI_BT-IAR, authcrypt-CY8CKIT_062_WIFI_BT-IAR, hashing-CY8CKIT_062_WIFI_BT-IAR, hashing-CY8CKIT_062_WIFI_BT-IAR, hashing-CY8CKIT_062_WIFI_BT-IAR, authcrypt-CY8CKIT_062_WIFI_BT-ARM, authcrypt-CY8CKIT_062_WIFI_BT-ARM, authcrypt-CY8CKIT_062_WIFI_BT-GCC_ARM, hashing-CY8CKIT_062_WIFI_BT-ARM, hashing-CY8CKIT_062_WIFI_BT-ARM. I don't understand what's going on there.The non-reproducible CY8CKIT_062_WIFI_BT failures look like one board is non-responsive and other boards are working. There are enough passes to show that this PR is ok.
CI has at least one bad Cypress board in it causing tests to not complete successfully. I manually tested our mbed-os-example-mbed-crypto/getting-started example on
CY8CKIT_062_WIFI_BTwithGCC_ARMand the merge result of this PR withdevelopment. This run went well.With
ARMC6, the example run hung after printing the following, which is a known issue:This is due to the version of
ARMC6(Component: ARM Compiler 6.10.1 Tool: armclang [5d143200]) having an optimizer bug. Using a custom build profile to set cflags to-O1, the example run completes successfully.PR looks good to me
@gilles-peskine-arm What is the meaning of the
fixup!prefix in the commit messages? (I just find it confusing, because I usually mark commits like that if I later want to rebase and fixup some other commits with them.)@yanesca It's a git convention and feature indicating that the commit is an amendment to the previous commit with the same title minus the
fixup!prefix. This convention is built into the--autosquashoption ofgit rebase.Normally a fixup is only in work in progress and shouldn't be pushed: you should rebase and squash the fixup before pushing. But here the defective commit was already present in the history, so the amendment can't be squashed.