3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2015 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <blockcipher_descriptor.h>
25 #include <bcal-basic.h>
32 #define DUMP_LEN_LINE(x, len, line) do { \
33 printf("\n\n (DBG <" __FILE__ " %s " #line ">)" #x ":", __func__); \
34 cli_hexdump_block((x), (len), 4, 16); \
35 uart0_flush(); } while (0)
37 #define DUMP_dummy(x, len, v) DUMP_LEN_LINE(x, len, v)
38 #define DUMP_LEN(x, len) DUMP_dummy(x, len, __LINE__)
41 #define DUMP(x) DUMP_LEN(x, sizeof(x))
44 #define BLOCK_BYTES GCM128_BLOCK_BYTES
45 #define BLOCK_BITS GCM128_BLOCK_BITS
47 #define COUNT_BYTES GCM128_COUNT_BYTES
48 #define COUNT_BITS GCM128_COUNT_BITS
50 #define POLY_BYTE 0xE1
53 static uint8_t shift_block_right(void *a)
56 uint8_t i = BLOCK_BYTES;
72 uint8_t c, v[BLOCK_BYTES], t, dummy[BLOCK_BYTES + 1], *(lut[2]);
75 memset(dest, 0, BLOCK_BYTES);
76 memset(dummy, 0, BLOCK_BYTES);
77 dummy[BLOCK_BYTES] = POLY_BYTE;
78 memcpy(v, a, BLOCK_BYTES);
86 memxor(dest, lut[t >> 7], BLOCK_BYTES);
88 c = shift_block_right(v);
89 v[0] ^= dummy[15 + c];
94 static void ghash128_init(ghash128_ctx_t *ctx)
96 memset(ctx->tag, 0, 16);
99 static void ghash128_block(
103 uint8_t tmp[BLOCK_BYTES];
104 memcpy(tmp, ctx->tag, BLOCK_BYTES);
105 memxor(tmp, block, BLOCK_BYTES);
106 gmul128(ctx->tag, tmp, ctx->key);
109 static void inc32(void *a)
113 c &= ((p[2] += c) == 0);
114 c &= ((p[1] += c) == 0);
120 const bcdesc_t *cipher,
122 uint16_t key_length_b,
124 uint16_t iv_length_b)
127 uint8_t tmp[BLOCK_BYTES];
128 if (bcal_cipher_getBlocksize_b(cipher) != BLOCK_BITS) {
131 if ((r = bcal_cipher_init(cipher, key, key_length_b, &ctx->cipher_ctx))) {
132 printf_P(PSTR("Error: return code: %"PRId8" key length: %"PRId16" <%s %s %d>\n"), r, key_length_b, __FILE__, __func__, __LINE__);
136 memset(ctx->ghash_ctx.key, 0, BLOCK_BYTES);
137 bcal_cipher_enc(ctx->ghash_ctx.key, &ctx->cipher_ctx);
138 ghash128_init(&ctx->ghash_ctx);
139 if (iv_length_b == BLOCK_BITS - COUNT_BITS) {
140 memcpy(ctx->ctr, iv, (BLOCK_BITS - COUNT_BITS) / 8);
141 memset(&ctx->ctr[BLOCK_BYTES - COUNT_BYTES], 0, COUNT_BYTES - 1);
142 ctx->ctr[BLOCK_BYTES - 1] = 1;
144 uint16_t ctr = iv_length_b / BLOCK_BITS;
147 ghash128_block(&ctx->ghash_ctx, iv);
148 iv = &((uint8_t*)iv)[BLOCK_BYTES];
150 memset(tmp, 0, BLOCK_BYTES);
151 memcpy(tmp, iv, (iv_length_b % BLOCK_BITS + 7) / 8);
152 if (iv_length_b & 7) {
153 tmp[(iv_length_b % BLOCK_BITS) / 8] &= 0xff << (8 - (iv_length_b & 7));
155 ghash128_block(&ctx->ghash_ctx, tmp);
156 memset(tmp, 0, BLOCK_BYTES);
157 tmp[BLOCK_BYTES - 2] = iv_length_b >> 8;
158 tmp[BLOCK_BYTES - 1] = iv_length_b & 0xff;
159 ghash128_block(&ctx->ghash_ctx, tmp);
160 memcpy(ctx->ctr, ctx->ghash_ctx.tag, BLOCK_BYTES);
161 ghash128_init(&ctx->ghash_ctx);
163 memcpy(ctx->j0, &ctx->ctr[BLOCK_BYTES - COUNT_BYTES], COUNT_BYTES);
169 void gcm128_add_ad_block(
173 ghash128_block(&ctx->ghash_ctx, block);
174 ctx->length_a += BLOCK_BITS;
177 void gcm128_add_ad_final_block(
182 uint8_t tmp[BLOCK_BYTES];
183 while (length_b >= BLOCK_BITS)
185 gcm128_add_ad_block(ctx, block);
186 length_b -= BLOCK_BITS;
187 block = &((uint8_t*)block)[BLOCK_BYTES];
190 memset(tmp, 0, BLOCK_BYTES);
191 memcpy(tmp, block, (length_b + 7) / 8);
193 tmp[length_b / 8] &= 0xff << (8 - (length_b & 7));
195 ghash128_block(&ctx->ghash_ctx, tmp);
196 ctx->length_a += length_b;
200 void gcm128_encrypt_block(
205 uint8_t tmp[BLOCK_BYTES];
206 inc32(&ctx->ctr[BLOCK_BYTES - COUNT_BYTES]);
207 memcpy(tmp, ctx->ctr, BLOCK_BYTES);
208 bcal_cipher_enc(tmp, &ctx->cipher_ctx);
209 memxor(tmp, src, BLOCK_BYTES);
210 ghash128_block(&ctx->ghash_ctx, tmp);
211 ctx->length_c += BLOCK_BITS;
213 memcpy(dest, tmp, BLOCK_BYTES);
217 void gcm128_encrypt_final_block(
224 uint8_t tmp[BLOCK_BYTES];
225 while (length_b >= BLOCK_BITS) {
226 gcm128_encrypt_block(ctx, dest, src);
227 length_b -= BLOCK_BITS;
229 dest = &((uint8_t*)dest)[BLOCK_BYTES];
231 src = &((uint8_t*)src)[BLOCK_BYTES];
234 inc32(&ctx->ctr[BLOCK_BYTES - COUNT_BYTES]);
235 memcpy(tmp, ctx->ctr, BLOCK_BYTES);
236 bcal_cipher_enc(tmp, &ctx->cipher_ctx);
237 memxor(tmp, src, BLOCK_BYTES);
238 memset(&tmp[(length_b + 7) / 8], 0, BLOCK_BYTES - (length_b + 7) / 8);
240 tmp[length_b / 8] &= 0xff << (8 - (length_b & 7));
242 ghash128_block(&ctx->ghash_ctx, tmp);
243 ctx->length_c += length_b;
245 memcpy(dest, tmp, (length_b + 7) / 8);
250 void gcm128_decrypt_block(
255 uint8_t tmp[BLOCK_BYTES];
256 ghash128_block(&ctx->ghash_ctx, src);
257 inc32(&ctx->ctr[BLOCK_BYTES - COUNT_BYTES]);
258 memcpy(tmp, ctx->ctr, BLOCK_BYTES);
259 bcal_cipher_enc(tmp, &ctx->cipher_ctx);
260 memxor(tmp, src, BLOCK_BYTES);
261 ctx->length_c += BLOCK_BITS;
263 memcpy(dest, tmp, BLOCK_BYTES);
267 void gcm128_decrypt_final_block(
273 uint8_t tmp[BLOCK_BYTES];
274 while (length_b > BLOCK_BITS) {
275 gcm128_decrypt_block(ctx, dest, src);
276 length_b -= BLOCK_BITS;
278 dest = &((uint8_t*)dest)[BLOCK_BYTES];
280 src = &((uint8_t*)src)[BLOCK_BYTES];
283 memcpy(tmp, src, (length_b + 7) / 8);
284 memset(&tmp[(length_b + 7) / 8], 0, BLOCK_BYTES - (length_b + 7) / 8);
286 tmp[length_b / 8] &= 0xff << (8 - (length_b & 7));
288 ghash128_block(&ctx->ghash_ctx, tmp);
289 inc32(&ctx->ctr[BLOCK_BYTES - COUNT_BYTES]);
290 memcpy(tmp, ctx->ctr, BLOCK_BYTES);
291 bcal_cipher_enc(tmp, &ctx->cipher_ctx);
292 memxor(tmp, src, BLOCK_BYTES);
293 memset(&tmp[(length_b + 7) / 8], 0, BLOCK_BYTES - (length_b + 7) / 8);
295 tmp[length_b / 8] &= 0xff << (8 - (length_b & 7));
297 ctx->length_c += length_b;
299 memcpy(dest, tmp, (length_b + 7) / 8);
304 void gcm128_finalize(gcm128_ctx_t *ctx, void *tag, uint16_t tag_length_b)
306 uint8_t tmp[BLOCK_BYTES];
307 memset(tmp, 0, BLOCK_BYTES);
308 tmp[4] = ctx->length_a >> 24;
309 tmp[5] = ctx->length_a >> 16;
310 tmp[6] = ctx->length_a >> 8;
311 tmp[7] = ctx->length_a;
312 tmp[12] = ctx->length_c >> 24;
313 tmp[13] = ctx->length_c >> 16;
314 tmp[14] = ctx->length_c >> 8;
315 tmp[15] = ctx->length_c;
316 ghash128_block(&ctx->ghash_ctx, tmp);
317 memcpy(tmp, ctx->ctr, BLOCK_BYTES - COUNT_BYTES);
318 memcpy(&tmp[BLOCK_BYTES - COUNT_BYTES], ctx->j0, COUNT_BYTES);
319 bcal_cipher_enc(tmp, &ctx->cipher_ctx);
320 bcal_cipher_free(&ctx->cipher_ctx);
321 memxor(tmp, ctx->ghash_ctx.tag, BLOCK_BYTES);
322 if (tag_length_b > BLOCK_BITS) {
323 tag_length_b = BLOCK_BITS;
325 if (tag_length_b & 7) {
326 tmp[tag_length_b / 8] &= 0xff << (8 - (tag_length_b & 7));
329 memcpy(tag, tmp, (tag_length_b + 7) / 8);