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.

entropy.c 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. FILE_LICENCE ( GPL2_OR_LATER );
  19. /** @file
  20. *
  21. * Entropy source
  22. *
  23. * This algorithm is designed to comply with ANS X9.82 Part 4 (April
  24. * 2011 Draft) Section 13.3. This standard is unfortunately not
  25. * freely available.
  26. */
  27. #include <stdint.h>
  28. #include <assert.h>
  29. #include <string.h>
  30. #include <ipxe/crypto.h>
  31. #include <ipxe/hash_df.h>
  32. #include <ipxe/entropy.h>
  33. /**
  34. * Get entropy sample
  35. *
  36. * @ret entropy Entropy sample
  37. * @ret rc Return status code
  38. *
  39. * This is the GetEntropy function defined in ANS X9.82 Part 2
  40. * (October 2011 Draft) Section 6.5.1.
  41. */
  42. static int get_entropy ( entropy_sample_t *entropy ) {
  43. noise_sample_t noise;
  44. int rc;
  45. /* Get noise sample */
  46. if ( ( rc = get_noise ( &noise ) ) != 0 )
  47. return rc;
  48. /* We do not use any optional conditioning component */
  49. *entropy = noise;
  50. return 0;
  51. }
  52. /**
  53. * Create next nonce value
  54. *
  55. * @ret nonce Nonce
  56. *
  57. * This is the MakeNextNonce function defined in ANS X9.82 Part 4
  58. * (April 2011 Draft) Section 13.3.4.2.
  59. */
  60. static uint32_t make_next_nonce ( void ) {
  61. static uint32_t nonce;
  62. /* The simplest implementation of a nonce uses a large counter */
  63. nonce++;
  64. return nonce;
  65. }
  66. /**
  67. * Obtain entropy input temporary buffer
  68. *
  69. * @v num_samples Number of entropy samples
  70. * @v tmp Temporary buffer
  71. * @v tmp_len Length of temporary buffer
  72. * @ret rc Return status code
  73. *
  74. * This is (part of) the implementation of the Get_entropy_input
  75. * function (using an entropy source as the source of entropy input
  76. * and condensing each entropy source output after each GetEntropy
  77. * call) as defined in ANS X9.82 Part 4 (April 2011 Draft) Section
  78. * 13.3.4.2.
  79. *
  80. * To minimise code size, the number of samples required is calculated
  81. * at compilation time.
  82. */
  83. int get_entropy_input_tmp ( unsigned int num_samples, uint8_t *tmp,
  84. size_t tmp_len ) {
  85. struct {
  86. uint32_t nonce;
  87. entropy_sample_t sample;
  88. } __attribute__ (( packed )) data;;
  89. uint8_t df_buf[tmp_len];
  90. unsigned int i;
  91. int rc;
  92. /* Enable entropy gathering */
  93. entropy_enable();
  94. /* 3. entropy_total = 0
  95. *
  96. * (Nothing to do; the number of entropy samples required has
  97. * already been precalculated.)
  98. */
  99. /* 4. tmp = a fixed n-bit value, such as 0^n */
  100. memset ( tmp, 0, tmp_len );
  101. /* 5. While ( entropy_total < min_entropy ) */
  102. while ( num_samples-- ) {
  103. /* 5.1. ( status, entropy_bitstring, assessed_entropy )
  104. * = GetEntropy()
  105. * 5.2. If status indicates an error, return ( status, Null )
  106. */
  107. if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
  108. goto err_get_entropy;
  109. /* 5.3. nonce = MakeNextNonce() */
  110. data.nonce = make_next_nonce();
  111. /* 5.4. tmp = tmp XOR
  112. * df ( ( nonce || entropy_bitstring ), n )
  113. */
  114. hash_df ( &data, sizeof ( data ), df_buf, sizeof ( df_buf ) );
  115. for ( i = 0 ; i < tmp_len ; i++ )
  116. tmp[i] ^= df_buf[i];
  117. /* 5.5. entropy_total = entropy_total + assessed_entropy
  118. *
  119. * (Nothing to do; the number of entropy samples
  120. * required has already been precalculated.)
  121. */
  122. }
  123. /* Disable entropy gathering */
  124. entropy_disable();
  125. return 0;
  126. err_get_entropy:
  127. entropy_disable();
  128. return rc;
  129. }