diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc index 830605086c..0858bee1cd 100644 --- a/crypto/asn1/asn1_test.cc +++ b/crypto/asn1/asn1_test.cc @@ -1194,8 +1194,8 @@ TEST(ASN1Test, AdjTime) { struct tm tm1, tm2; int days, secs; - OPENSSL_posix_to_tm(0, &tm1); - OPENSSL_posix_to_tm(0, &tm2); + EXPECT_TRUE(OPENSSL_posix_to_tm(0, &tm1)); + EXPECT_TRUE(OPENSSL_posix_to_tm(0, &tm2)); // Test values that are too large and should be rejected. EXPECT_FALSE(OPENSSL_gmtime_adj(&tm1, INT_MIN, INT_MIN)); EXPECT_FALSE(OPENSSL_gmtime_adj(&tm1, INT_MAX, INT_MAX)); @@ -2480,6 +2480,91 @@ TEST(ASN1Test, ASN1Dup) { 0); } +static std::tuple TimeToTuple(const tm &t) { + return std::make_tuple(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec); +} + +TEST(ASN1Test, TimeOverflow) { + // Input time is out of range and may overflow internal calculations to shift + // |tm_year| and |tm_mon| to a more normal value. + tm overflow_year; + OPENSSL_memset(&overflow_year, 0, sizeof(overflow_year)); + overflow_year.tm_year = INT_MAX - 1899; + overflow_year.tm_mday = 1; + tm overflow_month; + OPENSSL_memset(&overflow_month, 0, sizeof(overflow_month)); + overflow_month.tm_mon = INT_MAX; + overflow_month.tm_mday = 1; + int64_t posix_u64; + EXPECT_FALSE(OPENSSL_tm_to_posix(&overflow_year, &posix_u64)); + EXPECT_FALSE(OPENSSL_tm_to_posix(&overflow_month, &posix_u64)); + time_t posix; + EXPECT_FALSE(OPENSSL_timegm(&overflow_year, &posix)); + EXPECT_FALSE(OPENSSL_timegm(&overflow_month, &posix)); + EXPECT_FALSE( + OPENSSL_gmtime_adj(&overflow_year, /*offset_day=*/0, /*offset_sec=*/0)); + EXPECT_FALSE( + OPENSSL_gmtime_adj(&overflow_month, /*offset_day=*/0, /*offset_sec=*/0)); + int days, secs; + EXPECT_FALSE( + OPENSSL_gmtime_diff(&days, &secs, &overflow_year, &overflow_year)); + EXPECT_FALSE( + OPENSSL_gmtime_diff(&days, &secs, &overflow_month, &overflow_month)); + + // Input time is in range, but even adding one second puts it out of range. + tm max_time; + OPENSSL_memset(&max_time, 0, sizeof(max_time)); + max_time.tm_year = 9999 - 1900; + max_time.tm_mon = 12 - 1; + max_time.tm_mday = 31; + max_time.tm_hour = 23; + max_time.tm_min = 59; + max_time.tm_sec = 59; + tm copy = max_time; + EXPECT_TRUE(OPENSSL_gmtime_adj(©, /*offset_day=*/0, /*offset_sec=*/0)); + EXPECT_EQ(TimeToTuple(copy), TimeToTuple(max_time)); + EXPECT_FALSE(OPENSSL_gmtime_adj(©, /*offset_day=*/0, /*offset_sec=*/1)); + + // Likewise for the earliest representable time. + tm min_time; + OPENSSL_memset(&min_time, 0, sizeof(min_time)); + min_time.tm_year = 0 - 1900; + min_time.tm_mon = 1 - 1; + min_time.tm_mday = 1; + min_time.tm_hour = 0; + min_time.tm_min = 0; + min_time.tm_sec = 0; + copy = min_time; + EXPECT_TRUE(OPENSSL_gmtime_adj(©, /*offset_day=*/0, /*offset_sec=*/0)); + EXPECT_EQ(TimeToTuple(copy), TimeToTuple(min_time)); + EXPECT_FALSE(OPENSSL_gmtime_adj(©, /*offset_day=*/0, /*offset_sec=*/-1)); + + // Test we can offset between the minimum and maximum times. + const int64_t kValidTimeRange = 315569519999; + copy = min_time; + EXPECT_TRUE(OPENSSL_gmtime_adj(©, /*offset_day=*/0, kValidTimeRange)); + EXPECT_EQ(TimeToTuple(copy), TimeToTuple(max_time)); + EXPECT_TRUE(OPENSSL_gmtime_adj(©, /*offset_day=*/0, -kValidTimeRange)); + EXPECT_EQ(TimeToTuple(copy), TimeToTuple(min_time)); + + // The second offset may even exceed kValidTimeRange if it is canceled out by + // offset_day. + EXPECT_TRUE(OPENSSL_gmtime_adj(©, /*offset_day=*/-1, + kValidTimeRange + 24 * 3600)); + EXPECT_EQ(TimeToTuple(copy), TimeToTuple(max_time)); + EXPECT_TRUE(OPENSSL_gmtime_adj(©, /*offset_day=*/1, + -kValidTimeRange - 24 * 3600)); + EXPECT_EQ(TimeToTuple(copy), TimeToTuple(min_time)); + + // Make sure the internal calculations for |OPENSSL_gmtime_adj| stay in + // bounds. + copy = max_time; + EXPECT_FALSE(OPENSSL_gmtime_adj(©, INT_MAX, LONG_MAX)); + copy = min_time; + EXPECT_FALSE(OPENSSL_gmtime_adj(©, INT_MIN, LONG_MIN)); +} + // The ASN.1 macros do not work on Windows shared library builds, where usage of // |OPENSSL_EXPORT| is a bit stricter. #if !defined(OPENSSL_WINDOWS) || !defined(BORINGSSL_SHARED_LIBRARY) diff --git a/crypto/asn1/internal.h b/crypto/asn1/internal.h index c05ead243a..6a632c2e01 100644 --- a/crypto/asn1/internal.h +++ b/crypto/asn1/internal.h @@ -63,6 +63,9 @@ #include #include +#include + +#include "../internal.h" #if defined(__cplusplus) extern "C" { @@ -71,33 +74,17 @@ extern "C" { // Wrapper functions for time functions. -// OPENSSL_posix_to_tm converts a int64_t POSIX time value in |time| which must -// be in the range of year 0000 to 9999 to a broken out time value in |tm|. It -// returns one on success and zero on error. -OPENSSL_EXPORT int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm); - -// OPENSSL_tm_to_posix converts a time value between the years 0 and 9999 in -// |tm| to a POSIX time value in |out|. One is returned on success, zero is -// returned on failure. It is a failure if the tm contains out of range values. -OPENSSL_EXPORT int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out); - // OPENSSL_gmtime converts a time_t value in |time| which must be in the range // of year 0000 to 9999 to a broken out time value in |tm|. On success |tm| is // returned. On failure NULL is returned. OPENSSL_EXPORT struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result); -// OPENSSL_timegm converts a time value between the years 0 and 9999 in |tm| to -// a time_t value in |out|. One is returned on success, zero is returned on -// failure. It is a failure if the converted time can not be represented in a -// time_t, or if the tm contains out of range values. -OPENSSL_EXPORT int OPENSSL_timegm(const struct tm *tm, time_t *out); - // OPENSSL_gmtime_adj returns one on success, and updates |tm| by adding // |offset_day| days and |offset_sec| seconds. It returns zero on failure. |tm| // must be in the range of year 0000 to 9999 both before and after the update or // a failure will be returned. OPENSSL_EXPORT int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, - long offset_sec); + int64_t offset_sec); // OPENSSL_gmtime_diff calculates the difference between |from| and |to|. It // returns one, and outputs the difference as a number of days and seconds in diff --git a/crypto/asn1/posix_time.c b/crypto/asn1/posix_time.c index 556a25cb79..976979032c 100644 --- a/crypto/asn1/posix_time.c +++ b/crypto/asn1/posix_time.c @@ -21,16 +21,15 @@ #include #include -#include "../internal.h" #include "internal.h" #define SECS_PER_HOUR (60 * 60) -#define SECS_PER_DAY (24 * SECS_PER_HOUR) +#define SECS_PER_DAY (INT64_C(24) * SECS_PER_HOUR) // Is a year/month/day combination valid, in the range from year 0000 // to 9999? -static int is_valid_date(int year, int month, int day) { +static int is_valid_date(int64_t year, int64_t month, int64_t day) { if (day < 1 || month < 1 || year < 0 || year > 9999) { return 0; } @@ -61,7 +60,7 @@ static int is_valid_date(int year, int month, int day) { // Is a time valid? Leap seconds of 60 are not considered valid, as // the POSIX time in seconds does not include them. -static int is_valid_time(int hours, int minutes, int seconds) { +static int is_valid_time(int64_t hours, int64_t minutes, int64_t seconds) { if (hours < 0 || minutes < 0 || seconds < 0 || hours > 23 || minutes > 59 || seconds > 59) { return 0; @@ -69,17 +68,22 @@ static int is_valid_time(int hours, int minutes, int seconds) { return 1; } -// Is a int64 time representing a time within our expected range? -static int is_valid_epoch_time(int64_t time) { - // 0000-01-01 00:00:00 UTC to 9999-12-31 23:59:59 UTC - return (int64_t)-62167219200 <= time && time <= (int64_t)253402300799; +// 0000-01-01 00:00:00 UTC +#define MIN_POSIX_TIME INT64_C(-62167219200) +// 9999-12-31 23:59:59 UTC +#define MAX_POSIX_TIME INT64_C(253402300799) + +// Is an int64 time within our expected range? +static int is_valid_posix_time(int64_t time) { + return MIN_POSIX_TIME <= time && time <= MAX_POSIX_TIME; } // Inspired by algorithms presented in // https://howardhinnant.github.io/date_algorithms.html // (Public Domain) -static int posix_time_from_utc(int year, int month, int day, int hours, - int minutes, int seconds, int64_t *out_time) { +static int posix_time_from_utc(int64_t year, int64_t month, int64_t day, + int64_t hours, int64_t minutes, int64_t seconds, + int64_t *out_time) { if (!is_valid_date(year, month, day) || !is_valid_time(hours, minutes, seconds)) { return 0; @@ -107,7 +111,7 @@ static int posix_time_from_utc(int year, int month, int day, int hours, static int utc_from_posix_time(int64_t time, int *out_year, int *out_month, int *out_day, int *out_hours, int *out_minutes, int *out_seconds) { - if (!is_valid_epoch_time(time)) { + if (!is_valid_posix_time(time)) { return 0; } int64_t days = time / SECS_PER_DAY; @@ -142,8 +146,9 @@ static int utc_from_posix_time(int64_t time, int *out_year, int *out_month, } int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out) { - return posix_time_from_utc(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, out); + return posix_time_from_utc(tm->tm_year + INT64_C(1900), + tm->tm_mon + INT64_C(1), tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_sec, out); } int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm) { @@ -151,14 +156,16 @@ int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm) { OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); return 0; } - OPENSSL_memset(out_tm, 0, sizeof(struct tm)); - if (!utc_from_posix_time(time, &out_tm->tm_year, &out_tm->tm_mon, - &out_tm->tm_mday, &out_tm->tm_hour, &out_tm->tm_min, - &out_tm->tm_sec)) { + struct tm tmp_tm; + OPENSSL_memset(&tmp_tm, 0, sizeof(tmp_tm)); + if (!utc_from_posix_time(time, &tmp_tm.tm_year, &tmp_tm.tm_mon, + &tmp_tm.tm_mday, &tmp_tm.tm_hour, &tmp_tm.tm_min, + &tmp_tm.tm_sec)) { return 0; } - out_tm->tm_year -= 1900; - out_tm->tm_mon -= 1; + tmp_tm.tm_year -= 1900; + tmp_tm.tm_mon -= 1; + *out_tm = tmp_tm; return 1; } @@ -190,43 +197,47 @@ struct tm *OPENSSL_gmtime(const time_t *time, struct tm *out_tm) { return out_tm; } -int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) { +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, int64_t offset_sec) { int64_t posix_time; - if (!posix_time_from_utc(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, &posix_time)) { + if (!OPENSSL_tm_to_posix(tm, &posix_time)) { + return 0; + } + OPENSSL_STATIC_ASSERT(INT_MAX <= INT64_MAX / SECS_PER_DAY, + day_offset_in_seconds_cannot_overflow) + OPENSSL_STATIC_ASSERT(MAX_POSIX_TIME <= INT64_MAX - INT_MAX * SECS_PER_DAY, + addition_cannot_overflow) + OPENSSL_STATIC_ASSERT(MIN_POSIX_TIME >= INT64_MIN - INT_MIN * SECS_PER_DAY, + addition_cannot_underflow) + posix_time += offset_day * SECS_PER_DAY; + if (posix_time > 0 && offset_sec > INT64_MAX - posix_time) { return 0; } - if (!utc_from_posix_time( - posix_time + (int64_t)off_day * SECS_PER_DAY + offset_sec, - &tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, &tm->tm_min, - &tm->tm_sec)) { + if (posix_time < 0 && offset_sec < INT64_MIN - posix_time) { + return 0; + } + posix_time += offset_sec; + + if (!OPENSSL_posix_to_tm(posix_time, tm)) { return 0; } - tm->tm_year -= 1900; - tm->tm_mon -= 1; return 1; } int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, const struct tm *to) { - int64_t time_to; - if (!posix_time_from_utc(to->tm_year + 1900, to->tm_mon + 1, to->tm_mday, - to->tm_hour, to->tm_min, to->tm_sec, &time_to)) { - return 0; - } - int64_t time_from; - if (!posix_time_from_utc(from->tm_year + 1900, from->tm_mon + 1, - from->tm_mday, from->tm_hour, from->tm_min, - from->tm_sec, &time_from)) { + int64_t time_to, time_from; + if (!OPENSSL_tm_to_posix(to, &time_to) || + !OPENSSL_tm_to_posix(from, &time_from)) { return 0; } + // Times are in range, so these calculations can not overflow. + OPENSSL_STATIC_ASSERT(SECS_PER_DAY <= INT_MAX, seconds_per_day_does_not_fit_in_int) + OPENSSL_STATIC_ASSERT((MAX_POSIX_TIME - MIN_POSIX_TIME) / SECS_PER_DAY <= INT_MAX, + range_of_valid_POSIX_times_in_days_does_not_fit_in_int) int64_t timediff = time_to - time_from; int64_t daydiff = timediff / SECS_PER_DAY; timediff %= SECS_PER_DAY; - if (daydiff > INT_MAX || daydiff < INT_MIN) { - return 0; - } *out_secs = (int)timediff; *out_days = (int)daydiff; return 1; diff --git a/crypto/bio/bio.c b/crypto/bio/bio.c index 0fccaefbce..2523f308d6 100644 --- a/crypto/bio/bio.c +++ b/crypto/bio/bio.c @@ -504,11 +504,11 @@ int BIO_set_close(BIO *bio, int close_flag) { return (int)BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); } -OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) { +OPENSSL_EXPORT uint64_t BIO_number_read(const BIO *bio) { return bio->num_read; } -OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio) { +OPENSSL_EXPORT uint64_t BIO_number_written(const BIO *bio) { return bio->num_write; } diff --git a/crypto/cipher_extra/e_des.c b/crypto/cipher_extra/e_des.c index c4d022424d..a4a876e028 100644 --- a/crypto/cipher_extra/e_des.c +++ b/crypto/cipher_extra/e_des.c @@ -58,6 +58,7 @@ #include #include +#include "../des/internal.h" #include "../fipsmodule/cipher/internal.h" #include "internal.h" @@ -71,20 +72,15 @@ typedef struct { static int des_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { - DES_cblock *deskey = (DES_cblock *)key; EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; - - DES_set_key_unchecked(deskey, &dat->ks.ks); + DES_set_key_ex(key, &dat->ks.ks); return 1; } static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; - - DES_ncbc_encrypt(in, out, in_len, &dat->ks.ks, (DES_cblock *)ctx->iv, - ctx->encrypt); - + DES_ncbc_encrypt_ex(in, out, in_len, &dat->ks.ks, ctx->iv, ctx->encrypt); return 1; } @@ -113,8 +109,7 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { - DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), - &dat->ks.ks, ctx->encrypt); + DES_ecb_encrypt_ex(in + i, out + i, &dat->ks.ks, ctx->encrypt); } return 1; } @@ -144,23 +139,18 @@ typedef struct { static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { - DES_cblock *deskey = (DES_cblock *)key; DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; - - DES_set_key_unchecked(&deskey[0], &dat->ks.ks[0]); - DES_set_key_unchecked(&deskey[1], &dat->ks.ks[1]); - DES_set_key_unchecked(&deskey[2], &dat->ks.ks[2]); - + DES_set_key_ex(key, &dat->ks.ks[0]); + DES_set_key_ex(key + 8, &dat->ks.ks[1]); + DES_set_key_ex(key + 16, &dat->ks.ks[2]); return 1; } static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; - - DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1], - &dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt); - + DES_ede3_cbc_encrypt_ex(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1], + &dat->ks.ks[2], ctx->iv, ctx->encrypt); return 1; } @@ -182,13 +172,11 @@ const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &evp_des_ede3_cbc; } static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { - DES_cblock *deskey = (DES_cblock *)key; DES_EDE_KEY *dat = (DES_EDE_KEY *)ctx->cipher_data; - - DES_set_key_unchecked(&deskey[0], &dat->ks.ks[0]); - DES_set_key_unchecked(&deskey[1], &dat->ks.ks[1]); - DES_set_key_unchecked(&deskey[0], &dat->ks.ks[2]); - + // 2-DES is 3-DES with the first key used twice. + DES_set_key_ex(key, &dat->ks.ks[0]); + DES_set_key_ex(key + 8, &dat->ks.ks[1]); + DES_set_key_ex(key, &dat->ks.ks[2]); return 1; } @@ -217,9 +205,8 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { - DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), - &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2], - ctx->encrypt); + DES_ecb3_encrypt_ex(in + i, out + i, &dat->ks.ks[0], &dat->ks.ks[1], + &dat->ks.ks[2], ctx->encrypt); } return 1; } diff --git a/crypto/des/des.c b/crypto/des/des.c index e40fc7659d..693c178b6b 100644 --- a/crypto/des/des.c +++ b/crypto/des/des.c @@ -379,13 +379,17 @@ static const uint32_t DES_SPtrans[8][64] = { (a) = (a) ^ (t) ^ ((t) >> (16 - (n)))) void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) { + DES_set_key_ex(key->bytes, schedule); +} + +void DES_set_key_ex(const uint8_t key[8], DES_key_schedule *schedule) { static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0}; uint32_t c, d, t, s, t2; const uint8_t *in; int i; - in = key->bytes; + in = key; c2l(in, c); c2l(in, d); @@ -693,32 +697,34 @@ void DES_decrypt3(uint32_t data[2], const DES_key_schedule *ks1, void DES_ecb_encrypt(const DES_cblock *in_block, DES_cblock *out_block, const DES_key_schedule *schedule, int is_encrypt) { - uint32_t l; - uint32_t ll[2]; - const uint8_t *in = in_block->bytes; - uint8_t *out = out_block->bytes; + DES_ecb_encrypt_ex(in_block->bytes, out_block->bytes, schedule, is_encrypt); +} - c2l(in, l); - ll[0] = l; - c2l(in, l); - ll[1] = l; +void DES_ecb_encrypt_ex(const uint8_t in[8], uint8_t out[8], + const DES_key_schedule *schedule, int is_encrypt) { + uint32_t ll[2]; + ll[0] = CRYPTO_load_u32_le(in); + ll[1] = CRYPTO_load_u32_le(in + 4); DES_encrypt1(ll, schedule, is_encrypt); - l = ll[0]; - l2c(l, out); - l = ll[1]; - l2c(l, out); - ll[0] = ll[1] = 0; + CRYPTO_store_u32_le(out, ll[0]); + CRYPTO_store_u32_le(out + 4, ll[1]); } void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, const DES_key_schedule *schedule, DES_cblock *ivec, int enc) { + DES_ncbc_encrypt_ex(in, out, len, schedule, ivec->bytes, enc); +} + +void DES_ncbc_encrypt_ex(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *schedule, uint8_t ivec[8], + int enc) { uint32_t tin0, tin1; uint32_t tout0, tout1, xor0, xor1; uint32_t tin[2]; unsigned char *iv; - iv = ivec->bytes; + iv = ivec; if (enc) { c2l(iv, tout0); @@ -748,7 +754,7 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tout1 = tin[1]; l2c(tout1, out); } - iv = ivec->bytes; + iv = ivec; l2c(tout0, iv); l2c(tout1, iv); } else { @@ -779,7 +785,7 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, xor0 = tin0; xor1 = tin1; } - iv = ivec->bytes; + iv = ivec; l2c(xor0, iv); l2c(xor1, iv); } @@ -789,24 +795,23 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, void DES_ecb3_encrypt(const DES_cblock *input, DES_cblock *output, const DES_key_schedule *ks1, const DES_key_schedule *ks2, const DES_key_schedule *ks3, int enc) { - uint32_t l0, l1; - uint32_t ll[2]; - const uint8_t *in = input->bytes; - uint8_t *out = output->bytes; + DES_ecb3_encrypt_ex(input->bytes, output->bytes, ks1, ks2, ks3, enc); +} - c2l(in, l0); - c2l(in, l1); - ll[0] = l0; - ll[1] = l1; +void DES_ecb3_encrypt_ex(const uint8_t in[8], uint8_t out[8], + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, int enc) { + uint32_t ll[2]; + ll[0] = CRYPTO_load_u32_le(in); + ll[1] = CRYPTO_load_u32_le(in + 4); if (enc) { DES_encrypt3(ll, ks1, ks2, ks3); } else { DES_decrypt3(ll, ks1, ks2, ks3); } - l0 = ll[0]; - l1 = ll[1]; - l2c(l0, out); - l2c(l1, out); + CRYPTO_store_u32_le(out, ll[0]); + CRYPTO_store_u32_le(out + 4, ll[1]); } void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, @@ -814,12 +819,20 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, const DES_key_schedule *ks2, const DES_key_schedule *ks3, DES_cblock *ivec, int enc) { + DES_ede3_cbc_encrypt_ex(in, out, len, ks1, ks2, ks3, ivec->bytes, enc); +} + +void DES_ede3_cbc_encrypt_ex(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, uint8_t ivec[8], + int enc) { uint32_t tin0, tin1; uint32_t tout0, tout1, xor0, xor1; uint32_t tin[2]; uint8_t *iv; - iv = ivec->bytes; + iv = ivec; if (enc) { c2l(iv, tout0); @@ -853,7 +866,7 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, l2c(tout0, out); l2c(tout1, out); } - iv = ivec->bytes; + iv = ivec; l2c(tout0, iv); l2c(tout1, iv); } else { @@ -901,7 +914,7 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, xor1 = t1; } - iv = ivec->bytes; + iv = ivec; l2c(xor0, iv); l2c(xor1, iv); } diff --git a/crypto/des/internal.h b/crypto/des/internal.h index 0d07a1b026..ac6c71945f 100644 --- a/crypto/des/internal.h +++ b/crypto/des/internal.h @@ -67,6 +67,9 @@ extern "C" { #endif +// TODO(davidben): Ideally these macros would be replaced with +// |CRYPTO_load_u32_le| and |CRYPTO_store_u32_le|. + #define c2l(c, l) \ do { \ (l) = ((uint32_t)(*((c)++))); \ @@ -147,6 +150,27 @@ extern "C" { } while (0) +// Correctly-typed versions of DES functions. +// +// See https://crbug.com/boringssl/683. + +void DES_set_key_ex(const uint8_t key[8], DES_key_schedule *schedule); +void DES_ecb_encrypt_ex(const uint8_t in[8], uint8_t out[8], + const DES_key_schedule *schedule, int is_encrypt); +void DES_ncbc_encrypt_ex(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *schedule, uint8_t ivec[8], + int enc); +void DES_ecb3_encrypt_ex(const uint8_t input[8], uint8_t output[8], + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, int enc); +void DES_ede3_cbc_encrypt_ex(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, uint8_t ivec[8], + int enc); + + // Private functions. // // These functions are only exported for use in |decrepit|. diff --git a/crypto/fipsmodule/bn/asm/armv4-mont.pl b/crypto/fipsmodule/bn/asm/armv4-mont.pl index 0bda9037d7..2ee87b1dcc 100644 --- a/crypto/fipsmodule/bn/asm/armv4-mont.pl +++ b/crypto/fipsmodule/bn/asm/armv4-mont.pl @@ -114,37 +114,13 @@ .code 32 #endif -#if __ARM_MAX_ARCH__>=7 -.align 5 -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lbn_mul_mont -#endif - -.global bn_mul_mont -.type bn_mul_mont,%function +.global bn_mul_mont_nohw +.type bn_mul_mont_nohw,%function .align 5 -bn_mul_mont: -.Lbn_mul_mont: +bn_mul_mont_nohw: ldr ip,[sp,#4] @ load num stmdb sp!,{r0,r2} @ sp points at argument block -#if __ARM_MAX_ARCH__>=7 - tst ip,#7 - bne .Lialu - adr r0,.Lbn_mul_mont - ldr r2,.LOPENSSL_armcap - ldr r0,[r0,r2] -#ifdef __APPLE__ - ldr r0,[r0] -#endif - tst r0,#ARMV7_NEON @ NEON available? - ldmia sp, {r0,r2} - beq .Lialu - add sp,sp,#8 - b bn_mul8x_mont_neon -.align 4 -.Lialu: -#endif cmp ip,#2 mov $num,ip @ load num #ifdef __thumb2__ @@ -295,7 +271,7 @@ moveq pc,lr @ be binary compatible with V4, yet bx lr @ interoperable with Thumb ISA:-) #endif -.size bn_mul_mont,.-bn_mul_mont +.size bn_mul_mont_nohw,.-bn_mul_mont_nohw ___ { my ($A0,$A1,$A2,$A3)=map("d$_",(0..3)); @@ -314,6 +290,7 @@ .arch armv7-a .fpu neon +.global bn_mul8x_mont_neon .type bn_mul8x_mont_neon,%function .align 5 bn_mul8x_mont_neon: @@ -747,11 +724,6 @@ } $code.=<<___; .asciz "Montgomery multiplication for ARMv4/NEON, CRYPTOGAMS by " -.align 2 -#if __ARM_MAX_ARCH__>=7 -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif ___ foreach (split("\n",$code)) { diff --git a/crypto/fipsmodule/bn/asm/x86_64-mont.pl b/crypto/fipsmodule/bn/asm/x86_64-mont.pl index 0a5a662da9..2b3a1e470b 100755 --- a/crypto/fipsmodule/bn/asm/x86_64-mont.pl +++ b/crypto/fipsmodule/bn/asm/x86_64-mont.pl @@ -89,8 +89,6 @@ $code=<<___; .text -.extern OPENSSL_ia32cap_P - .globl bn_mul_mont_nohw .type bn_mul_mont_nohw,\@function,6 .align 16 @@ -789,7 +787,7 @@ # int bn_sqr8x_mont( my $rptr="%rdi"; # const BN_ULONG *rptr, my $aptr="%rsi"; # const BN_ULONG *aptr, -my $bptr="%rdx"; # not used +my $mulx_adx_capable="%rdx"; # Different than upstream! my $nptr="%rcx"; # const BN_ULONG *nptr, my $n0 ="%r8"; # const BN_ULONG *n0); my $num ="%r9"; # int num, has to be divisible by 8 @@ -893,11 +891,8 @@ ___ $code.=<<___ if ($addx); #ifndef MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX - leaq OPENSSL_ia32cap_P(%rip),%rax - mov 8(%rax),%eax - and \$0x80100,%eax - cmp \$0x80100,%eax - jne .Lsqr8x_nox + test $mulx_adx_capable,$mulx_adx_capable + jz .Lsqr8x_nox call bn_sqrx8x_internal # see x86_64-mont5 module # %rax top-most carry diff --git a/crypto/fipsmodule/bn/bn_test.cc b/crypto/fipsmodule/bn/bn_test.cc index 5e13d782f8..d710cef6f5 100644 --- a/crypto/fipsmodule/bn/bn_test.cc +++ b/crypto/fipsmodule/bn/bn_test.cc @@ -2864,10 +2864,21 @@ TEST_F(BNTest, BNMulMontABI) { mont->n0, words); #if !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) if (bn_sqr8x_mont_capable(words)) { - CHECK_ABI(bn_sqr8x_mont, r.data(), a.data(), a.data(), mont->N.d, - mont->n0, words); + CHECK_ABI(bn_sqr8x_mont, r.data(), a.data(), bn_mulx_adx_capable(), + mont->N.d, mont->n0, words); } #endif // !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) +#elif defined(OPENSSL_ARM) + if (bn_mul8x_mont_neon_capable(words)) { + CHECK_ABI(bn_mul8x_mont_neon, r.data(), a.data(), b.data(), mont->N.d, + mont->n0, words); + CHECK_ABI(bn_mul8x_mont_neon, r.data(), a.data(), a.data(), mont->N.d, + mont->n0, words); + } + CHECK_ABI(bn_mul_mont_nohw, r.data(), a.data(), b.data(), mont->N.d, + mont->n0, words); + CHECK_ABI(bn_mul_mont_nohw, r.data(), a.data(), a.data(), mont->N.d, + mont->n0, words); #else CHECK_ABI(bn_mul_mont, r.data(), a.data(), b.data(), mont->N.d, mont->n0, words); diff --git a/crypto/fipsmodule/bn/internal.h b/crypto/fipsmodule/bn/internal.h index b8674b1db1..c5ae9364f2 100644 --- a/crypto/fipsmodule/bn/internal.h +++ b/crypto/fipsmodule/bn/internal.h @@ -407,6 +407,10 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, size_t num); #if defined(OPENSSL_X86_64) +OPENSSL_INLINE int bn_mulx_adx_capable(void) { + // MULX is in BMI2. + return CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable(); +} int bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, size_t num); OPENSSL_INLINE int bn_mul4x_mont_capable(size_t num) { @@ -416,18 +420,24 @@ int bn_mul4x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, size_t num); #if !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) OPENSSL_INLINE int bn_mulx4x_mont_capable(size_t num) { - // MULX is in BMI2. - return bn_mul4x_mont_capable(num) && CRYPTO_is_BMI2_capable() && - CRYPTO_is_ADX_capable(); + return bn_mul4x_mont_capable(num) && bn_mulx_adx_capable(); } int bn_mulx4x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, size_t num); OPENSSL_INLINE int bn_sqr8x_mont_capable(size_t num) { return (num >= 8) && ((num & 7) == 0); } -int bn_sqr8x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *unused_bp, +int bn_sqr8x_mont(BN_ULONG *rp, const BN_ULONG *ap, BN_ULONG mulx_adx_capable, const BN_ULONG *np, const BN_ULONG *n0, size_t num); #endif // !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) +#elif defined(OPENSSL_ARM) + OPENSSL_INLINE int bn_mul8x_mont_neon_capable(size_t num) { + return (num & 7) == 0 && CRYPTO_is_NEON_capable(); + } + int bn_mul8x_mont_neon(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num); + int bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num); #endif // defined(OPENSSL_X86_64) #endif diff --git a/crypto/fipsmodule/bn/montgomery.c b/crypto/fipsmodule/bn/montgomery.c index 9028a77acc..38a651b9bb 100644 --- a/crypto/fipsmodule/bn/montgomery.c +++ b/crypto/fipsmodule/bn/montgomery.c @@ -639,7 +639,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, { #if !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) if (ap == bp && bn_sqr8x_mont_capable(num)) { - return bn_sqr8x_mont(rp, ap, bp, np, n0, num); + return bn_sqr8x_mont(rp, ap, bn_mulx_adx_capable(), np, n0, num); } if (bn_mulx4x_mont_capable(num)) { return bn_mulx4x_mont(rp, ap, bp, np, n0, num); @@ -651,3 +651,13 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, return bn_mul_mont_nohw(rp, ap, bp, np, n0, num); } #endif + +#if defined(OPENSSL_BN_ASM_MONT) && defined(OPENSSL_ARM) +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num) { + if (bn_mul8x_mont_neon_capable(num)) { + return bn_mul8x_mont_neon(rp, ap, bp, np, n0, num); + } + return bn_mul_mont_nohw(rp, ap, bp, np, n0, num); +} +#endif diff --git a/crypto/fipsmodule/sha/asm/sha1-armv4-large.pl b/crypto/fipsmodule/sha/asm/sha1-armv4-large.pl index b845a824a7..6466d8caf5 100644 --- a/crypto/fipsmodule/sha/asm/sha1-armv4-large.pl +++ b/crypto/fipsmodule/sha/asm/sha1-armv4-large.pl @@ -199,24 +199,11 @@ sub BODY_40_59 { .code 32 #endif -.global sha1_block_data_order -.type sha1_block_data_order,%function +.global sha1_block_data_order_nohw +.type sha1_block_data_order_nohw,%function .align 5 -sha1_block_data_order: -#if __ARM_MAX_ARCH__>=7 -.Lsha1_block: - adr r3,.Lsha1_block - ldr r12,.LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV8_SHA1 - bne .LARMv8 - tst r12,#ARMV7_NEON - bne .LNEON -#endif +sha1_block_data_order_nohw: stmdb sp!,{r4-r12,lr} add $len,$inp,$len,lsl#6 @ $len to point at the end of $inp ldmia $ctx,{$a,$b,$c,$d,$e} @@ -306,17 +293,13 @@ sub BODY_40_59 { moveq pc,lr @ be binary compatible with V4, yet bx lr @ interoperable with Thumb ISA:-) #endif -.size sha1_block_data_order,.-sha1_block_data_order +.size sha1_block_data_order_nohw,.-sha1_block_data_order_nohw .align 5 .LK_00_19: .word 0x5a827999 .LK_20_39: .word 0x6ed9eba1 .LK_40_59: .word 0x8f1bbcdc .LK_60_79: .word 0xca62c1d6 -#if __ARM_MAX_ARCH__>=7 -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lsha1_block -#endif .asciz "SHA1 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by " .align 5 ___ @@ -532,10 +515,10 @@ () .arch armv7-a .fpu neon +.global sha1_block_data_order_neon .type sha1_block_data_order_neon,%function .align 4 sha1_block_data_order_neon: -.LNEON: stmdb sp!,{r4-r12,lr} add $len,$inp,$len,lsl#6 @ $len to point at the end of $inp @ dmb @ errata #451034 on early Cortex A8 @@ -627,10 +610,10 @@ () # define INST(a,b,c,d) .byte a,b,c,d|0x10 # endif -.type sha1_block_data_order_armv8,%function +.global sha1_block_data_order_hw +.type sha1_block_data_order_hw,%function .align 5 -sha1_block_data_order_armv8: -.LARMv8: +sha1_block_data_order_hw: vstmdb sp!,{d8-d15} @ ABI specification says so veor $E,$E,$E @@ -695,16 +678,10 @@ () vldmia sp!,{d8-d15} ret @ bx lr -.size sha1_block_data_order_armv8,.-sha1_block_data_order_armv8 +.size sha1_block_data_order_hw,.-sha1_block_data_order_hw #endif ___ }}} -$code.=<<___; -#if __ARM_MAX_ARCH__>=7 -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif -___ { my %opcode = ( "sha1c" => 0xf2000c40, "sha1p" => 0xf2100c40, diff --git a/crypto/fipsmodule/sha/asm/sha256-armv4.pl b/crypto/fipsmodule/sha/asm/sha256-armv4.pl index ff509a6eb0..221978b6c9 100644 --- a/crypto/fipsmodule/sha/asm/sha256-armv4.pl +++ b/crypto/fipsmodule/sha/asm/sha256-armv4.pl @@ -219,34 +219,15 @@ sub BODY_16_XX { .word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 .size K256,.-K256 .word 0 @ terminator -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lsha256_block_data_order -#endif .align 5 -.global sha256_block_data_order -.type sha256_block_data_order,%function -sha256_block_data_order: -.Lsha256_block_data_order: - adr r3,.Lsha256_block_data_order -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) - ldr r12,.LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV8_SHA256 - bne .LARMv8 - tst r12,#ARMV7_NEON - bne .LNEON -#endif +.global sha256_block_data_order_nohw +.type sha256_block_data_order_nohw,%function +sha256_block_data_order_nohw: add $len,$inp,$len,lsl#6 @ len to point at the end of inp stmdb sp!,{$ctx,$inp,$len,r4-r11,lr} ldmia $ctx,{$A,$B,$C,$D,$E,$F,$G,$H} - @ TODO(davidben): When the OPENSSL_armcap logic above is removed, - @ replace this with a simple ADR. - sub $Ktbl,r3,#256+32 @ K256 + adr $Ktbl,K256 sub sp,sp,#16*4 @ alloca(X[16]) .Loop: # if __ARM_ARCH>=7 @@ -300,7 +281,7 @@ sub BODY_16_XX { moveq pc,lr @ be binary compatible with V4, yet bx lr @ interoperable with Thumb ISA:-) #endif -.size sha256_block_data_order,.-sha256_block_data_order +.size sha256_block_data_order_nohw,.-sha256_block_data_order_nohw ___ ###################################################################### # NEON stuff @@ -493,7 +474,6 @@ () .align 5 .skip 16 sha256_block_data_order_neon: -.LNEON: stmdb sp!,{r4-r12,lr} sub $H,sp,#16*4+16 @@ -637,23 +617,23 @@ () # define INST(a,b,c,d) .byte a,b,c,d # endif -.LK256_shortcut_armv8: +.LK256_shortcut_hw: @ PC is 8 bytes ahead in Arm mode and 4 bytes ahead in Thumb mode. #if defined(__thumb2__) -.word K256-(.LK256_add_armv8+4) +.word K256-(.LK256_add_hw+4) #else -.word K256-(.LK256_add_armv8+8) +.word K256-(.LK256_add_hw+8) #endif -.type sha256_block_data_order_armv8,%function +.global sha256_block_data_order_hw +.type sha256_block_data_order_hw,%function .align 5 -sha256_block_data_order_armv8: -.LARMv8: +sha256_block_data_order_hw: @ K256 is too far to reference from one ADR command in Thumb mode. In @ Arm mode, we could make it fit by aligning the ADR offset to a 64-byte - @ boundary. For simplicity, just load the offset from .LK256_shortcut_armv8. - ldr $Ktbl,.LK256_shortcut_armv8 -.LK256_add_armv8: + @ boundary. For simplicity, just load the offset from .LK256_shortcut_hw. + ldr $Ktbl,.LK256_shortcut_hw +.LK256_add_hw: add $Ktbl,pc,$Ktbl vld1.32 {$ABCD,$EFGH},[$ctx] @@ -718,17 +698,13 @@ () vst1.32 {$ABCD,$EFGH},[$ctx] ret @ bx lr -.size sha256_block_data_order_armv8,.-sha256_block_data_order_armv8 +.size sha256_block_data_order_hw,.-sha256_block_data_order_hw #endif ___ }}} $code.=<<___; .asciz "SHA256 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by " .align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif ___ open SELF,$0; diff --git a/crypto/fipsmodule/sha/asm/sha512-armv4.pl b/crypto/fipsmodule/sha/asm/sha512-armv4.pl index 8da171dbc5..20a6e40580 100644 --- a/crypto/fipsmodule/sha/asm/sha512-armv4.pl +++ b/crypto/fipsmodule/sha/asm/sha512-armv4.pl @@ -278,33 +278,13 @@ () WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .size K512,.-K512 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lsha512_block_data_order -.skip 32-4 -#else -.skip 32 -#endif -.global sha512_block_data_order -.type sha512_block_data_order,%function -sha512_block_data_order: -.Lsha512_block_data_order: - adr r3,.Lsha512_block_data_order -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) - ldr r12,.LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV7_NEON - bne .LNEON -#endif +.global sha512_block_data_order_nohw +.type sha512_block_data_order_nohw,%function +sha512_block_data_order_nohw: add $len,$inp,$len,lsl#7 @ len to point at the end of inp stmdb sp!,{r4-r12,lr} - @ TODO(davidben): When the OPENSSL_armcap logic above is removed, - @ replace this with a simple ADR. - sub $Ktbl,r3,#672 @ K512 + adr $Ktbl,K512 sub sp,sp,#9*8 ldr $Elo,[$ctx,#$Eoff+$lo] @@ -503,7 +483,7 @@ () moveq pc,lr @ be binary compatible with V4, yet bx lr @ interoperable with Thumb ISA:-) #endif -.size sha512_block_data_order,.-sha512_block_data_order +.size sha512_block_data_order_nohw,.-sha512_block_data_order_nohw ___ { @@ -614,7 +594,6 @@ () .type sha512_block_data_order_neon,%function .align 4 sha512_block_data_order_neon: -.LNEON: dmb @ errata #451034 on early Cortex A8 add $len,$inp,$len,lsl#7 @ len to point at the end of inp adr $Ktbl,K512 @@ -652,10 +631,6 @@ () $code.=<<___; .asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by " .align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; diff --git a/crypto/fipsmodule/sha/internal.h b/crypto/fipsmodule/sha/internal.h index 8c58b76a98..e92d85fed7 100644 --- a/crypto/fipsmodule/sha/internal.h +++ b/crypto/fipsmodule/sha/internal.h @@ -91,7 +91,7 @@ struct keccak_st { void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num_blocks); -#elif !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_ARM)) +#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) #define SHA1_ASM #define SHA256_ASM #define SHA512_ASM @@ -103,6 +103,35 @@ void sha256_block_data_order(uint32_t *state, const uint8_t *data, void sha512_block_data_order(uint64_t *state, const uint8_t *data, size_t num_blocks); +#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM) + +#define SHA1_ASM_NOHW +#define SHA256_ASM_NOHW +#define SHA512_ASM_NOHW + +#define SHA1_ASM_HW +OPENSSL_INLINE int sha1_hw_capable(void) { + return CRYPTO_is_ARMv8_SHA1_capable(); +} + +#define SHA1_ASM_NEON +void sha1_block_data_order_neon(uint32_t *state, const uint8_t *data, + size_t num); + +#define SHA256_ASM_HW +OPENSSL_INLINE int sha256_hw_capable(void) { + return CRYPTO_is_ARMv8_SHA256_capable(); +} + +#define SHA256_ASM_NEON +void sha256_block_data_order_neon(uint32_t *state, const uint8_t *data, + size_t num); + +// Armv8.2 SHA-512 instructions are not available in 32-bit. +#define SHA512_ASM_NEON +void sha512_block_data_order_neon(uint64_t *state, const uint8_t *data, + size_t num); + #elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) #define SHA1_ASM_NOHW @@ -227,6 +256,7 @@ void sha256_block_data_order_nohw(uint32_t *state, const uint8_t *data, void sha512_block_data_order_hw(uint64_t *state, const uint8_t *data, size_t num); #endif + #if defined(SHA512_ASM_NOHW) void sha512_block_data_order_nohw(uint64_t *state, const uint8_t *data, size_t num); diff --git a/crypto/fipsmodule/sha/sha1.c b/crypto/fipsmodule/sha/sha1.c index 681bff37d9..9387e0f090 100644 --- a/crypto/fipsmodule/sha/sha1.c +++ b/crypto/fipsmodule/sha/sha1.c @@ -413,6 +413,12 @@ static void sha1_block_data_order(uint32_t *state, const uint8_t *data, sha1_block_data_order_ssse3(state, data, num); return; } +#endif +#if defined(SHA1_ASM_NEON) + if (CRYPTO_is_NEON_capable()) { + sha1_block_data_order_neon(state, data, num); + return; + } #endif sha1_block_data_order_nohw(state, data, num); } diff --git a/crypto/fipsmodule/sha/sha256.c b/crypto/fipsmodule/sha/sha256.c index d2e7c7b334..e39dcede5c 100644 --- a/crypto/fipsmodule/sha/sha256.c +++ b/crypto/fipsmodule/sha/sha256.c @@ -403,6 +403,12 @@ static void sha256_block_data_order(uint32_t *state, const uint8_t *data, sha256_block_data_order_ssse3(state, data, num); return; } +#endif +#if defined(SHA256_ASM_NEON) + if (CRYPTO_is_NEON_capable()) { + sha256_block_data_order_neon(state, data, num); + return; + } #endif sha256_block_data_order_nohw(state, data, num); } diff --git a/crypto/fipsmodule/sha/sha512.c b/crypto/fipsmodule/sha/sha512.c index f9d9d88dc6..f7dbe2c159 100644 --- a/crypto/fipsmodule/sha/sha512.c +++ b/crypto/fipsmodule/sha/sha512.c @@ -694,6 +694,12 @@ static void sha512_block_data_order(uint64_t *state, const uint8_t *data, sha512_block_data_order_avx(state, data, num); return; } +#endif +#if defined(SHA512_ASM_NEON) + if (CRYPTO_is_NEON_capable()) { + sha512_block_data_order_neon(state, data, num); + return; + } #endif sha512_block_data_order_nohw(state, data, num); } diff --git a/crypto/fipsmodule/sha/sha_test.cc b/crypto/fipsmodule/sha/sha_test.cc index c79e3912c7..e8854fd8bf 100644 --- a/crypto/fipsmodule/sha/sha_test.cc +++ b/crypto/fipsmodule/sha/sha_test.cc @@ -44,13 +44,16 @@ TEST(SHATest, SHA1ABI) { #if defined(SHA1_ASM_AVX) && !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_AVX) if (sha1_avx_capable()) { CHECK_ABI(sha1_block_data_order_avx, ctx.h, kBuf, blocks); - return; } #endif #if defined(SHA1_ASM_SSSE3) if (sha1_ssse3_capable()) { CHECK_ABI(sha1_block_data_order_ssse3, ctx.h, kBuf, blocks); - return; + } +#endif +#if defined(SHA1_ASM_NEON) + if (CRYPTO_is_NEON_capable()) { + CHECK_ABI(sha1_block_data_order_neon, ctx.h, kBuf, blocks); } #endif #if defined(SHA1_ASM_NOHW) @@ -76,13 +79,16 @@ TEST(SHATest, SHA256ABI) { #if defined(SHA256_ASM_AVX) && !defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_AVX) if (sha256_avx_capable()) { CHECK_ABI(sha256_block_data_order_avx, ctx.h, kBuf, blocks); - return; } #endif #if defined(SHA256_ASM_SSSE3) if (sha256_ssse3_capable()) { CHECK_ABI(sha256_block_data_order_ssse3, ctx.h, kBuf, blocks); - return; + } +#endif +#if defined(SHA256_ASM_NEON) + if (CRYPTO_is_NEON_capable()) { + CHECK_ABI(sha256_block_data_order_neon, ctx.h, kBuf, blocks); } #endif #if defined(SHA256_ASM_NOHW) @@ -110,6 +116,11 @@ TEST(SHATest, SHA512ABI) { CHECK_ABI(sha512_block_data_order_avx, ctx.h, kBuf, blocks); } #endif +#if defined(SHA512_ASM_NEON) + if (CRYPTO_is_NEON_capable()) { + CHECK_ABI(sha512_block_data_order_neon, ctx.h, kBuf, blocks); + } +#endif #if defined(SHA512_ASM_NOHW) CHECK_ABI(sha512_block_data_order_nohw, ctx.h, kBuf, blocks); #endif diff --git a/crypto/internal.h b/crypto/internal.h index 3bfeaf7a78..62ce4a3271 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -206,10 +206,18 @@ typedef __uint128_t uint128_t; #define OPENSSL_SSE2 #endif -// For convenience in testing 64-bit generic code, we allow disabling SSE2 -// intrinsics via |OPENSSL_NO_SSE2_FOR_TESTING|. x86_64 always has SSE2 -// available, so we would otherwise need to test such code on a non-x86_64 -// platform. +#if defined(OPENSSL_X86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_SSE2) +#error \ + "x86 assembly requires SSE2. Build with -msse2 (recommended), or disable assembly optimizations with -DOPENSSL_NO_ASM." +#endif + +// For convenience in testing the fallback code, we allow disabling SSE2 +// intrinsics via |OPENSSL_NO_SSE2_FOR_TESTING|. We require SSE2 on x86 and +// x86_64, so we would otherwise need to test such code on a non-x86 platform. +// +// This does not remove the above requirement for SSE2 support with assembly +// optimizations. It only disables some intrinsics-based optimizations so that +// we can test the fallback code on CI. #if defined(OPENSSL_SSE2) && defined(OPENSSL_NO_SSE2_FOR_TESTING) #undef OPENSSL_SSE2 #endif diff --git a/generated-src/ios-arm/crypto/fipsmodule/armv4-mont.S b/generated-src/ios-arm/crypto/fipsmodule/armv4-mont.S index 07d1b064b0..cec1cc9251 100644 --- a/generated-src/ios-arm/crypto/fipsmodule/armv4-mont.S +++ b/generated-src/ios-arm/crypto/fipsmodule/armv4-mont.S @@ -18,40 +18,16 @@ .code 32 #endif -#if __ARM_MAX_ARCH__>=7 -.align 5 -LOPENSSL_armcap: -.word OPENSSL_armcap_P-Lbn_mul_mont -#endif - -.globl _bn_mul_mont -.private_extern _bn_mul_mont +.globl _bn_mul_mont_nohw +.private_extern _bn_mul_mont_nohw #ifdef __thumb2__ -.thumb_func _bn_mul_mont +.thumb_func _bn_mul_mont_nohw #endif .align 5 -_bn_mul_mont: -Lbn_mul_mont: +_bn_mul_mont_nohw: ldr ip,[sp,#4] @ load num stmdb sp!,{r0,r2} @ sp points at argument block -#if __ARM_MAX_ARCH__>=7 - tst ip,#7 - bne Lialu - adr r0,Lbn_mul_mont - ldr r2,LOPENSSL_armcap - ldr r0,[r0,r2] -#ifdef __APPLE__ - ldr r0,[r0] -#endif - tst r0,#ARMV7_NEON @ NEON available? - ldmia sp, {r0,r2} - beq Lialu - add sp,sp,#8 - b bn_mul8x_mont_neon -.align 4 -Lialu: -#endif cmp ip,#2 mov r0,ip @ load num #ifdef __thumb2__ @@ -207,11 +183,13 @@ Labrt: +.globl _bn_mul8x_mont_neon +.private_extern _bn_mul8x_mont_neon #ifdef __thumb2__ -.thumb_func bn_mul8x_mont_neon +.thumb_func _bn_mul8x_mont_neon #endif .align 5 -bn_mul8x_mont_neon: +_bn_mul8x_mont_neon: mov ip,sp stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11} vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so @@ -962,13 +940,4 @@ LNEON_copy_n_zap: #endif .byte 77,111,110,116,103,111,109,101,114,121,32,109,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 -.align 2 -#if __ARM_MAX_ARCH__>=7 -.comm _OPENSSL_armcap_P,4 -.non_lazy_symbol_pointer -OPENSSL_armcap_P: -.indirect_symbol _OPENSSL_armcap_P -.long 0 -.private_extern _OPENSSL_armcap_P -#endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__APPLE__) diff --git a/generated-src/ios-arm/crypto/fipsmodule/sha1-armv4-large.S b/generated-src/ios-arm/crypto/fipsmodule/sha1-armv4-large.S index aaae29b579..1806c29b5e 100644 --- a/generated-src/ios-arm/crypto/fipsmodule/sha1-armv4-large.S +++ b/generated-src/ios-arm/crypto/fipsmodule/sha1-armv4-large.S @@ -14,27 +14,14 @@ .code 32 #endif -.globl _sha1_block_data_order -.private_extern _sha1_block_data_order +.globl _sha1_block_data_order_nohw +.private_extern _sha1_block_data_order_nohw #ifdef __thumb2__ -.thumb_func _sha1_block_data_order +.thumb_func _sha1_block_data_order_nohw #endif .align 5 -_sha1_block_data_order: -#if __ARM_MAX_ARCH__>=7 -Lsha1_block: - adr r3,Lsha1_block - ldr r12,LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV8_SHA1 - bne LARMv8 - tst r12,#ARMV7_NEON - bne LNEON -#endif +_sha1_block_data_order_nohw: stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 ldmia r0,{r3,r4,r5,r6,r7} @@ -492,10 +479,6 @@ LK_00_19:.word 0x5a827999 LK_20_39:.word 0x6ed9eba1 LK_40_59:.word 0x8f1bbcdc LK_60_79:.word 0xca62c1d6 -#if __ARM_MAX_ARCH__>=7 -LOPENSSL_armcap: -.word OPENSSL_armcap_P-Lsha1_block -#endif .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 5 @@ -503,12 +486,13 @@ LOPENSSL_armcap: +.globl _sha1_block_data_order_neon +.private_extern _sha1_block_data_order_neon #ifdef __thumb2__ -.thumb_func sha1_block_data_order_neon +.thumb_func _sha1_block_data_order_neon #endif .align 4 -sha1_block_data_order_neon: -LNEON: +_sha1_block_data_order_neon: stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 @ dmb @ errata #451034 on early Cortex A8 @@ -1364,12 +1348,13 @@ Loop_neon: # define INST(a,b,c,d) .byte a,b,c,d|0x10 # endif +.globl _sha1_block_data_order_hw +.private_extern _sha1_block_data_order_hw #ifdef __thumb2__ -.thumb_func sha1_block_data_order_armv8 +.thumb_func _sha1_block_data_order_hw #endif .align 5 -sha1_block_data_order_armv8: -LARMv8: +_sha1_block_data_order_hw: vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so veor q1,q1,q1 @@ -1498,13 +1483,5 @@ Loop_v8: vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} bx lr @ bx lr -#endif -#if __ARM_MAX_ARCH__>=7 -.comm _OPENSSL_armcap_P,4 -.non_lazy_symbol_pointer -OPENSSL_armcap_P: -.indirect_symbol _OPENSSL_armcap_P -.long 0 -.private_extern _OPENSSL_armcap_P #endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__APPLE__) diff --git a/generated-src/ios-arm/crypto/fipsmodule/sha256-armv4.S b/generated-src/ios-arm/crypto/fipsmodule/sha256-armv4.S index 31747007d3..598212a5e3 100644 --- a/generated-src/ios-arm/crypto/fipsmodule/sha256-armv4.S +++ b/generated-src/ios-arm/crypto/fipsmodule/sha256-armv4.S @@ -90,37 +90,18 @@ K256: .word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 .word 0 @ terminator -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -LOPENSSL_armcap: -.word OPENSSL_armcap_P-Lsha256_block_data_order -#endif .align 5 -.globl _sha256_block_data_order -.private_extern _sha256_block_data_order +.globl _sha256_block_data_order_nohw +.private_extern _sha256_block_data_order_nohw #ifdef __thumb2__ -.thumb_func _sha256_block_data_order -#endif -_sha256_block_data_order: -Lsha256_block_data_order: - adr r3,Lsha256_block_data_order -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) - ldr r12,LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV8_SHA256 - bne LARMv8 - tst r12,#ARMV7_NEON - bne LNEON +.thumb_func _sha256_block_data_order_nohw #endif +_sha256_block_data_order_nohw: add r2,r1,r2,lsl#6 @ len to point at the end of inp stmdb sp!,{r0,r1,r2,r4-r11,lr} ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} - @ TODO(davidben): When the OPENSSL_armcap logic above is removed, - @ replace this with a simple ADR. - sub r14,r3,#256+32 @ K256 + adr r14,K256 sub sp,sp,#16*4 @ alloca(X[16]) Loop: # if __ARM_ARCH>=7 @@ -1903,7 +1884,6 @@ LK256_shortcut_neon: .align 5 .skip 16 _sha256_block_data_order_neon: -LNEON: stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} sub r11,sp,#16*4+16 @@ -2703,25 +2683,26 @@ L_00_48: # define INST(a,b,c,d) .byte a,b,c,d # endif -LK256_shortcut_armv8: +LK256_shortcut_hw: @ PC is 8 bytes ahead in Arm mode and 4 bytes ahead in Thumb mode. #if defined(__thumb2__) -.word K256-(LK256_add_armv8+4) +.word K256-(LK256_add_hw+4) #else -.word K256-(LK256_add_armv8+8) +.word K256-(LK256_add_hw+8) #endif +.globl _sha256_block_data_order_hw +.private_extern _sha256_block_data_order_hw #ifdef __thumb2__ -.thumb_func sha256_block_data_order_armv8 +.thumb_func _sha256_block_data_order_hw #endif .align 5 -sha256_block_data_order_armv8: -LARMv8: +_sha256_block_data_order_hw: @ K256 is too far to reference from one ADR command in Thumb mode. In @ Arm mode, we could make it fit by aligning the ADR offset to a 64-byte - @ boundary. For simplicity, just load the offset from .LK256_shortcut_armv8. - ldr r3,LK256_shortcut_armv8 -LK256_add_armv8: + @ boundary. For simplicity, just load the offset from .LK256_shortcut_hw. + ldr r3,LK256_shortcut_hw +LK256_add_hw: add r3,pc,r3 vld1.32 {q0,q1},[r0] @@ -2861,12 +2842,4 @@ Loop_v8: .byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm _OPENSSL_armcap_P,4 -.non_lazy_symbol_pointer -OPENSSL_armcap_P: -.indirect_symbol _OPENSSL_armcap_P -.long 0 -.private_extern _OPENSSL_armcap_P -#endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__APPLE__) diff --git a/generated-src/ios-arm/crypto/fipsmodule/sha512-armv4.S b/generated-src/ios-arm/crypto/fipsmodule/sha512-armv4.S index fb737619a4..ea71446d2c 100644 --- a/generated-src/ios-arm/crypto/fipsmodule/sha512-armv4.S +++ b/generated-src/ios-arm/crypto/fipsmodule/sha512-armv4.S @@ -135,36 +135,16 @@ K512: WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -LOPENSSL_armcap: -.word OPENSSL_armcap_P-Lsha512_block_data_order -.skip 32-4 -#else -.skip 32 -#endif -.globl _sha512_block_data_order -.private_extern _sha512_block_data_order +.globl _sha512_block_data_order_nohw +.private_extern _sha512_block_data_order_nohw #ifdef __thumb2__ -.thumb_func _sha512_block_data_order -#endif -_sha512_block_data_order: -Lsha512_block_data_order: - adr r3,Lsha512_block_data_order -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) - ldr r12,LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV7_NEON - bne LNEON +.thumb_func _sha512_block_data_order_nohw #endif +_sha512_block_data_order_nohw: add r2,r1,r2,lsl#7 @ len to point at the end of inp stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} - @ TODO(davidben): When the OPENSSL_armcap logic above is removed, - @ replace this with a simple ADR. - sub r14,r3,#672 @ K512 + adr r14,K512 sub sp,sp,#9*8 ldr r7,[r0,#32+LO] @@ -551,7 +531,6 @@ L16_79: #endif .align 4 _sha512_block_data_order_neon: -LNEON: dmb @ errata #451034 on early Cortex A8 add r2,r1,r2,lsl#7 @ len to point at the end of inp adr r3,K512 @@ -1877,12 +1856,4 @@ L16_79_neon: .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm _OPENSSL_armcap_P,4 -.non_lazy_symbol_pointer -OPENSSL_armcap_P: -.indirect_symbol _OPENSSL_armcap_P -.long 0 -.private_extern _OPENSSL_armcap_P -#endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__APPLE__) diff --git a/generated-src/linux-arm/crypto/fipsmodule/armv4-mont.S b/generated-src/linux-arm/crypto/fipsmodule/armv4-mont.S index 8073aa62f3..0b845b6e9b 100644 --- a/generated-src/linux-arm/crypto/fipsmodule/armv4-mont.S +++ b/generated-src/linux-arm/crypto/fipsmodule/armv4-mont.S @@ -18,38 +18,14 @@ .code 32 #endif -#if __ARM_MAX_ARCH__>=7 -.align 5 -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lbn_mul_mont -#endif - -.globl bn_mul_mont -.hidden bn_mul_mont -.type bn_mul_mont,%function +.globl bn_mul_mont_nohw +.hidden bn_mul_mont_nohw +.type bn_mul_mont_nohw,%function .align 5 -bn_mul_mont: -.Lbn_mul_mont: +bn_mul_mont_nohw: ldr ip,[sp,#4] @ load num stmdb sp!,{r0,r2} @ sp points at argument block -#if __ARM_MAX_ARCH__>=7 - tst ip,#7 - bne .Lialu - adr r0,.Lbn_mul_mont - ldr r2,.LOPENSSL_armcap - ldr r0,[r0,r2] -#ifdef __APPLE__ - ldr r0,[r0] -#endif - tst r0,#ARMV7_NEON @ NEON available? - ldmia sp, {r0,r2} - beq .Lialu - add sp,sp,#8 - b bn_mul8x_mont_neon -.align 4 -.Lialu: -#endif cmp ip,#2 mov r0,ip @ load num #ifdef __thumb2__ @@ -200,11 +176,13 @@ bn_mul_mont: moveq pc,lr @ be binary compatible with V4, yet .word 0xe12fff1e @ interoperable with Thumb ISA:-) #endif -.size bn_mul_mont,.-bn_mul_mont +.size bn_mul_mont_nohw,.-bn_mul_mont_nohw #if __ARM_MAX_ARCH__>=7 .arch armv7-a .fpu neon +.globl bn_mul8x_mont_neon +.hidden bn_mul8x_mont_neon .type bn_mul8x_mont_neon,%function .align 5 bn_mul8x_mont_neon: @@ -958,9 +936,4 @@ bn_mul8x_mont_neon: #endif .byte 77,111,110,116,103,111,109,101,114,121,32,109,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 -.align 2 -#if __ARM_MAX_ARCH__>=7 -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__ELF__) diff --git a/generated-src/linux-arm/crypto/fipsmodule/sha1-armv4-large.S b/generated-src/linux-arm/crypto/fipsmodule/sha1-armv4-large.S index b284c3f9a5..323e6e6e12 100644 --- a/generated-src/linux-arm/crypto/fipsmodule/sha1-armv4-large.S +++ b/generated-src/linux-arm/crypto/fipsmodule/sha1-armv4-large.S @@ -14,25 +14,12 @@ .code 32 #endif -.globl sha1_block_data_order -.hidden sha1_block_data_order -.type sha1_block_data_order,%function +.globl sha1_block_data_order_nohw +.hidden sha1_block_data_order_nohw +.type sha1_block_data_order_nohw,%function .align 5 -sha1_block_data_order: -#if __ARM_MAX_ARCH__>=7 -.Lsha1_block: - adr r3,.Lsha1_block - ldr r12,.LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV8_SHA1 - bne .LARMv8 - tst r12,#ARMV7_NEON - bne .LNEON -#endif +sha1_block_data_order_nohw: stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 ldmia r0,{r3,r4,r5,r6,r7} @@ -483,17 +470,13 @@ sha1_block_data_order: moveq pc,lr @ be binary compatible with V4, yet .word 0xe12fff1e @ interoperable with Thumb ISA:-) #endif -.size sha1_block_data_order,.-sha1_block_data_order +.size sha1_block_data_order_nohw,.-sha1_block_data_order_nohw .align 5 .LK_00_19:.word 0x5a827999 .LK_20_39:.word 0x6ed9eba1 .LK_40_59:.word 0x8f1bbcdc .LK_60_79:.word 0xca62c1d6 -#if __ARM_MAX_ARCH__>=7 -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lsha1_block -#endif .byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 5 @@ -501,10 +484,11 @@ sha1_block_data_order: .arch armv7-a .fpu neon +.globl sha1_block_data_order_neon +.hidden sha1_block_data_order_neon .type sha1_block_data_order_neon,%function .align 4 sha1_block_data_order_neon: -.LNEON: stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} add r2,r1,r2,lsl#6 @ r2 to point at the end of r1 @ dmb @ errata #451034 on early Cortex A8 @@ -1360,10 +1344,11 @@ sha1_block_data_order_neon: # define INST(a,b,c,d) .byte a,b,c,d|0x10 # endif -.type sha1_block_data_order_armv8,%function +.globl sha1_block_data_order_hw +.hidden sha1_block_data_order_hw +.type sha1_block_data_order_hw,%function .align 5 -sha1_block_data_order_armv8: -.LARMv8: +sha1_block_data_order_hw: vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so veor q1,q1,q1 @@ -1491,10 +1476,6 @@ sha1_block_data_order_armv8: vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15} bx lr @ bx lr -.size sha1_block_data_order_armv8,.-sha1_block_data_order_armv8 -#endif -#if __ARM_MAX_ARCH__>=7 -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P +.size sha1_block_data_order_hw,.-sha1_block_data_order_hw #endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__ELF__) diff --git a/generated-src/linux-arm/crypto/fipsmodule/sha256-armv4.S b/generated-src/linux-arm/crypto/fipsmodule/sha256-armv4.S index 610a35afc0..fca0681f9c 100644 --- a/generated-src/linux-arm/crypto/fipsmodule/sha256-armv4.S +++ b/generated-src/linux-arm/crypto/fipsmodule/sha256-armv4.S @@ -90,35 +90,16 @@ K256: .word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 .size K256,.-K256 .word 0 @ terminator -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lsha256_block_data_order -#endif .align 5 -.globl sha256_block_data_order -.hidden sha256_block_data_order -.type sha256_block_data_order,%function -sha256_block_data_order: -.Lsha256_block_data_order: - adr r3,.Lsha256_block_data_order -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) - ldr r12,.LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV8_SHA256 - bne .LARMv8 - tst r12,#ARMV7_NEON - bne .LNEON -#endif +.globl sha256_block_data_order_nohw +.hidden sha256_block_data_order_nohw +.type sha256_block_data_order_nohw,%function +sha256_block_data_order_nohw: add r2,r1,r2,lsl#6 @ len to point at the end of inp stmdb sp!,{r0,r1,r2,r4-r11,lr} ldmia r0,{r4,r5,r6,r7,r8,r9,r10,r11} - @ TODO(davidben): When the OPENSSL_armcap logic above is removed, - @ replace this with a simple ADR. - sub r14,r3,#256+32 @ K256 + adr r14,K256 sub sp,sp,#16*4 @ alloca(X[16]) .Loop: # if __ARM_ARCH>=7 @@ -1880,7 +1861,7 @@ sha256_block_data_order: moveq pc,lr @ be binary compatible with V4, yet .word 0xe12fff1e @ interoperable with Thumb ISA:-) #endif -.size sha256_block_data_order,.-sha256_block_data_order +.size sha256_block_data_order_nohw,.-sha256_block_data_order_nohw #if __ARM_MAX_ARCH__>=7 .arch armv7-a .fpu neon @@ -1899,7 +1880,6 @@ sha256_block_data_order: .align 5 .skip 16 sha256_block_data_order_neon: -.LNEON: stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} sub r11,sp,#16*4+16 @@ -2699,23 +2679,24 @@ sha256_block_data_order_neon: # define INST(a,b,c,d) .byte a,b,c,d # endif -.LK256_shortcut_armv8: +.LK256_shortcut_hw: @ PC is 8 bytes ahead in Arm mode and 4 bytes ahead in Thumb mode. #if defined(__thumb2__) -.word K256-(.LK256_add_armv8+4) +.word K256-(.LK256_add_hw+4) #else -.word K256-(.LK256_add_armv8+8) +.word K256-(.LK256_add_hw+8) #endif -.type sha256_block_data_order_armv8,%function +.globl sha256_block_data_order_hw +.hidden sha256_block_data_order_hw +.type sha256_block_data_order_hw,%function .align 5 -sha256_block_data_order_armv8: -.LARMv8: +sha256_block_data_order_hw: @ K256 is too far to reference from one ADR command in Thumb mode. In @ Arm mode, we could make it fit by aligning the ADR offset to a 64-byte - @ boundary. For simplicity, just load the offset from .LK256_shortcut_armv8. - ldr r3,.LK256_shortcut_armv8 -.LK256_add_armv8: + @ boundary. For simplicity, just load the offset from .LK256_shortcut_hw. + ldr r3,.LK256_shortcut_hw +.LK256_add_hw: add r3,pc,r3 vld1.32 {q0,q1},[r0] @@ -2850,13 +2831,9 @@ sha256_block_data_order_armv8: vst1.32 {q0,q1},[r0] bx lr @ bx lr -.size sha256_block_data_order_armv8,.-sha256_block_data_order_armv8 +.size sha256_block_data_order_hw,.-sha256_block_data_order_hw #endif .byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,47,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__ELF__) diff --git a/generated-src/linux-arm/crypto/fipsmodule/sha512-armv4.S b/generated-src/linux-arm/crypto/fipsmodule/sha512-armv4.S index 135d23338e..5500686524 100644 --- a/generated-src/linux-arm/crypto/fipsmodule/sha512-armv4.S +++ b/generated-src/linux-arm/crypto/fipsmodule/sha512-armv4.S @@ -135,34 +135,14 @@ K512: WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) .size K512,.-K512 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.LOPENSSL_armcap: -.word OPENSSL_armcap_P-.Lsha512_block_data_order -.skip 32-4 -#else -.skip 32 -#endif -.globl sha512_block_data_order -.hidden sha512_block_data_order -.type sha512_block_data_order,%function -sha512_block_data_order: -.Lsha512_block_data_order: - adr r3,.Lsha512_block_data_order -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) - ldr r12,.LOPENSSL_armcap - ldr r12,[r3,r12] @ OPENSSL_armcap_P -#ifdef __APPLE__ - ldr r12,[r12] -#endif - tst r12,#ARMV7_NEON - bne .LNEON -#endif +.globl sha512_block_data_order_nohw +.hidden sha512_block_data_order_nohw +.type sha512_block_data_order_nohw,%function +sha512_block_data_order_nohw: add r2,r1,r2,lsl#7 @ len to point at the end of inp stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} - @ TODO(davidben): When the OPENSSL_armcap logic above is removed, - @ replace this with a simple ADR. - sub r14,r3,#672 @ K512 + adr r14,K512 sub sp,sp,#9*8 ldr r7,[r0,#32+LO] @@ -537,7 +517,7 @@ sha512_block_data_order: moveq pc,lr @ be binary compatible with V4, yet .word 0xe12fff1e @ interoperable with Thumb ISA:-) #endif -.size sha512_block_data_order,.-sha512_block_data_order +.size sha512_block_data_order_nohw,.-sha512_block_data_order_nohw #if __ARM_MAX_ARCH__>=7 .arch armv7-a .fpu neon @@ -547,7 +527,6 @@ sha512_block_data_order: .type sha512_block_data_order_neon,%function .align 4 sha512_block_data_order_neon: -.LNEON: dmb @ errata #451034 on early Cortex A8 add r2,r1,r2,lsl#7 @ len to point at the end of inp adr r3,K512 @@ -1873,8 +1852,4 @@ sha512_block_data_order_neon: .byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0 .align 2 .align 2 -#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) -.comm OPENSSL_armcap_P,4,4 -.hidden OPENSSL_armcap_P -#endif #endif // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__ELF__) diff --git a/generated-src/linux-x86_64/crypto/fipsmodule/x86_64-mont.S b/generated-src/linux-x86_64/crypto/fipsmodule/x86_64-mont.S index cd3633f97e..20c14fccba 100644 --- a/generated-src/linux-x86_64/crypto/fipsmodule/x86_64-mont.S +++ b/generated-src/linux-x86_64/crypto/fipsmodule/x86_64-mont.S @@ -6,9 +6,6 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__ELF__) .text -.extern OPENSSL_ia32cap_P -.hidden OPENSSL_ia32cap_P - .globl bn_mul_mont_nohw .hidden bn_mul_mont_nohw .type bn_mul_mont_nohw,@function @@ -776,11 +773,8 @@ _CET_ENDBR .byte 102,72,15,110,207 .byte 102,73,15,110,218 #ifndef MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX - leaq OPENSSL_ia32cap_P(%rip),%rax - movl 8(%rax),%eax - andl $0x80100,%eax - cmpl $0x80100,%eax - jne .Lsqr8x_nox + testq %rdx,%rdx + jz .Lsqr8x_nox call bn_sqrx8x_internal diff --git a/generated-src/mac-x86_64/crypto/fipsmodule/x86_64-mont.S b/generated-src/mac-x86_64/crypto/fipsmodule/x86_64-mont.S index 85e6f95301..3facc4418b 100644 --- a/generated-src/mac-x86_64/crypto/fipsmodule/x86_64-mont.S +++ b/generated-src/mac-x86_64/crypto/fipsmodule/x86_64-mont.S @@ -6,8 +6,6 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__APPLE__) .text - - .globl _bn_mul_mont_nohw .private_extern _bn_mul_mont_nohw @@ -773,11 +771,8 @@ L$sqr8x_body: .byte 102,72,15,110,207 .byte 102,73,15,110,218 #ifndef MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX - leaq _OPENSSL_ia32cap_P(%rip),%rax - movl 8(%rax),%eax - andl $0x80100,%eax - cmpl $0x80100,%eax - jne L$sqr8x_nox + testq %rdx,%rdx + jz L$sqr8x_nox call _bn_sqrx8x_internal diff --git a/generated-src/win-x86_64/crypto/fipsmodule/x86_64-mont.asm b/generated-src/win-x86_64/crypto/fipsmodule/x86_64-mont.asm index 1276e89249..a1d7c24323 100644 --- a/generated-src/win-x86_64/crypto/fipsmodule/x86_64-mont.asm +++ b/generated-src/win-x86_64/crypto/fipsmodule/x86_64-mont.asm @@ -12,8 +12,6 @@ default rel section .text code align=64 -EXTERN OPENSSL_ia32cap_P - global bn_mul_mont_nohw ALIGN 16 @@ -816,11 +814,8 @@ DB 102,72,15,110,209 DB 102,72,15,110,207 DB 102,73,15,110,218 %ifndef MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX - lea rax,[OPENSSL_ia32cap_P] - mov eax,DWORD[8+rax] - and eax,0x80100 - cmp eax,0x80100 - jne NEAR $L$sqr8x_nox + test rdx,rdx + jz NEAR $L$sqr8x_nox call bn_sqrx8x_internal diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index 69bb666a0d..4a6aa0d645 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h @@ -1745,18 +1745,18 @@ OPENSSL_EXPORT int ASN1_STRING_print(BIO *out, const ASN1_STRING *str); // ASN1_STRFLGS_ESC_2253 causes characters to be escaped as in RFC 2253, section // 2.4. -#define ASN1_STRFLGS_ESC_2253 1 +#define ASN1_STRFLGS_ESC_2253 1ul // ASN1_STRFLGS_ESC_CTRL causes all control characters to be escaped. -#define ASN1_STRFLGS_ESC_CTRL 2 +#define ASN1_STRFLGS_ESC_CTRL 2ul // ASN1_STRFLGS_ESC_MSB causes all characters above 127 to be escaped. -#define ASN1_STRFLGS_ESC_MSB 4 +#define ASN1_STRFLGS_ESC_MSB 4ul // ASN1_STRFLGS_ESC_QUOTE causes the string to be surrounded by quotes, rather // than using backslashes, when characters are escaped. Fewer characters will // require escapes in this case. -#define ASN1_STRFLGS_ESC_QUOTE 8 +#define ASN1_STRFLGS_ESC_QUOTE 8ul // ASN1_STRFLGS_UTF8_CONVERT causes the string to be encoded as UTF-8, with each // byte in the UTF-8 encoding treated as an individual character for purposes of @@ -1764,29 +1764,29 @@ OPENSSL_EXPORT int ASN1_STRING_print(BIO *out, const ASN1_STRING *str); // as a character, with wide characters escaped as "\Uxxxx" or "\Wxxxxxxxx". // Note this can be ambiguous if |ASN1_STRFLGS_ESC_*| are all unset. In that // case, backslashes are not escaped, but wide characters are. -#define ASN1_STRFLGS_UTF8_CONVERT 0x10 +#define ASN1_STRFLGS_UTF8_CONVERT 0x10ul // ASN1_STRFLGS_IGNORE_TYPE causes the string type to be ignored. The // |ASN1_STRING| in-memory representation will be printed directly. -#define ASN1_STRFLGS_IGNORE_TYPE 0x20 +#define ASN1_STRFLGS_IGNORE_TYPE 0x20ul // ASN1_STRFLGS_SHOW_TYPE causes the string type to be included in the output. -#define ASN1_STRFLGS_SHOW_TYPE 0x40 +#define ASN1_STRFLGS_SHOW_TYPE 0x40ul // ASN1_STRFLGS_DUMP_ALL causes all strings to be printed as a hexdump, using // RFC 2253 hexstring notation, such as "#0123456789ABCDEF". -#define ASN1_STRFLGS_DUMP_ALL 0x80 +#define ASN1_STRFLGS_DUMP_ALL 0x80ul // ASN1_STRFLGS_DUMP_UNKNOWN behaves like |ASN1_STRFLGS_DUMP_ALL| but only // applies to values of unknown type. If unset, unknown values will print // their contents as single-byte characters with escape sequences. -#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 +#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100ul // ASN1_STRFLGS_DUMP_DER causes hexdumped strings (as determined by // |ASN1_STRFLGS_DUMP_ALL| or |ASN1_STRFLGS_DUMP_UNKNOWN|) to print the entire // DER element as in RFC 2253, rather than only the contents of the // |ASN1_STRING|. -#define ASN1_STRFLGS_DUMP_DER 0x200 +#define ASN1_STRFLGS_DUMP_DER 0x200ul // ASN1_STRFLGS_RFC2253 causes the string to be escaped as in RFC 2253, // additionally escaping control characters. diff --git a/include/openssl/bio.h b/include/openssl/bio.h index 730601467a..6b4a770830 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -319,11 +319,11 @@ OPENSSL_EXPORT int BIO_set_close(BIO *bio, int close_flag); // BIO_number_read returns the number of bytes that have been read from // |bio|. -OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio); +OPENSSL_EXPORT uint64_t BIO_number_read(const BIO *bio); // BIO_number_written returns the number of bytes that have been written to // |bio|. -OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio); +OPENSSL_EXPORT uint64_t BIO_number_written(const BIO *bio); // BIO_set_callback_ex sets the |callback_ex| for |bio|. OPENSSL_EXPORT void BIO_set_callback_ex(BIO *bio, BIO_callback_fn_ex callback_ex); @@ -1013,7 +1013,7 @@ struct bio_st { // next_bio points to the next |BIO| in a chain. This |BIO| owns a reference // to |next_bio|. BIO *next_bio; // used by filter BIOs - size_t num_read, num_write; + uint64_t num_read, num_write; }; #define BIO_C_SET_CONNECT 100 diff --git a/include/openssl/posix_time.h b/include/openssl/posix_time.h index 7910e3424a..7f9411ef35 100644 --- a/include/openssl/posix_time.h +++ b/include/openssl/posix_time.h @@ -37,6 +37,12 @@ OPENSSL_EXPORT int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm); // returned on failure. It is a failure if |tm| contains out of range values. OPENSSL_EXPORT int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out); +// OPENSSL_timegm converts a time value between the years 0 and 9999 in |tm| to +// a time_t value in |out|. One is returned on success, zero is returned on +// failure. It is a failure if the converted time can not be represented in a +// time_t, or if the tm contains out of range values. +OPENSSL_EXPORT int OPENSSL_timegm(const struct tm *tm, time_t *out); + #if defined(__cplusplus) } // extern C diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index d7e7a20168..fc38e901c4 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -242,6 +242,13 @@ OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); // RSA_PKCS1_PADDING denotes PKCS#1 v1.5 padding. When used with encryption, // this is RSAES-PKCS1-v1_5. When used with signing, this is RSASSA-PKCS1-v1_5. +// +// WARNING: The RSAES-PKCS1-v1_5 encryption scheme is vulnerable to a +// chosen-ciphertext attack. Decrypting attacker-supplied ciphertext with +// RSAES-PKCS1-v1_5 may give the attacker control over your private key. This +// does not impact the RSASSA-PKCS1-v1_5 signature scheme. See "Chosen +// Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard +// PKCS #1", Daniel Bleichenbacher, Advances in Cryptology (Crypto '98). #define RSA_PKCS1_PADDING 1 // RSA_NO_PADDING denotes a raw RSA operation. @@ -262,8 +269,7 @@ OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); // It returns 1 on success or zero on error. // // The |padding| argument must be one of the |RSA_*_PADDING| values. If in -// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but -// |RSA_PKCS1_PADDING| is most common. +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -277,12 +283,16 @@ OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, // The |padding| argument must be one of the |RSA_*_PADDING| values. If in // doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. // -// Passing |RSA_PKCS1_PADDING| into this function is deprecated and insecure. If -// implementing a protocol using RSAES-PKCS1-V1_5, use |RSA_NO_PADDING| and then -// check padding in constant-time combined with a swap to a random session key -// or other mitigation. See "Chosen Ciphertext Attacks Against Protocols Based -// on the RSA Encryption Standard PKCS #1", Daniel Bleichenbacher, Advances in -// Cryptology (Crypto '98). +// WARNING: Passing |RSA_PKCS1_PADDING| into this function is deprecated and +// insecure. RSAES-PKCS1-v1_5 is vulnerable to a chosen-ciphertext attack. +// Decrypting attacker-supplied ciphertext with RSAES-PKCS1-v1_5 may give the +// attacker control over your private key. See "Chosen Ciphertext Attacks +// Against Protocols Based on the RSA Encryption Standard PKCS #1", Daniel +// Bleichenbacher, Advances in Cryptology (Crypto '98). +// +// In some limited cases, such as TLS RSA key exchange, it is possible to +// mitigate this flaw with custom, protocol-specific padding logic. This +// should be implemented with |RSA_NO_PADDING|, not |RSA_PKCS1_PADDING|. OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -291,8 +301,7 @@ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, // |rsa| and writes the encrypted data to |to|. The |to| buffer must have at // least |RSA_size| bytes of space. It returns the number of bytes written, or // -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| -// values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but -// |RSA_PKCS1_PADDING| is most common. +// values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. // // WARNING: this function is dangerous because it breaks the usual return value // convention. Use |RSA_encrypt| instead. diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 4d96920910..82fdc87b99 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1276,9 +1276,11 @@ OPENSSL_EXPORT int SSL_set_chain_and_key( SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); -// SSL_CTX_get0_chain returns the list of |CRYPTO_BUFFER|s that were set by -// |SSL_CTX_set_chain_and_key|. Reference counts are not incremented by this -// call. The return value may be |NULL| if no chain has been set. + +// SSL_get0_chain returns the list of |CRYPTO_BUFFER|s that were set by +// |SSL_set_chain_and_key|, unless they have been discarded. Reference counts +// are not incremented by this call. The return value may be |NULL| if no chain +// has been set. // // (Note: if a chain was configured by non-|CRYPTO_BUFFER|-based functions then // the return value is undefined and, even if not NULL, the stack itself may diff --git a/include/openssl/x509.h b/include/openssl/x509.h index f0a392a6c3..31a24b140a 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -3309,35 +3309,35 @@ OPENSSL_EXPORT int X509_REQ_print_fp(FILE *fp, X509_REQ *req); // XN_FLAG_COMPAT prints with |X509_NAME_print|'s format and return value // convention. -#define XN_FLAG_COMPAT 0 +#define XN_FLAG_COMPAT 0ul // XN_FLAG_SEP_MASK determines the separators to use between attributes. -#define XN_FLAG_SEP_MASK (0xf << 16) +#define XN_FLAG_SEP_MASK (0xful << 16) // XN_FLAG_SEP_COMMA_PLUS separates RDNs with "," and attributes within an RDN // with "+", as in RFC 2253. -#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) +#define XN_FLAG_SEP_COMMA_PLUS (1ul << 16) // XN_FLAG_SEP_CPLUS_SPC behaves like |XN_FLAG_SEP_COMMA_PLUS| but adds spaces // between the separators. -#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) +#define XN_FLAG_SEP_CPLUS_SPC (2ul << 16) // XN_FLAG_SEP_SPLUS_SPC separates RDNs with "; " and attributes within an RDN // with " + ". -#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) +#define XN_FLAG_SEP_SPLUS_SPC (3ul << 16) // XN_FLAG_SEP_MULTILINE prints each attribute on one line. -#define XN_FLAG_SEP_MULTILINE (4 << 16) +#define XN_FLAG_SEP_MULTILINE (4ul << 16) // XN_FLAG_DN_REV prints RDNs in reverse, from least significant to most // significant, as RFC 2253. -#define XN_FLAG_DN_REV (1 << 20) +#define XN_FLAG_DN_REV (1ul << 20) // XN_FLAG_FN_MASK determines how attribute types are displayed. -#define XN_FLAG_FN_MASK (0x3 << 21) +#define XN_FLAG_FN_MASK (0x3ul << 21) // XN_FLAG_FN_SN uses the attribute type's short name, when available. -#define XN_FLAG_FN_SN 0 +#define XN_FLAG_FN_SN 0ul // XN_FLAG_FN_LN uses the attribute type's long name, when available. #define XN_FLAG_FN_LN (1 << 21) @@ -3349,11 +3349,11 @@ OPENSSL_EXPORT int X509_REQ_print_fp(FILE *fp, X509_REQ *req); #define XN_FLAG_FN_NONE (3 << 21) // XN_FLAG_SPC_EQ wraps the "=" operator with spaces when printing attributes. -#define XN_FLAG_SPC_EQ (1 << 23) +#define XN_FLAG_SPC_EQ (1ul << 23) // XN_FLAG_DUMP_UNKNOWN_FIELDS causes unknown attribute types to be printed in // hex, as in RFC 2253. -#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1ul << 24) // XN_FLAG_FN_ALIGN aligns attribute names to 10 characters if using short // names, and 25 characters if using long names.