18199d687Smrg/*
28199d687Smrg * Copyright (c) 2014 Google Inc.
38199d687Smrg *
48199d687Smrg * Permission to use, copy, modify, and distribute this software for any
58199d687Smrg * purpose with or without fee is hereby granted, provided that the above
68199d687Smrg * copyright notice and this permission notice appear in all copies.
78199d687Smrg *
88199d687Smrg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
98199d687Smrg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
108199d687Smrg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
118199d687Smrg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
128199d687Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
138199d687Smrg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
148199d687Smrg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
158199d687Smrg */
168199d687Smrg
178199d687Smrg#include <limits.h>
188199d687Smrg#include <string.h>
198199d687Smrg#include <X11/Xfuncproto.h>
208199d687Smrg#include <dix-config.h>
218199d687Smrg#include "os.h"
228199d687Smrg
238199d687Smrgint
248199d687Smrgtimingsafe_memcmp(const void *b1, const void *b2, size_t len)
258199d687Smrg{
268199d687Smrg        const unsigned char *p1 = b1, *p2 = b2;
278199d687Smrg        size_t i;
288199d687Smrg        int res = 0, done = 0;
298199d687Smrg
308199d687Smrg        for (i = 0; i < len; i++) {
318199d687Smrg                /* lt is -1 if p1[i] < p2[i]; else 0. */
328199d687Smrg                int lt = (p1[i] - p2[i]) >> CHAR_BIT;
338199d687Smrg
348199d687Smrg                /* gt is -1 if p1[i] > p2[i]; else 0. */
358199d687Smrg                int gt = (p2[i] - p1[i]) >> CHAR_BIT;
368199d687Smrg
378199d687Smrg                /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
388199d687Smrg                int cmp = lt - gt;
398199d687Smrg
408199d687Smrg                /* set res = cmp if !done. */
418199d687Smrg                res |= cmp & ~done;
428199d687Smrg
438199d687Smrg                /* set done if p1[i] != p2[i]. */
448199d687Smrg                done |= lt | gt;
458199d687Smrg        }
468199d687Smrg
478199d687Smrg        return (res);
488199d687Smrg}
49