Skip to content

Commit ff3ee47

Browse files
committed
Add one-shot HMAC generate and verify API
Add wc_HmacGenerate() and wc_HmacVerify(), plus _ex variants taking caller provided Hmac storage, heap and devId, modeled on the AES-CMAC one-shots. Tags are full length only. Move the async wait macro out of HAVE_HKDF so both can use it. Add docs and API tests.
1 parent 7d7e00b commit ff3ee47

5 files changed

Lines changed: 587 additions & 17 deletions

File tree

‎doc/dox_comments/header_files/hmac.h‎

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,163 @@ int wc_HmacFinal(Hmac* hmac, byte* out);
125125
*/
126126
int wolfSSL_GetHmacMaxSize(void);
127127

128+
/*!
129+
\ingroup HMAC
130+
131+
\brief Single shot function for generating an HMAC. Initializes, keys,
132+
hashes the message and finalizes in one call. The full digest size tag of
133+
the hash type is always written.
134+
135+
\return 0 on success
136+
\return BAD_FUNC_ARG if out or outSz is NULL, in is NULL with a non-zero
137+
inSz, key is NULL with a non-zero keySz, or type is invalid
138+
\return BUFFER_E if *outSz is smaller than the digest size of type
139+
\return MEMORY_E if allocating the HMAC context fails
140+
\return HMAC_MIN_KEYLEN_E may be returned in FIPS builds when the key is
141+
shorter than the FIPS minimum
142+
143+
\param type hash type, such as WC_SHA256 or WC_SHA3_384
144+
\param out buffer to hold the tag
145+
\param outSz on input the size of out, at least the digest size of type
146+
(WC_MAX_DIGEST_SIZE always fits); on output the digest size
147+
\param in message to authenticate
148+
\param inSz length of the message
149+
\param key HMAC key; may be NULL when keySz is 0
150+
\param keySz length of the key
151+
152+
_Example_
153+
\code
154+
byte tag[WC_SHA256_DIGEST_SIZE];
155+
word32 tagSz = sizeof(tag);
156+
ret = wc_HmacGenerate(WC_SHA256, tag, &tagSz, msg, msgSz, key, keySz);
157+
\endcode
158+
159+
\sa wc_HmacGenerate_ex
160+
\sa wc_HmacVerify
161+
*/
162+
int wc_HmacGenerate(int type, byte* out, word32* outSz,
163+
const byte* in, word32 inSz,
164+
const byte* key, word32 keySz);
165+
166+
/*!
167+
\ingroup HMAC
168+
169+
\brief Same as wc_HmacGenerate, but uses caller provided storage for the
170+
HMAC context and takes a heap hint and device ID. The context is
171+
initialized with wc_HmacInit and released with wc_HmacFree inside this
172+
call, so it must not hold a live HMAC operation on entry.
173+
174+
\return see wc_HmacGenerate; also BAD_FUNC_ARG if hmac is NULL
175+
\return WC_PENDING_E if a crypto callback device returned pending; the
176+
context has already been freed, so repeat the call with the same
177+
arguments
178+
179+
\param hmac storage for the HMAC context
180+
\param type hash type, such as WC_SHA256 or WC_SHA3_384
181+
\param out buffer to hold the tag
182+
\param outSz on input the size of out; on output the digest size
183+
\param in message to authenticate
184+
\param inSz length of the message
185+
\param key HMAC key; may be NULL when keySz is 0
186+
\param keySz length of the key
187+
\param heap heap hint for dynamic memory, or NULL
188+
\param devId device ID for crypto callbacks or async, or INVALID_DEVID
189+
190+
_Example_
191+
\code
192+
Hmac hmac;
193+
byte tag[WC_SHA256_DIGEST_SIZE];
194+
word32 tagSz = sizeof(tag);
195+
ret = wc_HmacGenerate_ex(&hmac, WC_SHA256, tag, &tagSz, msg, msgSz,
196+
key, keySz, NULL, devId);
197+
\endcode
198+
199+
\sa wc_HmacGenerate
200+
\sa wc_HmacVerify_ex
201+
*/
202+
int wc_HmacGenerate_ex(Hmac* hmac, int type, byte* out, word32* outSz,
203+
const byte* in, word32 inSz,
204+
const byte* key, word32 keySz,
205+
void* heap, int devId);
206+
207+
/*!
208+
\ingroup HMAC
209+
210+
\brief Single shot function for validating an HMAC. Computes the tag over
211+
the message and compares it against check in constant time. Only full
212+
length tags are accepted.
213+
214+
\return 0 if the tag matches
215+
\return MAC_CMP_FAILED_E if the tag does not match
216+
\return BAD_FUNC_ARG if check is NULL, checkSz is not the digest size of
217+
type, or any wc_HmacGenerate argument check fails
218+
\return MEMORY_E if allocating the HMAC context fails
219+
\return HMAC_MIN_KEYLEN_E may be returned in FIPS builds when the key is
220+
shorter than the FIPS minimum
221+
222+
\param type hash type, such as WC_SHA256 or WC_SHA3_384
223+
\param check expected tag
224+
\param checkSz length of the expected tag; must equal the digest size of
225+
type
226+
\param in message that was authenticated
227+
\param inSz length of the message
228+
\param key HMAC key; may be NULL when keySz is 0
229+
\param keySz length of the key
230+
231+
_Example_
232+
\code
233+
ret = wc_HmacVerify(WC_SHA256, tag, tagSz, msg, msgSz, key, keySz);
234+
if (ret == MAC_CMP_FAILED_E) {
235+
// reject the message
236+
}
237+
\endcode
238+
239+
\sa wc_HmacVerify_ex
240+
\sa wc_HmacGenerate
241+
*/
242+
int wc_HmacVerify(int type, const byte* check, word32 checkSz,
243+
const byte* in, word32 inSz,
244+
const byte* key, word32 keySz);
245+
246+
/*!
247+
\ingroup HMAC
248+
249+
\brief Same as wc_HmacVerify, but uses caller provided storage for the
250+
HMAC context and takes a heap hint and device ID. The context is
251+
initialized and freed inside this call.
252+
253+
\return see wc_HmacVerify; also BAD_FUNC_ARG if hmac is NULL
254+
\return WC_PENDING_E if a crypto callback device returned pending; the
255+
context has already been freed, so repeat the call with the same
256+
arguments
257+
258+
\param hmac storage for the HMAC context
259+
\param type hash type, such as WC_SHA256 or WC_SHA3_384
260+
\param check expected tag
261+
\param checkSz length of the expected tag; must equal the digest size of
262+
type
263+
\param in message that was authenticated
264+
\param inSz length of the message
265+
\param key HMAC key; may be NULL when keySz is 0
266+
\param keySz length of the key
267+
\param heap heap hint for dynamic memory, or NULL
268+
\param devId device ID for crypto callbacks or async, or INVALID_DEVID
269+
270+
_Example_
271+
\code
272+
Hmac hmac;
273+
ret = wc_HmacVerify_ex(&hmac, WC_SHA256, tag, tagSz, msg, msgSz,
274+
key, keySz, NULL, devId);
275+
\endcode
276+
277+
\sa wc_HmacVerify
278+
\sa wc_HmacGenerate_ex
279+
*/
280+
int wc_HmacVerify_ex(Hmac* hmac, int type, const byte* check, word32 checkSz,
281+
const byte* in, word32 inSz,
282+
const byte* key, word32 keySz,
283+
void* heap, int devId);
284+
128285
/*!
129286
\ingroup HMAC
130287

0 commit comments

Comments
 (0)