drbg.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * (c) 2015-2017 Marcos Del Sol Vives
  3. * (c) 2016 javiMaD
  4. *
  5. * SPDX-License-Identifier: MIT
  6. */
  7. #include "drbg.h"
  8. #include <assert.h>
  9. #include <string.h>
  10. #include <mbedtls/md.h>
  11. void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize) {
  12. assert(ctx != NULL);
  13. assert(hmacKey != NULL);
  14. assert(seed != NULL);
  15. assert(seedSize <= NFC3D_DRBG_MAX_SEED_SIZE);
  16. // Initialize primitives
  17. ctx->used = false;
  18. ctx->iteration = 0;
  19. ctx->bufferSize = sizeof(ctx->iteration) + seedSize;
  20. // The 16-bit counter is prepended to the seed when hashing, so we'll leave 2 bytes at the start
  21. memcpy(ctx->buffer + sizeof(uint16_t), seed, seedSize);
  22. // Initialize underlying HMAC context
  23. mbedtls_md_init(&ctx->hmacCtx);
  24. mbedtls_md_setup(&ctx->hmacCtx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);
  25. mbedtls_md_hmac_starts(&ctx->hmacCtx, hmacKey, hmacKeySize);
  26. }
  27. void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * output) {
  28. assert(ctx != NULL);
  29. assert(output != NULL);
  30. if (ctx->used) {
  31. // If used at least once, reinitialize the HMAC
  32. mbedtls_md_hmac_reset(&ctx->hmacCtx);
  33. } else {
  34. ctx->used = true;
  35. }
  36. // Store counter in big endian, and increment it
  37. ctx->buffer[0] = ctx->iteration >> 8;
  38. ctx->buffer[1] = ctx->iteration >> 0;
  39. ctx->iteration++;
  40. // Do HMAC magic
  41. mbedtls_md_hmac_update(&ctx->hmacCtx, ctx->buffer, ctx->bufferSize);
  42. mbedtls_md_hmac_finish(&ctx->hmacCtx, output);
  43. }
  44. void nfc3d_drbg_cleanup(nfc3d_drbg_ctx * ctx) {
  45. assert(ctx != NULL);
  46. mbedtls_md_free(&ctx->hmacCtx);
  47. }
  48. 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) {
  49. uint8_t temp[NFC3D_DRBG_OUTPUT_SIZE];
  50. nfc3d_drbg_ctx rngCtx;
  51. nfc3d_drbg_init(&rngCtx, hmacKey, hmacKeySize, seed, seedSize);
  52. while (outputSize > 0) {
  53. if (outputSize < NFC3D_DRBG_OUTPUT_SIZE) {
  54. nfc3d_drbg_step(&rngCtx, temp);
  55. memcpy(output, temp, outputSize);
  56. break;
  57. }
  58. nfc3d_drbg_step(&rngCtx, output);
  59. output += NFC3D_DRBG_OUTPUT_SIZE;
  60. outputSize -= NFC3D_DRBG_OUTPUT_SIZE;
  61. }
  62. nfc3d_drbg_cleanup(&rngCtx);
  63. }