1 // SPDX-License-Identifier: BSD-2-Clause 2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 3 * 4 * LibTomCrypt is a library that provides various cryptographic 5 * algorithms in a highly modular and flexible manner. 6 * 7 * The library is free for all purposes without any express 8 * guarantee it works. 9 */ 10 #include "tomcrypt_private.h" 11 12 #ifdef LTC_CCM_MODE 13 14 /** 15 Add nonce data to the CCM state 16 @param ccm The CCM state 17 @param nonce The nonce data to add 18 @param noncelen The length of the nonce 19 @return CRYPT_OK on success 20 */ ccm_add_nonce(ccm_state * ccm,const unsigned char * nonce,unsigned long noncelen)21int ccm_add_nonce(ccm_state *ccm, 22 const unsigned char *nonce, unsigned long noncelen) 23 { 24 unsigned long x, y, len; 25 int err; 26 27 LTC_ARGCHK(ccm != NULL); 28 LTC_ARGCHK(nonce != NULL); 29 30 /* increase L to match the nonce len */ 31 ccm->noncelen = (noncelen > 13) ? 13 : noncelen; 32 if ((15 - ccm->noncelen) > ccm->L) { 33 ccm->L = 15 - ccm->noncelen; 34 } 35 36 /* decrease noncelen to match L */ 37 if ((ccm->noncelen + ccm->L) > 15) { 38 ccm->noncelen = 15 - ccm->L; 39 } 40 41 /* form B_0 == flags | Nonce N | l(m) */ 42 x = 0; 43 ccm->PAD[x++] = (unsigned char)(((ccm->aadlen > 0) ? (1<<6) : 0) | 44 (((ccm->taglen - 2)>>1)<<3) | 45 (ccm->L-1)); 46 47 /* nonce */ 48 for (y = 0; y < (16 - (ccm->L + 1)); y++) { 49 ccm->PAD[x++] = nonce[y]; 50 } 51 52 /* store len */ 53 len = ccm->ptlen; 54 55 /* shift len so the upper bytes of len are the contents of the length */ 56 for (y = ccm->L; y < 4; y++) { 57 len <<= 8; 58 } 59 60 /* store l(m) (only store 32-bits) */ 61 for (y = 0; ccm->L > 4 && (ccm->L-y)>4; y++) { 62 ccm->PAD[x++] = 0; 63 } 64 for (; y < ccm->L; y++) { 65 ccm->PAD[x++] = (unsigned char)((len >> 24) & 255); 66 len <<= 8; 67 } 68 69 /* encrypt PAD */ 70 if ((err = cipher_descriptor[ccm->cipher]->ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { 71 return err; 72 } 73 74 /* handle header */ 75 ccm->x = 0; 76 if (ccm->aadlen > 0) { 77 /* store length */ 78 if (ccm->aadlen < ((1UL<<16) - (1UL<<8))) { 79 ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255; 80 ccm->PAD[ccm->x++] ^= ccm->aadlen & 255; 81 } else { 82 ccm->PAD[ccm->x++] ^= 0xFF; 83 ccm->PAD[ccm->x++] ^= 0xFE; 84 ccm->PAD[ccm->x++] ^= (ccm->aadlen>>24) & 255; 85 ccm->PAD[ccm->x++] ^= (ccm->aadlen>>16) & 255; 86 ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255; 87 ccm->PAD[ccm->x++] ^= ccm->aadlen & 255; 88 } 89 } 90 91 /* setup the ctr counter */ 92 x = 0; 93 94 /* flags */ 95 ccm->ctr[x++] = (unsigned char)ccm->L-1; 96 97 /* nonce */ 98 for (y = 0; y < (16 - (ccm->L+1)); ++y) { 99 ccm->ctr[x++] = nonce[y]; 100 } 101 /* offset */ 102 while (x < 16) { 103 ccm->ctr[x++] = 0; 104 } 105 106 ccm->CTRlen = 16; 107 return CRYPT_OK; 108 } 109 110 #endif 111 112 /* ref: $Format:%D$ */ 113 /* git commit: $Format:%H$ */ 114 /* commit time: $Format:%ai$ */ 115