diff --git a/src/apps/snmp/snmp_msg.c b/src/apps/snmp/snmp_msg.c index 9cd4b071..9c0a15c5 100644 --- a/src/apps/snmp/snmp_msg.c +++ b/src/apps/snmp/snmp_msg.c @@ -1058,7 +1058,7 @@ snmp_parse_inbound_frame(struct snmp_request *request) IF_PARSE_EXEC(snmpv3_get_user((char *)request->msg_user_name, &auth, key, NULL, NULL)); IF_PARSE_EXEC(snmpv3_auth(&auth_stream, request->inbound_pbuf->tot_len, key, auth, hmac)); - if (memcmp(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH)) { + if (lwip_memcmp_consttime(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH)) { snmp_stats.wrongdigests++; request->msg_flags = SNMP_V3_NOAUTHNOPRIV; request->error_status = SNMP_ERR_AUTHORIZATIONERROR; diff --git a/src/core/def.c b/src/core/def.c index 282fb41d..b2b079c6 100644 --- a/src/core/def.c +++ b/src/core/def.c @@ -261,3 +261,26 @@ lwip_itoa(char *result, size_t bufsize, int number) memmove(res, tmp, (size_t)((result + bufsize) - tmp)); } #endif + +#ifndef lwip_memcmp_consttime +/** + * @ingroup sys_nonstandard + * The goal of this function is to compare memory with constant runtime in order to prevent + * timing attacks to various parts in the stack. + * To do that, in contrast to memcmp(), it only returns: + * 0: equal + * != 0: not equal + */ +int lwip_memcmp_consttime(const void* s1, const void* s2, size_t len) +{ + size_t i; + const unsigned char* a1 = s1; + const unsigned char* a2 = s2; + unsigned char ret = 0; + + for (i = 0; i < len; i++) { + ret |= a1[i] ^ a2[i]; + } + return ret; +} +#endif diff --git a/src/include/lwip/def.h b/src/include/lwip/def.h index d6bf7630..fd7c6a21 100644 --- a/src/include/lwip/def.h +++ b/src/include/lwip/def.h @@ -148,6 +148,16 @@ char* lwip_strnstr(const char* buffer, const char* token, size_t n); /* This can be #defined to strnistr() depending on your platform */ char* lwip_strnistr(const char* buffer, const char* token, size_t n); #endif +#ifndef lwip_memcmp_consttime +/* This could be #defined to something existing on your platform + * The goal of this function is to compare memory with constant runtime in order to prevent + * timing attacks to various parts in the stack. + * To do that, in contrast to memcmp(), it only returns: + * 0: equal + * != 0: not equal + */ +int lwip_memcmp_consttime(const void* s1, const void* s2, size_t len); +#endif #ifdef __cplusplus }