Created
August 10, 2015 16:14
-
-
Save landonf/2b36ca4c632b20df6d7e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2014 Plausible Labs Cooperative, Inc. | |
* All rights reserved. | |
*/ | |
#import "PLCryptoConstantTime.h" | |
/** | |
* @ingroup plcrypto | |
* @{ | |
*/ | |
NSUInteger plcrypto_constant_time_compare_internal (const void *s1, size_t s1len, const void *s2, size_t s2len); | |
/* Function pointer indirection, used to prevent the compiler from inlining plcrypto_constant_time_compare_internal() */ | |
NSUInteger (* volatile plcrypto_constant_time_compare_internal_ptr)(const void *s1, size_t s1len, const void *s2, size_t s2len) = plcrypto_constant_time_compare_internal; | |
/** | |
* @internal | |
* | |
* Returns 0 if @a s1 is equal to @a s2, performing the comparison in constant time as to avoid leaking | |
* information regarding where the values differ. | |
* | |
* @param s1 The first array to compare. | |
* @param s1len The length of s1. | |
* @param s2 The second array to compare. | |
* @param s2len The length of s2. | |
* @return 0 If the receiver is equal to @a other, otherwise a non-zero value. | |
*/ | |
NSUInteger plcrypto_constant_time_compare_internal (const void *s1, size_t s1len, const void *s2, size_t s2len) { | |
if (s1len != s2len) { | |
return 1; | |
} | |
const uint8_t *aPtr = s1; | |
const uint8_t *bPtr = s2; | |
NSUInteger accumulator = 0; | |
for (NSUInteger i = 0; i < s1len; i++) { | |
accumulator |= (aPtr[i] ^ bPtr[i]); | |
} | |
/* We don't do a == 0 here, as we don't want a way-too-smart compiler to optimize the above to a memcmp */ | |
return accumulator; | |
} | |
/** | |
* Returns a Boolean value that indicates whether the receiver is equal to the given instance, | |
* performing the comparison in constant time as to avoid leaking information regarding where | |
* the values differ. | |
* | |
* Note that if the two values do not have the same length, this function returns immediately. | |
* | |
* @param other The object with which to compare the receiver. | |
* @return YES If the receiver is equal to @a other, otherwise NO. | |
*/ | |
BOOL plcrypto_constant_time_compare (const void *s1, size_t s1len, const void *s2, size_t s2len) { | |
return plcrypto_constant_time_compare_internal_ptr(s1, s1len, s2, s2len) == 0; | |
} | |
/** | |
* @} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment