Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Utilities for constant-time cryptography.
      3  *
      4  * Author: Emilia Kasper (emilia (at) openssl.org)
      5  * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
      6  * (Google).
      7  * ====================================================================
      8  * Copyright (c) 2014 The OpenSSL Project.  All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *    "This product includes cryptographic software written by
     21  *     Eric Young (eay (at) cryptsoft.com)"
     22  *    The word 'cryptographic' can be left out if the rouines from the library
     23  *    being used are not cryptographic related :-).
     24  * 4. If you include any Windows specific code (or a derivative thereof) from
     25  *    the apps directory (application code) you must include an acknowledgement:
     26  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     27  *
     28  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  * SUCH DAMAGE.
     39  *
     40  * The licence and distribution terms for any publically available version or
     41  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     42  * copied and put under another distribution licence
     43  * [including the GNU Public Licence.]
     44  */
     45 
     46 #include "internal.h"
     47 
     48 #include <limits.h>
     49 #include <stdio.h>
     50 #include <stdlib.h>
     51 
     52 #include <gtest/gtest.h>
     53 
     54 
     55 static const unsigned CONSTTIME_TRUE = (unsigned)(~0);
     56 static const unsigned CONSTTIME_FALSE = 0;
     57 static const uint8_t CONSTTIME_TRUE_8 = 0xff;
     58 static const uint8_t CONSTTIME_FALSE_8 = 0;
     59 
     60 static unsigned FromBool(bool b) {
     61   return b ? CONSTTIME_TRUE : CONSTTIME_FALSE;
     62 }
     63 
     64 static uint8_t FromBool8(bool b) {
     65   return b ? CONSTTIME_TRUE_8 : CONSTTIME_FALSE_8;
     66 }
     67 
     68 static unsigned test_values[] = {
     69     0,
     70     1,
     71     1024,
     72     12345,
     73     32000,
     74     UINT_MAX / 2 - 1,
     75     UINT_MAX / 2,
     76     UINT_MAX / 2 + 1,
     77     UINT_MAX - 1,
     78     UINT_MAX,
     79 };
     80 
     81 static uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
     82 
     83 static int signed_test_values[] = {
     84     0,     1,      -1,      1024,    -1024,       12345,      -12345,
     85     32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, INT_MIN + 1};
     86 
     87 TEST(ConstantTimeTest, Test) {
     88   for (unsigned a : test_values) {
     89     SCOPED_TRACE(a);
     90 
     91     EXPECT_EQ(FromBool(a == 0), constant_time_is_zero(a));
     92     EXPECT_EQ(FromBool8(a == 0), constant_time_is_zero_8(a));
     93 
     94     for (unsigned b : test_values) {
     95       SCOPED_TRACE(b);
     96 
     97       EXPECT_EQ(FromBool(a < b), constant_time_lt(a, b));
     98       EXPECT_EQ(FromBool8(a < b), constant_time_lt_8(a, b));
     99 
    100       EXPECT_EQ(FromBool(a >= b), constant_time_ge(a, b));
    101       EXPECT_EQ(FromBool8(a >= b), constant_time_ge_8(a, b));
    102 
    103       EXPECT_EQ(FromBool(a == b), constant_time_eq(a, b));
    104       EXPECT_EQ(FromBool8(a == b), constant_time_eq_8(a, b));
    105 
    106       EXPECT_EQ(a, constant_time_select(CONSTTIME_TRUE, a, b));
    107       EXPECT_EQ(b, constant_time_select(CONSTTIME_FALSE, a, b));
    108     }
    109   }
    110 
    111   for (int a : signed_test_values) {
    112     SCOPED_TRACE(a);
    113     for (int b : signed_test_values) {
    114       SCOPED_TRACE(b);
    115 
    116       EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE, a, b));
    117       EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE, a, b));
    118 
    119       EXPECT_EQ(FromBool(a == b), constant_time_eq_int(a, b));
    120       EXPECT_EQ(FromBool8(a == b), constant_time_eq_int_8(a, b));
    121     }
    122   }
    123 
    124   for (uint8_t a : test_values_8) {
    125     SCOPED_TRACE(static_cast<int>(a));
    126     for (uint8_t b : test_values_8) {
    127       SCOPED_TRACE(static_cast<int>(b));
    128       EXPECT_EQ(a, constant_time_select_8(CONSTTIME_TRUE_8, a, b));
    129       EXPECT_EQ(b, constant_time_select_8(CONSTTIME_FALSE_8, a, b));
    130     }
    131   }
    132 }
    133