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.
 
 
 

105 rivejä
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_ecb_keyexp(&ctx, key);
  26. aes256_ecb(buffer, ctr, 1, &ctx);
  27. aes256_ctx_release(&ctx);
  28. }
  29. void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength);
  30. void nist_kat_init(uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength) {
  31. uint8_t seed_material[48];
  32. assert(security_strength == 256);
  33. memcpy(seed_material, entropy_input, 48);
  34. if (personalization_string) {
  35. for (int i = 0; i < 48; i++) {
  36. seed_material[i] ^= personalization_string[i];
  37. }
  38. }
  39. memset(DRBG_ctx.Key, 0x00, 32);
  40. memset(DRBG_ctx.V, 0x00, 16);
  41. AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V);
  42. DRBG_ctx.reseed_counter = 1;
  43. }
  44. int randombytes(uint8_t *buf, size_t n) {
  45. uint8_t block[16];
  46. int i = 0;
  47. while (n > 0) {
  48. //increment V
  49. for (int j = 15; j >= 0; j--) {
  50. if (DRBG_ctx.V[j] == 0xff) {
  51. DRBG_ctx.V[j] = 0x00;
  52. } else {
  53. DRBG_ctx.V[j]++;
  54. break;
  55. }
  56. }
  57. AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block);
  58. if (n > 15) {
  59. memcpy(buf + i, block, 16);
  60. i += 16;
  61. n -= 16;
  62. } else {
  63. memcpy(buf + i, block, n);
  64. n = 0;
  65. }
  66. }
  67. AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V);
  68. DRBG_ctx.reseed_counter++;
  69. return 0;
  70. }
  71. static void AES256_CTR_DRBG_Update(const uint8_t *provided_data, uint8_t *Key, uint8_t *V) {
  72. uint8_t temp[48];
  73. for (int i = 0; i < 3; i++) {
  74. //increment V
  75. for (int j = 15; j >= 0; j--) {
  76. if (V[j] == 0xff) {
  77. V[j] = 0x00;
  78. } else {
  79. V[j]++;
  80. break;
  81. }
  82. }
  83. AES256_ECB(Key, V, temp + 16 * i);
  84. }
  85. if (provided_data != NULL) {
  86. for (int i = 0; i < 48; i++) {
  87. temp[i] ^= provided_data[i];
  88. }
  89. }
  90. memcpy(Key, temp, 32);
  91. memcpy(V, temp + 32, 16);
  92. }