diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/codec/base64/base64.cpp | 10 | ||||
-rw-r--r-- | src/lib/math/bigint/bigint.cpp | 4 | ||||
-rw-r--r-- | src/lib/math/numbertheory/mp_numth.cpp | 2 | ||||
-rw-r--r-- | src/lib/modes/cbc/cbc.cpp | 1 | ||||
-rw-r--r-- | src/lib/modes/ecb/ecb.cpp | 1 | ||||
-rw-r--r-- | src/lib/modes/xts/xts.cpp | 1 | ||||
-rw-r--r-- | src/lib/utils/calendar.cpp | 27 | ||||
-rw-r--r-- | src/lib/utils/calendar.h | 8 | ||||
-rw-r--r-- | src/lib/utils/rounding.h | 11 | ||||
-rw-r--r-- | src/tests/catchy/test_utils.cpp | 107 |
10 files changed, 152 insertions, 20 deletions
diff --git a/src/lib/codec/base64/base64.cpp b/src/lib/codec/base64/base64.cpp index 1b1767aa1..a63d2b373 100644 --- a/src/lib/codec/base64/base64.cpp +++ b/src/lib/codec/base64/base64.cpp @@ -78,9 +78,7 @@ size_t base64_encode(char out[], std::string base64_encode(const byte input[], size_t input_length) { - const size_t output_length = (input_length == 0) - ? 0 - : (round_up<size_t>(input_length, 3) / 3) * 4; + const size_t output_length = (round_up(input_length, 3) / 3) * 4; std::string output(output_length, 0); size_t consumed = 0; @@ -231,10 +229,8 @@ size_t base64_decode(byte output[], secure_vector<byte> base64_decode(const char input[], size_t input_length, bool ignore_ws) - { - const size_t output_length = (input_length == 0) - ? 0 - : (round_up<size_t>(input_length, 4) * 3) / 4; + { + const size_t output_length = (round_up(input_length, 4) * 3) / 4; secure_vector<byte> bin(output_length); size_t written = base64_decode(bin.data(), diff --git a/src/lib/math/bigint/bigint.cpp b/src/lib/math/bigint/bigint.cpp index b5a8e0dd5..c9aa1d981 100644 --- a/src/lib/math/bigint/bigint.cpp +++ b/src/lib/math/bigint/bigint.cpp @@ -34,7 +34,7 @@ BigInt::BigInt(u64bit n) */ BigInt::BigInt(Sign s, size_t size) { - m_reg.resize(round_up<size_t>(size, 8)); + m_reg.resize(round_up(size, 8)); m_signedness = s; } @@ -271,7 +271,7 @@ void BigInt::binary_decode(const byte buf[], size_t length) const size_t WORD_BYTES = sizeof(word); clear(); - m_reg.resize(round_up<size_t>((length / WORD_BYTES) + 1, 8)); + m_reg.resize(round_up((length / WORD_BYTES) + 1, 8)); for(size_t i = 0; i != length / WORD_BYTES; ++i) { diff --git a/src/lib/math/numbertheory/mp_numth.cpp b/src/lib/math/numbertheory/mp_numth.cpp index fafc6b03f..6eb938286 100644 --- a/src/lib/math/numbertheory/mp_numth.cpp +++ b/src/lib/math/numbertheory/mp_numth.cpp @@ -19,7 +19,7 @@ BigInt square(const BigInt& x) { const size_t x_sw = x.sig_words(); - BigInt z(BigInt::Positive, round_up<size_t>(2*x_sw, 16)); + BigInt z(BigInt::Positive, round_up(2*x_sw, 16)); secure_vector<word> workspace(z.size()); bigint_sqr(z.mutable_data(), z.size(), diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp index 27f2bce4a..dd6550fce 100644 --- a/src/lib/modes/cbc/cbc.cpp +++ b/src/lib/modes/cbc/cbc.cpp @@ -105,6 +105,7 @@ size_t CBC_Encryption::minimum_final_size() const size_t CBC_Encryption::output_length(size_t input_length) const { + BOTAN_ASSERT(input_length != 0, "CBC_Encryption::output_length() call"); return round_up(input_length, cipher().block_size()); } diff --git a/src/lib/modes/ecb/ecb.cpp b/src/lib/modes/ecb/ecb.cpp index 73a241394..6de00f18a 100644 --- a/src/lib/modes/ecb/ecb.cpp +++ b/src/lib/modes/ecb/ecb.cpp @@ -83,6 +83,7 @@ size_t ECB_Encryption::minimum_final_size() const size_t ECB_Encryption::output_length(size_t input_length) const { + BOTAN_ASSERT(input_length != 0, "ECB_Encryption::output_length() call"); return round_up(input_length, cipher().block_size()); } diff --git a/src/lib/modes/xts/xts.cpp b/src/lib/modes/xts/xts.cpp index cc0e6d54c..4eaf03fe5 100644 --- a/src/lib/modes/xts/xts.cpp +++ b/src/lib/modes/xts/xts.cpp @@ -135,6 +135,7 @@ void XTS_Mode::update_tweak(size_t which) size_t XTS_Encryption::output_length(size_t input_length) const { + BOTAN_ASSERT(input_length != 0, "XTS_Encryption::output_length() call"); return round_up(input_length, cipher().block_size()); } diff --git a/src/lib/utils/calendar.cpp b/src/lib/utils/calendar.cpp index 3ce5170fc..b578f6be9 100644 --- a/src/lib/utils/calendar.cpp +++ b/src/lib/utils/calendar.cpp @@ -33,9 +33,30 @@ std::tm do_gmtime(std::time_t time_val) } -/* -* Convert a time_point to a calendar_point -*/ +std::chrono::system_clock::time_point calendar_point::to_std_timepoint() + { + if (year < 1900) + throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years before 1990."); + + std::tm tm; + tm.tm_sec = seconds; + tm.tm_min = minutes; + tm.tm_hour = hour; + tm.tm_mday = day; + tm.tm_mon = month - 1; + tm.tm_year = year - 1900; + + // Convert std::tm to std::time_t + // http://stackoverflow.com/questions/16647819/timegm-cross-platform + #if defined(BOTAN_TARGET_OS_IS_WINDOWS) + #define timegm _mkgmtime + #endif + std::time_t tt = timegm(&tm); + + return std::chrono::system_clock::from_time_t(tt); + } + + calendar_point calendar_value( const std::chrono::system_clock::time_point& time_point) { diff --git a/src/lib/utils/calendar.h b/src/lib/utils/calendar.h index 4efff0edc..4f882e49f 100644 --- a/src/lib/utils/calendar.h +++ b/src/lib/utils/calendar.h @@ -49,9 +49,15 @@ struct BOTAN_DLL calendar_point */ calendar_point(u32bit y, byte mon, byte d, byte h, byte min, byte sec) : year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} + + /** + * Returns an STL timepoint object + */ + std::chrono::system_clock::time_point to_std_timepoint(); }; -/* +/** +* Convert a time_point to a calendar_point * @param time_point a time point from the system clock * @return calendar_point object representing this time point */ diff --git a/src/lib/utils/rounding.h b/src/lib/utils/rounding.h index 02edb1929..8ad324225 100644 --- a/src/lib/utils/rounding.h +++ b/src/lib/utils/rounding.h @@ -9,22 +9,21 @@ #define BOTAN_ROUNDING_H__ #include <botan/types.h> +#include <botan/assert.h> namespace Botan { /** * Round up -* @param n an integer +* @param n a non-negative integer * @param align_to the alignment boundary * @return n rounded up to a multiple of align_to */ -template<typename T> -inline T round_up(T n, T align_to) +inline size_t round_up(size_t n, size_t align_to) { - if(align_to == 0) - return n; + BOTAN_ASSERT(align_to != 0, "align_to must not be 0"); - if(n % align_to || n == 0) + if(n % align_to) n += align_to - (n % align_to); return n; } diff --git a/src/tests/catchy/test_utils.cpp b/src/tests/catchy/test_utils.cpp index 17c35a678..41eef3e45 100644 --- a/src/tests/catchy/test_utils.cpp +++ b/src/tests/catchy/test_utils.cpp @@ -3,5 +3,112 @@ #include "catch.hpp" +#include <botan/calendar.h> +#include <botan/internal/rounding.h> + using namespace Botan; +TEST_CASE("round_up strictly positive", "[utils]") + { + CHECK(( round_up( 1, 10) == 10 )); + CHECK(( round_up( 3, 10) == 10 )); + CHECK(( round_up( 9, 10) == 10 )); + CHECK(( round_up(10, 10) == 10 )); + + CHECK(( round_up( 1, 4) == 4 )); + CHECK(( round_up( 3, 4) == 4 )); + CHECK(( round_up( 4, 4) == 4 )); + CHECK(( round_up( 9, 4) == 12 )); + CHECK(( round_up(10, 4) == 12 )); + } + +/* +This was broken + +TEST_CASE("round_up strictly negative", "[utils]") + { + CHECK(( round_up( -1, 10) == 0 )); + CHECK(( round_up( -3, 10) == 0 )); + CHECK(( round_up( -9, 10) == 0 )); + CHECK(( round_up(-10, 10) == -10 )); + + CHECK(( round_up( -1, 3) == 0 )); + CHECK(( round_up( -3, 3) == -3 )); + CHECK(( round_up( -8, 3) == -3 )); + CHECK(( round_up( -9, 3) == -9 )); + CHECK(( round_up(-10, 3) == -9 )); + } +*/ + +TEST_CASE("round_up zero", "[utils]") + { + CHECK(( round_up(0, 2) == 0 )); + CHECK(( round_up(0, 10) == 0 )); + CHECK(( round_up(0, 1000) == 0 )); + CHECK(( round_up(0, 99999) == 0 )); + CHECK(( round_up(0, 2222222) == 0 )); + } + +TEST_CASE("round_up invalid input", "[utils]") + { + CHECK_THROWS( round_up(3, 0) ); + CHECK_THROWS( round_up(5, 0) ); + } + +TEST_CASE("calendar_point constructor works", "[utils]") + { + auto point1 = calendar_point(1988, 04, 23, 14, 37, 28); + CHECK(( point1.year == 1988 )); + CHECK(( point1.month == 4 )); + CHECK(( point1.day == 23 )); + CHECK(( point1.hour == 14 )); + CHECK(( point1.minutes == 37 )); + CHECK(( point1.seconds == 28 )); + + auto point2 = calendar_point(1800, 01, 01, 0, 0, 0); + CHECK(( point2.year == 1800 )); + CHECK(( point2.month == 1 )); + CHECK(( point2.day == 1 )); + CHECK(( point2.hour == 0 )); + CHECK(( point2.minutes == 0 )); + CHECK(( point2.seconds == 0 )); + + auto point3 = calendar_point(2037, 12, 31, 24, 59, 59); + CHECK(( point3.year == 2037 )); + CHECK(( point3.month == 12 )); + CHECK(( point3.day == 31 )); + CHECK(( point3.hour == 24 )); + CHECK(( point3.minutes == 59 )); + CHECK(( point3.seconds == 59 )); + } + +TEST_CASE("calendar_point to stl timepoint and back", "[utils]") + { + { + auto in = calendar_point(1988, 04, 23, 14, 37, 28); + auto out = calendar_value(in.to_std_timepoint()); + CHECK(( out.year == 1988 )); + CHECK(( out.month == 4 )); + CHECK(( out.day == 23 )); + CHECK(( out.hour == 14 )); + CHECK(( out.minutes == 37 )); + CHECK(( out.seconds == 28 )); + } + + { + auto in = calendar_point(2037, 12, 31, 23, 59, 59); + auto out = calendar_value(in.to_std_timepoint()); + CHECK(( out.year == 2037 )); + CHECK(( out.month == 12 )); + CHECK(( out.day == 31 )); + CHECK(( out.hour == 23 )); + CHECK(( out.minutes == 59 )); + CHECK(( out.seconds == 59 )); + } + + SECTION("year too early") + { + auto in = calendar_point(1800, 01, 01, 0, 0, 0); + CHECK_THROWS( in.to_std_timepoint() ); + } + } |