ccm128.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/crypto.h>
  10. #include "modes_local.h"
  11. #include <string.h>
  12. #ifndef STRICT_ALIGNMENT
  13. # ifdef __GNUC__
  14. typedef u64 u64_a1 __attribute((__aligned__(1)));
  15. # else
  16. typedef u64 u64_a1;
  17. # endif
  18. #endif
  19. /*
  20. * First you setup M and L parameters and pass the key schedule. This is
  21. * called once per session setup...
  22. */
  23. void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
  24. unsigned int M, unsigned int L, void *key,
  25. block128_f block)
  26. {
  27. memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
  28. ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
  29. ctx->blocks = 0;
  30. ctx->block = block;
  31. ctx->key = key;
  32. }
  33. /* !!! Following interfaces are to be called *once* per packet !!! */
  34. /* Then you setup per-message nonce and pass the length of the message */
  35. int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
  36. const unsigned char *nonce, size_t nlen, size_t mlen)
  37. {
  38. unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
  39. if (nlen < (14 - L))
  40. return -1; /* nonce is too short */
  41. if (sizeof(mlen) == 8 && L >= 3) {
  42. ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
  43. ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
  44. ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
  45. ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
  46. } else
  47. ctx->nonce.u[1] = 0;
  48. ctx->nonce.c[12] = (u8)(mlen >> 24);
  49. ctx->nonce.c[13] = (u8)(mlen >> 16);
  50. ctx->nonce.c[14] = (u8)(mlen >> 8);
  51. ctx->nonce.c[15] = (u8)mlen;
  52. ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
  53. memcpy(&ctx->nonce.c[1], nonce, 14 - L);
  54. return 0;
  55. }
  56. /* Then you pass additional authentication data, this is optional */
  57. void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
  58. const unsigned char *aad, size_t alen)
  59. {
  60. unsigned int i;
  61. block128_f block = ctx->block;
  62. if (alen == 0)
  63. return;
  64. ctx->nonce.c[0] |= 0x40; /* set Adata flag */
  65. (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
  66. if (alen < (0x10000 - 0x100)) {
  67. ctx->cmac.c[0] ^= (u8)(alen >> 8);
  68. ctx->cmac.c[1] ^= (u8)alen;
  69. i = 2;
  70. } else if (sizeof(alen) == 8
  71. && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
  72. ctx->cmac.c[0] ^= 0xFF;
  73. ctx->cmac.c[1] ^= 0xFF;
  74. ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
  75. ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
  76. ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
  77. ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
  78. ctx->cmac.c[6] ^= (u8)(alen >> 24);
  79. ctx->cmac.c[7] ^= (u8)(alen >> 16);
  80. ctx->cmac.c[8] ^= (u8)(alen >> 8);
  81. ctx->cmac.c[9] ^= (u8)alen;
  82. i = 10;
  83. } else {
  84. ctx->cmac.c[0] ^= 0xFF;
  85. ctx->cmac.c[1] ^= 0xFE;
  86. ctx->cmac.c[2] ^= (u8)(alen >> 24);
  87. ctx->cmac.c[3] ^= (u8)(alen >> 16);
  88. ctx->cmac.c[4] ^= (u8)(alen >> 8);
  89. ctx->cmac.c[5] ^= (u8)alen;
  90. i = 6;
  91. }
  92. do {
  93. for (; i < 16 && alen; ++i, ++aad, --alen)
  94. ctx->cmac.c[i] ^= *aad;
  95. (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
  96. i = 0;
  97. } while (alen);
  98. }
  99. /* Finally you encrypt or decrypt the message */
  100. /*
  101. * counter part of nonce may not be larger than L*8 bits, L is not larger
  102. * than 8, therefore 64-bit counter...
  103. */
  104. static void ctr64_inc(unsigned char *counter)
  105. {
  106. unsigned int n = 8;
  107. u8 c;
  108. counter += 8;
  109. do {
  110. --n;
  111. c = counter[n];
  112. ++c;
  113. counter[n] = c;
  114. if (c)
  115. return;
  116. } while (n);
  117. }
  118. int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
  119. const unsigned char *inp, unsigned char *out,
  120. size_t len)
  121. {
  122. size_t n;
  123. unsigned int i, L;
  124. unsigned char flags0 = ctx->nonce.c[0];
  125. block128_f block = ctx->block;
  126. void *key = ctx->key;
  127. union {
  128. u64 u[2];
  129. u8 c[16];
  130. } scratch;
  131. if (!(flags0 & 0x40))
  132. (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
  133. ctx->nonce.c[0] = L = flags0 & 7;
  134. for (n = 0, i = 15 - L; i < 15; ++i) {
  135. n |= ctx->nonce.c[i];
  136. ctx->nonce.c[i] = 0;
  137. n <<= 8;
  138. }
  139. n |= ctx->nonce.c[15]; /* reconstructed length */
  140. ctx->nonce.c[15] = 1;
  141. if (n != len)
  142. return -1; /* length mismatch */
  143. ctx->blocks += ((len + 15) >> 3) | 1;
  144. if (ctx->blocks > (U64(1) << 61))
  145. return -2; /* too much data */
  146. while (len >= 16) {
  147. #if defined(STRICT_ALIGNMENT)
  148. union {
  149. u64 u[2];
  150. u8 c[16];
  151. } temp;
  152. memcpy(temp.c, inp, 16);
  153. ctx->cmac.u[0] ^= temp.u[0];
  154. ctx->cmac.u[1] ^= temp.u[1];
  155. #else
  156. ctx->cmac.u[0] ^= ((u64_a1 *)inp)[0];
  157. ctx->cmac.u[1] ^= ((u64_a1 *)inp)[1];
  158. #endif
  159. (*block) (ctx->cmac.c, ctx->cmac.c, key);
  160. (*block) (ctx->nonce.c, scratch.c, key);
  161. ctr64_inc(ctx->nonce.c);
  162. #if defined(STRICT_ALIGNMENT)
  163. temp.u[0] ^= scratch.u[0];
  164. temp.u[1] ^= scratch.u[1];
  165. memcpy(out, temp.c, 16);
  166. #else
  167. ((u64_a1 *)out)[0] = scratch.u[0] ^ ((u64_a1 *)inp)[0];
  168. ((u64_a1 *)out)[1] = scratch.u[1] ^ ((u64_a1 *)inp)[1];
  169. #endif
  170. inp += 16;
  171. out += 16;
  172. len -= 16;
  173. }
  174. if (len) {
  175. for (i = 0; i < len; ++i)
  176. ctx->cmac.c[i] ^= inp[i];
  177. (*block) (ctx->cmac.c, ctx->cmac.c, key);
  178. (*block) (ctx->nonce.c, scratch.c, key);
  179. for (i = 0; i < len; ++i)
  180. out[i] = scratch.c[i] ^ inp[i];
  181. }
  182. for (i = 15 - L; i < 16; ++i)
  183. ctx->nonce.c[i] = 0;
  184. (*block) (ctx->nonce.c, scratch.c, key);
  185. ctx->cmac.u[0] ^= scratch.u[0];
  186. ctx->cmac.u[1] ^= scratch.u[1];
  187. ctx->nonce.c[0] = flags0;
  188. return 0;
  189. }
  190. int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
  191. const unsigned char *inp, unsigned char *out,
  192. size_t len)
  193. {
  194. size_t n;
  195. unsigned int i, L;
  196. unsigned char flags0 = ctx->nonce.c[0];
  197. block128_f block = ctx->block;
  198. void *key = ctx->key;
  199. union {
  200. u64 u[2];
  201. u8 c[16];
  202. } scratch;
  203. if (!(flags0 & 0x40))
  204. (*block) (ctx->nonce.c, ctx->cmac.c, key);
  205. ctx->nonce.c[0] = L = flags0 & 7;
  206. for (n = 0, i = 15 - L; i < 15; ++i) {
  207. n |= ctx->nonce.c[i];
  208. ctx->nonce.c[i] = 0;
  209. n <<= 8;
  210. }
  211. n |= ctx->nonce.c[15]; /* reconstructed length */
  212. ctx->nonce.c[15] = 1;
  213. if (n != len)
  214. return -1;
  215. while (len >= 16) {
  216. #if defined(STRICT_ALIGNMENT)
  217. union {
  218. u64 u[2];
  219. u8 c[16];
  220. } temp;
  221. #endif
  222. (*block) (ctx->nonce.c, scratch.c, key);
  223. ctr64_inc(ctx->nonce.c);
  224. #if defined(STRICT_ALIGNMENT)
  225. memcpy(temp.c, inp, 16);
  226. ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
  227. ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
  228. memcpy(out, scratch.c, 16);
  229. #else
  230. ctx->cmac.u[0] ^= (((u64_a1 *)out)[0]
  231. = scratch.u[0] ^ ((u64_a1 *)inp)[0]);
  232. ctx->cmac.u[1] ^= (((u64_a1 *)out)[1]
  233. = scratch.u[1] ^ ((u64_a1 *)inp)[1]);
  234. #endif
  235. (*block) (ctx->cmac.c, ctx->cmac.c, key);
  236. inp += 16;
  237. out += 16;
  238. len -= 16;
  239. }
  240. if (len) {
  241. (*block) (ctx->nonce.c, scratch.c, key);
  242. for (i = 0; i < len; ++i)
  243. ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
  244. (*block) (ctx->cmac.c, ctx->cmac.c, key);
  245. }
  246. for (i = 15 - L; i < 16; ++i)
  247. ctx->nonce.c[i] = 0;
  248. (*block) (ctx->nonce.c, scratch.c, key);
  249. ctx->cmac.u[0] ^= scratch.u[0];
  250. ctx->cmac.u[1] ^= scratch.u[1];
  251. ctx->nonce.c[0] = flags0;
  252. return 0;
  253. }
  254. static void ctr64_add(unsigned char *counter, size_t inc)
  255. {
  256. size_t n = 8, val = 0;
  257. counter += 8;
  258. do {
  259. --n;
  260. val += counter[n] + (inc & 0xff);
  261. counter[n] = (unsigned char)val;
  262. val >>= 8; /* carry bit */
  263. inc >>= 8;
  264. } while (n && (inc || val));
  265. }
  266. int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
  267. const unsigned char *inp, unsigned char *out,
  268. size_t len, ccm128_f stream)
  269. {
  270. size_t n;
  271. unsigned int i, L;
  272. unsigned char flags0 = ctx->nonce.c[0];
  273. block128_f block = ctx->block;
  274. void *key = ctx->key;
  275. union {
  276. u64 u[2];
  277. u8 c[16];
  278. } scratch;
  279. if (!(flags0 & 0x40))
  280. (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
  281. ctx->nonce.c[0] = L = flags0 & 7;
  282. for (n = 0, i = 15 - L; i < 15; ++i) {
  283. n |= ctx->nonce.c[i];
  284. ctx->nonce.c[i] = 0;
  285. n <<= 8;
  286. }
  287. n |= ctx->nonce.c[15]; /* reconstructed length */
  288. ctx->nonce.c[15] = 1;
  289. if (n != len)
  290. return -1; /* length mismatch */
  291. ctx->blocks += ((len + 15) >> 3) | 1;
  292. if (ctx->blocks > (U64(1) << 61))
  293. return -2; /* too much data */
  294. if ((n = len / 16)) {
  295. (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
  296. n *= 16;
  297. inp += n;
  298. out += n;
  299. len -= n;
  300. if (len)
  301. ctr64_add(ctx->nonce.c, n / 16);
  302. }
  303. if (len) {
  304. for (i = 0; i < len; ++i)
  305. ctx->cmac.c[i] ^= inp[i];
  306. (*block) (ctx->cmac.c, ctx->cmac.c, key);
  307. (*block) (ctx->nonce.c, scratch.c, key);
  308. for (i = 0; i < len; ++i)
  309. out[i] = scratch.c[i] ^ inp[i];
  310. }
  311. for (i = 15 - L; i < 16; ++i)
  312. ctx->nonce.c[i] = 0;
  313. (*block) (ctx->nonce.c, scratch.c, key);
  314. ctx->cmac.u[0] ^= scratch.u[0];
  315. ctx->cmac.u[1] ^= scratch.u[1];
  316. ctx->nonce.c[0] = flags0;
  317. return 0;
  318. }
  319. int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
  320. const unsigned char *inp, unsigned char *out,
  321. size_t len, ccm128_f stream)
  322. {
  323. size_t n;
  324. unsigned int i, L;
  325. unsigned char flags0 = ctx->nonce.c[0];
  326. block128_f block = ctx->block;
  327. void *key = ctx->key;
  328. union {
  329. u64 u[2];
  330. u8 c[16];
  331. } scratch;
  332. if (!(flags0 & 0x40))
  333. (*block) (ctx->nonce.c, ctx->cmac.c, key);
  334. ctx->nonce.c[0] = L = flags0 & 7;
  335. for (n = 0, i = 15 - L; i < 15; ++i) {
  336. n |= ctx->nonce.c[i];
  337. ctx->nonce.c[i] = 0;
  338. n <<= 8;
  339. }
  340. n |= ctx->nonce.c[15]; /* reconstructed length */
  341. ctx->nonce.c[15] = 1;
  342. if (n != len)
  343. return -1;
  344. if ((n = len / 16)) {
  345. (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
  346. n *= 16;
  347. inp += n;
  348. out += n;
  349. len -= n;
  350. if (len)
  351. ctr64_add(ctx->nonce.c, n / 16);
  352. }
  353. if (len) {
  354. (*block) (ctx->nonce.c, scratch.c, key);
  355. for (i = 0; i < len; ++i)
  356. ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
  357. (*block) (ctx->cmac.c, ctx->cmac.c, key);
  358. }
  359. for (i = 15 - L; i < 16; ++i)
  360. ctx->nonce.c[i] = 0;
  361. (*block) (ctx->nonce.c, scratch.c, key);
  362. ctx->cmac.u[0] ^= scratch.u[0];
  363. ctx->cmac.u[1] ^= scratch.u[1];
  364. ctx->nonce.c[0] = flags0;
  365. return 0;
  366. }
  367. size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
  368. {
  369. unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
  370. M *= 2;
  371. M += 2;
  372. if (len != M)
  373. return 0;
  374. memcpy(tag, ctx->cmac.c, M);
  375. return M;
  376. }