int tc_ccm_generation_encryption()

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;
}