4 * This file is part of BeRTOS.
6 * Bertos 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 2 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
33 * \brief OMAC implementation
34 * \author Giovanni Bajo <rasky@develer.com>
38 #include <cfg/macros.h>
41 static void omac_set_key(Mac *ctx_, const void* key, size_t len)
43 OmacContext *ctx = (OmacContext *)ctx_;
44 cipher_set_vkey(ctx->c, key, len);
47 static void omac_begin(Mac *ctx_)
49 OmacContext *ctx = (OmacContext *)ctx_;
53 memset(ctx->Y, 0, cipher_block_len(ctx->c));
54 cipher_cbc_begin(ctx->c, ctx->Y);
57 static void omac_update(Mac *ctx_, const void *data_, size_t len)
59 OmacContext *ctx = (OmacContext *)ctx_;
60 size_t blen = cipher_block_len(ctx->c);
61 const uint8_t *data = (const uint8_t *)data_;
65 ASSERT(ctx->acc <= blen);
68 cipher_cbc_encrypt(ctx->c, ctx->accum);
72 size_t L = MIN(len, blen - ctx->acc);
73 memcpy(ctx->accum + ctx->acc, data, L);
80 static void omac_shift_left(uint8_t *L, size_t len)
82 int firstbit = L[0] >> 7;
85 for (i=0; i<len-1; ++i)
86 L[i] = (L[i] << 1) | (L[i+1] >> 7);
100 static void omac_shift_right(uint8_t *L, size_t len)
102 int firstbit = L[len-1] & 1;
105 for (i=len-1; i>0; --i)
106 L[i] = (L[i] >> 1) | (L[i-1] << 7);
121 static uint8_t *omac1_final(Mac *ctx_)
123 OmacContext *ctx = (OmacContext *)ctx_;
124 size_t blen = cipher_block_len(ctx->c);
128 cipher_ecb_encrypt(ctx->c, L);
130 omac_shift_left(L, blen);
133 ctx->accum[ctx->acc++] = 0x80;
134 memset(ctx->accum + ctx->acc, 0, blen - ctx->acc);
135 omac_shift_left(L, blen);
138 xor_block(ctx->accum, ctx->accum, L, blen);
139 cipher_cbc_encrypt(ctx->c, ctx->accum);
143 static uint8_t *omac2_final(Mac *ctx_)
145 OmacContext *ctx = (OmacContext *)ctx_;
146 size_t blen = cipher_block_len(ctx->c);
150 cipher_ecb_encrypt(ctx->c, L);
154 ctx->accum[ctx->acc++] = 0x80;
155 memset(ctx->accum + ctx->acc, 0, blen - ctx->acc);
156 omac_shift_right(L, blen);
159 omac_shift_left(L, blen);
161 xor_block(ctx->accum, ctx->accum, L, blen);
162 cipher_cbc_encrypt(ctx->c, ctx->accum);
167 /****************************************************************************/
169 static void omac_init(OmacContext *ctx, BlockCipher *c)
171 ctx->mac.set_key = omac_set_key;
172 ctx->mac.begin = omac_begin;
173 ctx->mac.update = omac_update;
174 ctx->mac.key_len = cipher_key_len(c);
175 ctx->mac.digest_len = cipher_block_len(c);
178 ASSERT(cipher_block_len(c) == 8 || cipher_block_len(c) == 16);
179 ASSERT(sizeof(ctx->Y) >= cipher_block_len(c));
180 ASSERT(sizeof(ctx->accum) >= cipher_block_len(c));
183 void omac1_init(OmacContext *ctx, BlockCipher *c)
186 ctx->mac.final = omac1_final;
189 void omac2_init(OmacContext *ctx, BlockCipher *c)
192 ctx->mac.final = omac2_final;