in ext/tinycrypt/src/ccm_mode.c [137:196]
int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen,
const uint8_t *associated_data,
unsigned int alen, const uint8_t *payload,
unsigned int plen, TCCcmMode_t c)
{
/* input sanity check: */
if ((out == (uint8_t *) 0) ||
(c == (TCCcmMode_t) 0) ||
((plen > 0) && (payload == (uint8_t *) 0)) ||
((alen > 0) && (associated_data == (uint8_t *) 0)) ||
(alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
(plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
(olen < (plen + c->mlen))) { /* invalid output buffer size */
return TC_CRYPTO_FAIL;
}
uint8_t b[Nb * Nk];
uint8_t tag[Nb * Nk];
unsigned int i;
/* GENERATING THE AUTHENTICATION TAG: */
/* formatting the sequence b for authentication: */
b[0] = ((alen > 0) ? 0x40:0) | (((c->mlen - 2) / 2 << 3)) | (1);
for (i = 1; i <= 13; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = (uint8_t)(plen >> 8);
b[15] = (uint8_t)(plen);
/* computing the authentication tag using cbc-mac: */
(void) tc_aes_encrypt(tag, b, c->sched);
if (alen > 0) {
ccm_cbc_mac(tag, associated_data, alen, 1, c->sched);
}
if (plen > 0) {
ccm_cbc_mac(tag, payload, plen, 0, c->sched);
}
/* ENCRYPTION: */
/* formatting the sequence b for encryption: */
b[0] = 1; /* q - 1 = 2 - 1 = 1 */
b[14] = b[15] = TC_ZERO_BYTE;
/* encrypting payload using ctr mode: */
ccm_ctr_mode(out, plen, payload, plen, b, c->sched);
b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/
/* encrypting b and adding the tag to the output: */
(void) tc_aes_encrypt(b, b, c->sched);
out += plen;
for (i = 0; i < c->mlen; ++i) {
*out++ = tag[i] ^ b[i];
}
return TC_CRYPTO_SUCCESS;
}