5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt/*
8688e7005afed694ca129d00d3cd73b32828804bTinderbox User * Copyright (C) 2013, 2015-2017 Internet Systems Consortium, Inc. ("ISC")
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt */
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt/*! \file */
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt#include <config.h>
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt#include <isc/safe.h>
7f8ccd62f20c2efc0d51f576d84b23ee9ba0d72eMark Andrews#include <isc/string.h>
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt#include <isc/util.h>
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#ifdef WIN32
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#include <windows.h>
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#endif
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt#ifdef _MSC_VER
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt#pragma optimize("", off)
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt#endif
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Huntisc_boolean_t
420a43c8d8028992a4e9c170022f97bfac689025Evan Huntisc_safe_memequal(const void *s1, const void *s2, size_t n) {
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt isc_uint8_t acc = 0;
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
f4e309b17743e86c15cdb5960da51f684a1f4a6fEvan Hunt if (n != 0U) {
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt const isc_uint8_t *p1 = s1, *p2 = s2;
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt do {
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt acc |= *p1++ ^ *p2++;
f4e309b17743e86c15cdb5960da51f684a1f4a6fEvan Hunt } while (--n != 0U);
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt }
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt return (ISC_TF(acc == 0));
5b7abbef511cea0b568be0bc8d5b3120a0b9034dEvan Hunt}
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
420a43c8d8028992a4e9c170022f97bfac689025Evan Huntint
420a43c8d8028992a4e9c170022f97bfac689025Evan Huntisc_safe_memcompare(const void *b1, const void *b2, size_t len) {
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User const unsigned char *p1 = b1, *p2 = b2;
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User size_t i;
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User int res = 0, done = 0;
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User for (i = 0; i < len; i++) {
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User /* lt is -1 if p1[i] < p2[i]; else 0. */
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User int lt = (p1[i] - p2[i]) >> CHAR_BIT;
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User /* gt is -1 if p1[i] > p2[i]; else 0. */
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User int gt = (p2[i] - p1[i]) >> CHAR_BIT;
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User int cmp = lt - gt;
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User /* set res = cmp if !done. */
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User res |= cmp & ~done;
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User /* set done if p1[i] != p2[i]. */
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User done |= lt | gt;
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User }
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt
161b5249b9277b95479ae933387ae9de65fbad30Tinderbox User return (res);
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt}
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaramanvoid
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaramanisc_safe_memwipe(void *ptr, size_t len) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (ISC_UNLIKELY(ptr == NULL || len == 0))
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman return;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#ifdef WIN32
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman SecureZeroMemory(ptr, len);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#elif HAVE_EXPLICIT_BZERO
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman explicit_bzero(ptr, len);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#else
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman memset(ptr, 0, len);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman#endif
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman}