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   Initialize a CCM state
9   @param ccm     The CCM state to initialize
10   @param cipher  The index of the cipher to use
11   @param key     The secret key
12   @param keylen  The length of the secret key
13   @param ptlen   The length of the plain/cipher text that will be processed
14   @param taglen  The max length of the MAC tag
15   @param aadlen  The length of the AAD
16 
17   @return CRYPT_OK on success
18  */
ccm_init(ccm_state * ccm,int cipher,const unsigned char * key,int keylen,int ptlen,int taglen,int aadlen)19 int ccm_init(ccm_state *ccm, int cipher,
20              const unsigned char *key, int keylen, int ptlen, int taglen, int aadlen)
21 {
22    int            err;
23 
24    LTC_ARGCHK(ccm    != NULL);
25    LTC_ARGCHK(key    != NULL);
26 
27    XMEMSET(ccm, 0, sizeof(ccm_state));
28 
29    /* check cipher input */
30    if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
31       return err;
32    }
33    if (cipher_descriptor[cipher]->block_length != 16) {
34       return CRYPT_INVALID_CIPHER;
35    }
36 
37    /* make sure the taglen is valid */
38    if (taglen < 4 || taglen > 16 || (taglen % 2) == 1 || aadlen < 0 || ptlen < 0) {
39       return CRYPT_INVALID_ARG;
40    }
41    ccm->taglen = taglen;
42 
43    /* schedule key */
44    if ((err = cipher_descriptor[cipher]->setup(key, keylen, 0, &ccm->K)) != CRYPT_OK) {
45       return err;
46    }
47    ccm->cipher = cipher;
48 
49    /* let's get the L value */
50    ccm->ptlen = ptlen;
51    ccm->L   = 0;
52    while (ptlen) {
53       ++ccm->L;
54       ptlen >>= 8;
55    }
56    if (ccm->L <= 1) {
57       ccm->L = 2;
58    }
59 
60    ccm->aadlen = aadlen;
61    return CRYPT_OK;
62 }
63 
64 #endif
65