Skip to content

Commit 5518204

Browse files
committed
Sync: OpenSSL: Implement HMAC using the EVP_MAC API
https://w1.fi/cgit/hostap/commit/?id=e31500adea726897b2c308dae74ca2a3017d17c7 * OpenSSL: Implement HMAC using the EVP_MAC API OpenSSL 3.0 deprecated the low-level HMAC functions, so use the EVP_MAC API for this. Maintain the HMAC API variant for older versions. Signed-off-by: Jouni Malinen <[email protected]> https://w1.fi/cgit/hostap/commit/?id=c9c2c2d9c73d8d74a1e285505a56d2127a7507d3 * OpenSSL: Fix a memory leak on crypto_hash_init() error path The EVP_MAC context data needs to be freed on error paths. Fixes: e31500adea72 ("OpenSSL: Implement HMAC using the EVP_MAC API") Signed-off-by: Jouni Malinen <[email protected]>
1 parent 3c7fd8e commit 5518204

File tree

1 file changed

+249
-10
lines changed

1 file changed

+249
-10
lines changed

src/crypto/crypto_openssl.c

100644100755
Lines changed: 249 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -985,13 +985,73 @@ void dh5_free(void *ctx)
985985

986986

987987
struct crypto_hash {
988+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
989+
EVP_MAC_CTX *ctx;
990+
#else /* OpenSSL version >= 3.0 */
988991
HMAC_CTX *ctx;
992+
#endif /* OpenSSL version >= 3.0 */
989993
};
990994

991995

992996
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
993997
size_t key_len)
994998
{
999+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1000+
struct crypto_hash *ctx;
1001+
EVP_MAC *mac;
1002+
OSSL_PARAM params[2];
1003+
char *a = NULL;
1004+
1005+
switch (alg) {
1006+
#ifndef OPENSSL_NO_MD5
1007+
case CRYPTO_HASH_ALG_HMAC_MD5:
1008+
a = "MD5";
1009+
break;
1010+
#endif /* OPENSSL_NO_MD5 */
1011+
#ifndef OPENSSL_NO_SHA
1012+
case CRYPTO_HASH_ALG_HMAC_SHA1:
1013+
a = "SHA1";
1014+
break;
1015+
#endif /* OPENSSL_NO_SHA */
1016+
#ifndef OPENSSL_NO_SHA256
1017+
#ifdef CONFIG_SHA256
1018+
case CRYPTO_HASH_ALG_HMAC_SHA256:
1019+
a = "SHA256";
1020+
break;
1021+
#endif /* CONFIG_SHA256 */
1022+
#endif /* OPENSSL_NO_SHA256 */
1023+
default:
1024+
return NULL;
1025+
}
1026+
1027+
mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
1028+
if (!mac)
1029+
return NULL;
1030+
1031+
params[0] = OSSL_PARAM_construct_utf8_string("digest", a, 0);
1032+
params[1] = OSSL_PARAM_construct_end();
1033+
1034+
ctx = os_zalloc(sizeof(*ctx));
1035+
if (!ctx)
1036+
goto fail;
1037+
ctx->ctx = EVP_MAC_CTX_new(mac);
1038+
if (!ctx->ctx) {
1039+
os_free(ctx);
1040+
ctx = NULL;
1041+
goto fail;
1042+
}
1043+
1044+
if (EVP_MAC_init(ctx->ctx, key, key_len, params) != 1) {
1045+
EVP_MAC_CTX_free(ctx->ctx);
1046+
bin_clear_free(ctx, sizeof(*ctx));
1047+
ctx = NULL;
1048+
goto fail;
1049+
}
1050+
1051+
fail:
1052+
EVP_MAC_free(mac);
1053+
return ctx;
1054+
#else /* OpenSSL version >= 3.0 */
9951055
struct crypto_hash *ctx;
9961056
const EVP_MD *md;
9971057

@@ -1033,19 +1093,57 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
10331093
}
10341094

10351095
return ctx;
1096+
#endif /* OpenSSL version >= 3.0 */
10361097
}
10371098

10381099

10391100
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
10401101
{
10411102
if (ctx == NULL)
10421103
return;
1104+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1105+
EVP_MAC_update(ctx->ctx, data, len);
1106+
#else /* OpenSSL version >= 3.0 */
10431107
HMAC_Update(ctx->ctx, data, len);
1108+
#endif /* OpenSSL version >= 3.0 */
10441109
}
10451110

10461111

10471112
int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
10481113
{
1114+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1115+
size_t mdlen;
1116+
int res;
1117+
1118+
if (!ctx)
1119+
return -2;
1120+
1121+
if (!mac || !len) {
1122+
EVP_MAC_CTX_free(ctx->ctx);
1123+
bin_clear_free(ctx, sizeof(*ctx));
1124+
return 0;
1125+
}
1126+
1127+
res = EVP_MAC_final(ctx->ctx, NULL, &mdlen, 0);
1128+
if (res != 1) {
1129+
EVP_MAC_CTX_free(ctx->ctx);
1130+
bin_clear_free(ctx, sizeof(*ctx));
1131+
return -1;
1132+
}
1133+
res = EVP_MAC_final(ctx->ctx, mac, &mdlen, mdlen);
1134+
EVP_MAC_CTX_free(ctx->ctx);
1135+
bin_clear_free(ctx, sizeof(*ctx));
1136+
1137+
if (TEST_FAIL())
1138+
return -1;
1139+
1140+
if (res == 1) {
1141+
*len = mdlen;
1142+
return 0;
1143+
}
1144+
1145+
return -1;
1146+
#else /* OpenSSL version >= 3.0 */
10491147
unsigned int mdlen;
10501148
int res;
10511149

@@ -1071,10 +1169,149 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
10711169
return 0;
10721170
}
10731171

