Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

AESInStream.cxx 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* Copyright (C) 2022 Dinglan Peng
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #include <assert.h>
  22. #include <rdr/AESInStream.h>
  23. #include <rdr/Exception.h>
  24. #ifdef HAVE_NETTLE
  25. using namespace rdr;
  26. AESInStream::AESInStream(InStream* _in, const uint8_t* key,
  27. int _keySize)
  28. : keySize(_keySize), in(_in), counter()
  29. {
  30. if (keySize == 128)
  31. EAX_SET_KEY(&eaxCtx128, aes128_set_encrypt_key, aes128_encrypt, key);
  32. else if (keySize == 256)
  33. EAX_SET_KEY(&eaxCtx256, aes256_set_encrypt_key, aes256_encrypt, key);
  34. else
  35. assert(!"incorrect key size");
  36. }
  37. AESInStream::~AESInStream() {}
  38. bool AESInStream::fillBuffer()
  39. {
  40. if (!in->hasData(2))
  41. return false;
  42. const uint8_t* ptr = in->getptr(2);
  43. size_t length = ((int)ptr[0] << 8) | (int)ptr[1];
  44. if (!in->hasData(2 + length + 16))
  45. return false;
  46. ensureSpace(length);
  47. ptr = in->getptr(2 + length + 16);
  48. const uint8_t* ad = ptr;
  49. const uint8_t* data = ptr + 2;
  50. const uint8_t* mac = ptr + 2 + length;
  51. uint8_t macComputed[16];
  52. if (keySize == 128) {
  53. EAX_SET_NONCE(&eaxCtx128, aes128_encrypt, 16, counter);
  54. EAX_UPDATE(&eaxCtx128, aes128_encrypt, 2, ad);
  55. EAX_DECRYPT(&eaxCtx128, aes128_encrypt, length, (uint8_t*)end, data);
  56. EAX_DIGEST(&eaxCtx128, aes128_encrypt, 16, macComputed);
  57. } else {
  58. EAX_SET_NONCE(&eaxCtx256, aes256_encrypt, 16, counter);
  59. EAX_UPDATE(&eaxCtx256, aes256_encrypt, 2, ad);
  60. EAX_DECRYPT(&eaxCtx256, aes256_encrypt, length, (uint8_t*)end, data);
  61. EAX_DIGEST(&eaxCtx256, aes256_encrypt, 16, macComputed);
  62. }
  63. if (memcmp(mac, macComputed, 16) != 0)
  64. throw Exception("AESInStream: failed to authenticate message");
  65. in->setptr(2 + length + 16);
  66. end += length;
  67. // Update nonce by incrementing the counter as a
  68. // 128bit little endian unsigned integer
  69. for (int i = 0; i < 16; ++i) {
  70. // increment until there is no carry
  71. if (++counter[i] != 0) {
  72. break;
  73. }
  74. }
  75. return true;
  76. }
  77. #endif