3 Counter with CBC-MAC mode, specified by NIST,
4 http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
6 Copyright (C) 2014 Exegin Technologies Limited
7 Copyright (C) 2014 Owen Kirby
9 This file is part of GNU Nettle.
11 GNU Nettle is free software: you can redistribute it and/or
12 modify it under the terms of either:
14 * the GNU Lesser General Public License as published by the Free
15 Software Foundation; either version 3 of the License, or (at your
16 option) any later version.
20 * the GNU General Public License as published by the Free
21 Software Foundation; either version 2 of the License, or (at your
22 option) any later version.
24 or both in parallel, as here.
26 GNU Nettle is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 General Public License for more details.
31 You should have received copies of the GNU General Public License and
32 the GNU Lesser General Public License along with this program. If
33 not, see http://www.gnu.org/licenses/.
48 #include "nettle-internal.h"
52 * The format of the CCM IV (for both CTR and CBC-MAC) is: flags | nonce | count
58 * sizeof(flags) + sizeof(nonce) + sizeof(count) == 1 block
60 #define CCM_FLAG_L 0x07
61 #define CCM_FLAG_M 0x38
62 #define CCM_FLAG_ADATA 0x40
63 #define CCM_FLAG_RESERVED 0x80
64 #define CCM_FLAG_GET_L(_x_) (((_x_) & CCM_FLAG_L) + 1)
65 #define CCM_FLAG_SET_L(_x_) (((_x_) - 1) & CCM_FLAG_L)
66 #define CCM_FLAG_SET_M(_x_) ((((_x_) - 2) << 2) & CCM_FLAG_M)
68 #define CCM_OFFSET_FLAGS 0
69 #define CCM_OFFSET_NONCE 1
70 #define CCM_L_SIZE(_nlen_) (CCM_BLOCK_SIZE - CCM_OFFSET_NONCE - (_nlen_))
73 * The data input to the CBC-MAC: L(a) | adata | padding | plaintext | padding
75 * blength is the length of data that has been added to the CBC-MAC modulus the
76 * cipher block size. If the value of blength is non-zero then some data has
77 * been XOR'ed into the CBC-MAC, and we will need to pad the block (XOR with 0),
78 * and iterate the cipher one more time.
80 * The end of adata is detected implicitly by the first call to the encrypt()
81 * and decrypt() functions, and will call ccm_pad() to insert the padding if
82 * necessary. Because of the underlying CTR encryption, the encrypt() and
83 * decrypt() functions must be called with a multiple of the block size and
84 * therefore blength should be zero on all but the first call.
86 * Likewise, the end of the plaintext is implicitly determined by the first call
87 * to the digest() function, which will pad if the final CTR encryption was not
88 * a multiple of the block size.
91 ccm_pad(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f)
93 if (ctx->blength) f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
98 ccm_build_iv(uint8_t *iv, size_t noncelen, const uint8_t *nonce,
99 uint8_t flags, size_t count)
103 /* Sanity check the nonce length. */
104 assert(noncelen >= CCM_MIN_NONCE_SIZE);
105 assert(noncelen <= CCM_MAX_NONCE_SIZE);
107 /* Generate the IV */
108 iv[CCM_OFFSET_FLAGS] = flags | CCM_FLAG_SET_L(CCM_L_SIZE(noncelen));
109 memcpy(&iv[CCM_OFFSET_NONCE], nonce, noncelen);
110 for (i=(CCM_BLOCK_SIZE - 1); i >= (CCM_OFFSET_NONCE + noncelen); i--) {
111 iv[i] = count & 0xff;
115 /* Ensure the count was not truncated. */
120 ccm_set_nonce(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
121 size_t length, const uint8_t *nonce,
122 size_t authlen, size_t msglen, size_t taglen)
124 /* Generate the IV for the CTR and CBC-MAC */
126 ccm_build_iv(ctx->tag.b, length, nonce, CCM_FLAG_SET_M(taglen), msglen);
127 ccm_build_iv(ctx->ctr.b, length, nonce, 0, 1);
129 /* If no auth data, encrypt B0 and skip L(a) */
131 f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
135 /* Encrypt B0 (with the adata flag), and input L(a) to the CBC-MAC. */
136 ctx->tag.b[CCM_OFFSET_FLAGS] |= CCM_FLAG_ADATA;
137 f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
138 #if SIZEOF_SIZE_T > 4
139 if (authlen >= (0x01ULL << 32)) {
140 /* Encode L(a) as 0xff || 0xff || <64-bit integer> */
141 ctx->tag.b[ctx->blength++] ^= 0xff;
142 ctx->tag.b[ctx->blength++] ^= 0xff;
143 ctx->tag.b[ctx->blength++] ^= (authlen >> 56) & 0xff;
144 ctx->tag.b[ctx->blength++] ^= (authlen >> 48) & 0xff;
145 ctx->tag.b[ctx->blength++] ^= (authlen >> 40) & 0xff;
146 ctx->tag.b[ctx->blength++] ^= (authlen >> 32) & 0xff;
147 ctx->tag.b[ctx->blength++] ^= (authlen >> 24) & 0xff;
148 ctx->tag.b[ctx->blength++] ^= (authlen >> 16) & 0xff;
152 if (authlen >= ((0x1ULL << 16) - (0x1ULL << 8))) {
153 /* Encode L(a) as 0xff || 0xfe || <32-bit integer> */
154 ctx->tag.b[ctx->blength++] ^= 0xff;
155 ctx->tag.b[ctx->blength++] ^= 0xfe;
156 ctx->tag.b[ctx->blength++] ^= (authlen >> 24) & 0xff;
157 ctx->tag.b[ctx->blength++] ^= (authlen >> 16) & 0xff;
159 ctx->tag.b[ctx->blength++] ^= (authlen >> 8) & 0xff;
160 ctx->tag.b[ctx->blength++] ^= (authlen >> 0) & 0xff;
164 ccm_update(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
165 size_t length, const uint8_t *data)
167 const uint8_t *end = data + length;
169 /* If we don't have enough to fill a block, save the data for later. */
170 if ((ctx->blength + length) < CCM_BLOCK_SIZE) {
171 memxor(&ctx->tag.b[ctx->blength], data, length);
172 ctx->blength += length;
176 /* Process a partially filled block. */
178 memxor(&ctx->tag.b[ctx->blength], data, CCM_BLOCK_SIZE - ctx->blength);
179 data += (CCM_BLOCK_SIZE - ctx->blength);
180 f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
183 /* Process full blocks. */
184 while ((data + CCM_BLOCK_SIZE) < end) {
185 memxor(ctx->tag.b, data, CCM_BLOCK_SIZE);
186 f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
187 data += CCM_BLOCK_SIZE;
190 /* Save leftovers for later. */
191 ctx->blength = (end - data);
192 if (ctx->blength) memxor(&ctx->tag.b, data, ctx->blength);
196 * Because of the underlying CTR mode encryption, when called multiple times
197 * the data in intermediate calls must be provided in multiples of the block
201 ccm_encrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
202 size_t length, uint8_t *dst, const uint8_t *src)
204 ccm_pad(ctx, cipher, f);
205 ccm_update(ctx, cipher, f, length, src);
206 ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src);
210 * Because of the underlying CTR mode decryption, when called multiple times
211 * the data in intermediate calls must be provided in multiples of the block
215 ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
216 size_t length, uint8_t *dst, const uint8_t *src)
218 ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src);
219 ccm_pad(ctx, cipher, f);
220 ccm_update(ctx, cipher, f, length, dst);
224 ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
225 size_t length, uint8_t *digest)
227 int i = CCM_BLOCK_SIZE - CCM_FLAG_GET_L(ctx->ctr.b[CCM_OFFSET_FLAGS]);
228 assert(length <= CCM_BLOCK_SIZE);
229 while (i < CCM_BLOCK_SIZE) ctx->ctr.b[i++] = 0;
230 ccm_pad(ctx, cipher, f);
231 ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, digest, ctx->tag.b);
235 ccm_encrypt_message(const void *cipher, nettle_cipher_func *f,
236 size_t nlength, const uint8_t *nonce,
237 size_t alength, const uint8_t *adata, size_t tlength,
238 size_t clength, uint8_t *dst, const uint8_t *src)
241 uint8_t *tag = dst + (clength-tlength);
242 assert(clength >= tlength);
243 ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, clength-tlength, tlength);
244 ccm_update(&ctx, cipher, f, alength, adata);
245 ccm_encrypt(&ctx, cipher, f, clength-tlength, dst, src);
246 ccm_digest(&ctx, cipher, f, tlength, tag);
249 /* FIXME: Should be made public, under some suitable name. */
251 memeql_sec (const void *a, const void *b, size_t n)
253 volatile const unsigned char *ap = (const unsigned char *) a;
254 volatile const unsigned char *bp = (const unsigned char *) b;
255 volatile unsigned char d;
257 for (d = i = 0; i < n; i++)
258 d |= (ap[i] ^ bp[i]);
263 ccm_decrypt_message(const void *cipher, nettle_cipher_func *f,
264 size_t nlength, const uint8_t *nonce,
265 size_t alength, const uint8_t *adata, size_t tlength,
266 size_t mlength, uint8_t *dst, const uint8_t *src)
269 uint8_t tag[CCM_BLOCK_SIZE];
270 ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, mlength, tlength);
271 ccm_update(&ctx, cipher, f, alength, adata);
272 ccm_decrypt(&ctx, cipher, f, mlength, dst, src);
273 ccm_digest(&ctx, cipher, f, tlength, tag);
274 return memeql_sec(tag, src + mlength, tlength);