1172+
return -1;
1173+
#endif /* OpenSSL version >= 3.0 */
1174+
}
1175+
1176+
1177+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1178+
1179+
static int openssl_hmac_vector(char *digest, const u8 *key,
1180+
size_t key_len, size_t num_elem,
1181+
const u8 *addr[], const size_t *len, u8 *mac,
1182+
unsigned int mdlen)
1183+
{
1184+
EVP_MAC *hmac;
1185+
OSSL_PARAM params[2];
1186+
EVP_MAC_CTX *ctx;
1187+
size_t i, mlen;
1188+
int res;
1189+
1190+
if (TEST_FAIL())
1191+
return -1;
1192+
1193+
hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
1194+
if (!hmac)
1195+
return -1;
1196+
1197+
params[0] = OSSL_PARAM_construct_utf8_string("digest", digest, 0);
1198+
params[1] = OSSL_PARAM_construct_end();
1199+
1200+
ctx = EVP_MAC_CTX_new(hmac);
1201+
EVP_MAC_free(hmac);
1202+
if (!ctx)
1203+
return -1;
1204+
1205+
if (EVP_MAC_init(ctx, key, key_len, params) != 1)
1206+
goto fail;
1207+
1208+
for (i = 0; i < num_elem; i++) {
1209+
if (EVP_MAC_update(ctx, addr[i], len[i]) != 1)
1210+
goto fail;
1211+
}
1212+
1213+
res = EVP_MAC_final(ctx, mac, &mlen, mdlen);
1214+
EVP_MAC_CTX_free(ctx);
1215+
1216+
return res == 1 ? 0 : -1;
1217+
fail:
1218+
EVP_MAC_CTX_free(ctx);
10741219
return -1;
10751220
}
10761221

10771222

1223+
#ifndef CONFIG_FIPS
1224+
1225+
int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
1226+
const u8 *addr[], const size_t *len, u8 *mac)
1227+
{
1228+
return openssl_hmac_vector("MD5", key ,key_len, num_elem, addr, len,
1229+
mac, 16);
1230+
}
1231+
1232+
1233+
int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
1234+
u8 *mac)
1235+
{
1236+
return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
1237+
}
1238+
1239+
#endif /* CONFIG_FIPS */
1240+
1241+
1242+
int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
1243+
const u8 *addr[], const size_t *len, u8 *mac)
1244+
{
1245+
return openssl_hmac_vector("SHA1", key, key_len, num_elem, addr,
1246+
len, mac, 20);
1247+
}
1248+
1249+
1250+
int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
1251+
u8 *mac)
1252+
{
1253+
return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
1254+
}
1255+
1256+
1257+
#ifdef CONFIG_SHA256
1258+
1259+
int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
1260+
const u8 *addr[], const size_t *len, u8 *mac)
1261+
{
1262+
return openssl_hmac_vector("SHA256", key, key_len, num_elem, addr,
1263+
len, mac, 32);
1264+
}
1265+
1266+
1267+
int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
1268+
size_t data_len, u8 *mac)
1269+
{
1270+
return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
1271+
}
1272+
1273+
#endif /* CONFIG_SHA256 */
1274+
1275+
1276+
#ifdef CONFIG_SHA384
1277+
1278+
int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
1279+
const u8 *addr[], const size_t *len, u8 *mac)
1280+
{
1281+
return openssl_hmac_vector("SHA384", key, key_len, num_elem, addr,
1282+
len, mac, 48);
1283+
}
1284+
1285+
1286+
int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
1287+
size_t data_len, u8 *mac)
1288+
{
1289+
return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
1290+
}
1291+
1292+
#endif /* CONFIG_SHA384 */
1293+
1294+
1295+
#ifdef CONFIG_SHA512
1296+
1297+
int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
1298+
const u8 *addr[], const size_t *len, u8 *mac)
1299+
{
1300+
return openssl_hmac_vector("SHA512", key, key_len, num_elem, addr,
1301+
len, mac, 64);
1302+
}
1303+
1304+
1305+
int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
1306+
size_t data_len, u8 *mac)
1307+
{
1308+
return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
1309+
}
1310+
1311+
#endif /* CONFIG_SHA512 */
1312+
1313+
#else /* OpenSSL version >= 3.0 */
1314+
10781315
static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
10791316
size_t key_len, size_t num_elem,
10801317
const u8 *addr[], const size_t *len, u8 *mac,
@@ -1124,16 +1361,6 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
11241361
#endif /* CONFIG_FIPS */
11251362

11261363

1127-
int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
1128-
int iterations, u8 *buf, size_t buflen)
1129-
{
1130-
if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
1131-
ssid_len, iterations, buflen, buf) != 1)
1132-
return -1;
1133-
return 0;
1134-
}
1135-
1136-
11371364
int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
11381365
const u8 *addr[], const size_t *len, u8 *mac)
11391366
{
@@ -1205,6 +1432,18 @@ int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
12051432

12061433
#endif /* CONFIG_SHA512 */
12071434

1435+
#endif /* OpenSSL version >= 3.0 */
1436+
1437+
1438+
int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
1439+
int iterations, u8 *buf, size_t buflen)
1440+
{
1441+
if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
1442+
ssid_len, iterations, buflen, buf) != 1)
1443+
return -1;
1444+
return 0;
1445+
}
1446+
12081447

12091448
int crypto_get_random(void *buf, size_t len)
12101449
{

0 commit comments

Comments
 (0)