A key sitting in memory leaks three ways, and every one of them compiles without a warning: a comparison that returns as soon as two bytes differ, a print that lands in a log, and the buffer still holding bytes when the function returns. That is why review catches them unevenly. Two of those spellings can be deleted outright. The third one you can answer in a destructor.
The first leak is the one people write about. memcmp(mac, expected, 16) == 0 returns on the first differing byte, so whoever can time the call learns how many leading bytes they guessed right, and then recovers the tag one byte at a time. That is CWE-208, and a constant-time comparison answers it. The other two are duller, and in my experience building custodial wallet services for BTC and ETH and payment flows on card rails, considerably more common. A secret reaches a log because somebody added a debug line during an incident and never took it out.…