HMAC(n->indigest, n->inkey, n->inkeylength, (unsigned char *) &inpkt->seqno, inpkt->len - n->inmaclength, (unsigned char *)hmac, NULL);
- return !memcmp(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength);
+ return !memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength);
}
static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
HMAC(n->indigest, n->inkey, n->inkeylength,
(unsigned char *) &inpkt->seqno, inpkt->len, (unsigned char *)hmac, NULL);
- if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) {
+ if(memcmp_constant_time(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)",
n->name, n->hostname);
return;
memcpy(&value, bitfield, size);
return value;
}
+
+/**
+ * As memcmp(), but constant-time.
+ * Returns 0 when data is equal, non-zero otherwise.
+ */
+int memcmp_constant_time (const void *a, const void *b, size_t size) {
+ const uint8_t *a1 = a, *b1 = b;
+ int ret = 0;
+ size_t i;
+
+ for (i = 0; i < size; i++)
+ ret |= *a1++ ^ *b1++;
+
+ return ret;
+}
extern unsigned int bitfield_to_int(const void *bitfield, size_t size);
+int memcmp_constant_time (const void *a, const void *b, size_t size);
+
#endif /* __TINC_UTILS_H__ */