Release v4.9237 - Ice Coffee :coffee:
[RRG-proxmark3.git] / client / deps / amiitool / drbg.c
blobc1297920f875433a9e0587ee9226a115bedf62f6
1 /*
2 * (c) 2015-2017 Marcos Del Sol Vives
3 * (c) 2016 javiMaD
5 * SPDX-License-Identifier: MIT
6 */
8 #include "drbg.h"
9 #include <assert.h>
10 #include <string.h>
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) {
14 assert(ctx != NULL);
15 assert(hmacKey != NULL);
16 assert(seed != NULL);
17 assert(seedSize <= NFC3D_DRBG_MAX_SEED_SIZE);
19 // Initialize primitives
20 ctx->used = false;
21 ctx->iteration = 0;
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) {
34 assert(ctx != NULL);
35 assert(output != NULL);
37 if (ctx->used) {
38 // If used at least once, reinitialize the HMAC
39 mbedtls_md_hmac_reset(&ctx->hmacCtx);
40 } else {
41 ctx->used = true;
44 // Store counter in big endian, and increment it
45 ctx->buffer[0] = ctx->iteration >> 8;
46 ctx->buffer[1] = ctx->iteration >> 0;
47 ctx->iteration++;
49 // Do HMAC magic
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) {
55 assert(ctx != NULL);
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);
69 break;
72 nfc3d_drbg_step(&rngCtx, output);
73 output += NFC3D_DRBG_OUTPUT_SIZE;
74 outputSize -= NFC3D_DRBG_OUTPUT_SIZE;
77 nfc3d_drbg_cleanup(&rngCtx);