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