123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- #include <tinycrypt/ccm_mode.h>
- #include <tinycrypt/constants.h>
- #include <tinycrypt/utils.h>
- #include <stdio.h>
- int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce,
- unsigned int nlen, unsigned int mlen)
- {
-
- if (c == (TCCcmMode_t) 0 ||
- sched == (TCAesKeySched_t) 0 ||
- nonce == (uint8_t *) 0) {
- return TC_CRYPTO_FAIL;
- } else if (nlen != 13) {
- return TC_CRYPTO_FAIL;
- } else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) {
- return TC_CRYPTO_FAIL;
- }
- c->mlen = mlen;
- c->sched = sched;
- c->nonce = nonce;
- return TC_CRYPTO_SUCCESS;
- }
- static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen,
- unsigned int flag, TCAesKeySched_t sched)
- {
- unsigned int i;
- if (flag > 0) {
- T[0] ^= (uint8_t)(dlen >> 8);
- T[1] ^= (uint8_t)(dlen);
- dlen += 2; i = 2;
- } else {
- i = 0;
- }
- while (i < dlen) {
- T[i++ % (Nb * Nk)] ^= *data++;
- if (((i % (Nb * Nk)) == 0) || dlen == i) {
- (void) tc_aes_encrypt(T, T, sched);
- }
- }
- }
- static int ccm_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
- unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
- {
- uint8_t buffer[TC_AES_BLOCK_SIZE];
- uint8_t nonce[TC_AES_BLOCK_SIZE];
- uint16_t block_num;
- unsigned int i;
-
- if (out == (uint8_t *) 0 ||
- in == (uint8_t *) 0 ||
- ctr == (uint8_t *) 0 ||
- sched == (TCAesKeySched_t) 0 ||
- inlen == 0 ||
- outlen == 0 ||
- outlen != inlen) {
- return TC_CRYPTO_FAIL;
- }
-
- (void) _copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
-
- block_num = (uint16_t) ((nonce[14] << 8)|(nonce[15]));
- for (i = 0; i < inlen; ++i) {
- if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
- block_num++;
- nonce[14] = (uint8_t)(block_num >> 8);
- nonce[15] = (uint8_t)(block_num);
- if (!tc_aes_encrypt(buffer, nonce, sched)) {
- return TC_CRYPTO_FAIL;
- }
- }
-
- *out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
- }
-
- ctr[14] = nonce[14]; ctr[15] = nonce[15];
- return TC_CRYPTO_SUCCESS;
- }
- 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)
- {
-
- 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) ||
- (plen >= TC_CCM_PAYLOAD_MAX_BYTES) ||
- (olen < (plen + c->mlen))) {
- return TC_CRYPTO_FAIL;
- }
- uint8_t b[Nb * Nk];
- uint8_t tag[Nb * Nk];
- unsigned int i;
-
-
- 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);
-
- (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);
- }
-
-
- b[0] = 1;
- b[14] = b[15] = TC_ZERO_BYTE;
-
- ccm_ctr_mode(out, plen, payload, plen, b, c->sched);
- b[14] = b[15] = TC_ZERO_BYTE;
-
- (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;
- }
- 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)
- {
-
- 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) ||
- (plen >= TC_CCM_PAYLOAD_MAX_BYTES) ||
- (olen < plen - c->mlen)) {
- return TC_CRYPTO_FAIL;
- }
- uint8_t b[Nb * Nk];
- uint8_t tag[Nb * Nk];
- unsigned int i;
-
-
- b[0] = 1;
- for (i = 1; i < 14; ++i) {
- b[i] = c->nonce[i - 1];
- }
- b[14] = b[15] = TC_ZERO_BYTE;
-
- ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched);
- b[14] = b[15] = TC_ZERO_BYTE;
-
- (void) tc_aes_encrypt(b, b, c->sched);
- for (i = 0; i < c->mlen; ++i) {
- tag[i] = *(payload + plen - c->mlen + i) ^ b[i];
- }
-
-
- 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);
-
- (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);
- }
-
- if (_compare(b, tag, c->mlen) == 0) {
- return TC_CRYPTO_SUCCESS;
- } else {
-
- _set(out, 0, plen - c->mlen);
- return TC_CRYPTO_FAIL;
- }
- }
|