Skip to content

Commit 0b10de7

Browse files
committed
Modify we_mac.c's HMAC code to be able to handle cases where key length is less
than hash's block size. OpenSSL will zero-pad an HMAC key that is less than the block size of the hash algorithm being used. This includes the case of a 0-length key; the resulting key will a block size string of zeros.
1 parent 06a9833 commit 0b10de7

File tree

1 file changed

+126
-30
lines changed

1 file changed

+126
-30
lines changed

src/we_mac.c

Lines changed: 126 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ typedef struct we_Mac
6565
int type;
6666
} we_Mac;
6767

68+
static int we_hmac_reset_key(we_Mac *mac);
69+
static int we_cmac_reset_key(we_Mac *mac, size_t newSize);
6870

6971
/**
7072
* Create ASN.1 octet string from key in context.
@@ -152,7 +154,6 @@ static int we_mac_pkey_init(EVP_PKEY_CTX *ctx, we_Mac** pMac)
152154
return ret;
153155
}
154156

155-
156157
/**
157158
* Get the MAC key and cache it in internal MAC object.
158159
*
@@ -169,17 +170,25 @@ static int we_mac_cache_key(EVP_PKEY_CTX *ctx, we_Mac *mac)
169170

170171
WOLFENGINE_ENTER(WE_LOG_MAC, "we_mac_cache_key");
171172

172-
/* Get PKEY associated with ctx for password/key. */
173-
pkey = EVP_PKEY_CTX_get0_pkey(ctx);
174-
if (pkey == NULL) {
173+
if (ctx == NULL || mac == NULL) {
174+
WOLFENGINE_ERROR_MSG(WE_LOG_MAC, "we_mac_cache_key called with null "
175+
"parameter.");
175176
ret = 0;
176177
}
178+
177179
if (ret == 1) {
178-
/* Get password/key as an ASN.1 octet string. */
179-
key = (ASN1_OCTET_STRING*)EVP_PKEY_get0(pkey);
180-
if (key == NULL) {
180+
/* Get PKEY associated with ctx for password/key. */
181+
pkey = EVP_PKEY_CTX_get0_pkey(ctx);
182+
if (pkey == NULL) {
181183
ret = 0;
182184
}
185+
if (ret == 1) {
186+
/* Get password/key as an ASN.1 octet string. */
187+
key = (ASN1_OCTET_STRING*)EVP_PKEY_get0(pkey);
188+
if (key == NULL) {
189+
ret = 0;
190+
}
191+
}
183192
}
184193

185194
if (ret == 1) {
@@ -191,20 +200,19 @@ static int we_mac_cache_key(EVP_PKEY_CTX *ctx, we_Mac *mac)
191200
}
192201
}
193202
if (ret == 1) {
194-
/* Dispose of old key. */
195-
if (mac->key != NULL) {
196-
OPENSSL_clear_free(mac->key, mac->keySz);
203+
if (mac->algo == WE_HMAC_ALGO) {
204+
ret = we_hmac_reset_key(mac);
197205
}
198-
/* Allocate memory to cache key, +1 for null terminator. */
199-
mac->key = (unsigned char *)OPENSSL_zalloc(mac->keySz + 1);
200-
if (mac->key == NULL) {
206+
else if (mac->algo == WE_CMAC_ALGO) {
207+
ret = we_cmac_reset_key(mac, mac->keySz);
208+
}
209+
else {
201210
ret = 0;
202211
}
203212
}
204213
if (ret == 1) {
205214
/* Copy key data into cache. */
206215
XMEMCPY(mac->key, data, mac->keySz);
207-
mac->key[mac->keySz] = '\0';
208216
}
209217

210218
WOLFENGINE_LEAVE(WE_LOG_MAC, "we_mac_cache_key", ret);
@@ -213,6 +221,42 @@ static int we_mac_cache_key(EVP_PKEY_CTX *ctx, we_Mac *mac)
213221
}
214222

215223
#ifdef WE_HAVE_HMAC
224+
/**
225+
* Clear out the existing HMAC key in mac and allocate a new key buffer large
226+
* enough to hold any hash block size (i.e. the largest supported block size,
227+
* WC_SHA3_224_BLOCK_SIZE). This is required because this function may be called
228+
* before the hash type is known. Set buffer to zeros.
229+
*
230+
* @param mac [in] Internal MAC object.
231+
* @returns 1 on success and 0 on failure.
232+
*/
233+
static int we_hmac_reset_key(we_Mac *mac)
234+
{
235+
int ret = 1;
236+
237+
WOLFENGINE_ENTER(WE_LOG_MAC, "we_hmac_reset_key");
238+
239+
if (mac == NULL) {
240+
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_MAC, "we_hmac_reset_key", mac);
241+
ret = 0;
242+
}
243+
244+
if (ret == 1) {
245+
/* Dispose of old key. */
246+
if (mac->key != NULL) {
247+
OPENSSL_clear_free(mac->key, mac->keySz);
248+
}
249+
mac->key = (unsigned char *)OPENSSL_zalloc(WC_SHA3_224_BLOCK_SIZE);
250+
if (mac->key == NULL) {
251+
ret = 0;
252+
}
253+
}
254+
255+
WOLFENGINE_LEAVE(WE_LOG_MAC, "we_hmac_reset_key", ret);
256+
257+
return ret;
258+
}
259+
216260
/**
217261
* Initialize the MAC for HMAC operations.
218262
*
@@ -224,6 +268,7 @@ static int we_mac_hmac_init(EVP_PKEY_CTX *ctx, we_Mac *mac)
224268
{
225269
int ret;
226270
int rc;
271+
int blockSize;
227272

228273
WOLFENGINE_ENTER(WE_LOG_MAC, "we_mac_hmac_init");
229274

@@ -232,12 +277,20 @@ static int we_mac_hmac_init(EVP_PKEY_CTX *ctx, we_Mac *mac)
232277
if (ret == 1) {
233278
/* Set HMAC key into wolfSSL HMAC object. */
234279
WOLFENGINE_MSG(WE_LOG_MAC, "Setting HMAC key");
235-
rc = wc_HmacSetKey(&mac->state.hmac, mac->type, (const byte*)mac->key,
236-
(word32)mac->keySz);
237-
if (rc != 0) {
238-
WOLFENGINE_ERROR_FUNC(WE_LOG_MAC, "wc_HmacSetKey", rc);
280+
blockSize = wc_HashGetBlockSize(mac->type);
281+
if (blockSize <= 0) {
282+
WOLFENGINE_ERROR_FUNC(WE_LOG_MAC, "wc_HashGetBlockSize", blockSize);
239283
ret = 0;
240284
}
285+
if (ret == 1) {
286+
mac->keySz = blockSize;
287+
rc = wc_HmacSetKey(&mac->state.hmac, mac->type,
288+
(const byte*)mac->key, (word32)mac->keySz);
289+
if (rc != 0) {
290+
WOLFENGINE_ERROR_FUNC(WE_LOG_MAC, "wc_HmacSetKey", rc);
291+
ret = 0;
292+
}
293+
}
241294
}
242295

243296
WOLFENGINE_LEAVE(WE_LOG_MAC, "we_mac_hmac_init", ret);
@@ -247,6 +300,46 @@ static int we_mac_hmac_init(EVP_PKEY_CTX *ctx, we_Mac *mac)
247300
#endif
248301

249302
#ifdef WE_HAVE_CMAC
303+
/**
304+
* Clear out the existing CMAC key in mac and allocate a new key buffer of
305+
* newSize bytes. Set buffer to zeros.
306+
*
307+
* @param mac [in] Internal MAC object.
308+
* @returns 1 on success and 0 on failure.
309+
*/
310+
static int we_cmac_reset_key(we_Mac *mac, size_t newSize)
311+
{
312+
int ret = 1;
313+
314+
WOLFENGINE_ENTER(WE_LOG_MAC, "we_cmac_reset_key");
315+
316+
if (mac == NULL) {
317+
WOLFENGINE_ERROR_MSG(WE_LOG_MAC, "we_cmac_reset_key called with NULL "
318+
"mac");
319+
ret = 0;
320+
}
321+
if (ret == 1 && newSize <= 0) {
322+
WOLFENGINE_ERROR_MSG(WE_LOG_MAC, "we_cmac_reset_key called with "
323+
"newSize <= 0");
324+
ret = 0;
325+
}
326+
327+
if (ret == 1) {
328+
/* Dispose of old key. */
329+
if (mac->key != NULL) {
330+
OPENSSL_clear_free(mac->key, mac->keySz);
331+
}
332+
mac->key = (unsigned char *)OPENSSL_zalloc(newSize);
333+
if (mac->key == NULL) {
334+
ret = 0;
335+
}
336+
}
337+
338+
WOLFENGINE_LEAVE(WE_LOG_MAC, "we_cmac_reset_key", ret);
339+
340+
return ret;
341+
}
342+
250343
/**
251344
* Initialize the MAC for CMAC operations.
252345
*
@@ -393,20 +486,19 @@ static int we_mac_pkey_ctrl(EVP_PKEY_CTX *ctx, int type, int num, void *ptr)
393486
*/
394487
WOLFENGINE_MSG(WE_LOG_MAC, "type: EVP_PKEY_CTRL_SET_MAC_KEY");
395488
if (ptr != NULL && num >= 0) {
396-
/* Dispose of old key safely. */
397-
if (mac->key != NULL) {
398-
OPENSSL_clear_free(mac->key, mac->keySz);
489+
if (mac->algo == WE_HMAC_ALGO) {
490+
ret = we_hmac_reset_key(mac);
399491
}
400-
/* Allocate memory for new key, +1 for null terminator. */
401-
mac->key = (unsigned char *)OPENSSL_zalloc(num + 1);
402-
if (mac->key == NULL) {
403-
ret = 0;
492+
else if (mac->algo == WE_CMAC_ALGO) {
493+
ret = we_cmac_reset_key(mac, num);
404494
}
405495
else {
496+
ret = 0;
497+
}
498+
if (ret == 1) {
406499
/* Copy in key data and store size. */
407500
XMEMCPY(mac->key, ptr, num);
408501
mac->keySz = num;
409-
mac->key[num] = '\0';
410502
}
411503
}
412504
else {
@@ -520,14 +612,18 @@ static int we_mac_dup(we_Mac *src, we_Mac **dst)
520612
mac->keySz = src->keySz;
521613
/* Duplicate the key if set. */
522614
if (src->keySz >= 0) {
523-
mac->key = (unsigned char *)OPENSSL_zalloc(src->keySz + 1);
524-
if (mac->key == NULL) {
525-
ret = 0;
615+
if (mac->algo == WE_HMAC_ALGO) {
616+
ret = we_hmac_reset_key(mac);
617+
}
618+
else if (mac->algo == WE_CMAC_ALGO) {
619+
ret = we_cmac_reset_key(mac, mac->keySz);
526620
}
527621
else {
622+
ret = 0;
623+
}
624+
if (ret == 1) {
528625
/* Copy over key bytes. */
529626
XMEMCPY(mac->key, src->key, src->keySz);
530-
mac->key[mac->keySz] = '\0';
531627
}
532628
}
533629
else {

0 commit comments

Comments
 (0)