consttime_memcmp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. The MIT License (MIT)
  3. Copyright (c) 2015 Christophe Meessen
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"), to deal
  6. in the Software without restriction, including without limitation the rights
  7. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the Software is
  9. furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. */
  20. /* Minimally modified for libgnunetutil: added license header
  21. (from https://github.com/chmike/cst_time_memcmp, LICENSE file), and
  22. renamed the exported symbol: */
  23. #define consttime_memcmp GNUNET_memcmp_ct_
  24. /* Rest of the file is 'original' */
  25. #include <stddef.h>
  26. #include <inttypes.h>
  27. /*
  28. * "constant time" memcmp. Time taken depends on the buffer length, of
  29. * course, but not on the content of the buffers.
  30. *
  31. * Just like the ordinary memcmp function, the return value is
  32. * tri-state: <0, 0, or >0. However, applications that need a
  33. * constant-time memory comparison function usually need only a
  34. * two-state result, signalling only whether the inputs were identical
  35. * or different, but not signalling which of the inputs was larger.
  36. * This code could be made significantly faster and simpler if the
  37. * requirement for a tri-state result were removed.
  38. *
  39. * In order to protect against adversaries who can observe timing,
  40. * cache hits or misses, page faults, etc., and who can use such
  41. * observations to learn something about the relationship between the
  42. * contents of the two buffers, we have to perform exactly the same
  43. * instructions and memory accesses regardless of the contents of the
  44. * buffers. We can't stop as soon as we find a difference, we can't
  45. * take different conditional branches depending on the data, and we
  46. * can't use different pointers or array indexes depending on the data.
  47. *
  48. * Further reading:
  49. *
  50. * .Rs
  51. * .%A Paul C. Kocher
  52. * .%T Timing Attacks on Implementations of Diffie-Hellman, RSA, DSS, and Other Systems
  53. * .%D 1996
  54. * .%J CRYPTO 1996
  55. * .%P 104-113
  56. * .%U http://www.cryptography.com/timingattack/paper.html
  57. * .%U http://www.webcitation.org/query?url=http%3A%2F%2Fwww.cryptography.com%2Ftimingattack%2Fpaper.html&date=2012-10-17
  58. * .Re
  59. *
  60. * .Rs
  61. * .%A D. Boneh
  62. * .%A D. Brumley
  63. * .%T Remote timing attacks are practical
  64. * .%D August 2003
  65. * .%J Proceedings of the 12th Usenix Security Symposium, 2003
  66. * .%U https://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html
  67. * .%U http://www.webcitation.org/query?url=https%3A%2F%2Fcrypto.stanford.edu%2F%7Edabo%2Fabstracts%2Fssl-timing.html&date=2012-10-17
  68. * .%U http://www.webcitation.org/query?url=http%3A%2F%2Fcrypto.stanford.edu%2F%7Edabo%2Fpubs%2Fpapers%2Fssl-timing.pdf&date=2012-10-17
  69. * .Es
  70. *
  71. * .Rs
  72. * .%A Coda Hale
  73. * .%T A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)
  74. * .%D 13 Aug 2009
  75. * .%U http://codahale.com/a-lesson-in-timing-attacks/
  76. * .%U http://www.webcitation.org/query?url=http%3A%2F%2Fcodahale.com%2Fa-lesson-in-timing-attacks%2F&date=2012-10-17
  77. * .Re
  78. *
  79. */
  80. /*
  81. * A note on portability:
  82. *
  83. * We assume that char is exactly 8 bits, the same as uint8_t, and that
  84. * integer types with exactly 16 bits and exactly 32 bits exist. (If
  85. * there is ever a need to change this, then the actual requirement is
  86. * that we need a type that is at least two bits wider than char, and
  87. * another type that is at least two bits wider than that, or we need to
  88. * fake it somehow.)
  89. *
  90. * We do not assume any particular size for the plain "int" type, except
  91. * that it is at least 16 bits, as is guaranteed by the C language
  92. * standard.
  93. *
  94. * We do not assume that signed integer overflow is harmless. We
  95. * ensure that signed integer overflow does not occur, so that
  96. * implementation-defined overflow behaviour is not invoked.
  97. *
  98. * We rely on the C standard's guarantees regarding the wraparound
  99. * behaviour of unsigned integer arithmetic, and on the analogous
  100. * guarantees regarding conversions from signed types to narrower
  101. * unsigned types.
  102. *
  103. * We do not assume that the platform uses two's complement arithmetic.
  104. */
  105. /*
  106. * How hard do we have to try to prevent unwanted compiler optimisations?
  107. *
  108. * Try compiling with "#define USE_VOLATILE_TEMPORARY 0", and examine
  109. * the compiler output. If the only conditional tests in the entire
  110. * function are to test whether len is zero, then all is well, but try
  111. * again with different optimisation flags to be sure. If the compiler
  112. * emitted code with conditional tests that do anything other than
  113. * testing whether len is zero, then that's a problem, so try again with
  114. * "#define USE_VOLATILE_TEMPORARY 1". If it's still bad, then you are
  115. * out of luck.
  116. */
  117. #define USE_VOLATILE_TEMPORARY 0
  118. int
  119. consttime_memcmp (const void *b1, const void *b2, size_t len)
  120. {
  121. const uint8_t *c1, *c2;
  122. uint16_t d, r, m;
  123. #if USE_VOLATILE_TEMPORARY
  124. volatile uint16_t v;
  125. #else
  126. uint16_t v;
  127. #endif
  128. c1 = b1;
  129. c2 = b2;
  130. r = 0;
  131. while (len)
  132. {
  133. /*
  134. * Take the low 8 bits of r (in the range 0x00 to 0xff,
  135. * or 0 to 255);
  136. * As explained elsewhere, the low 8 bits of r will be zero
  137. * if and only if all bytes compared so far were identical;
  138. * Zero-extend to a 16-bit type (in the range 0x0000 to
  139. * 0x00ff);
  140. * Add 255, yielding a result in the range 255 to 510;
  141. * Save that in a volatile variable to prevent
  142. * the compiler from trying any shortcuts (the
  143. * use of a volatile variable depends on "#ifdef
  144. * USE_VOLATILE_TEMPORARY", and most compilers won't
  145. * need it);
  146. * Divide by 256 yielding a result of 1 if the original
  147. * value of r was non-zero, or 0 if r was zero;
  148. * Subtract 1, yielding 0 if r was non-zero, or -1 if r
  149. * was zero;
  150. * Convert to uint16_t, yielding 0x0000 if r was
  151. * non-zero, or 0xffff if r was zero;
  152. * Save in m.
  153. */v = ((uint16_t) (uint8_t) r) + 255;
  154. m = v / 256 - 1;
  155. /*
  156. * Get the values from *c1 and *c2 as uint8_t (each will
  157. * be in the range 0 to 255, or 0x00 to 0xff);
  158. * Convert them to signed int values (still in the
  159. * range 0 to 255);
  160. * Subtract them using signed arithmetic, yielding a
  161. * result in the range -255 to +255;
  162. * Convert to uint16_t, yielding a result in the range
  163. * 0xff01 to 0xffff (for what was previously -255 to
  164. * -1), or 0, or in the range 0x0001 to 0x00ff (for what
  165. * was previously +1 to +255).
  166. */d = (uint16_t) ((int) *c1 - (int) *c2);
  167. /*
  168. * If the low 8 bits of r were previously 0, then m
  169. * is now 0xffff, so (d & m) is the same as d, so we
  170. * effectively copy d to r;
  171. * Otherwise, if r was previously non-zero, then m is
  172. * now 0, so (d & m) is zero, so leave r unchanged.
  173. * Note that the low 8 bits of d will be zero if and
  174. * only if d == 0, which happens when *c1 == *c2.
  175. * The low 8 bits of r are thus zero if and only if the
  176. * entirety of r is zero, which happens if and only if
  177. * all bytes compared so far were equal. As soon as a
  178. * non-zero value is stored in r, it remains unchanged
  179. * for the remainder of the loop.
  180. */r |= (d & m);
  181. /*
  182. * Increment pointers, decrement length, and loop.
  183. */
  184. ++c1;
  185. ++c2;
  186. --len;
  187. }
  188. /*
  189. * At this point, r is an unsigned value, which will be 0 if the
  190. * final result should be zero, or in the range 0x0001 to 0x00ff
  191. * (1 to 255) if the final result should be positive, or in the
  192. * range 0xff01 to 0xffff (65281 to 65535) if the final result
  193. * should be negative.
  194. *
  195. * We want to convert the unsigned values in the range 0xff01
  196. * to 0xffff to signed values in the range -255 to -1, while
  197. * converting the other unsigned values to equivalent signed
  198. * values (0, or +1 to +255).
  199. *
  200. * On a machine with two's complement arithmetic, simply copying
  201. * the underlying bits (with sign extension if int is wider than
  202. * 16 bits) would do the job, so something like this might work:
  203. *
  204. * return (int16_t)r;
  205. *
  206. * However, that invokes implementation-defined behaviour,
  207. * because values larger than 32767 can't fit in a signed 16-bit
  208. * integer without overflow.
  209. *
  210. * To avoid any implementation-defined behaviour, we go through
  211. * these contortions:
  212. *
  213. * a. Calculate ((uint32_t)r + 0x8000). The cast to uint32_t
  214. * it to prevent problems on platforms where int is narrower
  215. * than 32 bits. If int is a larger than 32-bits, then the
  216. * usual arithmetic conversions cause this addition to be
  217. * done in unsigned int arithmetic. If int is 32 bits
  218. * or narrower, then this addition is done in uint32_t
  219. * arithmetic. In either case, no overflow or wraparound
  220. * occurs, and the result from this step has a value that
  221. * will be one of 0x00008000 (32768), or in the range
  222. * 0x00008001 to 0x000080ff (32769 to 33023), or in the range
  223. * 0x00017f01 to 0x00017fff (98049 to 98303).
  224. *
  225. * b. Cast the result from (a) to uint16_t. This effectively
  226. * discards the high bits of the result, in a way that is
  227. * well defined by the C language. The result from this step
  228. * will be of type uint16_t, and its value will be one of
  229. * 0x8000 (32768), or in the range 0x8001 to 0x80ff (32769 to
  230. * 33023), or in the range 0x7f01 to 0x7fff (32513 to
  231. * 32767).
  232. *
  233. * c. Cast the result from (b) to int32_t. We use int32_t
  234. * instead of int because we need a type that's strictly
  235. * larger than 16 bits, and the C standard allows
  236. * implementations where int is only 16 bits. The result
  237. * from this step will be of type int32_t, and its value will
  238. * be one of 0x00008000 (32768), or in the range 0x00008001
  239. * to 0x000080ff (32769 to 33023), or in the range 0x00007f01
  240. * to 0x00007fff (32513 to 32767).
  241. *
  242. * d. Take the result from (c) and subtract 0x8000 (32768) using
  243. * signed int32_t arithmetic. The result from this step will
  244. * be of type int32_t and the value will be one of
  245. * 0x00000000 (0), or in the range 0x00000001 to 0x000000ff
  246. * (+1 to +255), or in the range 0xffffff01 to 0xffffffff
  247. * (-255 to -1).
  248. *
  249. * e. Cast the result from (d) to int. This does nothing
  250. * interesting, except to make explicit what would have been
  251. * implicit in the return statement. The final result is an
  252. * int in the range -255 to +255.
  253. *
  254. * Unfortunately, compilers don't seem to be good at figuring
  255. * out that most of this can be optimised away by careful choice
  256. * of register width and sign extension.
  257. *
  258. */return (/*e*/ int) (/*d*/
  259. (/*c*/ int32_t) (/*b*/ uint16_t) (/*a*/ (uint32_t) r + 0x8000)
  260. - 0x8000);
  261. }