ccm128.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* ====================================================================
  2. * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * openssl-core@openssl.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ====================================================================
  48. */
  49. #include <openssl/crypto.h>
  50. #include "modes_lcl.h"
  51. #include <string.h>
  52. #ifndef MODES_DEBUG
  53. # ifndef NDEBUG
  54. # define NDEBUG
  55. # endif
  56. #endif
  57. #include <assert.h>
  58. /* First you setup M and L parameters and pass the key schedule.
  59. * This is called once per session setup... */
  60. void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
  61. unsigned int M,unsigned int L,void *key,block128_f block)
  62. {
  63. memset(ctx->nonce.c,0,sizeof(ctx->nonce.c));
  64. ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3;
  65. ctx->blocks = 0;
  66. ctx->block = block;
  67. ctx->key = key;
  68. }
  69. /* !!! Following interfaces are to be called *once* per packet !!! */
  70. /* Then you setup per-message nonce and pass the length of the message */
  71. int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
  72. const unsigned char *nonce,size_t nlen,size_t mlen)
  73. {
  74. unsigned int L = ctx->nonce.c[0]&7; /* the L parameter */
  75. if (nlen<(14-L)) return -1; /* nonce is too short */
  76. if (sizeof(mlen)==8 && L>=3) {
  77. ctx->nonce.c[8] = (u8)(mlen>>(56%(sizeof(mlen)*8)));
  78. ctx->nonce.c[9] = (u8)(mlen>>(48%(sizeof(mlen)*8)));
  79. ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8)));
  80. ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
  81. }
  82. else
  83. *(u32*)(&ctx->nonce.c[8]) = 0;
  84. ctx->nonce.c[12] = (u8)(mlen>>24);
  85. ctx->nonce.c[13] = (u8)(mlen>>16);
  86. ctx->nonce.c[14] = (u8)(mlen>>8);
  87. ctx->nonce.c[15] = (u8)mlen;
  88. ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
  89. memcpy(&ctx->nonce.c[1],nonce,14-L);
  90. return 0;
  91. }
  92. /* Then you pass additional authentication data, this is optional */
  93. void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
  94. const unsigned char *aad,size_t alen)
  95. { unsigned int i;
  96. block128_f block = ctx->block;
  97. if (alen==0) return;
  98. ctx->nonce.c[0] |= 0x40; /* set Adata flag */
  99. (*block)(ctx->nonce.c,ctx->cmac.c,ctx->key),
  100. ctx->blocks++;
  101. if (alen<(0x10000-0x100)) {
  102. ctx->cmac.c[0] ^= (u8)(alen>>8);
  103. ctx->cmac.c[1] ^= (u8)alen;
  104. i=2;
  105. }
  106. else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) {
  107. ctx->cmac.c[0] ^= 0xFF;
  108. ctx->cmac.c[1] ^= 0xFF;
  109. ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8)));
  110. ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8)));
  111. ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8)));
  112. ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8)));
  113. ctx->cmac.c[6] ^= (u8)(alen>>24);
  114. ctx->cmac.c[7] ^= (u8)(alen>>16);
  115. ctx->cmac.c[8] ^= (u8)(alen>>8);
  116. ctx->cmac.c[9] ^= (u8)alen;
  117. i=10;
  118. }
  119. else {
  120. ctx->cmac.c[0] ^= 0xFF;
  121. ctx->cmac.c[1] ^= 0xFE;
  122. ctx->cmac.c[2] ^= (u8)(alen>>24);
  123. ctx->cmac.c[3] ^= (u8)(alen>>16);
  124. ctx->cmac.c[4] ^= (u8)(alen>>8);
  125. ctx->cmac.c[5] ^= (u8)alen;
  126. i=6;
  127. }
  128. do {
  129. for(;i<16 && alen;++i,++aad,--alen)
  130. ctx->cmac.c[i] ^= *aad;
  131. (*block)(ctx->cmac.c,ctx->cmac.c,ctx->key),
  132. ctx->blocks++;
  133. i=0;
  134. } while (alen);
  135. }
  136. /* Finally you encrypt or decrypt the message */
  137. /* counter part of nonce may not be larger than L*8 bits,
  138. * L is not larger than 8, therefore 64-bit counter... */
  139. static void ctr64_inc(unsigned char *counter) {
  140. unsigned int n=8;
  141. u8 c;
  142. counter += 8;
  143. do {
  144. --n;
  145. c = counter[n];
  146. ++c;
  147. counter[n] = c;
  148. if (c) return;
  149. } while (n);
  150. }
  151. int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
  152. const unsigned char *inp, unsigned char *out,
  153. size_t len)
  154. {
  155. size_t n;
  156. unsigned int i,L;
  157. unsigned char flags0 = ctx->nonce.c[0];
  158. block128_f block = ctx->block;
  159. void * key = ctx->key;
  160. union { u64 u[2]; u8 c[16]; } scratch;
  161. if (!(flags0&0x40))
  162. (*block)(ctx->nonce.c,ctx->cmac.c,key),
  163. ctx->blocks++;
  164. ctx->nonce.c[0] = L = flags0&7;
  165. for (n=0,i=15-L;i<15;++i) {
  166. n |= ctx->nonce.c[i];
  167. ctx->nonce.c[i]=0;
  168. n <<= 8;
  169. }
  170. n |= ctx->nonce.c[15]; /* reconstructed length */
  171. ctx->nonce.c[15]=1;
  172. if (n!=len) return -1; /* length mismatch */
  173. ctx->blocks += ((len+15)>>3)|1;
  174. if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */
  175. while (len>=16) {
  176. #if defined(STRICT_ALIGNMENT)
  177. union { u64 u[2]; u8 c[16]; } temp;
  178. memcpy (temp.c,inp,16);
  179. ctx->cmac.u[0] ^= temp.u[0];
  180. ctx->cmac.u[1] ^= temp.u[1];
  181. #else
  182. ctx->cmac.u[0] ^= ((u64*)inp)[0];
  183. ctx->cmac.u[1] ^= ((u64*)inp)[1];
  184. #endif
  185. (*block)(ctx->cmac.c,ctx->cmac.c,key);
  186. (*block)(ctx->nonce.c,scratch.c,key);
  187. ctr64_inc(ctx->nonce.c);
  188. #if defined(STRICT_ALIGNMENT)
  189. temp.u[0] ^= scratch.u[0];
  190. temp.u[1] ^= scratch.u[1];
  191. memcpy(out,temp.c,16);
  192. #else
  193. ((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0];
  194. ((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1];
  195. #endif
  196. inp += 16;
  197. out += 16;
  198. len -= 16;
  199. }
  200. if (len) {
  201. for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
  202. (*block)(ctx->cmac.c,ctx->cmac.c,key);
  203. (*block)(ctx->nonce.c,scratch.c,key);
  204. for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
  205. }
  206. for (i=15-L;i<16;++i)
  207. ctx->nonce.c[i]=0;
  208. (*block)(ctx->nonce.c,scratch.c,key);
  209. ctx->cmac.u[0] ^= scratch.u[0];
  210. ctx->cmac.u[1] ^= scratch.u[1];
  211. ctx->nonce.c[0] = flags0;
  212. return 0;
  213. }
  214. int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
  215. const unsigned char *inp, unsigned char *out,
  216. size_t len)
  217. {
  218. size_t n;
  219. unsigned int i,L;
  220. unsigned char flags0 = ctx->nonce.c[0];
  221. block128_f block = ctx->block;
  222. void * key = ctx->key;
  223. union { u64 u[2]; u8 c[16]; } scratch;
  224. if (!(flags0&0x40))
  225. (*block)(ctx->nonce.c,ctx->cmac.c,key);
  226. ctx->nonce.c[0] = L = flags0&7;
  227. for (n=0,i=15-L;i<15;++i) {
  228. n |= ctx->nonce.c[i];
  229. ctx->nonce.c[i]=0;
  230. n <<= 8;
  231. }
  232. n |= ctx->nonce.c[15]; /* reconstructed length */
  233. ctx->nonce.c[15]=1;
  234. if (n!=len) return -1;
  235. while (len>=16) {
  236. #if defined(STRICT_ALIGNMENT)
  237. union { u64 u[2]; u8 c[16]; } temp;
  238. #endif
  239. (*block)(ctx->nonce.c,scratch.c,key);
  240. ctr64_inc(ctx->nonce.c);
  241. #if defined(STRICT_ALIGNMENT)
  242. memcpy (temp.c,inp,16);
  243. ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
  244. ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
  245. memcpy (out,scratch.c,16);
  246. #else
  247. ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]);
  248. ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]);
  249. #endif
  250. (*block)(ctx->cmac.c,ctx->cmac.c,key);
  251. inp += 16;
  252. out += 16;
  253. len -= 16;
  254. }
  255. if (len) {
  256. (*block)(ctx->nonce.c,scratch.c,key);
  257. for (i=0; i<len; ++i)
  258. ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
  259. (*block)(ctx->cmac.c,ctx->cmac.c,key);
  260. }
  261. for (i=15-L;i<16;++i)
  262. ctx->nonce.c[i]=0;
  263. (*block)(ctx->nonce.c,scratch.c,key);
  264. ctx->cmac.u[0] ^= scratch.u[0];
  265. ctx->cmac.u[1] ^= scratch.u[1];
  266. ctx->nonce.c[0] = flags0;
  267. return 0;
  268. }
  269. static void ctr64_add (unsigned char *counter,size_t inc)
  270. { size_t n=8, val=0;
  271. counter += 8;
  272. do {
  273. --n;
  274. val += counter[n] + (inc&0xff);
  275. counter[n] = (unsigned char)val;
  276. val >>= 8; /* carry bit */
  277. inc >>= 8;
  278. } while(n && (inc || val));
  279. }
  280. int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
  281. const unsigned char *inp, unsigned char *out,
  282. size_t len,ccm128_f stream)
  283. {
  284. size_t n;
  285. unsigned int i,L;
  286. unsigned char flags0 = ctx->nonce.c[0];
  287. block128_f block = ctx->block;
  288. void * key = ctx->key;
  289. union { u64 u[2]; u8 c[16]; } scratch;
  290. if (!(flags0&0x40))
  291. (*block)(ctx->nonce.c,ctx->cmac.c,key),
  292. ctx->blocks++;
  293. ctx->nonce.c[0] = L = flags0&7;
  294. for (n=0,i=15-L;i<15;++i) {
  295. n |= ctx->nonce.c[i];
  296. ctx->nonce.c[i]=0;
  297. n <<= 8;
  298. }
  299. n |= ctx->nonce.c[15]; /* reconstructed length */
  300. ctx->nonce.c[15]=1;
  301. if (n!=len) return -1; /* length mismatch */
  302. ctx->blocks += ((len+15)>>3)|1;
  303. if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */
  304. if ((n=len/16)) {
  305. (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
  306. n *= 16;
  307. inp += n;
  308. out += n;
  309. len -= n;
  310. if (len) ctr64_add(ctx->nonce.c,n/16);
  311. }
  312. if (len) {
  313. for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i];
  314. (*block)(ctx->cmac.c,ctx->cmac.c,key);
  315. (*block)(ctx->nonce.c,scratch.c,key);
  316. for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i];
  317. }
  318. for (i=15-L;i<16;++i)
  319. ctx->nonce.c[i]=0;
  320. (*block)(ctx->nonce.c,scratch.c,key);
  321. ctx->cmac.u[0] ^= scratch.u[0];
  322. ctx->cmac.u[1] ^= scratch.u[1];
  323. ctx->nonce.c[0] = flags0;
  324. return 0;
  325. }
  326. int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
  327. const unsigned char *inp, unsigned char *out,
  328. size_t len,ccm128_f stream)
  329. {
  330. size_t n;
  331. unsigned int i,L;
  332. unsigned char flags0 = ctx->nonce.c[0];
  333. block128_f block = ctx->block;
  334. void * key = ctx->key;
  335. union { u64 u[2]; u8 c[16]; } scratch;
  336. if (!(flags0&0x40))
  337. (*block)(ctx->nonce.c,ctx->cmac.c,key);
  338. ctx->nonce.c[0] = L = flags0&7;
  339. for (n=0,i=15-L;i<15;++i) {
  340. n |= ctx->nonce.c[i];
  341. ctx->nonce.c[i]=0;
  342. n <<= 8;
  343. }
  344. n |= ctx->nonce.c[15]; /* reconstructed length */
  345. ctx->nonce.c[15]=1;
  346. if (n!=len) return -1;
  347. if ((n=len/16)) {
  348. (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
  349. n *= 16;
  350. inp += n;
  351. out += n;
  352. len -= n;
  353. if (len) ctr64_add(ctx->nonce.c,n/16);
  354. }
  355. if (len) {
  356. (*block)(ctx->nonce.c,scratch.c,key);
  357. for (i=0; i<len; ++i)
  358. ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
  359. (*block)(ctx->cmac.c,ctx->cmac.c,key);
  360. }
  361. for (i=15-L;i<16;++i)
  362. ctx->nonce.c[i]=0;
  363. (*block)(ctx->nonce.c,scratch.c,key);
  364. ctx->cmac.u[0] ^= scratch.u[0];
  365. ctx->cmac.u[1] ^= scratch.u[1];
  366. ctx->nonce.c[0] = flags0;
  367. return 0;
  368. }
  369. size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len)
  370. { unsigned int M = (ctx->nonce.c[0]>>3)&7; /* the M parameter */
  371. M *= 2; M += 2;
  372. if (len<M) return 0;
  373. memcpy(tag,ctx->cmac.c,M);
  374. return M;
  375. }