int tc_ccm_decryption_verification()

in ext/tinycrypt/src/ccm_mode.c [198:266]


int tc_ccm_decryption_verification(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;

	/* DECRYPTION: */

	/* formatting the sequence b for decryption: */
	b[0] = 1; /* q - 1 = 2 - 1 = 1 */
	for (i = 1; i < 14; ++i) {
		b[i] = c->nonce[i - 1];
	}
	b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */

	/* decrypting payload using ctr mode: */
	ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched);

	b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */

	/* encrypting b and restoring the tag from input: */
	(void) tc_aes_encrypt(b, b, c->sched);
	for (i = 0; i < c->mlen; ++i) {
		tag[i] = *(payload + plen - c->mlen + i) ^ b[i];
	}

	/* VERIFYING 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 < 14; ++i) {
		b[i] = c->nonce[i - 1];
	}
	b[14] = (uint8_t)((plen - c->mlen) >> 8);
	b[15] = (uint8_t)(plen - c->mlen);

	/* computing the authentication tag using cbc-mac: */
	(void) tc_aes_encrypt(b, b, c->sched);
	if (alen > 0) {
		ccm_cbc_mac(b, associated_data, alen, 1, c->sched);
	}
	if (plen > 0) {
		ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched);
	}

	/* comparing the received tag and the computed one: */
	if (_compare(b, tag, c->mlen) == 0) {
		return TC_CRYPTO_SUCCESS;
  	} else {
		/* erase the decrypted buffer in case of mac validation failure: */
		_set(out, 0, plen - c->mlen);
		return TC_CRYPTO_FAIL;
	}
}