2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 * Implementation Notes
29 * ====================
31 * The combined CTR + CBC-MAC functions can only handle full blocks,
32 * so some buffering is necessary. Moreover, EAX has a special padding
33 * rule for CBC-MAC, which implies that we cannot compute the MAC over
34 * the last received full block until we know whether we are at the
35 * end of the data or not.
37 * - 'ptr' contains a value from 1 to 16, which is the number of bytes
38 * accumulated in buf[] that still needs to be processed with the
39 * current OMAC computation. Beware that this can go to 16: a
40 * complete block cannot be processed until it is known whether it
41 * is the last block or not. However, it can never be 0, because
42 * OMAC^t works on an input that is at least one-block long.
44 * - When processing the message itself, CTR encryption/decryption is
45 * also done at the same time. The first 'ptr' bytes of buf[] then
46 * contains the encrypted bytes, while the last '16 - ptr' bytes of
47 * buf[] are the remnants of the stream block, to be used against
48 * the next input bytes, when available.
50 * - The current counter and running CBC-MAC values are kept in 'ctr'
51 * and 'cbcmac', respectively.
53 * - The derived keys for padding are kept in L2 and L4 (double and
54 * quadruple of Enc_K(0^n), in GF(2^128), respectively).
58 * Start an OMAC computation; the first block is the big-endian
59 * representation of the provided value ('val' must fit on one byte).
60 * We make it a delayed block because it may also be the last one,
63 omac_start(br_eax_context
*ctx
, unsigned val
)
65 memset(ctx
->cbcmac
, 0, sizeof ctx
->cbcmac
);
66 memset(ctx
->buf
, 0, sizeof ctx
->buf
);
72 * Double a value in finite field GF(2^128), defined with modulus
76 double_gf128(unsigned char *dst
, const unsigned char *src
)
81 cc
= 0x87 & -((unsigned)src
[0] >> 7);
82 for (i
= 15; i
>= 0; i
--) {
85 z
= (src
[i
] << 1) ^ cc
;
87 dst
[i
] = (unsigned char)z
;
92 * Apply padding to the last block, currently in ctx->buf (with
93 * ctx->ptr bytes), and finalize OMAC computation.
96 do_pad(br_eax_context
*ctx
)
105 ctx
->buf
[ptr
++] = 0x80;
106 memset(ctx
->buf
+ ptr
, 0x00, 16 - ptr
);
109 for (u
= 0; u
< sizeof ctx
->buf
; u
++) {
110 ctx
->buf
[u
] ^= pad
[u
];
112 (*ctx
->bctx
)->mac(ctx
->bctx
, ctx
->cbcmac
, ctx
->buf
, sizeof ctx
->buf
);
116 * Apply CBC-MAC on the provided data, with buffering management. This
117 * function assumes that on input, ctx->buf contains a full block of
121 do_cbcmac_chunk(br_eax_context
*ctx
, const void *data
, size_t len
)
128 ptr
= len
& (size_t)15;
135 (*ctx
->bctx
)->mac(ctx
->bctx
, ctx
->cbcmac
, ctx
->buf
, sizeof ctx
->buf
);
136 (*ctx
->bctx
)->mac(ctx
->bctx
, ctx
->cbcmac
, data
, len
);
137 memcpy(ctx
->buf
, (const unsigned char *)data
+ len
, ptr
);
141 /* see bearssl_aead.h */
143 br_eax_init(br_eax_context
*ctx
, const br_block_ctrcbc_class
**bctx
)
145 unsigned char tmp
[16], iv
[16];
147 ctx
->vtable
= &br_eax_vtable
;
151 * Encrypt a whole-zero block to compute L2 and L4.
153 memset(tmp
, 0, sizeof tmp
);
154 memset(iv
, 0, sizeof iv
);
155 (*bctx
)->ctr(bctx
, iv
, tmp
, sizeof tmp
);
156 double_gf128(ctx
->L2
, tmp
);
157 double_gf128(ctx
->L4
, ctx
->L2
);
160 /* see bearssl_aead.h */
162 br_eax_reset(br_eax_context
*ctx
, const void *nonce
, size_t len
)
165 * Process nonce with OMAC^0.
168 do_cbcmac_chunk(ctx
, nonce
, len
);
170 memcpy(ctx
->nonce
, ctx
->cbcmac
, sizeof ctx
->cbcmac
);
173 * Start OMAC^1 for the AAD ("header" in the EAX specification).
178 /* see bearssl_aead.h */
180 br_eax_aad_inject(br_eax_context
*ctx
, const void *data
, size_t len
)
187 * If there is a partial block, first complete it.
194 memcpy(ctx
->buf
+ ptr
, data
, len
);
195 ctx
->ptr
= ptr
+ len
;
198 memcpy(ctx
->buf
+ ptr
, data
, clen
);
199 data
= (const unsigned char *)data
+ clen
;
204 * We now have a full block in buf[], and this is not the last
207 do_cbcmac_chunk(ctx
, data
, len
);
210 /* see bearssl_aead.h */
212 br_eax_flip(br_eax_context
*ctx
)
215 * Complete the OMAC computation on the AAD.
218 memcpy(ctx
->head
, ctx
->cbcmac
, sizeof ctx
->cbcmac
);
221 * Start OMAC^2 for the encrypted data.
226 * Initial counter value for CTR is the processed nonce.
228 memcpy(ctx
->ctr
, ctx
->nonce
, sizeof ctx
->nonce
);
231 /* see bearssl_aead.h */
233 br_eax_run(br_eax_context
*ctx
, int encrypt
, void *data
, size_t len
)
239 * Ensure that there is actual data to process.
250 * We have a partially consumed block.
259 for (u
= 0; u
< clen
; u
++) {
260 ctx
->buf
[ptr
+ u
] ^= dbuf
[u
];
262 memcpy(dbuf
, ctx
->buf
+ ptr
, clen
);
264 for (u
= 0; u
< clen
; u
++) {
267 sx
= ctx
->buf
[ptr
+ u
];
269 ctx
->buf
[ptr
+ u
] = dx
;
275 ctx
->ptr
= ptr
+ clen
;
283 * We now have a complete encrypted block in buf[] that must still
284 * be processed with OMAC, and this is not the final buf.
286 (*ctx
->bctx
)->mac(ctx
->bctx
, ctx
->cbcmac
, ctx
->buf
, sizeof ctx
->buf
);
289 * Do CTR encryption or decryption and CBC-MAC for all full blocks
292 ptr
= len
& (size_t)15;
300 (*ctx
->bctx
)->encrypt(ctx
->bctx
, ctx
->ctr
, ctx
->cbcmac
,
303 (*ctx
->bctx
)->decrypt(ctx
->bctx
, ctx
->ctr
, ctx
->cbcmac
,
309 * Compute next block of CTR stream, and use it to finish
310 * encrypting or decrypting the data.
312 memset(ctx
->buf
, 0, sizeof ctx
->buf
);
313 (*ctx
->bctx
)->ctr(ctx
->bctx
, ctx
->ctr
, ctx
->buf
, sizeof ctx
->buf
);
317 for (u
= 0; u
< ptr
; u
++) {
318 ctx
->buf
[u
] ^= dbuf
[u
];
320 memcpy(dbuf
, ctx
->buf
, ptr
);
324 for (u
= 0; u
< ptr
; u
++) {
337 * Complete tag computation. The final tag is written in ctx->cbcmac.
340 do_final(br_eax_context
*ctx
)
347 * Authentication tag is the XOR of the three OMAC outputs for
348 * the nonce, AAD and encrypted data.
350 for (u
= 0; u
< 16; u
++) {
351 ctx
->cbcmac
[u
] ^= ctx
->nonce
[u
] ^ ctx
->head
[u
];
355 /* see bearssl_aead.h */
357 br_eax_get_tag(br_eax_context
*ctx
, void *tag
)
360 memcpy(tag
, ctx
->cbcmac
, sizeof ctx
->cbcmac
);
363 /* see bearssl_aead.h */
365 br_eax_get_tag_trunc(br_eax_context
*ctx
, void *tag
, size_t len
)
368 memcpy(tag
, ctx
->cbcmac
, len
);
371 /* see bearssl_aead.h */
373 br_eax_check_tag_trunc(br_eax_context
*ctx
, const void *tag
, size_t len
)
375 unsigned char tmp
[16];
379 br_eax_get_tag(ctx
, tmp
);
381 for (u
= 0; u
< len
; u
++) {
382 x
|= tmp
[u
] ^ ((const unsigned char *)tag
)[u
];
387 /* see bearssl_aead.h */
389 br_eax_check_tag(br_eax_context
*ctx
, const void *tag
)
391 return br_eax_check_tag_trunc(ctx
, tag
, 16);
394 /* see bearssl_aead.h */
395 const br_aead_class br_eax_vtable
= {
397 (void (*)(const br_aead_class
**, const void *, size_t))
399 (void (*)(const br_aead_class
**, const void *, size_t))
401 (void (*)(const br_aead_class
**))
403 (void (*)(const br_aead_class
**, int, void *, size_t))
405 (void (*)(const br_aead_class
**, void *))
407 (uint32_t (*)(const br_aead_class
**, const void *))
409 (void (*)(const br_aead_class
**, void *, size_t))
410 &br_eax_get_tag_trunc
,
411 (uint32_t (*)(const br_aead_class
**, const void *, size_t))
412 &br_eax_check_tag_trunc