I’ve printed the offset of index used for mbedtls_test_entropy_func() after every call. Here are the values:
**For SHA-1:**
md size = 20
Before mbedtls_hmac_drbg_seed() : 0
After mbedtls_hmac_drbg_seed() : 24
After mbedtls_hmac_drbg_random_with_add 1() : 40
========================================
**For SHA-256:**
md size = 32
Before mbedtls_hmac_drbg_seed() : 0
After mbedtls_hmac_drbg_seed() : 48
After mbedtls_hmac_drbg_random_with_add 1() : 80
Within 1 request file I’ve tests with SHA-1. SHA-256 and SHA-512. So I should be able to test any variant of SHA.
The #defines in config file are shown below:
The offsets don’t seem right to me. I’m using the same mbedtls_test_entropy_func() as I used for CTR_DRBG ( I’ve replicated mbedtls_test_entropy_func () from ctr_drbg_validate_internal ()).
* from the entropy source. See Sect 8.6.7 in SP800-90A. */
if( use_nonce )
{
/* Note: We don't merge the two calls to f_entropy() in order
* to avoid requesting too much entropy from f_entropy()
* at once. Specifically, if the underlying digest is not
* SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
* is larger than the maximum of 32 Bytes that our own
* entropy source implementation can emit in a single
* call in configurations disabling SHA-512. */
if( ( ret = ctx->f_entropy( ctx->p_entropy,
seed + seedlen,
ctx->entropy_len / 2 ) ) != 0 )
so, for SHA1 hmac_drbg, your offset should be 16 + 8 = 24 , and for SHA256, it should be 32 + 16 = 48 , as the results you are seeing. The reasoning for these values are in the standards mentioned in the comments.
Regards,
Mbed TLS Support
Ron
@roneld01: Thanks for the wonderful explanation.
Now I’ve updated my code to look like hmac_drbg you mentioned in the comment above. I’m using hmac_drbg_pr() as my reference.
My mbedtls_test_entropy_func() now matches whatever is in that file. Apart from that, all my calls match hmac_drbg_pr() from the file you mentioned.
ctx->len seems to be wrong. May be that’s what is causing the error?
entropy_ctx *ctx = (entropy_ctx *) data;
This line is not assigning anything to ctx->len is it?
In mbedtls_test_entropy_func() we just declare ctx of type entropy_ctx and assign data to it but nothing is assigned to ctx->len.
Also wanted to check one more thing.
Can you please confirm what’s the answer you should be getting while using the below inputs (listed what responses I get with OpenSSL and mbedTLS):
@roneld01: Hi, can you please confirm if this sounds right?
For SHA-1, after mbedtls_hmac_drbg_seed(), the entropy offset is 16+8 which is 24 (like you said in your previous comment) and that’s what I see.
And after first call to mbedtls_hmac_drbg_random_with_add() the offset is increased by 16, so the total is 40.
Does that sound right? That means for second mbedtls_hmac_drbg_random_with_add() there’s just 8 bytes left?
So the entropy input would be [6878f9ea4ff71310b5e1eb74d12c50a4c924feaafcfacaaf76e558351963eddca9704c677723b480c10c878636167c0d].
So for the mbedtls_hmac_drbg_seed() 6878f9ea4ff71310b5e1eb74d12c50a4c924feaafcfacaaf is used (24 bytes).
For first mbedtls_hmac_drbg_random_with_add() 76e558351963eddca9704c677723b480 is used (16 bytes).
For second mbedtls_hmac_drbg_random_with_add() just c10c878636167c0d is left (8 bytes).
Hi @athorath
As for your comparison between OpenSSL and Mbed TLS results, you should be comparing with test vectors, as it is not an efficient way to know where and if there is an issue.
And after first call to mbedtls_hmac_drbg_random_with_add() the offset is increased by 16, so the total is 40. Does that sound right?
Yes, the initial seeding uses nonce, which adds additional 8 bytes to the entropy, while the mbedtls_hmac_drbg_random_with_add() calls mbedtls_hmac_drbg_reseed() in case PR is on. Please try callingmbedtls_hmac_drbg_set_prediction_resistance() with MBEDTLS_HMAC_DRBG_PR_OFF and compare the outputs wiht openSSL.
@roneld01: Thanks for the comment.
I agree with your statement that I should be comparing with test vector. I’m looking at test_suite_hmac_drbg.pr.data for reference and uncovered a problem where I was not considering the nonce. So that suggestion helped me with one of the issues.
Now I’m using the same inputs as mentioned in the above file. Updated my request file from test_vector. I’m using the first test instance. The one where input would be “a0c9ab58f1e2e5a4de3ebd4ff73e9c5b64efd8ca028cf81148a584fe69ab5aee42aa4d42176099d45e1397dc404d86a37bf55954756951e4” ( both in test_vector and test_suite_hmac_drbg.pr.data)
So with this update, I think my offsets are perfectly matching what you told earlier.
DEBUG entropy_inputs : [a0c9ab58f1e2e5a4de3ebd4ff73e9c5b64efd8ca028cf81148a584fe69ab5aee42aa4d42176099d45e1397dc404d86a37bf55954756951e4]
Before mbedtls_hmac_drbg_seed() : 0
After mbedtls_hmac_drbg_seed() : 24
After mbedtls_hmac_drbg_random_with_add 1() : 40
After mbedtls_hmac_drbg_random_with_add 2() : 56
However, the output should’ve been “9a00a2d00ed59bfe31ecb1399b608148d1969d250d3c1e94101098129325cab8fccc2d54731970c0107aa4892519955e4bc6001d7f4e6a2bf8a301ab46055c09a67188f1a740eef3e15c029b44af0344” but I get “e419b73378e43b4a450aa8472e2c3bd70a5f71a160b2f76597489224f2af83e8f600abdb13bf9c3ae60990428fe29aa1352265b4a3fa658a696e60a94415f09303f4083aeb1ad6b11cd645383e0a33a3”.
I’m doing the prediction resistance true scenario hence cannot turn it off. But apart from that my calls match hmac_drbg_pr(). Please let me know if you spot any errors. I can’t seem to find anything wrong at all but still get incorrect result.
Hi @athorath
I do see some issues, but they should not affect this specific test, as both additional input lengths are 0, and nonce_pers is also empty string.
However, the issues I see are:
nonce_pers shoujld not be measured with strlen. ALthough it is a personelization string, you should consider it as a hex binary, and use a length parameter, in case there is hte zero bytes as part of the string. Since in this test, the personelization string length is 0, it shouldn’t affect this failure.
2.For both additional input,s you use the same length :params->addInputLength. Is this always the case? Anyway, in this specific use case, the additional input lengths are 0 as well, so it shouldn’t effect.
Since, as you said, this test vector is also used in the test_suite_hmac_drbg.pr successfully, you should compare your code with the code in the test used by Mbed TLS.
Have you called mbedtls_hmac_drbg_init( &hmac_ctx ); ?
Have you verified that in fact strlen(nonce_pers) is 0?
Have you verified that params->addInputLength is 0?
Have you checked the two return codes (rc) in your calls?
Have you called mbedtls_hmac_drbg_init( &hmac_ctx ); ? Yes I have
Have you verified that in fact strlen(nonce_pers) is 0? nonce_pers is a concatenation of nonce and personalization string. In my testcase, personalization string is 0 length but nonce is not null (shown below);
Have you verified that params->addInputLength is 0? Yes
Have you checked the two return codes ( rc ) in your calls? (shown below)
Note that the initial seeding should receive only the PersonalizationString (which is length 0 in your case), and the input for the test, as Entropy, should receive only the nonce, meaning: EntropyInput || Nonce || EntropyInputPR || EntropyInputPR
Is this what you did?
So, I believe the issue you are having is becasue you are sending the nonce to mbedtls_hmac_drbg_seed() as well.
Regards
Correct the format I’m using is EntropyInput || Nonce_Pers || EntropyInputPR || EntropyInputPR
In the above example "Nonce_Pers " contains only Nonce as pers string is 0 length. But if pers string length is not 0, then it’ll be (nonce||pers_string).
Regarding your comment:
I agree that could be the issue. I’ve passed in NULL and results looks okay.
I’ll try it out for other scenarios.