ASCON Suite
ascon-hmac-common.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 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 /*
24  * The contents of this header file expand out to the full implementation of
25  * HMAC for a specific underlying hash algorithm. We expect a number of
26  * macros to be defined before this file is included to configure the
27  * underlying HMAC variant:
28  *
29  * HMAC_ALG_NAME Name of the HMAC algorithm; e.g. ascon_hmac
30  * HMAC_HASH_SIZE Size of the hash output for the underlying algorithm.
31  * HMAC_BLOCK_SIZE Size of the formatted key block for HMAC.
32  * HMAC_STATE Type for the HMAC state; e.g. ascon_hmac_state_t
33  * HMAC_HASH_INIT Name of the hash initialization function.
34  * HMAC_HASH_REINIT Name of the hash re-initialization function.
35  * HMAC_HASH_FREE Name of the hash state free function.
36  * HMAC_HASH_UPDATE Name of the hash update function.
37  * HMAC_HASH_FINALIZE Name of the hash finalization function.
38  */
39 #if defined(HMAC_ALG_NAME)
40 
41 #define HMAC_CONCAT_INNER(name,suffix) name##suffix
42 #define HMAC_CONCAT(name,suffix) HMAC_CONCAT_INNER(name,suffix)
43 
45 #define HMAC_IPAD 0x36
46 
48 #define HMAC_OPAD 0x5C
49 
58 static void HMAC_CONCAT(HMAC_ALG_NAME,_xor_pad)
59  (unsigned char *out, const unsigned char *in,
60  size_t size, unsigned char pad)
61 {
62  while (size > 0) {
63  *out++ = *in++ ^ pad;
64  --size;
65  }
66 }
67 
79 static void HMAC_CONCAT(HMAC_ALG_NAME,_absorb_key)
80  (HMAC_STATE *state, const unsigned char *key, size_t keylen,
81  unsigned char pad)
82 {
83  unsigned char temp[HMAC_HASH_SIZE];
84  size_t posn, len;
85 
86  /* Break the key up into smaller chunks and XOR it with "pad".
87  * We do it this way to avoid having a large buffer on the
88  * stack of size HMAC_BLOCK_SIZE. */
89  if (keylen <= HMAC_BLOCK_SIZE) {
90  posn = 0;
91  while (posn < keylen) {
92  len = keylen - posn;
93  if (len > HMAC_HASH_SIZE)
94  len = HMAC_HASH_SIZE;
95  HMAC_CONCAT(HMAC_ALG_NAME,_xor_pad)(temp, key + posn, len, pad);
96  HMAC_HASH_UPDATE(&(state->hash), temp, len);
97  posn += len;
98  }
99  } else {
100  /* Hash long keys down first and then absorb */
101  HMAC_HASH_UPDATE(&(state->hash), key, keylen);
102  HMAC_HASH_FINALIZE(&(state->hash), temp);
103  HMAC_HASH_REINIT(&(state->hash));
104  HMAC_CONCAT(HMAC_ALG_NAME,_xor_pad)(temp, temp, HMAC_HASH_SIZE, pad);
105  HMAC_HASH_UPDATE(&(state->hash), temp, HMAC_HASH_SIZE);
106  posn = HMAC_HASH_SIZE;
107  }
108 
109  /* Pad the rest of the block with the padding value */
110  memset(temp, pad, sizeof(temp));
111  while (posn < HMAC_BLOCK_SIZE) {
112  len = HMAC_BLOCK_SIZE - posn;
113  if (len > HMAC_HASH_SIZE)
114  len = HMAC_HASH_SIZE;
115  HMAC_HASH_UPDATE(&(state->hash), temp, len);
116  posn += len;
117  }
118 
119  /* Clean up sensitive key material on the stack */
120  ascon_clean(temp, sizeof(temp));
121 }
122 
123 void HMAC_ALG_NAME
124  (unsigned char *out,
125  const unsigned char *key, size_t keylen,
126  const unsigned char *in, size_t inlen)
127 {
129  HMAC_HASH_INIT(&(state.hash));
130  HMAC_CONCAT(HMAC_ALG_NAME,_absorb_key)(&state, key, keylen, HMAC_IPAD);
131  HMAC_HASH_UPDATE(&(state.hash), in, inlen);
132  HMAC_CONCAT(HMAC_ALG_NAME,_finalize)(&state, key, keylen, out);
133  HMAC_HASH_FREE(&(state.hash));
134 }
135 
136 void HMAC_CONCAT(HMAC_ALG_NAME,_init)
137  (HMAC_STATE *state, const unsigned char *key, size_t keylen)
138 {
139  HMAC_HASH_INIT(&(state->hash));
140  HMAC_CONCAT(HMAC_ALG_NAME,_absorb_key)(state, key, keylen, HMAC_IPAD);
141 }
142 
143 void HMAC_CONCAT(HMAC_ALG_NAME,_reinit)
144  (HMAC_STATE *state, const unsigned char *key, size_t keylen)
145 {
146  HMAC_HASH_REINIT(&(state->hash));
147  HMAC_CONCAT(HMAC_ALG_NAME,_absorb_key)(state, key, keylen, HMAC_IPAD);
148 }
149 
150 void HMAC_CONCAT(HMAC_ALG_NAME,_free)(HMAC_STATE *state)
151 {
152  if (state)
153  HMAC_HASH_FREE(&(state->hash));
154 }
155 
156 void HMAC_CONCAT(HMAC_ALG_NAME,_update)
157  (HMAC_STATE *state, const unsigned char *in, size_t inlen)
158 {
159  HMAC_HASH_UPDATE(&(state->hash), in, inlen);
160 }
161 
162 void HMAC_CONCAT(HMAC_ALG_NAME,_finalize)
163  (HMAC_STATE *state, const unsigned char *key, size_t keylen,
164  unsigned char *out)
165 {
166  unsigned char temp[HMAC_HASH_SIZE];
167  HMAC_HASH_FINALIZE(&(state->hash), temp);
168  HMAC_HASH_REINIT(&(state->hash));
169  HMAC_CONCAT(HMAC_ALG_NAME,_absorb_key)(state, key, keylen, HMAC_OPAD);
170  HMAC_HASH_UPDATE(&(state->hash), temp, HMAC_HASH_SIZE);
171  HMAC_HASH_FINALIZE(&(state->hash), out);
172  ascon_clean(temp, sizeof(temp));
173 }
174 
175 #endif /* HMAC_ALG_NAME */
176 
177 /* Now undefine everything so that we can include this file again for
178  * another variant on the HMAC algorithm */
179 #undef HMAC_ALG_NAME
180 #undef HMAC_HASH_SIZE
181 #undef HMAC_BLOCK_SIZE
182 #undef HMAC_STATE
183 #undef HMAC_HASH_INIT
184 #undef HMAC_HASH_REINIT
185 #undef HMAC_HASH_UPDATE
186 #undef HMAC_HASH_FINALIZE
187 #undef HMAC_CONCAT_INNER
188 #undef HMAC_CONCAT
189 #undef HMAC_IPAD
190 #undef HMAC_OPAD
#define HMAC_HASH_FINALIZE
Definition: ascon-hmac.c:38
#define HMAC_HASH_FREE
Definition: ascon-hmac.c:36
#define HMAC_HASH_INIT
Definition: ascon-hmac.c:34
#define HMAC_HASH_UPDATE
Definition: ascon-hmac.c:37
#define HMAC_STATE
Definition: ascon-hmac.c:33
#define HMAC_HASH_REINIT
Definition: ascon-hmac.c:35
#define HMAC_ALG_NAME
Definition: ascon-hmac.c:30
#define HMAC_HASH_SIZE
Definition: ascon-hmac.c:31
#define HMAC_BLOCK_SIZE
Definition: ascon-hmac.c:32
ascon_state_t state
[snippet_key]
Definition: snippets.c:2
void ascon_clean(void *buf, unsigned size)
Cleans a buffer that contains sensitive material.
Definition: ascon-clean.c:38