secure_random.c 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* libanode: the Anode C reference implementation
  2. * Copyright (C) 2009-2010 Adam Ierymenko <[email protected]>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU 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, see <http://www.gnu.org/licenses/>. */
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include "impl/aes.h"
  19. #include "impl/misc.h"
  20. #include "anode.h"
  21. #ifdef WINDOWS
  22. #include <windows.h>
  23. #include <wincrypt.h>
  24. #endif
  25. struct AnodeSecureRandomImpl
  26. {
  27. AnodeAesExpandedKey key;
  28. unsigned char state[ANODE_AES_BLOCK_SIZE];
  29. unsigned char block[ANODE_AES_BLOCK_SIZE];
  30. unsigned int ptr;
  31. };
  32. AnodeSecureRandom *AnodeSecureRandom_new()
  33. {
  34. unsigned char keybuf[ANODE_AES_KEY_SIZE + ANODE_AES_BLOCK_SIZE + ANODE_AES_BLOCK_SIZE];
  35. unsigned int i;
  36. struct AnodeSecureRandomImpl *srng;
  37. #ifdef WINDOWS
  38. HCRYPTPROV hProv;
  39. if (CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
  40. CryptGenRandom(hProv,sizeof(keybuf),keybuf);
  41. CryptReleaseContext(hProv,0);
  42. }
  43. #else
  44. FILE *urandf = fopen("/dev/urandom","rb");
  45. if (urandf) {
  46. fread((void *)keybuf,sizeof(keybuf),1,urandf);
  47. fclose(urandf);
  48. }
  49. #endif
  50. for(i=0;i<sizeof(keybuf);++i)
  51. keybuf[i] ^= (unsigned char)(Anode_rand() >> 5);
  52. srng = malloc(sizeof(struct AnodeSecureRandomImpl));
  53. Anode_aes256_expand_key(keybuf,&srng->key);
  54. for(i=0;i<ANODE_AES_BLOCK_SIZE;++i)
  55. srng->state[i] = keybuf[ANODE_AES_KEY_SIZE + i];
  56. for(i=0;i<ANODE_AES_BLOCK_SIZE;++i)
  57. srng->block[i] = keybuf[ANODE_AES_KEY_SIZE + ANODE_AES_KEY_SIZE + i];
  58. srng->ptr = ANODE_AES_BLOCK_SIZE;
  59. return (AnodeSecureRandom *)srng;
  60. }
  61. void AnodeSecureRandom_gen_bytes(AnodeSecureRandom *srng,void *buf,long count)
  62. {
  63. long i,j;
  64. for(i=0;i<count;++i) {
  65. if (((struct AnodeSecureRandomImpl *)srng)->ptr == ANODE_AES_BLOCK_SIZE) {
  66. Anode_aes256_encrypt(&((struct AnodeSecureRandomImpl *)srng)->key,((struct AnodeSecureRandomImpl *)srng)->state,((struct AnodeSecureRandomImpl *)srng)->state);
  67. for(j=0;j<ANODE_AES_KEY_SIZE;++j)
  68. ((struct AnodeSecureRandomImpl *)srng)->block[j] ^= ((struct AnodeSecureRandomImpl *)srng)->state[j];
  69. ((struct AnodeSecureRandomImpl *)srng)->ptr = 0;
  70. }
  71. ((unsigned char *)buf)[i] = ((struct AnodeSecureRandomImpl *)srng)->block[((struct AnodeSecureRandomImpl *)srng)->ptr++];
  72. }
  73. }
  74. void AnodeSecureRandom_delete(AnodeSecureRandom *srng)
  75. {
  76. free(srng);
  77. }