Arduino Cryptography Library
OMAC.cpp
1 /*
2  * Copyright (C) 2016 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "OMAC.h"
24 #include "GF128.h"
25 #include "Crypto.h"
26 #include <string.h>
27 
49  : _blockCipher(0)
50  , posn(0)
51 {
52 }
53 
60 {
61  clean(b);
62 }
63 
101 void OMAC::initFirst(uint8_t omac[16])
102 {
103  // Start the OMAC context. We assume that the data that follows
104  // will be at least 1 byte in length so that we can encrypt the
105  // zeroes now to derive the B value.
106  memset(omac, 0, 16);
107  _blockCipher->encryptBlock(omac, omac);
108  posn = 0;
109 
110  // Generate the B value from the encrypted block of zeroes.
111  // We will need this later when finalising the OMAC hashes.
112  memcpy(b, omac, 16);
113  GF128::dblEAX(b);
114 }
115 
127 void OMAC::initNext(uint8_t omac[16], uint8_t tag)
128 {
129  memset(omac, 0, 15);
130  omac[15] = tag;
131  posn = 16;
132 }
133 
143 void OMAC::update(uint8_t omac[16], const uint8_t *data, size_t size)
144 {
145  while (size > 0) {
146  // Encrypt the current block if it is already full.
147  if (posn == 16) {
148  _blockCipher->encryptBlock(omac, omac);
149  posn = 0;
150  }
151 
152  // XOR the incoming data with the current block.
153  uint8_t len = 16 - posn;
154  if (len > size)
155  len = (uint8_t)size;
156  for (uint8_t index = 0; index < len; ++index)
157  omac[posn++] ^= data[index];
158 
159  // Move onto the next block.
160  size -= len;
161  data += len;
162  }
163 }
164 
172 void OMAC::finalize(uint8_t omac[16])
173 {
174  // Apply padding if necessary.
175  if (posn != 16) {
176  // Need padding: XOR with P = 2 * B.
177  uint32_t p[4];
178  memcpy(p, b, 16);
179  GF128::dblEAX(p);
180  omac[posn] ^= 0x80;
181  for (uint8_t index = 0; index < 16; ++index)
182  omac[index] ^= ((const uint8_t *)p)[index];
183  clean(p);
184  } else {
185  // No padding necessary: XOR with B.
186  for (uint8_t index = 0; index < 16; ++index)
187  omac[index] ^= ((const uint8_t *)b)[index];
188  }
189 
190  // Encrypt the hash to get the final OMAC value.
191  _blockCipher->encryptBlock(omac, omac);
192 }
193 
198 {
199  clean(b);
200 }
virtual void encryptBlock(uint8_t *output, const uint8_t *input)=0
Encrypts a single block using this cipher.
static void dblEAX(uint32_t V[4])
Doubles a value in the GF(2^128) field using EAX conventions.
Definition: GF128.cpp:406
void initFirst(uint8_t omac[16])
Initialises the first OMAC hashing context and creates the B value.
Definition: OMAC.cpp:101
void clear()
Clears all security-sensitive state from this object.
Definition: OMAC.cpp:197
void update(uint8_t omac[16], const uint8_t *data, size_t size)
Updates an OMAC hashing context with more data.
Definition: OMAC.cpp:143
~OMAC()
Destroys this OMAC object.
Definition: OMAC.cpp:59
void initNext(uint8_t omac[16], uint8_t tag)
Initialises or restarts an OMAC hashing context.
Definition: OMAC.cpp:127
void finalize(uint8_t omac[16])
Finalises an OMAC hashing context.
Definition: OMAC.cpp:172
OMAC()
Constructs a new OMAC object.
Definition: OMAC.cpp:48