You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

104 lines
2.8 KiB

  1. //
  2. // rng.c
  3. //
  4. // Created by Bassham, Lawrence E (Fed) on 8/29/17.
  5. // Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
  6. // Modified for liboqs by Douglas Stebila
  7. //
  8. #include <assert.h>
  9. #include <string.h>
  10. #include "aes.h"
  11. #include "randombytes.h"
  12. typedef struct {
  13. uint8_t Key[32];
  14. uint8_t V[16];
  15. int reseed_counter;
  16. } AES256_CTR_DRBG_struct;
  17. static AES256_CTR_DRBG_struct DRBG_ctx;
  18. static void AES256_CTR_DRBG_Update(const uint8_t *provided_data, uint8_t *Key, uint8_t *V);
  19. // Use whatever AES implementation you have. This uses AES from openSSL library
  20. // key - 256-bit AES key
  21. // ctr - a 128-bit plaintext value
  22. // buffer - a 128-bit ciphertext value
  23. static void AES256_ECB(uint8_t *key, uint8_t *ctr, uint8_t *buffer) {
  24. aes256ctx ctx;
  25. aes256_keyexp(&ctx, key);
  26. aes256_ecb(buffer, ctr, 1, &ctx);
  27. }
  28. void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength);
  29. void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength) {
  30. uint8_t seed_material[48];
  31. assert(security_strength == 256);
  32. memcpy(seed_material, entropy_input, 48);
  33. if (personalization_string) {
  34. for (int i = 0; i < 48; i++) {
  35. seed_material[i] ^= personalization_string[i];
  36. }
  37. }
  38. memset(DRBG_ctx.Key, 0x00, 32);
  39. memset(DRBG_ctx.V, 0x00, 16);
  40. AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V);
  41. DRBG_ctx.reseed_counter = 1;
  42. }
  43. int randombytes(uint8_t *buf, size_t xlen) {
  44. uint8_t block[16];
  45. int i = 0;
  46. while (xlen > 0) {
  47. //increment V
  48. for (int j = 15; j >= 0; j--) {
  49. if (DRBG_ctx.V[j] == 0xff) {
  50. DRBG_ctx.V[j] = 0x00;
  51. } else {
  52. DRBG_ctx.V[j]++;
  53. break;
  54. }
  55. }
  56. AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block);
  57. if (xlen > 15) {
  58. memcpy(buf + i, block, 16);
  59. i += 16;
  60. xlen -= 16;
  61. } else {
  62. memcpy(buf + i, block, xlen);
  63. xlen = 0;
  64. }
  65. }
  66. AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V);
  67. DRBG_ctx.reseed_counter++;
  68. return 0;
  69. }
  70. static void AES256_CTR_DRBG_Update(const uint8_t *provided_data, uint8_t *Key, uint8_t *V) {
  71. uint8_t temp[48];
  72. for (int i = 0; i < 3; i++) {
  73. //increment V
  74. for (int j = 15; j >= 0; j--) {
  75. if (V[j] == 0xff) {
  76. V[j] = 0x00;
  77. } else {
  78. V[j]++;
  79. break;
  80. }
  81. }
  82. AES256_ECB(Key, V, temp + 16 * i);
  83. }
  84. if (provided_data != NULL) {
  85. for (int i = 0; i < 48; i++) {
  86. temp[i] ^= provided_data[i];
  87. }
  88. }
  89. memcpy(Key, temp, 32);
  90. memcpy(V, temp + 32, 16);
  91. }