hmac_drbg.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. * Copyright (c) 2019 Andrew R. Kozlik
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included
  12. * in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
  18. * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include "hmac_drbg.h"
  23. #include <string.h>
  24. #include "memzero.h"
  25. #include "sha2.h"
  26. static void update_k(
  27. HMAC_DRBG_CTX* ctx,
  28. uint8_t domain,
  29. const uint8_t* data1,
  30. size_t len1,
  31. const uint8_t* data2,
  32. size_t len2) {
  33. // Computes K = HMAC(K, V || domain || data1 || data 2).
  34. // First hash operation of HMAC.
  35. uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0};
  36. if(len1 + len2 == 0) {
  37. ctx->v[8] = 0x00800000;
  38. ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8;
  39. sha256_Transform(ctx->idig, ctx->v, h);
  40. ctx->v[8] = 0x80000000;
  41. ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8;
  42. } else {
  43. SHA256_CTX sha_ctx = {0};
  44. memcpy(sha_ctx.state, ctx->idig, SHA256_DIGEST_LENGTH);
  45. for(size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) {
  46. #if BYTE_ORDER == LITTLE_ENDIAN
  47. REVERSE32(ctx->v[i], sha_ctx.buffer[i]);
  48. #else
  49. sha_ctx.buffer[i] = ctx->v[i];
  50. #endif
  51. }
  52. ((uint8_t*)sha_ctx.buffer)[SHA256_DIGEST_LENGTH] = domain;
  53. sha_ctx.bitcount = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8;
  54. sha256_Update(&sha_ctx, data1, len1);
  55. sha256_Update(&sha_ctx, data2, len2);
  56. sha256_Final(&sha_ctx, (uint8_t*)h);
  57. #if BYTE_ORDER == LITTLE_ENDIAN
  58. for(size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) REVERSE32(h[i], h[i]);
  59. #endif
  60. }
  61. // Second hash operation of HMAC.
  62. h[8] = 0x80000000;
  63. h[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8;
  64. sha256_Transform(ctx->odig, h, h);
  65. // Precompute the inner digest and outer digest of K.
  66. h[8] = 0;
  67. h[15] = 0;
  68. for(size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) {
  69. h[i] ^= 0x36363636;
  70. }
  71. sha256_Transform(sha256_initial_hash_value, h, ctx->idig);
  72. for(size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) {
  73. h[i] = h[i] ^ 0x36363636 ^ 0x5c5c5c5c;
  74. }
  75. sha256_Transform(sha256_initial_hash_value, h, ctx->odig);
  76. memzero(h, sizeof(h));
  77. }
  78. static void update_v(HMAC_DRBG_CTX* ctx) {
  79. sha256_Transform(ctx->idig, ctx->v, ctx->v);
  80. sha256_Transform(ctx->odig, ctx->v, ctx->v);
  81. }
  82. void hmac_drbg_init(
  83. HMAC_DRBG_CTX* ctx,
  84. const uint8_t* entropy,
  85. size_t entropy_len,
  86. const uint8_t* nonce,
  87. size_t nonce_len) {
  88. uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0};
  89. // Precompute the inner digest and outer digest of K = 0x00 ... 0x00.
  90. memset(h, 0x36, sizeof(h));
  91. sha256_Transform(sha256_initial_hash_value, h, ctx->idig);
  92. memset(h, 0x5c, sizeof(h));
  93. sha256_Transform(sha256_initial_hash_value, h, ctx->odig);
  94. // Let V = 0x01 ... 0x01.
  95. memset(ctx->v, 1, SHA256_DIGEST_LENGTH);
  96. for(size_t i = 9; i < 15; i++) ctx->v[i] = 0;
  97. ctx->v[8] = 0x80000000;
  98. ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8;
  99. hmac_drbg_reseed(ctx, entropy, entropy_len, nonce, nonce_len);
  100. memzero(h, sizeof(h));
  101. }
  102. void hmac_drbg_reseed(
  103. HMAC_DRBG_CTX* ctx,
  104. const uint8_t* entropy,
  105. size_t len,
  106. const uint8_t* addin,
  107. size_t addin_len) {
  108. update_k(ctx, 0, entropy, len, addin, addin_len);
  109. update_v(ctx);
  110. if(len == 0) return;
  111. update_k(ctx, 1, entropy, len, addin, addin_len);
  112. update_v(ctx);
  113. }
  114. void hmac_drbg_generate(HMAC_DRBG_CTX* ctx, uint8_t* buf, size_t len) {
  115. size_t i = 0;
  116. while(i < len) {
  117. update_v(ctx);
  118. for(size_t j = 0; j < 8 && i < len; j++) {
  119. uint32_t r = ctx->v[j];
  120. for(int k = 24; k >= 0 && i < len; k -= 8) {
  121. buf[i++] = (r >> k) & 0xFF;
  122. }
  123. }
  124. }
  125. update_k(ctx, 0, NULL, 0, NULL, 0);
  126. update_v(ctx);
  127. }