2 * (c) 2015-2017 Marcos Del Sol Vives
5 * SPDX-License-Identifier: MIT
11 #include "mbedtls/md.h"
13 void nfc3d_drbg_init(nfc3d_drbg_ctx
*ctx
, const uint8_t *hmacKey
, size_t hmacKeySize
, const uint8_t *seed
, size_t seedSize
) {
15 assert(hmacKey
!= NULL
);
17 assert(seedSize
<= NFC3D_DRBG_MAX_SEED_SIZE
);
19 // Initialize primitives
22 ctx
->bufferSize
= sizeof(ctx
->iteration
) + seedSize
;
24 // The 16-bit counter is prepended to the seed when hashing, so we'll leave 2 bytes at the start
25 memcpy(ctx
->buffer
+ sizeof(uint16_t), seed
, seedSize
);
27 // Initialize underlying HMAC context
28 mbedtls_md_init(&ctx
->hmacCtx
);
29 mbedtls_md_setup(&ctx
->hmacCtx
, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256
), 1);
30 mbedtls_md_hmac_starts(&ctx
->hmacCtx
, hmacKey
, hmacKeySize
);
33 void nfc3d_drbg_step(nfc3d_drbg_ctx
*ctx
, uint8_t *output
) {
35 assert(output
!= NULL
);
38 // If used at least once, reinitialize the HMAC
39 mbedtls_md_hmac_reset(&ctx
->hmacCtx
);
44 // Store counter in big endian, and increment it
45 ctx
->buffer
[0] = ctx
->iteration
>> 8;
46 ctx
->buffer
[1] = ctx
->iteration
>> 0;
50 mbedtls_md_hmac_update(&ctx
->hmacCtx
, ctx
->buffer
, ctx
->bufferSize
);
51 mbedtls_md_hmac_finish(&ctx
->hmacCtx
, output
);
54 void nfc3d_drbg_cleanup(nfc3d_drbg_ctx
*ctx
) {
56 mbedtls_md_free(&ctx
->hmacCtx
);
59 void nfc3d_drbg_generate_bytes(const uint8_t *hmacKey
, size_t hmacKeySize
, const uint8_t *seed
, size_t seedSize
, uint8_t *output
, size_t outputSize
) {
60 uint8_t temp
[NFC3D_DRBG_OUTPUT_SIZE
];
62 nfc3d_drbg_ctx rngCtx
;
63 nfc3d_drbg_init(&rngCtx
, hmacKey
, hmacKeySize
, seed
, seedSize
);
65 while (outputSize
> 0) {
66 if (outputSize
< NFC3D_DRBG_OUTPUT_SIZE
) {
67 nfc3d_drbg_step(&rngCtx
, temp
);
68 memcpy(output
, temp
, outputSize
);
72 nfc3d_drbg_step(&rngCtx
, output
);
73 output
+= NFC3D_DRBG_OUTPUT_SIZE
;
74 outputSize
-= NFC3D_DRBG_OUTPUT_SIZE
;
77 nfc3d_drbg_cleanup(&rngCtx
);