ccm_process.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. */
  9. #include "tomcrypt.h"
  10. #ifdef LTC_CCM_MODE
  11. /**
  12. Process plaintext/ciphertext through CCM
  13. @param ccm The CCM state
  14. @param pt The plaintext
  15. @param ptlen The plaintext length (ciphertext length is the same)
  16. @param ct The ciphertext
  17. @param direction Encrypt or Decrypt mode (CCM_ENCRYPT or CCM_DECRYPT)
  18. @return CRYPT_OK on success
  19. */
  20. int ccm_process(ccm_state *ccm,
  21. unsigned char *pt, unsigned long ptlen,
  22. unsigned char *ct,
  23. int direction)
  24. {
  25. unsigned char z, b;
  26. unsigned long y;
  27. int err;
  28. LTC_ARGCHK(ccm != NULL);
  29. /* Check aad has been correctly added */
  30. if (ccm->aadlen != ccm->current_aadlen) {
  31. return CRYPT_ERROR;
  32. }
  33. /* Check we do not process too much data */
  34. if (ccm->ptlen < ccm->current_ptlen + ptlen) {
  35. return CRYPT_ERROR;
  36. }
  37. ccm->current_ptlen += ptlen;
  38. /* now handle the PT */
  39. if (ptlen > 0) {
  40. LTC_ARGCHK(pt != NULL);
  41. LTC_ARGCHK(ct != NULL);
  42. for (y = 0; y < ptlen; y++) {
  43. /* increment the ctr? */
  44. if (ccm->CTRlen == 16) {
  45. for (z = 15; z > 15-ccm->L; z--) {
  46. ccm->ctr[z] = (ccm->ctr[z] + 1) & 255;
  47. if (ccm->ctr[z]) break;
  48. }
  49. if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) {
  50. return err;
  51. }
  52. ccm->CTRlen = 0;
  53. }
  54. /* if we encrypt we add the bytes to the MAC first */
  55. if (direction == CCM_ENCRYPT) {
  56. b = pt[y];
  57. ct[y] = b ^ ccm->CTRPAD[ccm->CTRlen++];
  58. } else {
  59. b = ct[y] ^ ccm->CTRPAD[ccm->CTRlen++];
  60. pt[y] = b;
  61. }
  62. if (ccm->x == 16) {
  63. if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
  64. return err;
  65. }
  66. ccm->x = 0;
  67. }
  68. ccm->PAD[ccm->x++] ^= b;
  69. }
  70. }
  71. return CRYPT_OK;
  72. }
  73. #endif
  74. /* ref: $Format:%D$ */
  75. /* git commit: $Format:%H$ */
  76. /* commit time: $Format:%ai$ */