aes.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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 "aes.h"
  17. void Anode_cmac_aes256(
  18. const AnodeAesExpandedKey *expkey,
  19. const unsigned char *restrict data,
  20. unsigned long data_len,
  21. unsigned char *restrict mac)
  22. {
  23. unsigned char cbc[16];
  24. unsigned char pad[16];
  25. const unsigned char *restrict pos = data;
  26. unsigned long i;
  27. unsigned long remaining = data_len;
  28. unsigned char c;
  29. ((uint64_t *)((void *)cbc))[0] = 0ULL;
  30. ((uint64_t *)((void *)cbc))[1] = 0ULL;
  31. while (remaining >= 16) {
  32. ((uint64_t *)((void *)cbc))[0] ^= ((uint64_t *)((void *)pos))[0];
  33. ((uint64_t *)((void *)cbc))[1] ^= ((uint64_t *)((void *)pos))[1];
  34. pos += 16;
  35. if (remaining > 16)
  36. Anode_aes256_encrypt(expkey,cbc,cbc);
  37. remaining -= 16;
  38. }
  39. ((uint64_t *)((void *)pad))[0] = 0ULL;
  40. ((uint64_t *)((void *)pad))[1] = 0ULL;
  41. Anode_aes256_encrypt(expkey,pad,pad);
  42. c = pad[0] & 0x80;
  43. for(i=0;i<15;++i)
  44. pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
  45. pad[15] <<= 1;
  46. if (c)
  47. pad[15] ^= 0x87;
  48. if (remaining||(!data_len)) {
  49. for(i=0;i<remaining;++i)
  50. cbc[i] ^= *(pos++);
  51. cbc[remaining] ^= 0x80;
  52. c = pad[0] & 0x80;
  53. for(i=0;i<15;++i)
  54. pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
  55. pad[15] <<= 1;
  56. if (c)
  57. pad[15] ^= 0x87;
  58. }
  59. ((uint64_t *)((void *)mac))[0] = ((uint64_t *)((void *)pad))[0] ^ ((uint64_t *)((void *)cbc))[0];
  60. ((uint64_t *)((void *)mac))[1] = ((uint64_t *)((void *)pad))[1] ^ ((uint64_t *)((void *)cbc))[1];
  61. Anode_aes256_encrypt(expkey,mac,mac);
  62. }