aesrand.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. #include <stdlib.h>
  9. #include <stdint.h>
  10. #include <assert.h>
  11. #include <string.h>
  12. #include "rijndael-alg-fst.h"
  13. #include "random.h"
  14. #include "logger.h"
  15. #include "xalloc.h"
  16. #include "aesrand.h"
  17. #define AES_ROUNDS 10
  18. #define AES_BLOCK_WORDS 4
  19. #define AES_KEY_BYTES 16
  20. #define AES_KEY_BITS (AES_KEY_BYTES*8)
  21. #define OUTPUT_BYTES 16
  22. struct aesrand {
  23. uint32_t input[AES_BLOCK_WORDS];
  24. uint32_t sched[(AES_ROUNDS+1)*4];
  25. uint8_t output[OUTPUT_BYTES];
  26. };
  27. static aesrand_t* _aesrand_init(uint8_t *key)
  28. {
  29. aesrand_t *aes = xmalloc(sizeof(aesrand_t));
  30. memset(&aes->input, 0, AES_BLOCK_WORDS*4);
  31. if (rijndaelKeySetupEnc(aes->sched, key, AES_KEY_BITS) != AES_ROUNDS) {
  32. log_fatal("aesrand", "could not initialize AES key");
  33. }
  34. memset(aes->output, 0, OUTPUT_BYTES);
  35. return aes;
  36. }
  37. aesrand_t* aesrand_init_from_seed(uint64_t seed)
  38. {
  39. uint8_t key[AES_KEY_BYTES];
  40. memset(key, 0, AES_KEY_BYTES);
  41. for (uint8_t i = 0; i < sizeof(seed); ++i) {
  42. key[i] = (uint8_t) ((seed >> 8*i) & 0xFF);
  43. }
  44. return _aesrand_init(key);
  45. }
  46. aesrand_t* aesrand_init_from_random()
  47. {
  48. uint8_t key[AES_KEY_BYTES];
  49. if (!random_bytes(key, AES_KEY_BYTES)) {
  50. log_fatal("aesrand", "Couldn't get random bytes");
  51. }
  52. return _aesrand_init(key);
  53. }
  54. uint64_t aesrand_getword(aesrand_t *aes)
  55. {
  56. memcpy(aes->input, aes->output, sizeof(aes->input));
  57. rijndaelEncrypt(aes->sched, AES_ROUNDS,
  58. (uint8_t *)aes->input, aes->output);
  59. uint64_t retval;
  60. memcpy(&retval, aes->output, sizeof(retval));
  61. return retval;
  62. }