cmac_mode.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* cmac_mode.c - TinyCrypt CMAC mode implementation */
  2. /*
  3. * Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. *
  11. * - Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * - Neither the name of Intel Corporation nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include <tinycrypt/aes.h>
  32. #include <tinycrypt/cmac_mode.h>
  33. #include <tinycrypt/constants.h>
  34. #include <tinycrypt/utils.h>
  35. /* max number of calls until change the key (2^48).*/
  36. const static uint64_t MAX_CALLS = ((uint64_t)1 << 48);
  37. /*
  38. * gf_wrap -- In our implementation, GF(2^128) is represented as a 16 byte
  39. * array with byte 0 the most significant and byte 15 the least significant.
  40. * High bit carry reduction is based on the primitive polynomial
  41. *
  42. * X^128 + X^7 + X^2 + X + 1,
  43. *
  44. * which leads to the reduction formula X^128 = X^7 + X^2 + X + 1. Indeed,
  45. * since 0 = (X^128 + X^7 + X^2 + 1) mod (X^128 + X^7 + X^2 + X + 1) and since
  46. * addition of polynomials with coefficients in Z/Z(2) is just XOR, we can
  47. * add X^128 to both sides to get
  48. *
  49. * X^128 = (X^7 + X^2 + X + 1) mod (X^128 + X^7 + X^2 + X + 1)
  50. *
  51. * and the coefficients of the polynomial on the right hand side form the
  52. * string 1000 0111 = 0x87, which is the value of gf_wrap.
  53. *
  54. * This gets used in the following way. Doubling in GF(2^128) is just a left
  55. * shift by 1 bit, except when the most significant bit is 1. In the latter
  56. * case, the relation X^128 = X^7 + X^2 + X + 1 says that the high order bit
  57. * that overflows beyond 128 bits can be replaced by addition of
  58. * X^7 + X^2 + X + 1 <--> 0x87 to the low order 128 bits. Since addition
  59. * in GF(2^128) is represented by XOR, we therefore only have to XOR 0x87
  60. * into the low order byte after a left shift when the starting high order
  61. * bit is 1.
  62. */
  63. const unsigned char gf_wrap = 0x87;
  64. /*
  65. * assumes: out != NULL and points to a GF(2^n) value to receive the
  66. * doubled value;
  67. * in != NULL and points to a 16 byte GF(2^n) value
  68. * to double;
  69. * the in and out buffers do not overlap.
  70. * effects: doubles the GF(2^n) value pointed to by "in" and places
  71. * the result in the GF(2^n) value pointed to by "out."
  72. */
  73. void gf_double(uint8_t *out, uint8_t *in)
  74. {
  75. /* start with low order byte */
  76. uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1);
  77. /* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */
  78. uint8_t carry = (in[0] >> 7) ? gf_wrap : 0;
  79. out += (TC_AES_BLOCK_SIZE - 1);
  80. for (;;) {
  81. *out-- = (*x << 1) ^ carry;
  82. if (x == in) {
  83. break;
  84. }
  85. carry = *x-- >> 7;
  86. }
  87. }
  88. int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched)
  89. {
  90. /* input sanity check: */
  91. if (s == (TCCmacState_t) 0 ||
  92. key == (const uint8_t *) 0) {
  93. return TC_CRYPTO_FAIL;
  94. }
  95. /* put s into a known state */
  96. _set(s, 0, sizeof(*s));
  97. s->sched = sched;
  98. /* configure the encryption key used by the underlying block cipher */
  99. tc_aes128_set_encrypt_key(s->sched, key);
  100. /* compute s->K1 and s->K2 from s->iv using s->keyid */
  101. _set(s->iv, 0, TC_AES_BLOCK_SIZE);
  102. tc_aes_encrypt(s->iv, s->iv, s->sched);
  103. gf_double (s->K1, s->iv);
  104. gf_double (s->K2, s->K1);
  105. /* reset s->iv to 0 in case someone wants to compute now */
  106. tc_cmac_init(s);
  107. return TC_CRYPTO_SUCCESS;
  108. }
  109. int tc_cmac_erase(TCCmacState_t s)
  110. {
  111. if (s == (TCCmacState_t) 0) {
  112. return TC_CRYPTO_FAIL;
  113. }
  114. /* destroy the current state */
  115. _set(s, 0, sizeof(*s));
  116. return TC_CRYPTO_SUCCESS;
  117. }
  118. int tc_cmac_init(TCCmacState_t s)
  119. {
  120. /* input sanity check: */
  121. if (s == (TCCmacState_t) 0) {
  122. return TC_CRYPTO_FAIL;
  123. }
  124. /* CMAC starts with an all zero initialization vector */
  125. _set(s->iv, 0, TC_AES_BLOCK_SIZE);
  126. /* and the leftover buffer is empty */
  127. _set(s->leftover, 0, TC_AES_BLOCK_SIZE);
  128. s->leftover_offset = 0;
  129. /* Set countdown to max number of calls allowed before re-keying: */
  130. s->countdown = MAX_CALLS;
  131. return TC_CRYPTO_SUCCESS;
  132. }
  133. int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length)
  134. {
  135. unsigned int i;
  136. /* input sanity check: */
  137. if (s == (TCCmacState_t) 0) {
  138. return TC_CRYPTO_FAIL;
  139. }
  140. if (data_length == 0) {
  141. return TC_CRYPTO_SUCCESS;
  142. }
  143. if (data == (const uint8_t *) 0) {
  144. return TC_CRYPTO_FAIL;
  145. }
  146. if (s->countdown == 0) {
  147. return TC_CRYPTO_FAIL;
  148. }
  149. s->countdown--;
  150. if (s->leftover_offset > 0) {
  151. /* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */
  152. size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset;
  153. if (data_length < remaining_space) {
  154. /* still not enough data to encrypt this time either */
  155. _copy(&s->leftover[s->leftover_offset], data_length, data, data_length);
  156. s->leftover_offset += data_length;
  157. return TC_CRYPTO_SUCCESS;
  158. }
  159. /* leftover block is now full; encrypt it first */
  160. _copy(&s->leftover[s->leftover_offset],
  161. remaining_space,
  162. data,
  163. remaining_space);
  164. data_length -= remaining_space;
  165. data += remaining_space;
  166. s->leftover_offset = 0;
  167. for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
  168. s->iv[i] ^= s->leftover[i];
  169. }
  170. tc_aes_encrypt(s->iv, s->iv, s->sched);
  171. }
  172. /* CBC encrypt each (except the last) of the data blocks */
  173. while (data_length > TC_AES_BLOCK_SIZE) {
  174. for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
  175. s->iv[i] ^= data[i];
  176. }
  177. tc_aes_encrypt(s->iv, s->iv, s->sched);
  178. data += TC_AES_BLOCK_SIZE;
  179. data_length -= TC_AES_BLOCK_SIZE;
  180. }
  181. if (data_length > 0) {
  182. /* save leftover data for next time */
  183. _copy(s->leftover, data_length, data, data_length);
  184. s->leftover_offset = data_length;
  185. }
  186. return TC_CRYPTO_SUCCESS;
  187. }
  188. int tc_cmac_final(uint8_t *tag, TCCmacState_t s)
  189. {
  190. uint8_t *k;
  191. unsigned int i;
  192. /* input sanity check: */
  193. if (tag == (uint8_t *) 0 ||
  194. s == (TCCmacState_t) 0) {
  195. return TC_CRYPTO_FAIL;
  196. }
  197. if (s->leftover_offset == TC_AES_BLOCK_SIZE) {
  198. /* the last message block is a full-sized block */
  199. k = (uint8_t *) s->K1;
  200. } else {
  201. /* the final message block is not a full-sized block */
  202. size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset;
  203. _set(&s->leftover[s->leftover_offset], 0, remaining);
  204. s->leftover[s->leftover_offset] = TC_CMAC_PADDING;
  205. k = (uint8_t *) s->K2;
  206. }
  207. for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
  208. s->iv[i] ^= s->leftover[i] ^ k[i];
  209. }
  210. tc_aes_encrypt(tag, s->iv, s->sched);
  211. /* erasing state: */
  212. tc_cmac_erase(s);
  213. return TC_CRYPTO_SUCCESS;
  214. }