Commit c77b8186 authored by Jukka Rissanen's avatar Jukka Rissanen Committed by Alberto Escolar
Browse files

net: ipv6-pe: Verify that hmac calculation was ok

Make sure to check return values of mbedtls hmac APIs so that
the digest is calculated properly.

Fixes #75259
Fixes #75260
Fixes #75261

Coverity-CID: 366271
Coverity-CID: 366277
Coverify-CID: 366279

Signed-off-by: default avatarJukka Rissanen <jukka.rissanen@nordicsemi.no>
parent 7e229420
Loading
Loading
Loading
Loading
+28 −8
Changes for subsys/net/ip/ipv6_pe.c: 28 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -216,7 +216,7 @@ static bool ipv6_pe_prefix_update_lifetimes(struct net_if_ipv6 *ipv6,
}

/* RFC 8981 ch 3.3.2 */
static void gen_temporary_iid(struct net_if *iface,
static int gen_temporary_iid(struct net_if *iface,
			     const struct in6_addr *prefix,
			     uint8_t *network_id, size_t network_id_len,
			     uint8_t dad_counter,
@@ -226,6 +226,7 @@ static void gen_temporary_iid(struct net_if *iface,
	const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
	mbedtls_md_context_t ctx;
	uint8_t digest[32];
	int ret;
	static bool once;
	static uint8_t secret_key[16]; /* Min 128 bits, RFC 8981 ch 3.3.2 */
	struct {
@@ -256,12 +257,30 @@ static void gen_temporary_iid(struct net_if *iface,

	mbedtls_md_init(&ctx);
	mbedtls_md_setup(&ctx, md_info, true);
	mbedtls_md_hmac_starts(&ctx, secret_key, sizeof(secret_key));
	mbedtls_md_hmac_update(&ctx, (uint8_t *)&buf, sizeof(buf));
	mbedtls_md_hmac_finish(&ctx, digest);
	mbedtls_md_free(&ctx);
	ret = mbedtls_md_hmac_starts(&ctx, secret_key, sizeof(secret_key));
	if (ret != 0) {
		NET_DBG("Cannot %s hmac (%d)", "start", ret);
		goto err;
	}

	ret = mbedtls_md_hmac_update(&ctx, (uint8_t *)&buf, sizeof(buf));
	if (ret != 0) {
		NET_DBG("Cannot %s hmac (%d)", "update", ret);
		goto err;
	}

	ret = mbedtls_md_hmac_finish(&ctx, digest);
	if (ret != 0) {
		NET_DBG("Cannot %s hmac (%d)", "finish", ret);
		goto err;
	}

	memcpy(temporary_iid, digest, MIN(sizeof(digest), temporary_iid_len));

err:
	mbedtls_md_free(&ctx);

	return ret;
}

void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix,
@@ -272,7 +291,7 @@ void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix,
	struct in6_addr addr;
	k_ticks_t remaining;
	k_timeout_t vlifetimeout;
	int i, dad_count = 1;
	int i, ret, dad_count = 1;
	int32_t lifetime;
	bool valid = false;

@@ -328,7 +347,7 @@ void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix,
	net_ipaddr_copy(&addr, prefix);

	do {
		gen_temporary_iid(iface, prefix,
		ret = gen_temporary_iid(iface, prefix,
					COND_CODE_1(CONFIG_NET_INTERFACE_NAME,
						    (iface->config.name,
						     sizeof(iface->config.name)),
@@ -336,7 +355,7 @@ void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix,
						     strlen(net_if_get_device(iface)->name))),
					dad_count,
					&addr.s6_addr[8], 8U);

		if (ret == 0) {
			ifaddr = net_if_ipv6_addr_lookup(&addr, NULL);
			if (ifaddr == NULL && !net_ipv6_is_addr_unspecified(&addr) &&
			    memcmp(&addr, &reserved_anycast_subnet,
@@ -344,6 +363,7 @@ void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix,
				valid = true;
				break;
			}
		}

	} while (dad_count++ < TEMP_IDGEN_RETRIES);