Arduino Cryptography Library
GHASH.cpp
1 /*
2  * Copyright (C) 2015 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 "GHASH.h"
24 #include "GF128.h"
25 #include "Crypto.h"
26 #include <string.h>
27 
48 {
49  state.posn = 0;
50 }
51 
56 {
57  clean(state);
58 }
59 
67 void GHASH::reset(const void *key)
68 {
69  GF128::mulInit(state.H, key);
70  memset(state.Y, 0, sizeof(state.Y));
71  state.posn = 0;
72 }
73 
85 void GHASH::update(const void *data, size_t len)
86 {
87  // XOR the input with state.Y in 128-bit chunks and process them.
88  const uint8_t *d = (const uint8_t *)data;
89  while (len > 0) {
90  uint8_t size = 16 - state.posn;
91  if (size > len)
92  size = len;
93  uint8_t *y = ((uint8_t *)state.Y) + state.posn;
94  for (uint8_t i = 0; i < size; ++i)
95  y[i] ^= d[i];
96  state.posn += size;
97  len -= size;
98  d += size;
99  if (state.posn == 16) {
100  GF128::mul(state.Y, state.H);
101  state.posn = 0;
102  }
103  }
104 }
105 
121 void GHASH::finalize(void *token, size_t len)
122 {
123  // Pad with zeroes to a multiple of 16 bytes.
124  pad();
125 
126  // The token is the current value of Y.
127  if (len > 16)
128  len = 16;
129  memcpy(token, state.Y, len);
130 }
131 
138 {
139  if (state.posn != 0) {
140  // Padding involves XOR'ing the rest of state.Y with zeroes,
141  // which does nothing. Immediately process the next chunk.
142  GF128::mul(state.Y, state.H);
143  state.posn = 0;
144  }
145 }
146 
151 {
152  clean(state);
153 }
static void mulInit(uint32_t H[4], const void *key)
Initialize multiplication in the GF(2^128) field.
Definition: GF128.cpp:58
static void mul(uint32_t Y[4], const uint32_t H[4])
Perform a multiplication in the GF(2^128) field.
Definition: GF128.cpp:90
void update(const void *data, size_t len)
Updates the message authenticator with more data.
Definition: GHASH.cpp:85
GHASH()
Constructs a new GHASH message authenticator.
Definition: GHASH.cpp:47
void reset(const void *key)
Resets the GHASH message authenticator for a new session.
Definition: GHASH.cpp:67
void clear()
Clears the authenticator's state, removing all sensitive data.
Definition: GHASH.cpp:150
void pad()
Pads the input stream with zero bytes to a multiple of 16.
Definition: GHASH.cpp:137
void finalize(void *token, size_t len)
Finalizes the authentication process and returns the token.
Definition: GHASH.cpp:121
~GHASH()
Destroys this GHASH message authenticator.
Definition: GHASH.cpp:55