ccm_memory_ex.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtom.org
  10. */
  11. #include "tomcrypt.h"
  12. /**
  13. @file ccm_memory.c
  14. CCM support, process a block of memory, Tom St Denis
  15. */
  16. #ifdef LTC_CCM_MODE
  17. /**
  18. CCM encrypt/decrypt and produce an authentication tag
  19. @param cipher The index of the cipher desired
  20. @param key The secret key to use
  21. @param keylen The length of the secret key (octets)
  22. @param uskey A previously scheduled key [optional can be NULL]
  23. @param nonce The session nonce [use once]
  24. @param noncelen The length of the nonce
  25. @param header The header for the session
  26. @param headerlen The length of the header (octets)
  27. @param pt [out] The plaintext
  28. @param ptlen The length of the plaintext (octets)
  29. @param ct [out] The ciphertext
  30. @param tag [out] The destination tag
  31. @param taglen [in/out] The max size and resulting size of the authentication tag
  32. @param direction Encrypt or Decrypt direction (0 or 1)
  33. @return CRYPT_OK if successful
  34. */
  35. int ccm_memory_ex(int cipher,
  36. const unsigned char *key, unsigned long keylen,
  37. symmetric_key *uskey,
  38. const unsigned char *nonce, unsigned long noncelen,
  39. const unsigned char *header, unsigned long headerlen,
  40. unsigned char *pt, unsigned long ptlen,
  41. unsigned char *ct,
  42. unsigned char *tag, unsigned long *taglen,
  43. int direction,
  44. const unsigned char *B0,
  45. const unsigned char *CTR,
  46. int ctrwidth)
  47. {
  48. unsigned char PAD[16], ctr[16], CTRPAD[16], ctrcopy[16], b;
  49. symmetric_key *skey;
  50. int err;
  51. unsigned long len, L, x, y, z, CTRlen;
  52. if (uskey == NULL) {
  53. LTC_ARGCHK(key != NULL);
  54. }
  55. LTC_ARGCHK(nonce != NULL);
  56. if (headerlen > 0) {
  57. LTC_ARGCHK(header != NULL);
  58. }
  59. LTC_ARGCHK(pt != NULL);
  60. LTC_ARGCHK(ct != NULL);
  61. LTC_ARGCHK(tag != NULL);
  62. LTC_ARGCHK(taglen != NULL);
  63. #ifdef LTC_FAST
  64. if (16 % sizeof(LTC_FAST_TYPE)) {
  65. return CRYPT_INVALID_ARG;
  66. }
  67. #endif
  68. /* check cipher input */
  69. if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
  70. return err;
  71. }
  72. if (cipher_descriptor[cipher].block_length != 16) {
  73. return CRYPT_INVALID_CIPHER;
  74. }
  75. /* make sure the taglen is even and <= 16 */
  76. *taglen &= ~1;
  77. if (*taglen > 16) {
  78. *taglen = 16;
  79. }
  80. /* can't use < 4 */
  81. if (*taglen < 4) {
  82. return CRYPT_INVALID_ARG;
  83. }
  84. /* is there an accelerator? */
  85. if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
  86. return cipher_descriptor[cipher].accel_ccm_memory(
  87. key, keylen,
  88. uskey,
  89. nonce, noncelen,
  90. header, headerlen,
  91. pt, ptlen,
  92. ct,
  93. tag, taglen,
  94. direction);
  95. }
  96. /* let's get the L value */
  97. len = ptlen;
  98. L = 0;
  99. while (len) {
  100. ++L;
  101. len >>= 8;
  102. }
  103. if (L <= 1) {
  104. L = 2;
  105. }
  106. /* increase L to match the nonce len */
  107. noncelen = (noncelen > 13) ? 13 : noncelen;
  108. if ((15 - noncelen) > L) {
  109. L = 15 - noncelen;
  110. }
  111. /* decrease noncelen to match L */
  112. if ((noncelen + L) > 15) {
  113. noncelen = 15 - L;
  114. }
  115. /* allocate mem for the symmetric key */
  116. if (uskey == NULL) {
  117. skey = XMALLOC(sizeof(*skey));
  118. if (skey == NULL) {
  119. return CRYPT_MEM;
  120. }
  121. /* initialize the cipher */
  122. if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
  123. XFREE(skey);
  124. return err;
  125. }
  126. } else {
  127. skey = uskey;
  128. }
  129. /* form B_0 == flags | Nonce N | l(m) */
  130. x = 0;
  131. if (B0 == NULL) {
  132. PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
  133. (((*taglen - 2)>>1)<<3) |
  134. (L-1));
  135. /* nonce */
  136. for (y = 0; y < (16 - (L + 1)); y++) {
  137. PAD[x++] = nonce[y];
  138. }
  139. /* store len */
  140. len = ptlen;
  141. /* shift len so the upper bytes of len are the contents of the length */
  142. for (y = L; y < 4; y++) {
  143. len <<= 8;
  144. }
  145. /* store l(m) (only store 32-bits) */
  146. for (y = 0; L > 4 && (L-y)>4; y++) {
  147. PAD[x++] = 0;
  148. }
  149. for (; y < L; y++) {
  150. PAD[x++] = (unsigned char)((len >> 24) & 255);
  151. len <<= 8;
  152. }
  153. } else {
  154. // B0 != NULL
  155. XMEMCPY(PAD, B0, 16);
  156. }
  157. /* encrypt PAD */
  158. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  159. goto error;
  160. }
  161. /* handle header */
  162. if (headerlen > 0) {
  163. x = 0;
  164. #if 0
  165. /* store length */
  166. if (headerlen < ((1UL<<16) - (1UL<<8))) {
  167. PAD[x++] ^= (headerlen>>8) & 255;
  168. PAD[x++] ^= headerlen & 255;
  169. } else {
  170. PAD[x++] ^= 0xFF;
  171. PAD[x++] ^= 0xFE;
  172. PAD[x++] ^= (headerlen>>24) & 255;
  173. PAD[x++] ^= (headerlen>>16) & 255;
  174. PAD[x++] ^= (headerlen>>8) & 255;
  175. PAD[x++] ^= headerlen & 255;
  176. }
  177. #endif
  178. /* now add the data */
  179. for (y = 0; y < headerlen; y++) {
  180. if (x == 16) {
  181. /* full block so let's encrypt it */
  182. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  183. goto error;
  184. }
  185. x = 0;
  186. }
  187. PAD[x++] ^= header[y];
  188. }
  189. /* remainder? */
  190. if (x != 0) {
  191. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  192. goto error;
  193. }
  194. }
  195. }
  196. /* setup the ctr counter */
  197. if (CTR == NULL) {
  198. x = 0;
  199. /* flags */
  200. ctr[x++] = (unsigned char)L-1;
  201. /* nonce */
  202. for (y = 0; y < (16 - (L+1)); ++y) {
  203. ctr[x++] = nonce[y];
  204. }
  205. /* offset */
  206. while (x < 16) {
  207. ctr[x++] = 0;
  208. }
  209. } else {
  210. XMEMCPY(ctr, CTR, 16);
  211. }
  212. x = 0;
  213. CTRlen = 16;
  214. /* now handle the PT */
  215. if (ptlen > 0) {
  216. y = 0;
  217. #ifdef LTC_FAST2
  218. if (ptlen & ~15) {
  219. if (direction == CCM_ENCRYPT) {
  220. for (; y < (ptlen & ~15); y += 16) {
  221. /* increment the ctr? */
  222. for (z = 15; (int)z > (int)(15-ctrwidth); z--) {
  223. ctr[z] = (ctr[z] + 1) & 255;
  224. if (ctr[z]) break;
  225. }
  226. if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
  227. goto error;
  228. }
  229. /* xor the PT against the pad first */
  230. for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
  231. *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
  232. *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
  233. }
  234. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  235. goto error;
  236. }
  237. }
  238. } else {
  239. for (; y < (ptlen & ~15); y += 16) {
  240. /* increment the ctr? */
  241. for (z = 15; (int)z > (int)(15-ctrwidth); z--) {
  242. ctr[z] = (ctr[z] + 1) & 255;
  243. if (ctr[z]) break;
  244. }
  245. if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
  246. goto error;
  247. }
  248. /* xor the PT against the pad last */
  249. for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
  250. *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
  251. *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
  252. }
  253. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  254. goto error;
  255. }
  256. }
  257. }
  258. }
  259. #endif
  260. for (; y < ptlen; y++) {
  261. /* increment the ctr? */
  262. if (CTRlen == 16) {
  263. for (z = 15; (int)z > (int)(15-ctrwidth); z--) {
  264. ctr[z] = (ctr[z] + 1) & 255;
  265. if (ctr[z]) break;
  266. }
  267. if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
  268. goto error;
  269. }
  270. CTRlen = 0;
  271. }
  272. /* if we encrypt we add the bytes to the MAC first */
  273. if (direction == CCM_ENCRYPT) {
  274. b = pt[y];
  275. ct[y] = b ^ CTRPAD[CTRlen++];
  276. } else {
  277. b = ct[y] ^ CTRPAD[CTRlen++];
  278. pt[y] = b;
  279. }
  280. if (x == 16) {
  281. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  282. goto error;
  283. }
  284. x = 0;
  285. }
  286. PAD[x++] ^= b;
  287. }
  288. if (x != 0) {
  289. if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
  290. goto error;
  291. }
  292. }
  293. }
  294. // grab the CTR
  295. memcpy(ctrcopy, ctr, 16);
  296. /* setup CTR for the TAG (zero the count) */
  297. if (CTR == NULL) {
  298. for (y = 15; y > 15 - L; y--) {
  299. ctr[y] = 0x00;
  300. }
  301. } else {
  302. XMEMCPY(ctr, CTR, 16);
  303. }
  304. if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
  305. goto error;
  306. }
  307. if (skey != uskey) {
  308. cipher_descriptor[cipher].done(skey);
  309. }
  310. /* store the TAG */
  311. for (x = 0; x < 16 && x < *taglen; x++) {
  312. tag[x] = PAD[x] ^ CTRPAD[x];
  313. }
  314. *taglen = x;
  315. if (CTR != NULL) {
  316. for (z = 15; (int)z > (int)(15-ctrwidth); z--) {
  317. ctrcopy[z] = (ctrcopy[z] + 1) & 255;
  318. if (ctrcopy[z]) break;
  319. }
  320. memcpy(CTR, ctrcopy, 16);
  321. }
  322. #ifdef LTC_CLEAN_STACK
  323. zeromem(skey, sizeof(*skey));
  324. zeromem(PAD, sizeof(PAD));
  325. zeromem(CTRPAD, sizeof(CTRPAD));
  326. #endif
  327. error:
  328. if (skey != uskey) {
  329. XFREE(skey);
  330. }
  331. return err;
  332. }
  333. #endif
  334. /* $Source$ */
  335. /* $Revision$ */
  336. /* $Date$ */