Add dependencies locally

This commit is contained in:
Ahrimdon 2024-03-06 15:11:36 -05:00
parent 2b6ab07460
commit 2253182bf3
209 changed files with 9374 additions and 3905 deletions

44
deps/GSL/README.md vendored
View File

@ -26,18 +26,18 @@ Feature | Suppo
-------------------------------------------------------------------------|:----------:|------------- -------------------------------------------------------------------------|:----------:|-------------
[**1. Views**][cg-views] | | [**1. Views**][cg-views] | |
[owner](docs/headers.md#user-content-H-pointers-owner) | ☑ | An alias for a raw pointer [owner](docs/headers.md#user-content-H-pointers-owner) | ☑ | An alias for a raw pointer
[not_null](docs/headers.md#user-content-H-pointers-not_null) | ☑ | Restricts a pointer / smart pointer to hold non-null values [not_null](docs/headers.md#user-content-H-pointers-not_null) | ☑ | Restricts a pointer/smart pointer to hold non-null values
[span](docs/headers.md#user-content-H-span-span) | ☑ | A view over a contiguous sequence of memory. Based on the standardized version of `std::span`, however `gsl::span` enforces bounds checking. [span](docs/headers.md#user-content-H-span-span) | ☑ | A view over a contiguous sequence of memory. Based on the standardized version of `std::span`, however `gsl::span` enforces bounds checking.
span_p | ☐ | Spans a range starting from a pointer to the first place for which the predicate is true span_p | ☐ | Spans a range starting from a pointer to the first place for which the predicate is true
[basic_zstring](docs/headers.md#user-content-H-string_span) | ☑ | A pointer to a C-string (zero-terminated array) with a templated char type [basic_zstring](docs/headers.md#user-content-H-zstring) | ☑ | A pointer to a C-string (zero-terminated array) with a templated char type
[zstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char [zstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `char`
[czstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char [czstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `const char`
[wzstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of wchar_t [wzstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `wchar_t`
[cwzstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const wchar_t [cwzstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `const wchar_t`
[u16zstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char16_t [u16zstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `char16_t`
[cu16zstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char16_t [cu16zstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `const char16_t`
[u32zstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of char32_t [u32zstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `char32_t`
[cu32zstring](docs/headers.md#user-content-H-string_span) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of const char32_t [cu32zstring](docs/headers.md#user-content-H-zstring) | ☑ | An alias to `basic_zstring` with dynamic extent and a char type of `const char32_t`
[**2. Owners**][cg-owners] | | [**2. Owners**][cg-owners] | |
[unique_ptr](docs/headers.md#user-content-H-pointers-unique_ptr) | ☑ | An alias to `std::unique_ptr` [unique_ptr](docs/headers.md#user-content-H-pointers-unique_ptr) | ☑ | An alias to `std::unique_ptr`
[shared_ptr](docs/headers.md#user-content-H-pointers-shared_ptr) | ☑ | An alias to `std::shared_ptr` [shared_ptr](docs/headers.md#user-content-H-pointers-shared_ptr) | ☑ | An alias to `std::shared_ptr`
@ -50,31 +50,31 @@ dyn_array | &#x26
move_owner | ☐ | A helper function that moves one `owner` to the other move_owner | ☐ | A helper function that moves one `owner` to the other
[byte](docs/headers.md#user-content-H-byte-byte) | ☑ | Either an alias to `std::byte` or a byte type [byte](docs/headers.md#user-content-H-byte-byte) | ☑ | Either an alias to `std::byte` or a byte type
[final_action](docs/headers.md#user-content-H-util-final_action) | ☑ | A RAII style class that invokes a functor on its destruction [final_action](docs/headers.md#user-content-H-util-final_action) | ☑ | A RAII style class that invokes a functor on its destruction
[finally](docs/headers.md#user-content-H-util-finally) | ☑ | A helper function instantiating `final_action` [finally](docs/headers.md#user-content-H-util-finally) | ☑ | A helper function instantiating [final_action](docs/headers.md#user-content-H-util-final_action)
[GSL_SUPPRESS](docs/headers.md#user-content-H-assert-gsl_suppress) | ☑ | A macro that takes an argument and turns it into `[[gsl::suppress(x)]]` or `[[gsl::suppress("x")]]` [GSL_SUPPRESS](docs/headers.md#user-content-H-assert-gsl_suppress) | ☑ | A macro that takes an argument and turns it into `[[gsl::suppress(x)]]` or `[[gsl::suppress("x")]]`
[[implicit]] | ☐ | A "marker" to put on single-argument constructors to explicitly make them non-explicit [[implicit]] | ☐ | A "marker" to put on single-argument constructors to explicitly make them non-explicit
[index](docs/headers.md#user-content-H-util-index) | ☑ | A type to use for all container and array indexing (currently an alias for `std::ptrdiff_t`) [index](docs/headers.md#user-content-H-util-index) | ☑ | A type to use for all container and array indexing (currently an alias for `std::ptrdiff_t`)
joining_thread | ☐ | A RAII style version of `std::thread` that joins joining_thread | ☐ | A RAII style version of `std::thread` that joins
[narrow](docs/headers.md#user-content-H-narrow-narrow) | ☑ | A checked version of `narrow_cast`; it can throw `narrowing_error` [narrow](docs/headers.md#user-content-H-narrow-narrow) | ☑ | A checked version of `narrow_cast`; it can throw [narrowing_error](docs/headers.md#user-content-H-narrow-narrowing_error)
[narrow_cast](docs/headers.md#user-content-H-util-narrow_cast) | ☑ | A narrowing cast for values and a synonym for `static_cast` [narrow_cast](docs/headers.md#user-content-H-util-narrow_cast) | ☑ | A narrowing cast for values and a synonym for `static_cast`
[narrowing_error](docs/headers.md#user-content-H-narrow-narrowing_error) | ☑ | A custom exception type thrown by `narrow()` [narrowing_error](docs/headers.md#user-content-H-narrow-narrowing_error) | ☑ | A custom exception type thrown by [narrow](docs/headers.md#user-content-H-narrow-narrow)
[**5. Concepts**][cg-concepts] | ☐ | [**5. Concepts**][cg-concepts] | ☐ |
## The following features do not exist in or have been removed from the C++ Core Guidelines: ## The following features do not exist in or have been removed from the C++ Core Guidelines:
Feature | Supported? | Description Feature | Supported? | Description
-----------------------------------|:----------:|------------- -----------------------------------|:----------:|-------------
[strict_not_null](docs/headers.md#user-content-H-pointers-strict_not_null) | ☑ | A stricter version of `not_null` with explicit constructors [strict_not_null](docs/headers.md#user-content-H-pointers-strict_not_null) | ☑ | A stricter version of [not_null](docs/headers.md#user-content-H-pointers-not_null) with explicit constructors
multi_span | ☐ | Deprecated. Multi-dimensional span. multi_span | ☐ | Deprecated. Multi-dimensional span.
strided_span | ☐ | Deprecated. Support for this type has been discontinued. strided_span | ☐ | Deprecated. Support for this type has been discontinued.
basic_string_span | ☐ | Deprecated. Like `span` but for strings with a templated char type basic_string_span | ☐ | Deprecated. Like `span` but for strings with a templated char type
string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of char string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `char`
cstring_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of const char cstring_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `const char`
wstring_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of wchar_t wstring_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `wchar_t`
cwstring_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of const wchar_t cwstring_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `const wchar_t`
u16string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of char16_t u16string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `char16_t`
cu16string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of const char16_t cu16string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `const char16_t`
u32string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of char32_t u32string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `char32_t`
cu32string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of const char32_t cu32string_span | ☐ | Deprecated. An alias to `basic_string_span` with a char type of `const char32_t`
This is based on [CppCoreGuidelines semi-specification](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gsl-guidelines-support-library). This is based on [CppCoreGuidelines semi-specification](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gsl-guidelines-support-library).

View File

@ -14,7 +14,7 @@ See [GSL: Guidelines support library](https://isocpp.github.io/CppCoreGuidelines
- [`<pointers>`](#user-content-H-pointers) - [`<pointers>`](#user-content-H-pointers)
- [`<span>`](#user-content-H-span) - [`<span>`](#user-content-H-span)
- [`<span_ext>`](#user-content-H-span_ext) - [`<span_ext>`](#user-content-H-span_ext)
- [`<string_span>`](#user-content-H-string_span) - [`<zstring>`](#user-content-H-zstring)
- [`<util>`](#user-content-H-util) - [`<util>`](#user-content-H-util)
## <a name="H-algorithms" />`<algorithms>` ## <a name="H-algorithms" />`<algorithms>`
@ -729,7 +729,7 @@ crend(const span<ElementType, Extent>& s) noexcept;
Free functions for getting a non-const/const begin/end normal/reverse iterator for a [`span`](#user-content-H-span-span). Free functions for getting a non-const/const begin/end normal/reverse iterator for a [`span`](#user-content-H-span-span).
## <a name="H-string_span" />`<string_span>` ## <a name="H-zstring" />`<zstring>`
This header exports a family of `*zstring` types. This header exports a family of `*zstring` types.
@ -806,8 +806,7 @@ void operator=(final_action&&) = delete;
Move construction is allowed. Copy construction is deleted. Copy and move assignment are also explicitely deleted. Move construction is allowed. Copy construction is deleted. Copy and move assignment are also explicitely deleted.
#### Non-member functions #### <a name="H-util-finally" />Non-member functions
```cpp ```cpp
template <class F> template <class F>
auto finally(F&& f) noexcept; auto finally(F&& f) noexcept;

View File

@ -46,7 +46,7 @@
// Hopefully temporary until suppression standardization occurs // Hopefully temporary until suppression standardization occurs
// //
#if defined(__clang__) #if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] #define GSL_SUPPRESS(x) [[gsl::suppress(#x)]]
#else #else
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__NVCC__) #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__NVCC__)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] #define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
@ -55,9 +55,6 @@
#endif // _MSC_VER #endif // _MSC_VER
#endif // __clang__ #endif // __clang__
#define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1) #define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0) #define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)

View File

@ -17,20 +17,6 @@
#ifndef GSL_BYTE_H #ifndef GSL_BYTE_H
#define GSL_BYTE_H #define GSL_BYTE_H
//
// make suppress attributes work for some compilers
// Hopefully temporary until suppression standardization occurs
//
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__NVCC__)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // _MSC_VER
#endif // __clang__
#include <type_traits> #include <type_traits>
// VS2017 15.8 added support for the __cpp_lib_byte definition // VS2017 15.8 added support for the __cpp_lib_byte definition

View File

@ -22,7 +22,7 @@
#include "byte" // byte #include "byte" // byte
#include "pointers" // owner, not_null #include "pointers" // owner, not_null
#include "span" // span #include "span" // span
#include "string_span" // zstring, string_span, zstring_builder... #include "zstring" // zstring
#include "util" // finally()/narrow_cast()... #include "util" // finally()/narrow_cast()...
#ifdef __cpp_exceptions #ifdef __cpp_exceptions

View File

@ -1,4 +0,0 @@
#pragma once
#pragma message( \
"This header will soon be removed. Use <gsl/algorithm> instead of <gsl/gsl_algorithm>")
#include "algorithm"

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/assert> instead of <gsl/gsl_assert>")
#include "assert"

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/byte> instead of <gsl/gsl_byte>")
#include "byte"

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/narrow> instead of <gsl/gsl_narrow>")
#include "narrow"

View File

@ -1,3 +0,0 @@
#pragma once
#pragma message("This header will soon be removed. Use <gsl/util> instead of <gsl/gsl_util>")
#include "util"

View File

@ -24,6 +24,7 @@
#include <memory> // for shared_ptr, unique_ptr #include <memory> // for shared_ptr, unique_ptr
#include <system_error> // for hash #include <system_error> // for hash
#include <type_traits> // for enable_if_t, is_convertible, is_assignable #include <type_traits> // for enable_if_t, is_convertible, is_assignable
#include <utility> // for declval
#if !defined(GSL_NO_IOSTREAMS) #if !defined(GSL_NO_IOSTREAMS)
#include <iosfwd> // for ostream #include <iosfwd> // for ostream
@ -99,24 +100,25 @@ public:
static_assert(details::is_comparable_to_nullptr<T>::value, "T cannot be compared to nullptr."); static_assert(details::is_comparable_to_nullptr<T>::value, "T cannot be compared to nullptr.");
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(U&& u) : ptr_(std::forward<U>(u)) constexpr not_null(U&& u) noexcept(std::is_nothrow_move_constructible<T>::value) : ptr_(std::forward<U>(u))
{ {
Expects(ptr_ != nullptr); Expects(ptr_ != nullptr);
} }
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>> template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr not_null(T u) : ptr_(std::move(u)) constexpr not_null(T u) noexcept(std::is_nothrow_move_constructible<T>::value) : ptr_(std::move(u))
{ {
Expects(ptr_ != nullptr); Expects(ptr_ != nullptr);
} }
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>> template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(const not_null<U>& other) : not_null(other.get()) constexpr not_null(const not_null<U>& other) noexcept(std::is_nothrow_move_constructible<T>::value) : not_null(other.get())
{} {}
not_null(const not_null& other) = default; not_null(const not_null& other) = default;
not_null& operator=(const not_null& other) = default; not_null& operator=(const not_null& other) = default;
constexpr details::value_or_reference_return_t<T> get() const constexpr details::value_or_reference_return_t<T> get() const
noexcept(noexcept(details::value_or_reference_return_t<T>{std::declval<T&>()}))
{ {
return ptr_; return ptr_;
} }

View File

@ -777,8 +777,15 @@ span(const Container&) -> span<Element>;
#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) ) #endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND) #if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated" // Bug in clang-cl.exe which raises a C++17 -Wdeprecated warning about this static constexpr workaround in C++14 mode.
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
template <class ElementType, std::size_t Extent> template <class ElementType, std::size_t Extent>
constexpr const typename span<ElementType, Extent>::size_type span<ElementType, Extent>::extent; constexpr const typename span<ElementType, Extent>::size_type span<ElementType, Extent>::extent;
#if defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#pragma clang diagnostic pop
#endif // defined(__clang__) && defined(_MSC_VER) && defined(__cplusplus) && (__cplusplus < 201703L)
#endif #endif
namespace details namespace details

View File

@ -1,58 +1,4 @@
/////////////////////////////////////////////////////////////////////////////// #pragma once
// #pragma message( \
// Copyright (c) 2015 Microsoft Corporation. All rights reserved. "This header will soon be removed. Use <gsl/zstring> instead of <gsl/string_span>")
// #include "zstring"
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_STRING_SPAN_H
#define GSL_STRING_SPAN_H
#include "span_ext" // for dynamic_extent
#include <cstddef> // for size_t, nullptr_t
namespace gsl
{
//
// czstring and wzstring
//
// These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
// that allow static analysis to help find bugs.
//
// There are no additional features/semantics that we can find a way to add inside the
// type system for these types that will not either incur significant runtime costs or
// (sometimes needlessly) break existing programs when introduced.
//
template <typename CharT, std::size_t Extent = dynamic_extent>
using basic_zstring = CharT*;
using czstring = basic_zstring<const char, dynamic_extent>;
using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
using zstring = basic_zstring<char, dynamic_extent>;
using wzstring = basic_zstring<wchar_t, dynamic_extent>;
using u16zstring = basic_zstring<char16_t, dynamic_extent>;
using u32zstring = basic_zstring<char32_t, dynamic_extent>;
} // namespace gsl
#endif // GSL_STRING_SPAN_H

58
deps/GSL/include/gsl/zstring vendored Normal file
View File

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_ZSTRING_H
#define GSL_ZSTRING_H
#include "span_ext" // for dynamic_extent
#include <cstddef> // for size_t, nullptr_t
namespace gsl
{
//
// czstring and wzstring
//
// These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
// that allow static analysis to help find bugs.
//
// There are no additional features/semantics that we can find a way to add inside the
// type system for these types that will not either incur significant runtime costs or
// (sometimes needlessly) break existing programs when introduced.
//
template <typename CharT, std::size_t Extent = dynamic_extent>
using basic_zstring = CharT*;
using czstring = basic_zstring<const char, dynamic_extent>;
using cwzstring = basic_zstring<const wchar_t, dynamic_extent>;
using cu16zstring = basic_zstring<const char16_t, dynamic_extent>;
using cu32zstring = basic_zstring<const char32_t, dynamic_extent>;
using zstring = basic_zstring<char, dynamic_extent>;
using wzstring = basic_zstring<wchar_t, dynamic_extent>;
using u16zstring = basic_zstring<char16_t, dynamic_extent>;
using u32zstring = basic_zstring<char32_t, dynamic_extent>;
} // namespace gsl
#endif // GSL_ZSTRING_H

View File

@ -121,7 +121,12 @@ if(MSVC) # MSVC or simulating MSVC
) )
check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID) check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
if (WARN_RESERVED_ID) if (WARN_RESERVED_ID)
target_compile_options(gsl_tests_config INTERFACE "-Wno-reserved-identifier") target_compile_options(gsl_tests_config INTERFACE "-Wno-reserved-identifier")
endif()
check_cxx_compiler_flag("-Wno-unsafe-buffer-usage" WARN_UNSAFE_BUFFER)
if (WARN_UNSAFE_BUFFER)
# This test uses very greedy heuristics such as "no pointer arithmetic on raw buffer"
target_compile_options(gsl_tests_config INTERFACE "-Wno-unsafe-buffer-usage")
endif() endif()
else() else()
target_compile_options(gsl_tests_config INTERFACE target_compile_options(gsl_tests_config INTERFACE
@ -255,7 +260,12 @@ if(MSVC) # MSVC or simulating MSVC
) )
check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID) check_cxx_compiler_flag("-Wno-reserved-identifier" WARN_RESERVED_ID)
if (WARN_RESERVED_ID) if (WARN_RESERVED_ID)
target_compile_options(gsl_tests_config_noexcept INTERFACE "-Wno-reserved-identifier") target_compile_options(gsl_tests_config_noexcept INTERFACE "-Wno-reserved-identifier")
endif()
check_cxx_compiler_flag("-Wno-unsafe-buffer-usage" WARN_UNSAFE_BUFFER)
if (WARN_UNSAFE_BUFFER)
# This test uses very greedy heuristics such as "no pointer arithmetic on raw buffer"
target_compile_options(gsl_tests_config_noexcept INTERFACE "-Wno-unsafe-buffer-usage")
endif() endif()
else() else()
target_compile_options(gsl_tests_config_noexcept INTERFACE target_compile_options(gsl_tests_config_noexcept INTERFACE

View File

@ -37,9 +37,6 @@ TEST(byte_tests, construction)
EXPECT_TRUE(static_cast<unsigned char>(b) == 4); EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
} }
// clang-format off
GSL_SUPPRESS(es.49)
// clang-format on
{ {
const byte b = byte(12); const byte b = byte(12);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12); EXPECT_TRUE(static_cast<unsigned char>(b) == 12);

View File

@ -24,6 +24,7 @@
#include <sstream> // for operator<<, ostringstream, basic_ostream:... #include <sstream> // for operator<<, ostringstream, basic_ostream:...
#include <string> // for basic_string, operator==, string, operator<< #include <string> // for basic_string, operator==, string, operator<<
#include <typeinfo> // for type_info #include <typeinfo> // for type_info
#include <variant> // for variant, monostate, get
#include "deathTestCommon.h" #include "deathTestCommon.h"
using namespace gsl; using namespace gsl;
@ -514,6 +515,17 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
} }
#endif #endif
} }
TEST(notnull_tests, TestVariantEmplace)
{
int i = 0;
std::variant<std::monostate, not_null<int*>> v;
v.emplace<not_null<int*>>(&i);
EXPECT_FALSE(v.valueless_by_exception());
EXPECT_TRUE(v.index() == 1);
EXPECT_TRUE(std::get<not_null<int*>>(v) == &i);
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
TEST(notnull_tests, TestMakeNotNull) TEST(notnull_tests, TestMakeNotNull)

View File

@ -21,7 +21,10 @@ make clean &>/dev/null
echo "Build for valgrind..." echo "Build for valgrind..."
make -j$MAKE_JOBS CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$5" test LTC_DEBUG=1 1>gcc_1.txt 2>gcc_2.txt # set DWARFv4 as debug format for clang, since it creates DWARFv5 as default which isn't support in old valgrind
[ -z "$(echo $CC | grep "clang")" ] || GFLAG="-gdwarf-4"
make -j$MAKE_JOBS CFLAGS="$2 $CFLAGS $4 $GFLAG" EXTRALIBS="$5" test LTC_DEBUG=1 1>gcc_1.txt 2>gcc_2.txt
echo "Run tests with valgrind..." echo "Run tests with valgrind..."

View File

@ -32,12 +32,13 @@ jobs:
strategy: strategy:
matrix: matrix:
cc: [ gcc, clang ] cc: [ gcc, clang ]
os: [ ubuntu-18.04 ] os: [ ubuntu-20.04, ubuntu-22.04 ]
config: config:
- { BUILDNAME: 'META_BUILDS', BUILDOPTIONS: '-DGMP_DESC', BUILDSCRIPT: '.ci/meta_builds.sh' } - { BUILDNAME: 'META_BUILDS', BUILDOPTIONS: '-DGMP_DESC', BUILDSCRIPT: '.ci/meta_builds.sh' }
- { BUILDNAME: 'VALGRIND', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/valgrind.sh' } - { BUILDNAME: 'VALGRIND', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/valgrind.sh' }
- { BUILDNAME: 'STOCK', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'STOCK', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'STOCK-MPI', BUILDOPTIONS: '-ULTM_DESC -UTFM_DESC -UUSE_LTM -UUSE_TFM', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'STOCK-MPI', BUILDOPTIONS: '-ULTM_DESC -UTFM_DESC -UUSE_LTM -UUSE_TFM', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'STOCK+AESNI', BUILDOPTIONS: '-msse4.1 -maes', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'EASY', BUILDOPTIONS: '-DLTC_EASY', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'EASY', BUILDOPTIONS: '-DLTC_EASY', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'NOTABLES', BUILDOPTIONS: '-DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NOTABLES', BUILDOPTIONS: '-DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' }
@ -56,10 +57,11 @@ jobs:
- name: install dependencies - name: install dependencies
run: | run: |
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -y libtommath-dev libgmp-dev libtfm-dev valgrind libtool-bin clang-tools lcov sudo apt-get install -y libgmp-dev valgrind libtool-bin clang-tools lcov ruby clang
sudo apt-get remove -y libtommath1
sudo gem install coveralls-lcov sudo gem install coveralls-lcov
curl -s https://packagecloud.io/install/repositories/libtom/packages/script.deb.sh | sudo bash curl -s https://packagecloud.io/install/repositories/libtom/packages/script.deb.sh | sudo bash
sudo apt-get install libtfm1=0.13-5ubuntu1 sudo apt-get install libtfm-git-dev libtommath-git-dev
- name: run tests - name: run tests
env: env:
CC: "${{ matrix.cc }}" CC: "${{ matrix.cc }}"
@ -71,14 +73,16 @@ jobs:
- name: regular logs - name: regular logs
if: ${{ !failure() }} if: ${{ !failure() }}
run: | run: |
cat gcc_1.txt cat gcc_1.txt || true
cat gcc_2.txt cat gcc_2.txt || true
- name: error logs - name: error logs
if: ${{ failure() }} if: ${{ failure() }}
run: | run: |
cat test_std.txt cat gcc_1.txt || true
cat test_err.txt cat gcc_2.txt || true
cat tv.txt cat test_std.txt || true
cat test_err.txt || true
cat tv.txt || true
- name: pack build directory - name: pack build directory
if: ${{ failure() }} if: ${{ failure() }}
run: | run: |

View File

@ -24,6 +24,9 @@ include(CheckIPOSupported)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
# for potential builds against gnump # for potential builds against gnump
include(FindPkgConfig) include(FindPkgConfig)
# for potential builds with MSVC
include(CMakePushCheckState)
include(CheckSymbolExists)
# default is "No tests" # default is "No tests"
option(BUILD_TESTING "" OFF) option(BUILD_TESTING "" OFF)
include(CTest) include(CTest)
@ -33,10 +36,25 @@ include(sources.cmake)
# Options # Options
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
option(WITH_LTM "Build with support for libtommath" TRUE) option(WITH_LTM "Build with support for libtommath" TRUE)
option(WITH_TFM "Build with support for tomsfastmath" FALSE)
option(WITH_GMP "Build with support for GNU Multi Precision Arithmetic Library" FALSE) option(WITH_GMP "Build with support for GNU Multi Precision Arithmetic Library" FALSE)
set(MPI_PROVIDER "LTM" CACHE STRING "Build tests and demos against 'LTM', 'TFM' or 'GMP', default is LTM") set(MPI_PROVIDER "LTM" CACHE STRING "Build tests and demos against 'LTM', 'TFM' or 'GMP', default is LTM")
option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"ON\", default is static" OFF) option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"ON\", default is static" OFF)
#-----------------------------------------------------------------------------
# Add support for ccache if desired
#-----------------------------------------------------------------------------
find_program(CCACHE ccache)
if(CCACHE)
option(ENABLE_CCACHE "Enable ccache." ON)
endif()
# use ccache if installed
if(CCACHE AND ENABLE_CCACHE)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE})
endif()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Compose CFLAGS # Compose CFLAGS
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
@ -79,6 +97,16 @@ if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
list(APPEND LTC_C_FLAGS -no-undefined) list(APPEND LTC_C_FLAGS -no-undefined)
endif() endif()
if(MSVC)
cmake_push_check_state()
check_symbol_exists(BCryptGenRandom bcrypt.h BCRYPT_AVAILABLE)
cmake_pop_check_state()
if (BCRYPT_AVAILABLE)
target_link_libraries(${PROJECT_NAME} PRIVATE Bcrypt)
list(APPEND LTC_C_FLAGS -DLTC_WIN32_BCRYPT)
endif()
endif()
# If the user set the environment variables at generate-time, append them # If the user set the environment variables at generate-time, append them
# in order to allow overriding our defaults. # in order to allow overriding our defaults.
# ${LTC_CFLAGS} means the user passed it via sth like: # ${LTC_CFLAGS} means the user passed it via sth like:
@ -136,6 +164,22 @@ if(WITH_LTM)
target_compile_definitions(${PROJECT_NAME} PUBLIC USE_LTM) target_compile_definitions(${PROJECT_NAME} PUBLIC USE_LTM)
endif() endif()
target_link_libraries(${PROJECT_NAME} PUBLIC libtommath) target_link_libraries(${PROJECT_NAME} PUBLIC libtommath)
list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DLTM_DESC)
list(APPEND LTC_MPI_PROVIDERS_LIBS -ltommath)
list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libtommath-dev)
endif()
# tomsfastmath
if(WITH_TFM)
find_package(tomsfastmath 0.13.1 REQUIRED)
target_compile_definitions(${PROJECT_NAME} PUBLIC TFM_DESC)
if(MPI_PROVIDER MATCHES "TFM")
target_compile_definitions(${PROJECT_NAME} PUBLIC USE_TFM)
endif()
target_link_libraries(${PROJECT_NAME} PUBLIC tomsfastmath)
list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DTFM_DESC)
list(APPEND LTC_MPI_PROVIDERS_LIBS -ltfm)
list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libtfm-dev)
endif() endif()
# GNU MP # GNU MP
if(WITH_GMP) if(WITH_GMP)
@ -146,8 +190,14 @@ if(WITH_GMP)
target_compile_definitions(${PROJECT_NAME} PUBLIC USE_GMP) target_compile_definitions(${PROJECT_NAME} PUBLIC USE_GMP)
endif() endif()
target_link_libraries(${PROJECT_NAME} PUBLIC ${GMP_LIBRARIES}) target_link_libraries(${PROJECT_NAME} PUBLIC ${GMP_LIBRARIES})
list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DGMP_DESC)
list(APPEND LTC_MPI_PROVIDERS_LIBS -lgmp)
list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libgmp-dev)
endif() endif()
list(JOIN LTC_MPI_PROVIDERS_CFLAGS " " MPI_PROVIDERS_CFLAGS)
list(JOIN LTC_MPI_PROVIDERS_LIBS " " MPI_PROVIDERS_LIBS)
list(JOIN LTC_DEBIAN_MPI_PROVIDER_DEPENDS " " DEBIAN_MPI_PROVIDER_DEPENDS)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# demos&test targets # demos&test targets
@ -171,7 +221,7 @@ set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
install(TARGETS ${PROJECT_NAME} install(TARGETS ${PROJECT_NAME}
EXPORT ${TARGETS_EXPORT_NAME} EXPORT ${TARGETS_EXPORT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
) )
@ -250,6 +300,15 @@ else()
set(DISTRO_PACK_PATH ${CMAKE_SYSTEM_NAME}/) set(DISTRO_PACK_PATH ${CMAKE_SYSTEM_NAME}/)
endif() endif()
# make sure untagged versions get a different package name
execute_process(COMMAND git describe --exact-match --tags ERROR_QUIET RESULT_VARIABLE REPO_HAS_TAG)
if(REPO_HAS_TAG EQUAL 0)
set(PACKAGE_NAME_SUFFIX "")
else()
set(PACKAGE_NAME_SUFFIX "-git")
message(STATUS "Use -git suffix")
endif()
# default CPack generators # default CPack generators
set(CPACK_GENERATOR TGZ STGZ) set(CPACK_GENERATOR TGZ STGZ)
@ -262,13 +321,17 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
list(APPEND CPACK_GENERATOR FREEBSD) list(APPEND CPACK_GENERATOR FREEBSD)
endif() endif()
set(LTC_DEBIAN_SHARED_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}${PROJECT_VERSION_MAJOR}")
# general CPack config # general CPack config
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH}) set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH})
message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}") message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}")
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}")
set(CPACK_DEBIAN_PACKAGE_NAME "${LTC_DEBIAN_SHARED_PACKAGE_NAME}")
else() else()
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-devel") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-devel")
set(CPACK_DEBIAN_LIBRARIES_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}-dev")
endif() endif()
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomCrypt") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomCrypt")
@ -281,15 +344,21 @@ set(CPACK_STRIP_FILES ON)
# deb specific CPack config # deb specific CPack config
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION}) set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
set(CPACK_DEBIAN_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
set(CPACK_DEBIAN_PACKAGE_DEPENDS ${DEBIAN_MPI_PROVIDER_DEPENDS})
else() else()
set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}-dev") set(CPACK_DEBIAN_PACKAGE_SECTION "libdevel")
set(CPACK_DEBIAN_PACKAGE_SECTION "devel") set(CPACK_DEBIAN_PACKAGE_DEPENDS ${LTC_DEBIAN_SHARED_PACKAGE_NAME})
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_COMPONENTS_ALL Libraries)
endif() endif()
# rpm specific CPack config # rpm specific CPack config
set(CPACK_RPM_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION}) set(CPACK_RPM_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
set(CPACK_RPM_PACKAGE_ARCHITECTURE ${MACHINE_ARCH}) set(CPACK_RPM_PACKAGE_ARCHITECTURE ${MACHINE_ARCH})

View File

@ -98,9 +98,7 @@ int gcm_filehandle( int cipher,
* but again it's only for SSE2 anyways, so who cares? * but again it's only for SSE2 anyways, so who cares?
*/ */
#ifdef LTC_GCM_TABLES_SSE2 #ifdef LTC_GCM_TABLES_SSE2
if ((unsigned long)gcm & 15) { gcm = LTC_ALIGN_BUF(gcm, 16);
gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
}
#endif #endif
if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) { if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {

View File

@ -614,6 +614,10 @@ As of this release the current cipher\_descriptors elements are the following:
\hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 & 4 \\ \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 & 4 \\
\hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\ \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\ & aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& rijndael\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& rijndael\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
\hline AES & aesni\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
(only on x86 with SSE4.1) &&&&& \\
\hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 & 7 \\ \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 & 7 \\
\hline DES & des\_desc & 8 & 8 & 16 & 13 \\ \hline DES & des\_desc & 8 & 8 & 16 & 13 \\
\hline 3DES (EDE mode) & des3\_desc & 8 & 16, 24 & 16 & 14 \\ \hline 3DES (EDE mode) & des3\_desc & 8 & 16, 24 & 16 & 14 \\
@ -639,24 +643,30 @@ As of this release the current cipher\_descriptors elements are the following:
\begin{small} \begin{small}
\begin{enumerate} \begin{enumerate}
\item \item
For AES, (also known as Rijndael) there are four descriptors which complicate issues a little. The descriptors For AES, (also known as Rijndael) there are multiple descriptors which complicate issues a little. As of FIXME-version-next
rijndael\_desc and rijndael\_enc\_desc provide the cipher named \textit{rijndael}. The descriptors aes\_desc and the library also integrates hardware-accelerated AES operations (e.g. AES-NI on amd64 with SSE4.1). Therefor the functionality of
aes\_enc\_desc provide the cipher name \textit{aes}. Functionally both \textit{rijndael} and \textit{aes} are the same cipher. The the descriptors for the AES algorithm has changed. The rijndael\_desc and rijndael\_enc\_desc descriptors provide the cipher
named \textit{rijndael} which contains the software implementation of the algorithm. The descriptors aes\_desc and aes\_enc\_desc
provide the cipher named \textit{aes} and implement an auto-detection mechanism that chooses between the software-only \textit{rijndael}
and the hardware-accelerated implementation.
Functionally both \textit{rijndael} and \textit{aes} are the same cipher. The
only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with \textit{enc} only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with \textit{enc}
in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine
and tables. The decryption and self--test function pointers of both \textit{encrypt only} descriptors are set to \textbf{NULL} and and tables. The decryption and self--test function pointers of both \textit{encrypt only} descriptors are set to \textbf{NULL} and
should not be called. should not be called.
The \textit{encrypt only} descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such The \textit{encrypt only} descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such
as EAX, PMAC and OMAC only require the encryption function. So far this \textit{encrypt only} functionality has only been implemented for as EAX, PMAC and OMAC or the CTR mode only require the encryption function. So far this \textit{encrypt only} functionality has only
Rijndael as it makes the most sense for this cipher. been implemented for Rijndael as it makes the most sense for this cipher.
\item \item
Note that for \textit{DES} and \textit{3DES} they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in Note that for \textit{DES} and \textit{3DES} they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in
fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24 fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24
byte string from the real 7/21 byte key. byte string from the real 7/21 byte key.
For \textit{3DES} exists a two-key mode, that can be initialized by calling the setup function with a \textit{keylen} of 16. This results in the re-usage of key \textit{K1} as key \textit{K3}. This mode has been specified as \textit{Keying Option 2} in FIPS 46-3. For \textit{3DES} exists a two-key mode, that can be initialized by calling the setup function with a \textit{keylen} of 16.
This results in the re-usage of key \textit{K1} as key \textit{K3}. This mode has been specified as \textit{Keying Option 2} in FIPS 46-3.
\item \item
Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in
@ -4180,7 +4190,8 @@ int pkcs_1_oaep_encode(
unsigned long modulus_bitlen, unsigned long modulus_bitlen,
prng_state *prng, prng_state *prng,
int prng_idx, int prng_idx,
int hash_idx, int mgf_hash,
int lparam_hash,
unsigned char *out, unsigned char *out,
unsigned long *outlen); unsigned long *outlen);
\end{alltt} \end{alltt}
@ -4190,7 +4201,9 @@ tag that can be applied to the encoding. This is useful to identify which syste
\textit{lparam} can be set to \textbf{NULL}. \textit{lparam} can be set to \textbf{NULL}.
OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter
\textit{modulus\_bitlen}. \textit{hash\_idx} is the index into the hash descriptor table of the hash desired. PKCS \#1 allows any hash to be \textit{modulus\_bitlen}. \textit{mgf\_hash} is the index into the hash descriptor table of the hash desired for the mask generation function (MGF).
\textit{lparam\_hash} is the index into the hash descriptor table of the hash desired for the \textit{lparam}. This value can also be set to $-1$
to indicate usage of the same algorithm than for the MGF. PKCS \#1 allows any hash to be
used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum
sized input message. \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process. sized input message. \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process.
The padded message is stored in \textit{out} along with the length in \textit{outlen}. The padded message is stored in \textit{out} along with the length in \textit{outlen}.
@ -4211,7 +4224,8 @@ int pkcs_1_oaep_decode(
const unsigned char *lparam, const unsigned char *lparam,
unsigned long lparamlen, unsigned long lparamlen,
unsigned long modulus_bitlen, unsigned long modulus_bitlen,
int hash_idx, int mgf_hash,
int lparam_hash,
unsigned char *out, unsigned char *out,
unsigned long *outlen, unsigned long *outlen,
int *res); int *res);
@ -4220,8 +4234,8 @@ int pkcs_1_oaep_decode(
This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. \textit{msg} is the This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. \textit{msg} is the
output of pkcs\_1\_oaep\_encode() of length \textit{msglen}. \textit{lparam} is the same system variable passed to the OAEP encoder. If it does not output of pkcs\_1\_oaep\_encode() of length \textit{msglen}. \textit{lparam} is the same system variable passed to the OAEP encoder. If it does not
match what was used during encoding this function will not decode the packet. \textit{modulus\_bitlen} is the size of the RSA modulus in bits match what was used during encoding this function will not decode the packet. \textit{modulus\_bitlen} is the size of the RSA modulus in bits
and must match what was used during encoding. Similarly the \textit{hash\_idx} index into the hash descriptor table must match what was used and must match what was used during encoding. Similarly the \textit{mgf\_hash} and \textit{lparam\_hash} indexes into the hash descriptor table must
during encoding. match what was used during encoding.
If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a
$1$ in \textit{res}. If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason $1$ in \textit{res}. If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason
@ -4416,7 +4430,8 @@ int rsa_encrypt_key_ex(
unsigned long lparamlen, unsigned long lparamlen,
prng_state *prng, prng_state *prng,
int prng_idx, int prng_idx,
int hash_idx, int mgf_hash,
int lparam_hash,
int padding, int padding,
rsa_key *key); rsa_key *key);
\end{verbatim} \end{verbatim}
@ -4437,7 +4452,8 @@ int rsa_decrypt_key(
unsigned long *outlen, unsigned long *outlen,
const unsigned char *lparam, const unsigned char *lparam,
unsigned long lparamlen, unsigned long lparamlen,
int hash_idx, int mgf_hash,
int lparam_hash,
int *stat, int *stat,
rsa_key *key); rsa_key *key);
\end{verbatim} \end{verbatim}
@ -5175,7 +5191,7 @@ typedef struct {
} ltc_ecc_curve; } ltc_ecc_curve;
\end{verbatim} \end{verbatim}
The curve must be of the form $y^2 = x^3 - a \cdot x + b$, and all of the \textit{const char*} parameters have to be encoded in hexadecimal format. The curve must be of the form $y^2 = x^3 + a \cdot x + b$, and all of the \textit{const char*} parameters have to be encoded in hexadecimal format.
Advanced example of creating an ECC key: Advanced example of creating an ECC key:
\begin{small} \begin{small}

View File

@ -71,6 +71,7 @@ sub check_source {
my $n = $1; my $n = $1;
push @{$troubles->{invalid_macro_name}}, "$lineno($n)" push @{$troubles->{invalid_macro_name}}, "$lineno($n)"
unless ($file eq 'src/headers/tomcrypt_cfg.h' && $n eq '__has_builtin') || unless ($file eq 'src/headers/tomcrypt_cfg.h' && $n eq '__has_builtin') ||
($file eq 'src/headers/tomcrypt_cfg.h' && $n eq '_WIN32_WINNT') ||
($file eq 'src/prngs/rng_get_bytes.c' && $n eq '_WIN32_WINNT'); ($file eq 'src/prngs/rng_get_bytes.c' && $n eq '_WIN32_WINNT');
} }
$lineno++; $lineno++;
@ -316,7 +317,7 @@ sub process_makefiles {
my @t = qw(); my @t = qw();
find({ no_chdir => 1, wanted => sub { push @t, $_ if $_ =~ /(common|no_prng|_tests?|test).c$/ } }, 'tests'); find({ no_chdir => 1, wanted => sub { push @t, $_ if $_ =~ /(common|no_prng|_tests?|test).c$/ } }, 'tests');
my @o = sort ('src/ciphers/aes/aes_enc.o', map { my $x = $_; $x =~ s/\.c$/.o/; $x } @c); my @o = sort ('src/ciphers/aes/aes_enc.o', 'src/ciphers/aes/aes_enc_desc.o', map { my $x = $_; $x =~ s/\.c$/.o/; $x } @c);
my $var_o = prepare_variable("OBJECTS", @o); my $var_o = prepare_variable("OBJECTS", @o);
my $var_h = prepare_variable("HEADERS_PUB", (sort @h)); my $var_h = prepare_variable("HEADERS_PUB", (sort @h));
(my $var_obj = $var_o) =~ s/\.o\b/.obj/sg; (my $var_obj = $var_o) =~ s/\.o\b/.obj/sg;

View File

@ -1,10 +1,9 @@
prefix=@CMAKE_INSTALL_PREFIX@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix} libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@
Name: LibTomCrypt Name: LibTomCrypt
Description: public domain open source cryptographic toolkit Description: public domain open source cryptographic toolkit
Version: @PROJECT_VERSION@ Version: @PROJECT_VERSION@
Libs: -L${libdir} -ltomcrypt Libs: -L${libdir} -ltomcrypt @MPI_PROVIDERS_LIBS@
Cflags: -I${includedir} Cflags: -I${includedir} @MPI_PROVIDERS_CFLAGS@

View File

@ -410,6 +410,10 @@
RelativePath="src\ciphers\aes\aes.c" RelativePath="src\ciphers\aes\aes.c"
> >
</File> </File>
<File
RelativePath="src\ciphers\aes\aes_desc.c"
>
</File>
<File <File
RelativePath="src\ciphers\aes\aes_tab.c" RelativePath="src\ciphers\aes\aes_tab.c"
> >
@ -454,6 +458,10 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath="src\ciphers\aes\aesni.c"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="safer" Name="safer"

View File

@ -46,6 +46,11 @@ LTC_EXTRALIBS += $(EXTRALIBS)
#AES comes in two flavours... enc+dec and enc #AES comes in two flavours... enc+dec and enc
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
ifneq ($V,1)
@echo " * ${CC} $@" ${silent_echo}
endif
${silent} ${CC} ${LTC_CFLAGS} -DENCRYPT_ONLY -c $< -o $@
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes_desc.c
ifneq ($V,1) ifneq ($V,1)
@echo " * ${CC} $@" ${silent_echo} @echo " * ${CC} $@" ${silent_echo}
endif endif

View File

@ -35,7 +35,8 @@ LIBMAIN_I =libtomcrypt.dll.a
LIBMAIN_D =libtomcrypt.dll LIBMAIN_D =libtomcrypt.dll
#List of objects to compile (all goes to libtomcrypt.a) #List of objects to compile (all goes to libtomcrypt.a)
OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_enc.o src/ciphers/anubis.o src/ciphers/blowfish.o \ OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_desc.o src/ciphers/aes/aes_enc.o \
src/ciphers/aes/aes_enc_desc.o src/ciphers/aes/aesni.o src/ciphers/anubis.o src/ciphers/blowfish.o \
src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \ src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \
src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \ src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \
src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \ src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \
@ -246,6 +247,8 @@ default: $(LIBMAIN_S)
#SPECIAL: AES comes in two flavours - enc+dec and enc-only #SPECIAL: AES comes in two flavours - enc+dec and enc-only
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o $(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes_desc.c -o src/ciphers/aes/aes_enc_desc.o
#SPECIAL: these are the rules to make certain object files #SPECIAL: these are the rules to make certain object files
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c

View File

@ -28,7 +28,8 @@ VERSION=1.18.2-develop
LIBMAIN_S =tomcrypt.lib LIBMAIN_S =tomcrypt.lib
#List of objects to compile (all goes to tomcrypt.lib) #List of objects to compile (all goes to tomcrypt.lib)
OBJECTS=src/ciphers/aes/aes.obj src/ciphers/aes/aes_enc.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \ OBJECTS=src/ciphers/aes/aes.obj src/ciphers/aes/aes_desc.obj src/ciphers/aes/aes_enc.obj \
src/ciphers/aes/aes_enc_desc.obj src/ciphers/aes/aesni.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
src/ciphers/camellia.obj src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/idea.obj src/ciphers/kasumi.obj \ src/ciphers/camellia.obj src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/idea.obj src/ciphers/kasumi.obj \
src/ciphers/khazad.obj src/ciphers/kseed.obj src/ciphers/multi2.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \ src/ciphers/khazad.obj src/ciphers/kseed.obj src/ciphers/multi2.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
src/ciphers/rc5.obj src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/saferp.obj \ src/ciphers/rc5.obj src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/saferp.obj \
@ -239,6 +240,8 @@ default: $(LIBMAIN_S)
#SPECIAL: AES comes in two flavours - enc+dec and enc-only #SPECIAL: AES comes in two flavours - enc+dec and enc-only
src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(LTC_CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes.c /Fosrc/ciphers/aes/aes_enc.obj $(CC) $(LTC_CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes.c /Fosrc/ciphers/aes/aes_enc.obj
src/ciphers/aes/aes_enc_desc.obj: src/ciphers/aes/aes_desc.c
$(CC) $(LTC_CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes_desc.c /Fosrc/ciphers/aes/aes_enc_desc.obj
#SPECIAL: these are the rules to make certain object files #SPECIAL: these are the rules to make certain object files
src/ciphers/aes/aes.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c

View File

@ -54,10 +54,24 @@ endif
include makefile_include.mk include makefile_include.mk
ifneq ($(findstring -DLTM_DESC,$(LTC_CFLAGS)),)
LTC_MPI_PROVIDERS_CFLAGS += -DLTM_DESC
LTC_MPI_PROVIDERS_LIBS += -ltommath
endif
ifneq ($(findstring -DTFM_DESC,$(LTC_CFLAGS)),)
LTC_MPI_PROVIDERS_CFLAGS += -DTFM_DESC
LTC_MPI_PROVIDERS_LIBS += -ltfm
endif
ifneq ($(findstring -DGMP_DESC,$(LTC_CFLAGS)),)
LTC_MPI_PROVIDERS_CFLAGS += -DGMP_DESC
LTC_MPI_PROVIDERS_LIBS += -lgmp
endif
#ciphers come in two flavours... enc+dec and enc #ciphers come in two flavours... enc+dec and enc
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o $(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes_desc.c
$(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes_desc.c -o src/ciphers/aes/aes_enc_desc.o
.c.o: .c.o:
$(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -o $@ -c $< $(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -o $@ -c $<
@ -79,8 +93,10 @@ endef
$(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo)))) $(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo))))
install: $(call print-help,install,Installs the library + headers + pkg-config file) .common_install install: $(call print-help,install,Installs the library + headers + pkg-config file) .common_install
sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,@CMAKE_INSTALL_LIBDIR@,lib,' \ sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,^libdir=.*,libdir=$(LIBPATH),' \
-e 's,@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@,include/tomcrypt,' libtomcrypt.pc.in > libtomcrypt.pc -e 's,^includedir=.*,includedir=$(INCPATH),' \
-e 's,@MPI_PROVIDERS_LIBS@,$(LTC_MPI_PROVIDERS_LIBS),' \
-e 's,@MPI_PROVIDERS_CFLAGS@,$(LTC_MPI_PROVIDERS_CFLAGS),' libtomcrypt.pc.in > libtomcrypt.pc
install -p -d $(DESTDIR)$(LIBPATH)/pkgconfig install -p -d $(DESTDIR)$(LIBPATH)/pkgconfig
install -p -m 644 libtomcrypt.pc $(DESTDIR)$(LIBPATH)/pkgconfig/ install -p -m 644 libtomcrypt.pc $(DESTDIR)$(LIBPATH)/pkgconfig/

View File

@ -35,17 +35,22 @@ ARFLAGS = r
RANLIB = ranlib RANLIB = ranlib
CFLAGS = -O2 -DUSE_LTM -DLTM_DESC -I../libtommath CFLAGS = -O2 -DUSE_LTM -DLTM_DESC -I../libtommath
EXTRALIBS = ../libtommath/libtommath.a EXTRALIBS = ../libtommath/libtommath.a
# pkg-config flags, added to libtomcrypt.pc on install time
PC_CFLAGS = -DLTM_DESC
PC_LIBS = -ltommath
#Compilation flags #Compilation flags
LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS) LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS)
LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS) LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS)
VERSION=1.18.2-develop VERSION=1.18.2-develop
VERSION_PC=1.18.2
#Libraries to be created (this makefile builds only static libraries) #Libraries to be created (this makefile builds only static libraries)
LIBMAIN_S =libtomcrypt.a LIBMAIN_S =libtomcrypt.a
#List of objects to compile (all goes to libtomcrypt.a) #List of objects to compile (all goes to libtomcrypt.a)
OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_enc.o src/ciphers/anubis.o src/ciphers/blowfish.o \ OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_desc.o src/ciphers/aes/aes_enc.o \
src/ciphers/aes/aes_enc_desc.o src/ciphers/aes/aesni.o src/ciphers/anubis.o src/ciphers/blowfish.o \
src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \ src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \
src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \ src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \
src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \ src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \
@ -256,6 +261,8 @@ default: $(LIBMAIN_S)
#SPECIAL: AES comes in two flavours - enc+dec and enc-only #SPECIAL: AES comes in two flavours - enc+dec and enc-only
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o $(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes_desc.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes_desc.c -o src/ciphers/aes/aes_enc_desc.o
#SPECIAL: these are the rules to make certain object files #SPECIAL: these are the rules to make certain object files
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
@ -317,7 +324,10 @@ install: $(LIBMAIN_S)
@mkdir -p $(DESTDIR)$(INCPATH) $(DESTDIR)$(LIBPATH)/pkgconfig @mkdir -p $(DESTDIR)$(INCPATH) $(DESTDIR)$(LIBPATH)/pkgconfig
@cp $(LIBMAIN_S) $(DESTDIR)$(LIBPATH)/ @cp $(LIBMAIN_S) $(DESTDIR)$(LIBPATH)/
@cp $(HEADERS_PUB) $(DESTDIR)$(INCPATH)/ @cp $(HEADERS_PUB) $(DESTDIR)$(INCPATH)/
@sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION),' libtomcrypt.pc.in > $(DESTDIR)$(LIBPATH)/pkgconfig/libtomcrypt.pc @sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,^libdir=.*,libdir=$(LIBPATH),' \
-e 's,^includedir=.*,includedir=$(INCPATH),' \
-e 's,@MPI_PROVIDERS_LIBS@,$(PC_LIBS),' \
-e 's,@MPI_PROVIDERS_CFLAGS@,$(PC_CFLAGS),' libtomcrypt.pc.in > $(DESTDIR)$(LIBPATH)/pkgconfig/libtomcrypt.pc
#Install useful tools #Install useful tools
install_bins: hashsum install_bins: hashsum

View File

@ -13,16 +13,16 @@ ifndef CROSS_COMPILE
CROSS_COMPILE:= CROSS_COMPILE:=
endif endif
# We only need to go through this dance of determining the right compiler if we're using H := \#
# cross compilation, otherwise $(CC) is fine as-is. ifeq (CLANG,$(shell printf "$(H)ifdef __clang__\nCLANG\n$(H)endif\n" | $(CC) -E - | grep CLANG))
CC_IS_CLANG := 1
else
CC_IS_CLANG := 0
endif # Clang
ifneq (,$(CROSS_COMPILE)) ifneq (,$(CROSS_COMPILE))
ifeq ($(origin CC),default) ifeq ($(origin CC),default)
CSTR := "\#ifdef __clang__\nCLANG\n\#endif\n" ifeq ($(CC_IS_CLANG), 1)
ifeq ($(PLATFORM),FreeBSD)
# XXX: FreeBSD needs extra escaping for some reason
CSTR := $$$(CSTR)
endif
ifneq (,$(shell echo $(CSTR) | $(CC) -E - | grep CLANG))
CC := $(CROSS_COMPILE)clang CC := $(CROSS_COMPILE)clang
else else
CC := $(CROSS_COMPILE)gcc CC := $(CROSS_COMPILE)gcc
@ -55,10 +55,10 @@ endif
ifndef EXTRALIBS ifndef EXTRALIBS
ifneq ($(shell echo $(CFLAGS) | grep USE_LTM),) ifneq ($(shell echo $(CFLAGS) | grep USE_LTM),)
EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config libtommath --libs) EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs libtommath)
else else
ifneq ($(shell echo $(CFLAGS) | grep USE_TFM),) ifneq ($(shell echo $(CFLAGS) | grep USE_TFM),)
EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config tomsfastmath --libs) EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs tomsfastmath)
endif endif
endif endif
endif endif
@ -76,6 +76,12 @@ endef
# by giving them as a parameter to make: # by giving them as a parameter to make:
# make CFLAGS="-I./src/headers/ -DLTC_SOURCE ..." ... # make CFLAGS="-I./src/headers/ -DLTC_SOURCE ..." ...
# #
ifneq ($(shell echo $(CFLAGS) | grep LTM_DESC),)
LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I libtommath)
endif
ifneq ($(shell echo $(CFLAGS) | grep TFM_DESC),)
LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I tomsfastmath)
endif
LTC_CFLAGS += -I./src/headers/ -DLTC_SOURCE -Wall -Wsign-compare -Wshadow LTC_CFLAGS += -I./src/headers/ -DLTC_SOURCE -Wall -Wsign-compare -Wshadow
ifdef OLD_GCC ifdef OLD_GCC
@ -118,9 +124,10 @@ LTC_CFLAGS += -Os -DLTC_SMALL_CODE
endif # LTC_SMALL endif # LTC_SMALL
ifneq ($(findstring clang,$(CC)),) ifeq ($(CC_IS_CLANG), 1)
LTC_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header LTC_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header
LTC_CFLAGS += -Wno-missing-field-initializers -Wno-missing-braces -Wno-incomplete-setjmp-declaration LTC_CFLAGS += -Wno-missing-field-initializers -Wno-missing-braces -Wno-incomplete-setjmp-declaration -Wno-cast-align
LTC_CFLAGS += -Wno-declaration-after-statement
endif endif
ifneq ($(findstring mingw,$(CC)),) ifneq ($(findstring mingw,$(CC)),)
LTC_CFLAGS += -Wno-shadow -Wno-attributes LTC_CFLAGS += -Wno-shadow -Wno-attributes
@ -183,7 +190,7 @@ DEMOS = $(UNBROKEN_DEMOS) $(BROKEN_DEMOS)
DESTDIR ?= DESTDIR ?=
PREFIX ?= /usr/local PREFIX ?= /usr/local
LIBPATH ?= $(PREFIX)/lib LIBPATH ?= $(PREFIX)/lib
INCPATH ?= $(PREFIX)/include INCPATH ?= $(PREFIX)/include/libtomcrypt
DATAPATH ?= $(PREFIX)/share/doc/libtomcrypt/pdf DATAPATH ?= $(PREFIX)/share/doc/libtomcrypt/pdf
BINPATH ?= $(PREFIX)/bin BINPATH ?= $(PREFIX)/bin
@ -206,7 +213,8 @@ library: $(call print-help,library,Builds the library) $(LIBNAME)
# List of objects to compile (all goes to libtomcrypt.a) # List of objects to compile (all goes to libtomcrypt.a)
OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_enc.o src/ciphers/anubis.o src/ciphers/blowfish.o \ OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_desc.o src/ciphers/aes/aes_enc.o \
src/ciphers/aes/aes_enc_desc.o src/ciphers/aes/aesni.o src/ciphers/anubis.o src/ciphers/blowfish.o \
src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \ src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \
src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \ src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \
src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \ src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \
@ -420,6 +428,7 @@ src/hashes/sha2/sha512_224.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha512_22
src/hashes/sha2/sha512_256.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha512_256.c src/hashes/sha2/sha512_256.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha512_256.c
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
$(DOBJECTS): LTC_CFLAGS := -Itests $(LTC_CFLAGS) $(DOBJECTS): LTC_CFLAGS := -Itests $(LTC_CFLAGS)
$(TOBJECTS): LTC_CFLAGS := -Itests $(LTC_CFLAGS) $(TOBJECTS): LTC_CFLAGS := -Itests $(LTC_CFLAGS)

View File

@ -1,6 +1,8 @@
set(SOURCES set(SOURCES
src/ciphers/aes/aes.c src/ciphers/aes/aes.c
src/ciphers/aes/aes_desc.c
src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_tab.c
src/ciphers/aes/aesni.c
src/ciphers/anubis.c src/ciphers/anubis.c
src/ciphers/blowfish.c src/ciphers/blowfish.c
src/ciphers/camellia.c src/ciphers/camellia.c

View File

@ -44,15 +44,6 @@ const struct ltc_cipher_descriptor rijndael_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
}; };
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else #else
#define SETUP rijndael_enc_setup #define SETUP rijndael_enc_setup
@ -69,15 +60,6 @@ const struct ltc_cipher_descriptor rijndael_enc_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
}; };
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif #endif
#define LTC_AES_TAB_C #define LTC_AES_TAB_C
@ -114,7 +96,7 @@ static ulong32 setup_mix2(ulong32 temp)
int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{ {
int i; int i;
ulong32 temp, *rk; ulong32 temp, *rk, *K;
#ifndef ENCRYPT_ONLY #ifndef ENCRYPT_ONLY
ulong32 *rrk; ulong32 *rrk;
#endif #endif
@ -130,6 +112,10 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s
} }
skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
K = LTC_ALIGN_BUF(skey->rijndael.K, 16);
skey->rijndael.eK = K;
K += 60;
skey->rijndael.dK = K;
/* setup the forward key */ /* setup the forward key */
i = 0; i = 0;

View File

@ -0,0 +1,244 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* Auto-detection of AES implementation by Steffen Jaeckel */
/**
@file aes_desc.c
Run-time detection of correct AES implementation
*/
#include "tomcrypt_private.h"
#if defined(LTC_RIJNDAEL)
#ifndef ENCRYPT_ONLY
#define AES_SETUP aes_setup
#define AES_ENC aes_ecb_encrypt
#define AES_DEC aes_ecb_decrypt
#define AES_DONE aes_done
#define AES_TEST aes_test
#define AES_KS aes_keysize
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
AES_SETUP, AES_ENC, AES_DEC, AES_TEST, AES_DONE, AES_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else
#define AES_SETUP aes_enc_setup
#define AES_ENC aes_enc_ecb_encrypt
#define AES_DONE aes_enc_done
#define AES_KS aes_enc_keysize
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
AES_SETUP, AES_ENC, NULL, NULL, AES_DONE, AES_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */
#if defined(LTC_HAS_AES_NI)
static LTC_INLINE int s_aesni_is_supported(void)
{
static int initialized = 0, is_supported = 0;
if (initialized == 0) {
int a, b, c, d;
/* Look for CPUID.1.0.ECX[25]
* EAX = 1, ECX = 0
*/
a = 1;
c = 0;
asm volatile ("cpuid"
:"=a"(a), "=b"(b), "=c"(c), "=d"(d)
:"a"(a), "c"(c)
);
is_supported = ((c >> 25) & 1);
initialized = 1;
}
return is_supported;
}
#ifndef ENCRYPT_ONLY
int aesni_is_supported(void)
{
return s_aesni_is_supported();
}
#endif
#endif
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
if (s_aesni_is_supported()) {
return aesni_setup(key, keylen, num_rounds, skey);
}
#endif
/* Last resort, software AES */
return rijndael_setup(key, keylen, num_rounds, skey);
}
/**
Encrypts a block of text with AES
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
if (s_aesni_is_supported()) {
return aesni_ecb_encrypt(pt, ct, skey);
}
#endif
return rijndael_ecb_encrypt(pt, ct, skey);
}
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int AES_DEC(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
if (s_aesni_is_supported()) {
return aesni_ecb_decrypt(ct, pt, skey);
}
#endif
return rijndael_ecb_decrypt(ct, pt, skey);
}
/**
Performs a self-test of the AES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int AES_TEST(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
}, {
24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
}, {
32,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = aes_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
aes_ecb_encrypt(tests[i].pt, tmp[0], &key);
aes_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) aes_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) aes_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void AES_DONE(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int AES_KS(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
}
if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
}
*keysize = 32;
return CRYPT_OK;
}
#endif

371
deps/libtomcrypt/src/ciphers/aes/aesni.c vendored Normal file
View File

@ -0,0 +1,371 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* AES-NI implementation by Steffen Jaeckel */
/**
@file aesni.c
Implementation of AES via the AES-NI instruction on x86_64
*/
#include "tomcrypt_private.h"
#if defined(LTC_HAS_AES_NI)
const struct ltc_cipher_descriptor aesni_desc =
{
"aes",
6,
16, 32, 16, 10,
aesni_setup, aesni_ecb_encrypt, aesni_ecb_decrypt, aesni_test, aesni_done, aesni_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#include <emmintrin.h>
#include <smmintrin.h>
#include <wmmintrin.h>
#define setup_mix(t, c) _mm_extract_epi32(_mm_aeskeygenassist_si128(t, 0), c)
#define temp_load(k) _mm_loadu_si128((__m128i*)(k))
#define temp_update(t, k) _mm_insert_epi32(t, k, 3)
#define temp_invert(k) _mm_aesimc_si128(*((__m128i*)(k)))
static const ulong32 rcon[] = {
0x01UL, 0x02UL, 0x04UL, 0x08UL, 0x10UL, 0x20UL, 0x40UL, 0x80UL, 0x1BUL, 0x36UL
};
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i;
__m128i temp;
ulong32 *rk, *K;
ulong32 *rrk;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 0 && num_rounds != (keylen / 4 + 6)) {
return CRYPT_INVALID_ROUNDS;
}
skey->rijndael.Nr = keylen / 4 + 6;
K = LTC_ALIGN_BUF(skey->rijndael.K, 16);
skey->rijndael.eK = K;
K += 60;
skey->rijndael.dK = K;
/* setup the forward key */
i = 0;
rk = skey->rijndael.eK;
LOAD32L(rk[0], key);
LOAD32L(rk[1], key + 4);
LOAD32L(rk[2], key + 8);
LOAD32L(rk[3], key + 12);
if (keylen == 16) {
temp = temp_load(key);
for (;;) {
rk[4] = rk[0] ^ setup_mix(temp, 3) ^ rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
break;
}
temp = temp_update(temp, rk[7]);
rk += 4;
}
} else if (keylen == 24) {
LOAD32L(rk[4], key + 16);
LOAD32L(rk[5], key + 20);
temp = temp_load(key + 8);
for (;;) {
rk[6] = rk[0] ^ setup_mix(temp, 3) ^ rcon[i];
rk[7] = rk[1] ^ rk[6];
rk[8] = rk[2] ^ rk[7];
rk[9] = rk[3] ^ rk[8];
if (++i == 8) {
break;
}
rk[10] = rk[4] ^ rk[9];
rk[11] = rk[5] ^ rk[10];
temp = temp_update(temp, rk[11]);
rk += 6;
}
} else if (keylen == 32) {
LOAD32L(rk[4], key + 16);
LOAD32L(rk[5], key + 20);
LOAD32L(rk[6], key + 24);
LOAD32L(rk[7], key + 28);
temp = temp_load(key + 16);
for (;;) {
rk[8] = rk[0] ^ setup_mix(temp, 3) ^ rcon[i];
rk[9] = rk[1] ^ rk[8];
rk[10] = rk[2] ^ rk[9];
rk[11] = rk[3] ^ rk[10];
if (++i == 7) {
break;
}
temp = temp_update(temp, rk[11]);
rk[12] = rk[4] ^ setup_mix(temp, 2);
rk[13] = rk[5] ^ rk[12];
rk[14] = rk[6] ^ rk[13];
rk[15] = rk[7] ^ rk[14];
temp = temp_update(temp, rk[15]);
rk += 8;
}
} else {
/* this can't happen */
/* coverity[dead_error_line] */
return CRYPT_ERROR;
}
/* setup the inverse key now */
rk = skey->rijndael.dK;
rrk = skey->rijndael.eK + skey->rijndael.Nr * 4;
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
/* copy first */
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
rk -= 3;
rrk -= 3;
for (i = 1; i < skey->rijndael.Nr; i++) {
rrk -= 4;
rk += 4;
temp = temp_invert(rk);
*((__m128i*) rk) = temp_invert(rrk);
}
/* copy last */
rrk -= 4;
rk += 4;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
return CRYPT_OK;
}
/**
Encrypts a block of text with AES
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int s_aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
#else
int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
#endif
{
int Nr, r;
const __m128i *skeys;
__m128i block;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
if (Nr < 2 || Nr > 16) return CRYPT_INVALID_ROUNDS;
skeys = (__m128i*) skey->rijndael.eK;
block = _mm_loadu_si128((const __m128i*) (pt));
block = _mm_xor_si128(block, skeys[0]);
for (r = 1; r < Nr - 1; r += 2) {
block = _mm_aesenc_si128(block, skeys[r]);
block = _mm_aesenc_si128(block, skeys[r + 1]);
}
block = _mm_aesenc_si128(block, skeys[Nr - 1]);
block = _mm_aesenclast_si128(block, skeys[Nr]);
_mm_storeu_si128((__m128i*) ct, block);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
{
int err = s_aesni_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int s_aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
#else
int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
#endif
{
int Nr, r;
const __m128i *skeys;
__m128i block;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
if (Nr < 2 || Nr > 16) return CRYPT_INVALID_ROUNDS;
skeys = (__m128i*) skey->rijndael.dK;
block = _mm_loadu_si128((const __m128i*) (ct));
block = _mm_xor_si128(block, skeys[0]);
for (r = 1; r < Nr - 1; r += 2) {
block = _mm_aesdec_si128(block, skeys[r]);
block = _mm_aesdec_si128(block, skeys[r + 1]);
}
block = _mm_aesdec_si128(block, skeys[Nr - 1]);
block = _mm_aesdeclast_si128(block, skeys[Nr]);
_mm_storeu_si128((__m128i*) pt, block);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
{
int err = s_aesni_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
/**
Performs a self-test of the AES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int aesni_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
}, {
24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
}, {
32,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = aesni_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
aesni_ecb_encrypt(tests[i].pt, tmp[0], &key);
aesni_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES-NI Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES-NI Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) aesni_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) aesni_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void aesni_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int aesni_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
}
if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
}
*keysize = 32;
return CRYPT_OK;
}
#endif

View File

@ -161,6 +161,9 @@ int ccm_memory(int cipher,
PAD[x++] = 0; PAD[x++] = 0;
} }
for (; y < L; y++) { for (; y < L; y++) {
if (x >= sizeof(PAD)) {
return CRYPT_INVALID_ARG;
}
PAD[x++] = (unsigned char)((len >> 24) & 255); PAD[x++] = (unsigned char)((len >> 24) & 255);
len <<= 8; len <<= 8;
} }

View File

@ -215,14 +215,14 @@ int ccm_test(void)
XMEMCPY(tag3, tests[x].tag, tests[x].taglen); XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
tag3[0] ^= 0xff; /* set the tag to the wrong value */ tag3[0] ^= 0xff; /* set the tag to the wrong value */
taglen = tests[x].taglen; taglen = tests[x].taglen;
if ((err = ccm_memory(idx, if (ccm_memory(idx,
tests[x].key, 16, tests[x].key, 16,
NULL, NULL,
tests[x].nonce, tests[x].noncelen, tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen, tests[x].header, tests[x].headerlen,
buf2, tests[x].ptlen, buf2, tests[x].ptlen,
buf, buf,
tag3, &taglen, 1 )) != CRYPT_ERROR) { tag3, &taglen, 1 ) != CRYPT_ERROR) {
return CRYPT_FAIL_TESTVECTOR; return CRYPT_FAIL_TESTVECTOR;
} }
if (compare_testvector(buf2, tests[x].ptlen, zero, tests[x].ptlen, "CCM decrypt wrong tag", x)) { if (compare_testvector(buf2, tests[x].ptlen, zero, tests[x].ptlen, "CCM decrypt wrong tag", x)) {

View File

@ -70,9 +70,7 @@ int gcm_memory( int cipher,
* but again it's only for SSE2 anyways, so who cares? * but again it's only for SSE2 anyways, so who cares?
*/ */
#ifdef LTC_GCM_TABLES_SSE2 #ifdef LTC_GCM_TABLES_SSE2
if ((unsigned long)gcm & 15) { gcm = LTC_ALIGN_BUF(gcm, 16);
gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
}
#endif #endif
if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) { if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {

View File

@ -79,18 +79,23 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
* The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST**
* use the portable [slower] macros. * use the portable [slower] macros.
*/ */
/* detect x86/i386 32bit */ /* detect x86/i386/ARM 32bit */
#if defined(__i386__) || defined(__i386) || defined(_M_IX86) #if defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_ARM)
#define ENDIAN_LITTLE #define ENDIAN_LITTLE
#define ENDIAN_32BITWORD #define ENDIAN_32BITWORD
#define LTC_FAST #define LTC_FAST
#endif #endif
/* detect amd64/x64 */ /* detect amd64/x64/arm64 */
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) #if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || defined(_M_ARM64)
#define ENDIAN_LITTLE #define ENDIAN_LITTLE
#define ENDIAN_64BITWORD #define ENDIAN_64BITWORD
#define LTC_FAST #define LTC_FAST
#if defined(__SSE4_1__)
#if __SSE4_1__ == 1
#define LTC_AMD64_SSE4_1
#endif
#endif
#endif #endif
/* detect PPC32 */ /* detect PPC32 */
@ -190,7 +195,8 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \ defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \
defined(__LITTLE_ENDIAN__) || \ defined(__LITTLE_ENDIAN__) || \
defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || \
defined(_M_ARM) || defined(_M_ARM64)
#define ENDIAN_LITTLE #define ENDIAN_LITTLE
#else #else
#error Cannot detect endianness #error Cannot detect endianness
@ -203,7 +209,7 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
typedef unsigned __int64 ulong64; typedef unsigned __int64 ulong64;
typedef __int64 long64; typedef __int64 long64;
#else #else
#define CONST64(n) n ## ULL #define CONST64(n) n ## uLL
typedef unsigned long long ulong64; typedef unsigned long long ulong64;
typedef long long long64; typedef long long long64;
#endif #endif
@ -214,7 +220,7 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \ defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \
defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \
defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \
defined(__LP64__) || defined(_LP64) || defined(__64BIT__) defined(__LP64__) || defined(_LP64) || defined(__64BIT__) || defined(_M_ARM64)
typedef unsigned ulong32; typedef unsigned ulong32;
#if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD) #if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD)
#define ENDIAN_64BITWORD #define ENDIAN_64BITWORD
@ -295,6 +301,21 @@ typedef unsigned long ltc_mp_digit;
#define LTC_ALIGN(n) #define LTC_ALIGN(n)
#endif #endif
/* Choose Windows Vista as minimum Version if we're compiling with at least VS2019
* This is done in order to test the bcrypt RNG and can still be overridden by the user. */
#if defined(_MSC_VER) && _MSC_VER >= 1920
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0600
# endif
# ifndef WINVER
# define WINVER 0x0600
# endif
#endif
#if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && !defined(LTC_WIN32_BCRYPT)
# define LTC_WIN32_BCRYPT
#endif
/* Define `LTC_NO_NULL_TERMINATION_CHECK` in the user code /* Define `LTC_NO_NULL_TERMINATION_CHECK` in the user code
* before including `tomcrypt.h` to disable this functionality. * before including `tomcrypt.h` to disable this functionality.
*/ */

View File

@ -35,7 +35,9 @@ struct saferp_key {
#ifdef LTC_RIJNDAEL #ifdef LTC_RIJNDAEL
struct rijndael_key { struct rijndael_key {
ulong32 eK[60], dK[60]; unsigned char K[(60 + 60 + 4) * sizeof(ulong32)];
ulong32 *eK;
ulong32 *dK;
int Nr; int Nr;
}; };
#endif #endif
@ -127,24 +129,24 @@ struct khazad_key {
#ifdef LTC_ANUBIS #ifdef LTC_ANUBIS
struct anubis_key { struct anubis_key {
int keyBits;
int R;
ulong32 roundKeyEnc[18 + 1][4]; ulong32 roundKeyEnc[18 + 1][4];
ulong32 roundKeyDec[18 + 1][4]; ulong32 roundKeyDec[18 + 1][4];
int keyBits;
int R;
}; };
#endif #endif
#ifdef LTC_MULTI2 #ifdef LTC_MULTI2
struct multi2_key { struct multi2_key {
int N;
ulong32 uk[8]; ulong32 uk[8];
int N;
}; };
#endif #endif
#ifdef LTC_CAMELLIA #ifdef LTC_CAMELLIA
struct camellia_key { struct camellia_key {
int R;
ulong64 kw[4], k[24], kl[6]; ulong64 kw[4], k[24], kl[6];
int R;
}; };
#endif #endif
@ -245,60 +247,60 @@ typedef union Symmetric_key {
#ifdef LTC_ECB_MODE #ifdef LTC_ECB_MODE
/** A block cipher ECB structure */ /** A block cipher ECB structure */
typedef struct { typedef struct {
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */ /** The index of the cipher chosen */
int cipher, int cipher,
/** The block size of the given cipher */ /** The block size of the given cipher */
blocklen; blocklen;
/** The scheduled key */
symmetric_key key;
} symmetric_ECB; } symmetric_ECB;
#endif #endif
#ifdef LTC_CFB_MODE #ifdef LTC_CFB_MODE
/** A block cipher CFB structure */ /** A block cipher CFB structure */
typedef struct { typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
/** The current IV */ /** The current IV */
unsigned char IV[MAXBLOCKSIZE], unsigned char IV[MAXBLOCKSIZE],
/** The pad used to encrypt/decrypt */ /** The pad used to encrypt/decrypt */
pad[MAXBLOCKSIZE]; pad[MAXBLOCKSIZE];
/** The scheduled key */ /** The scheduled key */
symmetric_key key; symmetric_key key;
} symmetric_CFB;
#endif
#ifdef LTC_OFB_MODE
/** A block cipher OFB structure */
typedef struct {
/** The index of the cipher chosen */ /** The index of the cipher chosen */
int cipher, int cipher,
/** The block size of the given cipher */ /** The block size of the given cipher */
blocklen, blocklen,
/** The padding offset */ /** The padding offset */
padlen; padlen;
} symmetric_CFB;
#endif
#ifdef LTC_OFB_MODE
/** A block cipher OFB structure */
typedef struct {
/** The current IV */ /** The current IV */
unsigned char IV[MAXBLOCKSIZE]; unsigned char IV[MAXBLOCKSIZE];
/** The scheduled key */ /** The scheduled key */
symmetric_key key; symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
} symmetric_OFB; } symmetric_OFB;
#endif #endif
#ifdef LTC_CBC_MODE #ifdef LTC_CBC_MODE
/** A block cipher CBC structure */ /** A block cipher CBC structure */
typedef struct { typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen;
/** The current IV */ /** The current IV */
unsigned char IV[MAXBLOCKSIZE]; unsigned char IV[MAXBLOCKSIZE];
/** The scheduled key */ /** The scheduled key */
symmetric_key key; symmetric_key key;
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen;
} symmetric_CBC; } symmetric_CBC;
#endif #endif
@ -306,6 +308,13 @@ typedef struct {
#ifdef LTC_CTR_MODE #ifdef LTC_CTR_MODE
/** A block cipher CTR structure */ /** A block cipher CTR structure */
typedef struct { typedef struct {
/** The counter */
unsigned char ctr[MAXBLOCKSIZE];
/** The pad used to encrypt/decrypt */
unsigned char pad[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */ /** The index of the cipher chosen */
int cipher, int cipher,
/** The block size of the given cipher */ /** The block size of the given cipher */
@ -316,13 +325,6 @@ typedef struct {
mode, mode,
/** counter width */ /** counter width */
ctrlen; ctrlen;
/** The counter */
unsigned char ctr[MAXBLOCKSIZE];
/** The pad used to encrypt/decrypt */
unsigned char pad[MAXBLOCKSIZE] LTC_ALIGN(16);
/** The scheduled key */
symmetric_key key;
} symmetric_CTR; } symmetric_CTR;
#endif #endif
@ -330,9 +332,6 @@ typedef struct {
#ifdef LTC_LRW_MODE #ifdef LTC_LRW_MODE
/** A LRW structure */ /** A LRW structure */
typedef struct { typedef struct {
/** The index of the cipher chosen (must be a 128-bit block cipher) */
int cipher;
/** The current IV */ /** The current IV */
unsigned char IV[16], unsigned char IV[16],
@ -349,25 +348,28 @@ typedef struct {
/** The pre-computed multiplication table */ /** The pre-computed multiplication table */
unsigned char PC[16][256][16]; unsigned char PC[16][256][16];
#endif #endif
/** The index of the cipher chosen (must be a 128-bit block cipher) */
int cipher;
} symmetric_LRW; } symmetric_LRW;
#endif #endif
#ifdef LTC_F8_MODE #ifdef LTC_F8_MODE
/** A block cipher F8 structure */ /** A block cipher F8 structure */
typedef struct { typedef struct {
/** The current IV */
unsigned char IV[MAXBLOCKSIZE],
MIV[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
/** The index of the cipher chosen */ /** The index of the cipher chosen */
int cipher, int cipher,
/** The block size of the given cipher */ /** The block size of the given cipher */
blocklen, blocklen,
/** The padding offset */ /** The padding offset */
padlen; padlen;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE],
MIV[MAXBLOCKSIZE];
/** Current block count */ /** Current block count */
ulong32 blockcnt; ulong32 blockcnt;
/** The scheduled key */
symmetric_key key;
} symmetric_F8; } symmetric_F8;
#endif #endif
@ -688,18 +690,19 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer
#endif #endif
#ifdef LTC_RIJNDAEL #ifdef LTC_RIJNDAEL
/* declare aes properly now */
/* make aes an alias */ int aes_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
#define aes_setup rijndael_setup int aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
#define aes_ecb_encrypt rijndael_ecb_encrypt int aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
#define aes_ecb_decrypt rijndael_ecb_decrypt int aes_test(void);
#define aes_test rijndael_test void aes_done(symmetric_key *skey);
#define aes_done rijndael_done int aes_keysize(int *keysize);
#define aes_keysize rijndael_keysize int aes_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aes_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
#define aes_enc_setup rijndael_enc_setup void aes_enc_done(symmetric_key *skey);
#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt int aes_enc_keysize(int *keysize);
#define aes_enc_keysize rijndael_enc_keysize extern const struct ltc_cipher_descriptor aes_desc;
extern const struct ltc_cipher_descriptor aes_enc_desc;
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey); int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
@ -711,8 +714,19 @@ int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, sym
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey); int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
void rijndael_enc_done(symmetric_key *skey); void rijndael_enc_done(symmetric_key *skey);
int rijndael_enc_keysize(int *keysize); int rijndael_enc_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; extern const struct ltc_cipher_descriptor rijndael_desc;
extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; extern const struct ltc_cipher_descriptor rijndael_enc_desc;
#endif
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
int aesni_is_supported(void);
int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
int aesni_test(void);
void aesni_done(symmetric_key *skey);
int aesni_keysize(int *keysize);
extern const struct ltc_cipher_descriptor aesni_desc;
#endif #endif
#ifdef LTC_XTEA #ifdef LTC_XTEA

View File

@ -179,6 +179,9 @@
#define LTC_RC6 #define LTC_RC6
#define LTC_SAFERP #define LTC_SAFERP
#define LTC_RIJNDAEL #define LTC_RIJNDAEL
#ifndef LTC_NO_AES_NI
#define LTC_AES_NI
#endif
#define LTC_XTEA #define LTC_XTEA
/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
* (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
@ -332,11 +335,14 @@
/* Greg's SOBER128 stream cipher based PRNG */ /* Greg's SOBER128 stream cipher based PRNG */
#define LTC_SOBER128 #define LTC_SOBER128
#if !defined(_WIN32) && !defined(_WIN32_WCE)
/* the *nix style /dev/random device */ /* the *nix style /dev/random device */
#define LTC_DEVRANDOM #define LTC_DEVRANDOM
/* try /dev/urandom before trying /dev/random /* try /dev/urandom before trying /dev/random
* are you sure you want to disable this? http://www.2uo.de/myths-about-urandom/ */ * are you sure you want to disable this? http://www.2uo.de/myths-about-urandom/ */
#define LTC_TRY_URANDOM_FIRST #define LTC_TRY_URANDOM_FIRST
#endif /* not Windows */
/* rng_get_bytes() */ /* rng_get_bytes() */
#define LTC_RNG_GET_BYTES #define LTC_RNG_GET_BYTES
/* rng_make_prng() */ /* rng_make_prng() */

View File

@ -358,10 +358,10 @@ typedef struct {
unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */ unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */ aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */ adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
int adata_buffer_bytes; /* bytes in AAD buffer */
unsigned long ablock_index; /* index # for current adata (AAD) block */
symmetric_key key; /* scheduled key for cipher */ symmetric_key key; /* scheduled key for cipher */
int adata_buffer_bytes; /* bytes in AAD buffer */
unsigned long ablock_index; /* index # for current adata (AAD) block */
unsigned long block_index; /* index # for current data block */ unsigned long block_index; /* index # for current data block */
int cipher, /* cipher idx */ int cipher, /* cipher idx */
tag_len, /* length of tag */ tag_len, /* length of tag */
@ -407,7 +407,12 @@ int ocb3_test(void);
#define CCM_DECRYPT LTC_DECRYPT #define CCM_DECRYPT LTC_DECRYPT
typedef struct { typedef struct {
unsigned char PAD[16], /* flags | Nonce N | l(m) */
ctr[16],
CTRPAD[16];
symmetric_key K; symmetric_key K;
int cipher, /* which cipher */ int cipher, /* which cipher */
taglen, /* length of the tag (encoded in M value) */ taglen, /* length of the tag (encoded in M value) */
x; /* index in PAD */ x; /* index in PAD */
@ -419,10 +424,7 @@ typedef struct {
current_aadlen, /* length of the currently provided add */ current_aadlen, /* length of the currently provided add */
noncelen; /* length of the nonce */ noncelen; /* length of the nonce */
unsigned char PAD[16], /* flags | Nonce N | l(m) */ unsigned char CTRlen;
ctr[16],
CTRPAD[16],
CTRlen;
} ccm_state; } ccm_state;
int ccm_init(ccm_state *ccm, int cipher, int ccm_init(ccm_state *ccm, int cipher,
@ -478,13 +480,18 @@ extern const unsigned char gcm_shift_table[];
#define LTC_GCM_MODE_TEXT 2 #define LTC_GCM_MODE_TEXT 2
typedef struct { typedef struct {
symmetric_key K;
unsigned char H[16], /* multiplier */ unsigned char H[16], /* multiplier */
X[16], /* accumulator */ X[16], /* accumulator */
Y[16], /* counter */ Y[16], /* counter */
Y_0[16], /* initial counter */ Y_0[16], /* initial counter */
buf[16]; /* buffer for stuff */ buf[16]; /* buffer for stuff */
#ifdef LTC_GCM_TABLES
unsigned char PC[16][256][16]; /* 16 tables of 8x128 */
#endif
symmetric_key K;
int cipher, /* which cipher */ int cipher, /* which cipher */
ivmode, /* Which mode is the IV in? */ ivmode, /* Which mode is the IV in? */
mode, /* mode the GCM code is in */ mode, /* mode the GCM code is in */
@ -492,14 +499,6 @@ typedef struct {
ulong64 totlen, /* 64-bit counter used for IV and AAD */ ulong64 totlen, /* 64-bit counter used for IV and AAD */
pttotlen; /* 64-bit counter for the PT */ pttotlen; /* 64-bit counter for the PT */
#ifdef LTC_GCM_TABLES
unsigned char PC[16][256][16] /* 16 tables of 8x128 */
#ifdef LTC_GCM_TABLES_SSE2
LTC_ALIGN(16)
#endif
;
#endif
} gcm_state; } gcm_state;
void gcm_mult_h(const gcm_state *gcm, unsigned char *I); void gcm_mult_h(const gcm_state *gcm, unsigned char *I);

View File

@ -1,6 +1,11 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */ /* SPDX-License-Identifier: Unlicense */
#define LTC_TMPVAR__(n, l) n ## l
#define LTC_TMPVAR_(n, l) LTC_TMPVAR__(n, l)
#define LTC_TMPVAR(n) LTC_TMPVAR_(LTC_ ## n ## _, __LINE__)
/* ---- HELPER MACROS ---- */ /* ---- HELPER MACROS ---- */
#ifdef ENDIAN_NEUTRAL #ifdef ENDIAN_NEUTRAL
@ -275,20 +280,20 @@ static inline ulong32 ROR(ulong32 word, int i)
#ifndef LTC_NO_ROLC #ifndef LTC_NO_ROLC
#define ROLc(word,i) ({ \ #define ROLc(word,i) ({ \
ulong32 ROLc_tmp = (word); \ ulong32 LTC_TMPVAR(ROLc) = (word); \
__asm__ ("roll %2, %0" : \ __asm__ ("roll %2, %0" : \
"=r" (ROLc_tmp) : \ "=r" (LTC_TMPVAR(ROLc)) : \
"0" (ROLc_tmp), \ "0" (LTC_TMPVAR(ROLc)), \
"I" (i)); \ "I" (i)); \
ROLc_tmp; \ LTC_TMPVAR(ROLc); \
}) })
#define RORc(word,i) ({ \ #define RORc(word,i) ({ \
ulong32 RORc_tmp = (word); \ ulong32 LTC_TMPVAR(RORc) = (word); \
__asm__ ("rorl %2, %0" : \ __asm__ ("rorl %2, %0" : \
"=r" (RORc_tmp) : \ "=r" (LTC_TMPVAR(RORc)) : \
"0" (RORc_tmp), \ "0" (LTC_TMPVAR(RORc)), \
"I" (i)); \ "I" (i)); \
RORc_tmp; \ LTC_TMPVAR(RORc); \
}) })
#else #else
@ -393,20 +398,20 @@ static inline ulong64 ROR64(ulong64 word, int i)
#ifndef LTC_NO_ROLC #ifndef LTC_NO_ROLC
#define ROL64c(word,i) ({ \ #define ROL64c(word,i) ({ \
ulong64 ROL64c_tmp = word; \ ulong64 LTC_TMPVAR(ROL64c) = word; \
__asm__ ("rolq %2, %0" : \ __asm__ ("rolq %2, %0" : \
"=r" (ROL64c_tmp) : \ "=r" (LTC_TMPVAR(ROL64c)) : \
"0" (ROL64c_tmp), \ "0" (LTC_TMPVAR(ROL64c)), \
"J" (i)); \ "J" (i)); \
ROL64c_tmp; \ LTC_TMPVAR(ROL64c); \
}) })
#define ROR64c(word,i) ({ \ #define ROR64c(word,i) ({ \
ulong64 ROR64c_tmp = word; \ ulong64 LTC_TMPVAR(ROR64c) = word; \
__asm__ ("rorq %2, %0" : \ __asm__ ("rorq %2, %0" : \
"=r" (ROR64c_tmp) : \ "=r" (LTC_TMPVAR(ROR64c)) : \
"0" (ROR64c_tmp), \ "0" (LTC_TMPVAR(ROR64c)), \
"J" (i)); \ "J" (i)); \
ROR64c_tmp; \ LTC_TMPVAR(ROR64c); \
}) })
#else /* LTC_NO_ROLC */ #else /* LTC_NO_ROLC */

View File

@ -57,10 +57,10 @@ void rsa_free(rsa_key *key);
/* These use PKCS #1 v2.0 padding */ /* These use PKCS #1 v2.0 padding */
#define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \ #define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \
rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, LTC_PKCS_1_OAEP, key) rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, -1, LTC_PKCS_1_OAEP, key)
#define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \ #define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \
rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, LTC_PKCS_1_OAEP, stat, key) rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, -1, LTC_PKCS_1_OAEP, stat, key)
#define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \ #define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \
rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key) rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key)
@ -76,13 +76,15 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, prng_state *prng, int prng_idx,
int hash_idx, int padding, int mgf_hash, int lparam_hash,
int padding,
const rsa_key *key); const rsa_key *key);
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int padding, int mgf_hash, int lparam_hash,
int padding,
int *stat, const rsa_key *key); int *stat, const rsa_key *key);
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
@ -548,43 +550,43 @@ typedef struct ltc_asn1_list_ {
struct ltc_asn1_list_ *prev, *next, *child, *parent; struct ltc_asn1_list_ *prev, *next, *child, *parent;
} ltc_asn1_list; } ltc_asn1_list;
#define LTC_SET_ASN1(list, index, Type, Data, Size) \ #define LTC_SET_ASN1(list, index, Type, Data, Size) \
do { \ do { \
int LTC_MACRO_temp = (index); \ int LTC_TMPVAR(SA) = (index); \
ltc_asn1_list *LTC_MACRO_list = (list); \ ltc_asn1_list *LTC_TMPVAR(SA_list) = (list); \
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].type = (Type); \
LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].data = (void*)(Data); \
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].size = (Size); \
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].used = 0; \
LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].optional = 0; \
LTC_MACRO_list[LTC_MACRO_temp].klass = 0; \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].klass = 0; \
LTC_MACRO_list[LTC_MACRO_temp].pc = 0; \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].pc = 0; \
LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].tag = 0; \
} while (0) } while (0)
#define LTC_SET_ASN1_IDENTIFIER(list, index, Class, Pc, Tag) \ #define LTC_SET_ASN1_IDENTIFIER(list, index, Class, Pc, Tag) \
do { \ do { \
int LTC_MACRO_temp = (index); \ int LTC_TMPVAR(SAI) = (index); \
ltc_asn1_list *LTC_MACRO_list = (list); \ ltc_asn1_list *LTC_TMPVAR(SAI_list) = (list); \
LTC_MACRO_list[LTC_MACRO_temp].type = LTC_ASN1_CUSTOM_TYPE; \ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].type = LTC_ASN1_CUSTOM_TYPE; \
LTC_MACRO_list[LTC_MACRO_temp].klass = (Class); \ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].klass = (Class); \
LTC_MACRO_list[LTC_MACRO_temp].pc = (Pc); \ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].pc = (Pc); \
LTC_MACRO_list[LTC_MACRO_temp].tag = (Tag); \ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].tag = (Tag); \
} while (0) } while (0)
#define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \ #define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \
do { \ do { \
int LTC_MACRO_temp##__LINE__ = (index); \ int LTC_TMPVAR(SACC) = (index); \
LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, 1); \ LTC_SET_ASN1(list, LTC_TMPVAR(SACC), LTC_ASN1_CUSTOM_TYPE, Data, 1); \
LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_CONSTRUCTED, Tag); \ LTC_SET_ASN1_IDENTIFIER(list, LTC_TMPVAR(SACC), Class, LTC_ASN1_PC_CONSTRUCTED, Tag); \
} while (0) } while (0)
#define LTC_SET_ASN1_CUSTOM_PRIMITIVE(list, index, Class, Tag, Type, Data, Size) \ #define LTC_SET_ASN1_CUSTOM_PRIMITIVE(list, index, Class, Tag, Type, Data, Size) \
do { \ do { \
int LTC_MACRO_temp##__LINE__ = (index); \ int LTC_TMPVAR(SACP) = (index); \
LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, Size); \ LTC_SET_ASN1(list, LTC_TMPVAR(SACP), LTC_ASN1_CUSTOM_TYPE, Data, Size); \
LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_PRIMITIVE, Tag); \ LTC_SET_ASN1_IDENTIFIER(list, LTC_TMPVAR(SACP), Class, LTC_ASN1_PC_PRIMITIVE, Tag); \
list[LTC_MACRO_temp##__LINE__].used = (int)(Type); \ list[LTC_TMPVAR(SACP)].used = (int)(Type); \
} while (0) } while (0)
extern const char* der_asn1_class_to_string_map[]; extern const char* der_asn1_class_to_string_map[];

View File

@ -49,12 +49,14 @@ int pkcs_1_v1_5_decode(const unsigned char *msg,
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, prng_state *prng, unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, int hash_idx, int prng_idx,
int mgf_hash, int lparam_hash,
unsigned char *out, unsigned long *outlen); unsigned char *out, unsigned long *outlen);
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx, unsigned long modulus_bitlen,
int mgf_hash, int lparam_hash,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
int *res); int *res);

View File

@ -6,9 +6,30 @@
/* /*
* Internal Macros * Internal Macros
*/ */
/* Static assertion */
#define LTC_STATIC_ASSERT(msg, cond) typedef char ltc_static_assert_##msg[(cond) ? 1 : -1];
#define LTC_PAD_MASK (0xF000U) #define LTC_PAD_MASK (0xF000U)
#if defined(ENDIAN_64BITWORD)
#define CONSTPTR(n) CONST64(n)
#else
#define CONSTPTR(n) n ## uL
#endif
LTC_STATIC_ASSERT(correct_CONSTPTR_size, sizeof(CONSTPTR(1)) == sizeof(void*))
/* Poor-man's `uintptr_t` since we can't use stdint.h
* c.f. https://github.com/DCIT/perl-CryptX/issues/95#issuecomment-1745280962 */
typedef size_t ltc_uintptr;
LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*))
/* Aligns a `unsigned char` buffer `buf` to `n` bytes and returns that aligned address.
* Make sure that the buffer that is passed is huge enough.
*/
#define LTC_ALIGN_BUF(buf, n) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[n - 1] & (~(CONSTPTR(n) - CONSTPTR(1)))))
/* `NULL` as defined by the standard is not guaranteed to be of a pointer /* `NULL` as defined by the standard is not guaranteed to be of a pointer
* type. In order to make sure that in vararg API's a pointer type is used, * type. In order to make sure that in vararg API's a pointer type is used,
* define our own version and use that one internally. * define our own version and use that one internally.
@ -77,6 +98,10 @@ typedef struct
/* tomcrypt_cipher.h */ /* tomcrypt_cipher.h */
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
#define LTC_HAS_AES_NI
#endif
void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey); void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
int blowfish_expand(const unsigned char *key, int keylen, int blowfish_expand(const unsigned char *key, int keylen,
const unsigned char *data, int datalen, const unsigned char *data, int datalen,

View File

@ -1429,8 +1429,10 @@ int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen)
* and the mu INTEGER * and the mu INTEGER
*/ */
cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list)); cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list));
if (cache_entry == NULL) if (cache_entry == NULL) {
LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
return CRYPT_MEM; return CRYPT_MEM;
}
j = 1; /* handle the zero'th element later */ j = 1; /* handle the zero'th element later */
LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1); LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);

View File

@ -324,6 +324,9 @@ const char *crypt_build_settings =
#if defined(LTC_SOBER128) #if defined(LTC_SOBER128)
" SOBER128\n" " SOBER128\n"
#endif #endif
#if defined(LTC_WIN32_BCRYPT)
" WIN32_BCRYPT\n"
#endif
"\nPK Crypto:\n" "\nPK Crypto:\n"
#if defined(LTC_MRSA) #if defined(LTC_MRSA)
@ -416,6 +419,9 @@ const char *crypt_build_settings =
#if defined(LTC_ADLER32) #if defined(LTC_ADLER32)
" ADLER32 " " ADLER32 "
#endif #endif
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
" AES-NI "
#endif
#if defined(LTC_BASE64) #if defined(LTC_BASE64)
" BASE64 " " BASE64 "
#endif #endif

View File

@ -16,6 +16,7 @@
int register_all_ciphers(void) int register_all_ciphers(void)
{ {
#ifdef LTC_RIJNDAEL #ifdef LTC_RIJNDAEL
/* `aesni_desc` is explicitely not registered, since it's handled from within the `aes_desc` */
#ifdef ENCRYPT_ONLY #ifdef ENCRYPT_ONLY
/* alternative would be /* alternative would be
* register_cipher(&rijndael_enc_desc); * register_cipher(&rijndael_enc_desc);

View File

@ -169,6 +169,7 @@ int pkcs_5_test (void)
(unsigned char*)cases_5_2[i].S, cases_5_2[i].S_len, (unsigned char*)cases_5_2[i].S, cases_5_2[i].S_len,
cases_5_2[i].c, hash, cases_5_2[i].c, hash,
DK, &dkLen)) != CRYPT_OK) { DK, &dkLen)) != CRYPT_OK) {
LTC_UNUSED_PARAM(err);
#ifdef LTC_TEST_DBG #ifdef LTC_TEST_DBG
printf("\npkcs_5_alg2() #%d: Failed/1 (%s)\n", i, error_to_string(err)); printf("\npkcs_5_alg2() #%d: Failed/1 (%s)\n", i, error_to_string(err));
#endif #endif
@ -186,6 +187,7 @@ int pkcs_5_test (void)
(unsigned char*)cases_5_1[i].S, (unsigned char*)cases_5_1[i].S,
cases_5_1[i].c, hash, cases_5_1[i].c, hash,
DK, &dkLen)) != CRYPT_OK) { DK, &dkLen)) != CRYPT_OK) {
LTC_UNUSED_PARAM(err);
#ifdef LTC_TEST_DBG #ifdef LTC_TEST_DBG
printf("\npkcs_5_alg1() #%d: Failed/1 (%s)\n", i, error_to_string(err)); printf("\npkcs_5_alg1() #%d: Failed/1 (%s)\n", i, error_to_string(err));
#endif #endif
@ -203,6 +205,7 @@ int pkcs_5_test (void)
(unsigned char*)cases_5_1o[i].S, (unsigned char*)cases_5_1o[i].S,
cases_5_1o[i].c, hash, cases_5_1o[i].c, hash,
DK, &dkLen)) != CRYPT_OK) { DK, &dkLen)) != CRYPT_OK) {
LTC_UNUSED_PARAM(err);
#ifdef LTC_TEST_DBG #ifdef LTC_TEST_DBG
printf("\npkcs_5_alg1_openssl() #%d: Failed/1 (%s)\n", i, error_to_string(err)); printf("\npkcs_5_alg1_openssl() #%d: Failed/1 (%s)\n", i, error_to_string(err));
#endif #endif

View File

@ -134,7 +134,7 @@ int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
STORE32H(size, out); STORE32H(size, out);
out += 4; out += 4;
} }
if ((err = mp_to_unsigned_bin(vdata, out)) != CRYPT_OK) { if (mp_to_unsigned_bin(vdata, out) != CRYPT_OK) {
err = CRYPT_ERROR; err = CRYPT_ERROR;
goto error; goto error;
} }

View File

@ -65,7 +65,7 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_SHORT_INTEGER:
if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
if (der_length_short_integer(size, &z) == CRYPT_OK) { if (der_length_short_integer(*(unsigned long*)data, &z) == CRYPT_OK) {
list[x].used = 1; list[x].used = 1;
*inlen = z; *inlen = z;
return CRYPT_OK; return CRYPT_OK;

View File

@ -36,7 +36,7 @@ int der_encode_custom_type(const ltc_asn1_list *root,
/* get size of output that will be required */ /* get size of output that will be required */
y = 0; z = 0; y = 0; z = 0;
if ((err = der_length_custom_type(root, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG; if (der_length_custom_type(root, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
/* too big ? */ /* too big ? */
if (*outlen < y) { if (*outlen < y) {
@ -46,7 +46,7 @@ int der_encode_custom_type(const ltc_asn1_list *root,
} }
/* get length of the identifier, so we know the offset where to start writing */ /* get length of the identifier, so we know the offset where to start writing */
if ((err = der_length_asn1_identifier(root, &id_len)) != CRYPT_OK) return CRYPT_INVALID_ARG; if (der_length_asn1_identifier(root, &id_len) != CRYPT_OK) return CRYPT_INVALID_ARG;
x = id_len; x = id_len;

View File

@ -33,7 +33,7 @@ int der_encode_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
/* get size of output that will be required */ /* get size of output that will be required */
y = 0; z = 0; y = 0; z = 0;
if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG; if (der_length_sequence_ex(list, inlen, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
/* too big ? */ /* too big ? */
if (*outlen < y) { if (*outlen < y) {

View File

@ -56,7 +56,8 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
https://tools.ietf.org/html/rfc3629#section-3 https://tools.ietf.org/html/rfc3629#section-3
*/ */
for (y = 0; x < inlen; ) { len += x;
for (y = 0; x < len; ) {
/* read first byte */ /* read first byte */
tmp = in[x++]; tmp = in[x++];
@ -87,7 +88,7 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
/* now update z so it equals the number of additional bytes to read */ /* now update z so it equals the number of additional bytes to read */
if (z > 0) { --z; } if (z > 0) { --z; }
if (x + z > inlen) { if (x + z > len) {
return CRYPT_INVALID_PACKET; return CRYPT_INVALID_PACKET;
} }

View File

@ -72,14 +72,14 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
} }
} }
/* get key type */ /* get key type */
if ((err = der_decode_sequence_multi(in, inlen, if (der_decode_sequence_multi(in, inlen,
LTC_ASN1_SHORT_INTEGER, 1UL, &zero, LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->p,
LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->q,
LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->g,
LTC_ASN1_INTEGER, 1UL, key->y, LTC_ASN1_INTEGER, 1UL, key->y,
LTC_ASN1_INTEGER, 1UL, key->x, LTC_ASN1_INTEGER, 1UL, key->x,
LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { LTC_ASN1_EOL, 0UL, NULL) == CRYPT_OK) {
key->type = PK_PRIVATE; key->type = PK_PRIVATE;
} else { /* public */ } else { /* public */

View File

@ -33,8 +33,11 @@ int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, const ecc_k
} }
else if (type == PK_PRIVATE) { else if (type == PK_PRIVATE) {
if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH;
if (size > *outlen) {
*outlen = size;
return CRYPT_BUFFER_OVERFLOW;
}
*outlen = size; *outlen = size;
if (size > *outlen) return CRYPT_BUFFER_OVERFLOW;
if ((ksize = mp_unsigned_bin_size(key->k)) > size) return CRYPT_BUFFER_OVERFLOW; if ((ksize = mp_unsigned_bin_size(key->k)) > size) return CRYPT_BUFFER_OVERFLOW;
/* pad and store k */ /* pad and store k */
if ((err = mp_to_unsigned_bin(key->k, out + (size - ksize))) != CRYPT_OK) return err; if ((err = mp_to_unsigned_bin(key->k, out + (size - ksize))) != CRYPT_OK) return err;

View File

@ -64,7 +64,7 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
if (err != CRYPT_OK) return err; if (err != CRYPT_OK) return err;
if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) { if (pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l) == CRYPT_OK) {
/* Setup for basic structure */ /* Setup for basic structure */
n=0; n=0;
@ -73,7 +73,7 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, &priv_key); LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, &priv_key);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);
if (((err = s_der_flexi_sequence_cmp(l, flexi_should)) == CRYPT_OK) && if ((s_der_flexi_sequence_cmp(l, flexi_should) == CRYPT_OK) &&
(pk_oid_cmp_with_asn1(pka_ec_oid, seq->child) == CRYPT_OK)) { (pk_oid_cmp_with_asn1(pka_ec_oid, seq->child) == CRYPT_OK)) {
ltc_asn1_list *version, *field, *point, *point_g, *order, *p_cofactor; ltc_asn1_list *version, *field, *point, *point_g, *order, *p_cofactor;
@ -154,7 +154,7 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
/* load private key value 'k' */ /* load private key value 'k' */
len = priv_key->size; len = priv_key->size;
if ((err = der_decode_sequence_flexi(priv_key->data, &len, &p)) == CRYPT_OK) { if (der_decode_sequence_flexi(priv_key->data, &len, &p) == CRYPT_OK) {
if (p->type == LTC_ASN1_SEQUENCE && if (p->type == LTC_ASN1_SEQUENCE &&
LTC_ASN1_IS_TYPE(p->child, LTC_ASN1_INTEGER) && LTC_ASN1_IS_TYPE(p->child, LTC_ASN1_INTEGER) &&
LTC_ASN1_IS_TYPE(p->child->next, LTC_ASN1_OCTET_STRING)) { LTC_ASN1_IS_TYPE(p->child->next, LTC_ASN1_OCTET_STRING)) {

View File

@ -16,7 +16,8 @@
@param lparam The session or system data (can be NULL) @param lparam The session or system data (can be NULL)
@param lparamlen The length of the lparam @param lparamlen The length of the lparam
@param modulus_bitlen The bit length of the RSA modulus @param modulus_bitlen The bit length of the RSA modulus
@param hash_idx The index of the hash desired @param mgf_hash The hash algorithm used for the MGF
@param lparam_hash The hash algorithm used when hashing the lparam (can be -1)
@param out [out] Destination of decoding @param out [out] Destination of decoding
@param outlen [in/out] The max size and resulting size of the decoding @param outlen [in/out] The max size and resulting size of the decoding
@param res [out] Result of decoding, 1==valid, 0==invalid @param res [out] Result of decoding, 1==valid, 0==invalid
@ -24,13 +25,14 @@
*/ */
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx, unsigned long modulus_bitlen,
int mgf_hash, int lparam_hash,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
int *res) int *res)
{ {
unsigned char *DB, *seed, *mask; unsigned char *DB, *seed, *mask;
unsigned long hLen, x, y, modulus_len; unsigned long hLen, x, y, modulus_len;
int err, ret; int err, ret, lparam_hash_used;
LTC_ARGCHK(msg != NULL); LTC_ARGCHK(msg != NULL);
LTC_ARGCHK(out != NULL); LTC_ARGCHK(out != NULL);
@ -41,10 +43,18 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
*res = 0; *res = 0;
/* test valid hash */ /* test valid hash */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
return err; return err;
} }
hLen = hash_descriptor[hash_idx].hashsize; if (lparam_hash != -1) {
if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) {
return err;
}
lparam_hash_used = lparam_hash;
} else {
lparam_hash_used = mgf_hash;
}
hLen = hash_descriptor[lparam_hash_used].hashsize;
modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
/* test hash/message size */ /* test hash/message size */
@ -94,7 +104,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
x += modulus_len - hLen - 1; x += modulus_len - hLen - 1;
/* compute MGF1 of maskedDB (hLen) */ /* compute MGF1 of maskedDB (hLen) */
if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
@ -104,7 +114,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
} }
/* compute MGF1 of seed (k - hlen - 1) */ /* compute MGF1 of seed (k - hlen - 1) */
if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
@ -118,12 +128,12 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
/* compute lhash and store it in seed [reuse temps!] */ /* compute lhash and store it in seed [reuse temps!] */
x = modulus_len; x = modulus_len;
if (lparam != NULL) { if (lparam != NULL) {
if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, seed, &x)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
} else { } else {
/* can't pass hash_memory a NULL so use DB with zero length */ /* can't pass hash_memory a NULL so use DB with zero length */
if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { if ((err = hash_memory(lparam_hash_used, DB, 0, seed, &x)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
} }

View File

@ -26,28 +26,37 @@
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, prng_state *prng, unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, int hash_idx, int prng_idx,
int mgf_hash, int lparam_hash,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned char *DB, *seed, *mask; unsigned char *DB, *seed, *mask;
unsigned long hLen, x, y, modulus_len; unsigned long hLen, x, y, modulus_len;
int err; int err, lparam_hash_used;
LTC_ARGCHK((msglen == 0) || (msg != NULL)); LTC_ARGCHK((msglen == 0) || (msg != NULL));
LTC_ARGCHK(out != NULL); LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(outlen != NULL);
/* test valid hash */ /* test valid hash */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
return err; return err;
} }
if (lparam_hash != -1) {
if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) {
return err;
}
lparam_hash_used = lparam_hash;
} else {
lparam_hash_used = mgf_hash;
}
/* valid prng */ /* valid prng */
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
return err; return err;
} }
hLen = hash_descriptor[hash_idx].hashsize; hLen = hash_descriptor[lparam_hash_used].hashsize;
modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
/* test message size */ /* test message size */
@ -76,12 +85,12 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
/* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
x = modulus_len; x = modulus_len;
if (lparam != NULL) { if (lparam != NULL) {
if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) { if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, DB, &x)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
} else { } else {
/* can't pass hash_memory a NULL so use DB with zero length */ /* can't pass hash_memory a NULL so use DB with zero length */
if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) { if ((err = hash_memory(lparam_hash_used, DB, 0, DB, &x)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
} }
@ -108,7 +117,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
} }
/* compute MGF1 of seed (k - hlen - 1) */ /* compute MGF1 of seed (k - hlen - 1) */
if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }
@ -118,7 +127,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
} }
/* compute MGF1 of maskedDB (hLen) */ /* compute MGF1 of maskedDB (hLen) */
if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
goto LBL_ERR; goto LBL_ERR;
} }

View File

@ -17,7 +17,8 @@
@param outlen [in/out] The max size and resulting size of the plaintext (octets) @param outlen [in/out] The max size and resulting size of the plaintext (octets)
@param lparam The system "lparam" value @param lparam The system "lparam" value
@param lparamlen The length of the lparam value (octets) @param lparamlen The length of the lparam value (octets)
@param hash_idx The index of the hash desired @param mgf_hash The hash algorithm used for the MGF
@param lparam_hash The hash algorithm used when hashing the lparam (can be -1)
@param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
@param stat [out] Result of the decryption, 1==valid, 0==invalid @param stat [out] Result of the decryption, 1==valid, 0==invalid
@param key The corresponding private RSA key @param key The corresponding private RSA key
@ -26,7 +27,8 @@
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int padding, int mgf_hash, int lparam_hash,
int padding,
int *stat, const rsa_key *key) int *stat, const rsa_key *key)
{ {
unsigned long modulus_bitlen, modulus_bytelen, x; unsigned long modulus_bitlen, modulus_bytelen, x;
@ -43,7 +45,6 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen
*stat = 0; *stat = 0;
/* valid padding? */ /* valid padding? */
if ((padding != LTC_PKCS_1_V1_5) && if ((padding != LTC_PKCS_1_V1_5) &&
(padding != LTC_PKCS_1_OAEP)) { (padding != LTC_PKCS_1_OAEP)) {
return CRYPT_PK_INVALID_PADDING; return CRYPT_PK_INVALID_PADDING;
@ -51,7 +52,7 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen
if (padding == LTC_PKCS_1_OAEP) { if (padding == LTC_PKCS_1_OAEP) {
/* valid hash ? */ /* valid hash ? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
return err; return err;
} }
} }
@ -80,8 +81,8 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen
if (padding == LTC_PKCS_1_OAEP) { if (padding == LTC_PKCS_1_OAEP) {
/* now OAEP decode the packet */ /* now OAEP decode the packet */
err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, mgf_hash,
out, outlen, stat); lparam_hash, out, outlen, stat);
} else { } else {
/* now PKCS #1 v1.5 depad the packet */ /* now PKCS #1 v1.5 depad the packet */
err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);

View File

@ -28,7 +28,8 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, prng_state *prng, int prng_idx,
int hash_idx, int padding, int mgf_hash, int lparam_hash,
int padding,
const rsa_key *key) const rsa_key *key)
{ {
unsigned long modulus_bitlen, modulus_bytelen, x; unsigned long modulus_bitlen, modulus_bytelen, x;
@ -52,7 +53,7 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
if (padding == LTC_PKCS_1_OAEP) { if (padding == LTC_PKCS_1_OAEP) {
/* valid hash? */ /* valid hash? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
return err; return err;
} }
} }
@ -71,8 +72,8 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
/* OAEP pad the key */ /* OAEP pad the key */
x = *outlen; x = *outlen;
if ((err = pkcs_1_oaep_encode(in, inlen, lparam, if ((err = pkcs_1_oaep_encode(in, inlen, lparam,
lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, lparamlen, modulus_bitlen, prng, prng_idx, mgf_hash,
out, &x)) != CRYPT_OK) { lparam_hash, out, &x)) != CRYPT_OK) {
return err; return err;
} }
} else { } else {

View File

@ -136,7 +136,7 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle
LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { if (der_decode_sequence_strict(out, outlen, siginfo, 2) != CRYPT_OK) {
/* fallback to Legacy:missing NULL */ /* fallback to Legacy:missing NULL */
LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1);
if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) {

View File

@ -82,12 +82,27 @@ static unsigned long s_rng_ansic(unsigned char *buf, unsigned long len,
/* Try the Microsoft CSP */ /* Try the Microsoft CSP */
#if defined(_WIN32) || defined(_WIN32_WCE) #if defined(_WIN32) || defined(_WIN32_WCE)
#if defined(LTC_WIN32_BCRYPT)
#include <windows.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
static unsigned long s_rng_win32(unsigned char *buf, unsigned long len,
void (*callback)(void))
{
LTC_UNUSED_PARAM(callback);
return BCRYPT_SUCCESS(BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) ? len : 0;
}
#else
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400 #define _WIN32_WINNT 0x0501
#endif #endif
#ifdef _WIN32_WCE #ifndef WINVER
#define UNDER_CE #define WINVER 0x0501
#define ARM
#endif #endif
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -97,23 +112,23 @@ static unsigned long s_rng_ansic(unsigned char *buf, unsigned long len,
static unsigned long s_rng_win32(unsigned char *buf, unsigned long len, static unsigned long s_rng_win32(unsigned char *buf, unsigned long len,
void (*callback)(void)) void (*callback)(void))
{ {
HCRYPTPROV hProv = 0;
LTC_UNUSED_PARAM(callback); LTC_UNUSED_PARAM(callback);
if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
(CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
!CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
return 0;
if (CryptGenRandom(hProv, len, buf) == TRUE) { static HCRYPTPROV hProv = 0;
CryptReleaseContext(hProv, 0); if (hProv == 0) {
return len; HCRYPTPROV h = 0;
} else { if (!CryptAcquireContextW(&h, NULL, MS_DEF_PROV_W, PROV_RSA_FULL,
CryptReleaseContext(hProv, 0); (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
return 0; !CryptAcquireContextW(&h, NULL, MS_DEF_PROV_W, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) {
return 0;
}
hProv = h;
} }
}
return CryptGenRandom(hProv, (DWORD)len, (BYTE *)buf) == TRUE ? len : 0;
}
#endif /* Old WIN32 versions */
#endif /* WIN32 */ #endif /* WIN32 */
/** /**

View File

@ -13,6 +13,14 @@ int cipher_hash_test(void)
DOX(cipher_descriptor[x].test(), cipher_descriptor[x].name); DOX(cipher_descriptor[x].test(), cipher_descriptor[x].name);
} }
/* explicit AES-NI test */
#if defined(LTC_HAS_AES_NI)
if (aesni_is_supported()) {
DO(aesni_test());
}
DO(rijndael_test());
#endif
/* test stream ciphers */ /* test stream ciphers */
#ifdef LTC_CHACHA #ifdef LTC_CHACHA
DO(chacha_test()); DO(chacha_test());

View File

@ -11,6 +11,8 @@ int der_test(void)
#else #else
#include <wchar.h>
#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 2 #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 2
#define LTC_DER_TESTS_PRINT_FLEXI #define LTC_DER_TESTS_PRINT_FLEXI
#endif #endif
@ -252,7 +254,7 @@ static void s_free(void *p)
XFREE(p); XFREE(p);
} }
static void s_der_tests_print_flexi(ltc_asn1_list* l, unsigned int level) static void s_der_tests_print_flexi_i(ltc_asn1_list* l, unsigned int level)
{ {
char *buf = NULL; char *buf = NULL;
const char* name = NULL; const char* name = NULL;
@ -435,15 +437,28 @@ static void s_der_tests_print_flexi(ltc_asn1_list* l, unsigned int level)
} }
if (ostring) { if (ostring) {
s_der_tests_print_flexi(ostring, level + 1); s_der_tests_print_flexi_i(ostring, level + 1);
der_free_sequence_flexi(ostring); der_free_sequence_flexi(ostring);
} }
if (l->child) if (l->child)
s_der_tests_print_flexi(l->child, level + 1); s_der_tests_print_flexi_i(l->child, level + 1);
if (l->next) if (l->next)
s_der_tests_print_flexi(l->next, level); s_der_tests_print_flexi_i(l->next, level);
}
static void s_der_tests_print_flexi(ltc_asn1_list* l)
{
fprintf(stderr, "\n\n");
s_der_tests_print_flexi_i(l, 0);
fprintf(stderr, "\n\n");
}
#else
static void s_der_tests_print_flexi(ltc_asn1_list* l)
{
LTC_UNUSED_PARAM(l);
} }
#endif #endif
@ -471,11 +486,7 @@ static void der_cacert_test(void)
CHECK_ASN1_TYPE(decoded_list, LTC_ASN1_SEQUENCE); CHECK_ASN1_TYPE(decoded_list, LTC_ASN1_SEQUENCE);
CHECK_ASN1_HAS_NO_DATA(decoded_list); CHECK_ASN1_HAS_NO_DATA(decoded_list);
#ifdef LTC_DER_TESTS_PRINT_FLEXI s_der_tests_print_flexi(decoded_list);
printf("\n\n--- test print start ---\n\n");
s_der_tests_print_flexi(decoded_list, 0);
printf("\n\n--- test print end ---\n\n");
#endif
l = decoded_list; l = decoded_list;
@ -1086,7 +1097,7 @@ static int der_choice_n_custom_test(void)
for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; } for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; }
for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; } for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; }
for (x = 0; x < sizeof(utf8buf)/sizeof(utf8buf[0]); x++) { utf8buf[x] = L'a'; } for (x = 0; x < sizeof(utf8buf)/sizeof(utf8buf[0]); x++) { utf8buf[x] = L'a'; }
integer = 1; integer = 10000;
boolean[0] = 1; boolean[0] = 1;
for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; } for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; }
DO(mp_init(&mpinteger)); DO(mp_init(&mpinteger));
@ -1169,11 +1180,7 @@ static void s_der_decode_print(const void* p, unsigned long* plen)
{ {
ltc_asn1_list *list; ltc_asn1_list *list;
DO(der_decode_sequence_flexi(p, plen, &list)); DO(der_decode_sequence_flexi(p, plen, &list));
#ifdef LTC_DER_TESTS_PRINT_FLEXI s_der_tests_print_flexi(list);
fprintf(stderr, "\n\n");
s_der_tests_print_flexi(list, 0);
fprintf(stderr, "\n\n");
#endif
der_sequence_free(list); der_sequence_free(list);
} }
@ -1272,19 +1279,18 @@ static void der_Xcode_run(const der_Xcode_t* x)
{ {
unsigned long l1, l2, sz; unsigned long l1, l2, sz;
void *d1, *d2; void *d1, *d2;
int err;
l1 = 1; l1 = 1;
d1 = XMALLOC(l1 * x->type_sz); d1 = XMALLOC(l1 * x->type_sz);
sz = (x->in_sz * x->factor)/x->type_sz; sz = (x->in_sz * x->factor)/x->type_sz;
if ((err = x->encode(x->in, sz, d1, &l1)) == CRYPT_BUFFER_OVERFLOW) { if (x->encode(x->in, sz, d1, &l1) == CRYPT_BUFFER_OVERFLOW) {
d1 = XREALLOC(d1, l1 * x->type_sz); d1 = XREALLOC(d1, l1 * x->type_sz);
} }
DO(x->encode(x->in, sz, d1, &l1)); DO(x->encode(x->in, sz, d1, &l1));
l2 = 1; l2 = 1;
d2 = XMALLOC(l2 * x->type_sz); d2 = XMALLOC(l2 * x->type_sz);
while ((err = x->decode(d1, l1, d2, &l2)) == CRYPT_BUFFER_OVERFLOW) { while (x->decode(d1, l1, d2, &l2) == CRYPT_BUFFER_OVERFLOW) {
d2 = XREALLOC(d2, l2 * x->type_sz); d2 = XREALLOC(d2, l2 * x->type_sz);
} }
DO(x->decode(d1, l1, d2, &l2)); DO(x->decode(d1, l1, d2, &l2));
@ -1343,11 +1349,7 @@ static void der_Xcode_test(void)
i = sizeof(teletex_neg_int); i = sizeof(teletex_neg_int);
DO(der_decode_sequence_flexi(teletex_neg_int, &i, &list)); DO(der_decode_sequence_flexi(teletex_neg_int, &i, &list));
#ifdef LTC_DER_TESTS_PRINT_FLEXI s_der_tests_print_flexi(list);
fprintf(stderr, "\n\n");
s_der_tests_print_flexi(list, 0);
fprintf(stderr, "\n\n");
#endif
if (list->child == NULL || list->child->next == NULL) if (list->child == NULL || list->child->next == NULL)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
ttex_neg_int[0] = *list->child->next; ttex_neg_int[0] = *list->child->next;
@ -1369,11 +1371,7 @@ static int s_der_decode_sequence_flexi(const void *in, unsigned long inlen, void
{ {
ltc_asn1_list** list = ctx; ltc_asn1_list** list = ctx;
if (der_decode_sequence_flexi(in, &inlen, list) == CRYPT_OK) { if (der_decode_sequence_flexi(in, &inlen, list) == CRYPT_OK) {
#ifdef LTC_DER_TESTS_PRINT_FLEXI s_der_tests_print_flexi(*list);
fprintf(stderr, "\n\n");
s_der_tests_print_flexi(*list, 0);
fprintf(stderr, "\n\n");
#endif
der_sequence_free(*list); der_sequence_free(*list);
} }
return CRYPT_OK; return CRYPT_OK;
@ -1401,7 +1399,9 @@ static void s_der_regression_test(void)
"\xaa" /* One byte padding */ "\xaa" /* One byte padding */
"\x04\x82\xff\xff"; /* Start OCTET sequence of length 0xffff */ "\x04\x82\xff\xff"; /* Start OCTET sequence of length 0xffff */
/* (this will include the adjacent data into the decoded certificate) */ /* (this will include the adjacent data into the decoded certificate) */
unsigned long len; static const unsigned char utf8_length[] = "\x0c\x02\x61\x61\x61";
wchar_t wtmp[4];
unsigned long len, outlen;
void *x, *y; void *x, *y;
ltc_asn1_list seq[2]; ltc_asn1_list seq[2];
ltc_asn1_list *l; ltc_asn1_list *l;
@ -1422,6 +1422,11 @@ static void s_der_regression_test(void)
len = sizeof(issue_507); len = sizeof(issue_507);
SHOULD_FAIL(der_decode_sequence_flexi(issue_507, &len, &l)); SHOULD_FAIL(der_decode_sequence_flexi(issue_507, &len, &l));
len = sizeof(utf8_length);
outlen = sizeof(wtmp)/sizeof(wtmp[0]);
DO(der_decode_utf8_string(utf8_length, len, wtmp, &outlen));
ENSURE(outlen == 2);
} }
static void der_toolong_test(void) static void der_toolong_test(void)

View File

@ -198,6 +198,31 @@ static int s_ecc_test_shamir(void)
} }
#endif #endif
/* https://github.com/libtom/libtomcrypt/issues/630 */
static int s_ecc_issue630(void)
{
unsigned char protected_buffer[30], protected_buffer_copy[30];
unsigned long keylen = 0;
ecc_key key;
int low, high;
ecc_sizes(&low, &high);
DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), high, &key));
if (yarrow_read(protected_buffer, sizeof(protected_buffer), &yarrow_prng) != sizeof(protected_buffer)) {
return CRYPT_ERROR_READPRNG;
}
XMEMCPY(protected_buffer_copy, protected_buffer, sizeof(protected_buffer));
COMPARE_TESTVECTOR(protected_buffer, sizeof(protected_buffer), protected_buffer_copy, sizeof(protected_buffer), "Ensure copy is equal", 0);
keylen = 10;
SHOULD_FAIL(ecc_get_key(&protected_buffer[10], &keylen, PK_PRIVATE, &key));
COMPARE_TESTVECTOR(protected_buffer, 10, protected_buffer_copy, 10, "Start canary", 1);
COMPARE_TESTVECTOR(&protected_buffer[20], 10, &protected_buffer[20], 10, "End canary", 2);
ecc_free(&key);
return 0;
}
/* https://github.com/libtom/libtomcrypt/issues/108 */ /* https://github.com/libtom/libtomcrypt/issues/108 */
static int s_ecc_issue108(void) static int s_ecc_issue108(void)
{ {
@ -1591,6 +1616,7 @@ int ecc_test(void)
DO(s_ecc_test_mp()); DO(s_ecc_test_mp());
DO(s_ecc_issue108()); DO(s_ecc_issue108());
DO(s_ecc_issue443_447()); DO(s_ecc_issue443_447());
DO(s_ecc_issue630());
#ifdef LTC_ECC_SHAMIR #ifdef LTC_ECC_SHAMIR
DO(s_ecc_test_shamir()); DO(s_ecc_test_shamir());
DO(s_ecc_test_recovery()); DO(s_ecc_test_recovery());

View File

@ -43,9 +43,9 @@ int pkcs_1_eme_test(void)
unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf);
int stat; int stat;
prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc); prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc);
DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, LTC_PKCS_1_V1_5, key), s->name); DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, -1, LTC_PKCS_1_V1_5, key), s->name);
COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j); COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j);
DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, LTC_PKCS_1_V1_5, &stat, key), s->name); DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, -1, LTC_PKCS_1_V1_5, &stat, key), s->name);
DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
} /* for */ } /* for */

View File

@ -14,7 +14,7 @@ int pkcs_1_test(void)
{ {
unsigned char buf[3][128]; unsigned char buf[3][128];
int res1, res2, res3, prng_idx, hash_idx; int res1, res2, res3, prng_idx, hash_idx;
unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen; unsigned long x, y, l1, l2, l3, i1, lparamlen, saltlen, modlen;
static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
/* get hash/prng */ /* get hash/prng */
@ -46,11 +46,11 @@ int pkcs_1_test(void)
/* encode it */ /* encode it */
l1 = sizeof(buf[1]); l1 = sizeof(buf[1]);
DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1)); DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, -1, buf[1], &l1));
/* decode it */ /* decode it */
l2 = sizeof(buf[2]); l2 = sizeof(buf[2]);
DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1)); DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, -1, buf[2], &l2, &res1));
if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
@ -75,7 +75,7 @@ int pkcs_1_test(void)
DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2)); DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2));
buf[0][i1] ^= 1; buf[0][i1] ^= 1;
buf[1][i2 = abs(rand()) % (l1 - 1)] ^= 1; buf[1][abs(rand()) % (l1 - 1)] ^= 1;
pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3); pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3);
if (!(res1 == 1 && res2 == 0 && res3 == 0)) { if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen); fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);

View File

@ -441,8 +441,8 @@ int rsa_test(void)
{ {
unsigned char in[1024], out[1024], tmp[3072]; unsigned char in[1024], out[1024], tmp[3072];
rsa_key key, privKey, pubKey; rsa_key key, privKey, pubKey;
int hash_idx, prng_idx, stat, stat2, i; int hash_idx, prng_idx, stat, stat2, i, mgf_hash, label_hash;
unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2; unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2, max_msgsize;
static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
void* dP; void* dP;
unsigned char* p; unsigned char* p;
@ -497,60 +497,79 @@ print_hex("q", tmp, len);
rsa_free(&key); rsa_free(&key);
} }
} }
/* make a random key/msg */
ENSURE(yarrow_read(in, 117, &yarrow_prng) == 117);
/* encrypt the key (without lparam) */ #ifdef LTC_TEST_EXT
for (cnt = 0; cnt < 4; cnt++) { for (mgf_hash = 0; mgf_hash < TAB_SIZE; ++mgf_hash) {
for (rsa_msgsize = 0; rsa_msgsize <= 86; rsa_msgsize++) { if (hash_is_valid(mgf_hash) != CRYPT_OK)
/* make a random key/msg */ continue;
ENSURE(yarrow_read(in, rsa_msgsize, &yarrow_prng) == rsa_msgsize); #else
{
mgf_hash = hash_idx;
#endif
for (label_hash = 0; label_hash < TAB_SIZE; ++label_hash) {
if (hash_is_valid(label_hash) != CRYPT_OK)
continue;
if (2 * hash_descriptor[label_hash].hashsize > 126)
continue;
max_msgsize = 128 - (2 * hash_descriptor[label_hash].hashsize) - 2;
len = sizeof(out); #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
len2 = rsa_msgsize; fprintf(stderr, "Test MGF(%s), Labelhash(%s) with max_msgsize %lu\n", hash_descriptor[mgf_hash].name, hash_descriptor[label_hash].name, max_msgsize);
#endif
/* encrypt the key (without lparam) */
for (rsa_msgsize = 0; rsa_msgsize <= max_msgsize; rsa_msgsize++) {
DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); len = sizeof(out);
/* change a byte */ len2 = rsa_msgsize;
out[8] ^= 1;
SHOULD_FAIL(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key));
/* change a byte back */
out[8] ^= 1;
ENSURE(len2 == rsa_msgsize);
len2 = rsa_msgsize; DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key));
DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); /* change a byte */
ENSUREX(stat == 1 && stat2 == 0, "rsa_decrypt_key (without lparam)"); out[8] ^= 1;
DO(do_compare_testvector(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (without lparam)", cnt << 8 | rsa_msgsize)); SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key));
} /* change a byte back */
out[8] ^= 1;
ENSURE(len2 == rsa_msgsize);
len2 = rsa_msgsize;
DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key));
ENSUREX(stat == 1 && stat2 == 0, "rsa_decrypt_key (without lparam)");
DO(do_compare_testvector(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (without lparam)", cnt << 8 | rsa_msgsize));
}
/* encrypt the key (with lparam) */
for (rsa_msgsize = 0; rsa_msgsize <= max_msgsize; rsa_msgsize++) {
len = sizeof(out);
len2 = rsa_msgsize;
DO(rsa_encrypt_key_ex(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key));
/* change a byte */
out[8] ^= 1;
SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key));
ENSURE(len2 == rsa_msgsize);
/* change a byte back */
out[8] ^= 1;
len2 = rsa_msgsize;
DO(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key));
ENSURE(stat == 1 && stat2 == 0);
DO(do_compare_testvector(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (with lparam)", rsa_msgsize));
}
}
} }
/* encrypt the key (with lparam) */
for (rsa_msgsize = 0; rsa_msgsize <= 86; rsa_msgsize++) {
len = sizeof(out);
len2 = rsa_msgsize;
DO(rsa_encrypt_key(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key));
/* change a byte */
out[8] ^= 1;
SHOULD_FAIL(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key));
ENSURE(len2 == rsa_msgsize);
/* change a byte back */
out[8] ^= 1;
len2 = rsa_msgsize;
DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key));
ENSURE(stat == 1 && stat2 == 0);
DO(do_compare_testvector(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (with lparam)", rsa_msgsize));
}
/* encrypt the key PKCS #1 v1.5 (payload from 1 to 117 bytes) */ /* encrypt the key PKCS #1 v1.5 (payload from 1 to 117 bytes) */
for (rsa_msgsize = 0; rsa_msgsize <= 117; rsa_msgsize++) { for (rsa_msgsize = 0; rsa_msgsize <= 117; rsa_msgsize++) {
len = sizeof(out); len = sizeof(out);
len2 = rsa_msgsize; len2 = rsa_msgsize;
/* make a random key/msg */ DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, -1, LTC_PKCS_1_V1_5, &key));
ENSURE(yarrow_read(in, rsa_msgsize, &yarrow_prng) == rsa_msgsize);
DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, LTC_PKCS_1_V1_5, &key));
len2 = rsa_msgsize; len2 = rsa_msgsize;
DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, LTC_PKCS_1_V1_5, &stat, &key)); DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, -1, LTC_PKCS_1_V1_5, &stat, &key));
ENSURE(stat == 1); ENSURE(stat == 1);
DO(do_compare_testvector(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key_ex", rsa_msgsize)); DO(do_compare_testvector(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key_ex", rsa_msgsize));
} }

View File

@ -106,6 +106,7 @@ static void *run(void *arg)
static void s_unregister_all(void) static void s_unregister_all(void)
{ {
#ifdef LTC_RIJNDAEL #ifdef LTC_RIJNDAEL
/* `aesni_desc` is not registered, i.e. also shouldn't be unregistered */
#ifdef ENCRYPT_ONLY #ifdef ENCRYPT_ONLY
/* alternative would be /* alternative would be
* unregister_cipher(&rijndael_enc_desc); * unregister_cipher(&rijndael_enc_desc);

View File

@ -1,5 +1,7 @@
/.gitattributes export-ignore /.gitattributes export-ignore
/.gitignore export-ignore /.gitignore export-ignore
/.travis.yml export-ignore /.github/* export-ignore
/appveyor.yml export-ignore
/doc/.latexindent.yaml export-ignore
/** export-subst /** export-subst

View File

@ -27,21 +27,21 @@ jobs:
echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${{ env.ubuntu_codename }} main" | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${{ env.ubuntu_codename }} main" | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -y cmake gcc sudo apt-get install -y cmake gcc
- name: build static - name: build packages
run: | run: |
mkdir -p build mkdir -p build
cd build cd build
cmake -DBUILD_SHARED_LIBS=Off -DCMAKE_BUILD_TYPE=RelWithDebInfo .. cmake -DBUILD_SHARED_LIBS=Off -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="/usr" ..
make -j$(nproc) make -j$(nproc)
cpack -G DEB cpack -G DEB
cmake -DBUILD_SHARED_LIBS=On -DCMAKE_BUILD_TYPE=RelWithDebInfo .. cmake -DBUILD_SHARED_LIBS=On -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="/usr" ..
make -j$(nproc) make -j$(nproc)
cpack -G DEB cpack -G DEB
- name: push package to packagecloud.io - name: push deb packages to packagecloud.io
uses: computology/packagecloud-github-action@v0.6 uses: computology/packagecloud-github-action@v0.6
with: with:
PACKAGE-NAME: packages/ubuntu/${{ env.ubuntu_codename }}/*.deb PACKAGE-NAME: build/packages/ubuntu/${{ env.ubuntu_codename }}/*.deb
PACKAGECLOUD-USERNAME: libtom PACKAGECLOUD-USERNAME: libtom
PACKAGECLOUD-REPONAME: libtom PACKAGECLOUD-REPONAME: packages
PACKAGECLOUD-DISTRO: ubuntu/${{ env.ubuntu_codename }} PACKAGECLOUD-DISTRO: ubuntu/${{ env.ubuntu_codename }}
PACKAGECLOUD-TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }} PACKAGECLOUD-TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}

View File

@ -25,6 +25,20 @@ on:
- /^ci\/.*$/ - /^ci\/.*$/
jobs: jobs:
Docs:
runs-on: ubuntu-20.04
container: texlive/texlive:latest-full
steps:
- uses: actions/checkout@v2
- name: generate PDF
run: |
make docs V=1
cp doc/bn.pdf bn-${{ github.run_id }}.pdf
- name: upload PDF
uses: actions/upload-artifact@v3
with:
name: bn-${{ github.run_id }}.pdf
path: bn-${{ github.run_id }}.pdf
Testme: Testme:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:

View File

@ -146,7 +146,7 @@ set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
install(TARGETS ${PROJECT_NAME} install(TARGETS ${PROJECT_NAME}
EXPORT ${TARGETS_EXPORT_NAME} EXPORT ${TARGETS_EXPORT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
) )
@ -174,6 +174,14 @@ write_basic_package_version_file(
COMPATIBILITY SameMajorVersion COMPATIBILITY SameMajorVersion
) )
# Windows uses a different help sytem.
if((NOT WIN32) AND (NOT CMAKE_HOST_WIN32))
# install manpage (not gzipped, some BSD's do not want it compressed?)
install(FILES ${CMAKE_SOURCE_DIR}/doc/tommath.3
DESTINATION ${CMAKE_INSTALL_MANDIR}/man3/
)
endif()
# install version file # install version file
install(FILES ${PROJECT_VERSION_FILE} install(FILES ${PROJECT_VERSION_FILE}
DESTINATION ${CONFIG_INSTALL_DIR} DESTINATION ${CONFIG_INSTALL_DIR}
@ -226,11 +234,12 @@ else()
endif() endif()
# make sure untagged versions get a different package name # make sure untagged versions get a different package name
execute_process(COMMAND git describe --exact-match --tags RESULT_VARIABLE REPO_HAS_TAG) execute_process(COMMAND git describe --exact-match --tags ERROR_QUIET RESULT_VARIABLE REPO_HAS_TAG)
if(REPO_HAS_TAG EQUAL 0) if(REPO_HAS_TAG EQUAL 0)
set(PACKAGE_NAME_SUFFIX "") set(PACKAGE_NAME_SUFFIX "")
else() else()
set(PACKAGE_NAME_SUFFIX "-git") set(PACKAGE_NAME_SUFFIX "-git")
message(STATUS "Use -git suffix")
endif() endif()
# default CPack generators # default CPack generators
@ -245,15 +254,18 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
list(APPEND CPACK_GENERATOR FREEBSD) list(APPEND CPACK_GENERATOR FREEBSD)
endif() endif()
set(LTM_DEBIAN_SHARED_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}${PROJECT_VERSION_MAJOR}")
# general CPack config # general CPack config
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH}) set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH})
message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}") message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}")
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}")
set(CPACK_DEBIAN_PACKAGE_NAME "${LTM_DEBIAN_SHARED_PACKAGE_NAME}")
else() else()
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-devel") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-devel")
set(CPACK_DEBIAN_LIBRARIES_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}-dev")
endif() endif()
set(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME}${PACKAGE_NAME_SUFFIX}")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomMath") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomMath")
set(CPACK_PACKAGE_VENDOR "libtom projects") set(CPACK_PACKAGE_VENDOR "libtom projects")
@ -261,17 +273,20 @@ set(CPACK_PACKAGE_CONTACT "libtom@googlegroups.com")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(PACKAGE_NAME_TRAILER ${CPACK_PACKAGE_VERSION}-${PACKAGE_RELEASE_VERSION}_${MACHINE_ARCH}) set(PACKAGE_NAME_TRAILER ${CPACK_PACKAGE_VERSION}-${PACKAGE_RELEASE_VERSION}_${MACHINE_ARCH})
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PACKAGE_NAME_TRAILER}) set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PACKAGE_NAME_TRAILER})
set(CPACK_STRIP_FILES ON)
# deb specific CPack config # deb specific CPack config
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION}) set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION})
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)
set(CPACK_DEBIAN_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
else() else()
set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}-dev")
set(CPACK_DEBIAN_PACKAGE_SECTION "devel") set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
set(CPACK_DEBIAN_PACKAGE_DEPENDS ${LTM_DEBIAN_SHARED_PACKAGE_NAME})
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_COMPONENTS_ALL Libraries)
endif() endif()
# rpm specific CPack config # rpm specific CPack config

View File

@ -20,6 +20,12 @@ develop: [![Build status](https://ci.appveyor.com/api/projects/status/b80lpolw3i
API/ABI changes: [check here](https://abi-laboratory.pro/tracker/timeline/libtommath/) API/ABI changes: [check here](https://abi-laboratory.pro/tracker/timeline/libtommath/)
### Pre-built packages
We sometimes upload `deb` packages of the latest state from the develop branch to [packagecloud.io](https://packagecloud.io/libtom/packages).
Use those packages with caution and at your own discretion.
## Summary ## Summary
The `develop` branch contains the in-development version. Stable releases are tagged. The `develop` branch contains the in-development version. Stable releases are tagged.

View File

@ -1,4 +1,4 @@
version: 1.2.0-{build} version: 1.2.1-{build}
branches: branches:
only: only:
- master - master

View File

@ -1,3 +1,8 @@
Sep 04th, 2023
v1.2.1
-- Bugfix release because of potential integer overflow
c.f. PR #546 resp. CVE-2023-36328
Oct 22nd, 2019 Oct 22nd, 2019
v1.2.0 v1.2.0
-- A huge refactoring of the library happened - renaming, -- A huge refactoring of the library happened - renaming,

View File

@ -14,9 +14,9 @@ static long rand_long(void)
return x; return x;
} }
static int rand_int(void) static unsigned int rand_uint(void)
{ {
int x; unsigned int x;
if (s_mp_rand_jenkins(&x, sizeof(x)) != MP_OKAY) { if (s_mp_rand_jenkins(&x, sizeof(x)) != MP_OKAY) {
fprintf(stderr, "s_mp_rand_source failed\n"); fprintf(stderr, "s_mp_rand_source failed\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -24,6 +24,11 @@ static int rand_int(void)
return x; return x;
} }
static int rand_int(void)
{
return (int)rand_uint();
}
static int32_t rand_int32(void) static int32_t rand_int32(void)
{ {
int32_t x; int32_t x;
@ -448,7 +453,7 @@ static int test_mp_signed_rsh(void)
l = rand_long(); l = rand_long();
mp_set_l(&a, l); mp_set_l(&a, l);
em = abs(rand_int()) % 32; em = rand_uint() % 32;
mp_set_l(&d, l >> em); mp_set_l(&d, l >> em);
@ -1091,7 +1096,8 @@ LBL_ERR:
static int test_mp_montgomery_reduce(void) static int test_mp_montgomery_reduce(void)
{ {
mp_digit mp; mp_digit mp;
int ix, i, n; int ix, n;
unsigned int i;
char buf[4096]; char buf[4096];
/* size_t written; */ /* size_t written; */
@ -1106,7 +1112,7 @@ static int test_mp_montgomery_reduce(void)
printf(" digit size: %2d\r", i); printf(" digit size: %2d\r", i);
fflush(stdout); fflush(stdout);
for (n = 0; n < 1000; n++) { for (n = 0; n < 1000; n++) {
DO(mp_rand(&a, i)); DO(mp_rand(&a, (int)i));
a.dp[0] |= 1; a.dp[0] |= 1;
/* let's see if R is right */ /* let's see if R is right */
@ -1115,7 +1121,7 @@ static int test_mp_montgomery_reduce(void)
/* now test a random reduction */ /* now test a random reduction */
for (ix = 0; ix < 100; ix++) { for (ix = 0; ix < 100; ix++) {
DO(mp_rand(&c, 1 + (abs(rand_int()) % (2*i)))); DO(mp_rand(&c, 1 + (int)(rand_uint() % (2*i))));
DO(mp_copy(&c, &d)); DO(mp_copy(&c, &d));
DO(mp_copy(&c, &e)); DO(mp_copy(&c, &e));
@ -1274,7 +1280,7 @@ static int test_s_mp_div_3(void)
printf("\r %9d", cnt); printf("\r %9d", cnt);
fflush(stdout); fflush(stdout);
} }
DO(mp_rand(&a, (abs(rand_int()) % 128) + 1)); DO(mp_rand(&a, (int)(rand_uint() % 128) + 1));
DO(mp_div(&a, &d, &b, &e)); DO(mp_div(&a, &d, &b, &e));
DO(s_mp_div_3(&a, &c, &r2)); DO(s_mp_div_3(&a, &c, &r2));

View File

@ -51,7 +51,7 @@
\begin{document} \begin{document}
\frontmatter \frontmatter
\pagestyle{empty} \pagestyle{empty}
\title{LibTomMath User Manual \\ v1.2.0} \title{LibTomMath User Manual \\ v1.2.1}
\author{LibTom Projects \\ www.libtom.net} \author{LibTom Projects \\ www.libtom.net}
\maketitle \maketitle
This text, the library and the accompanying textbook are all hereby placed in the public domain. This text, the library and the accompanying textbook are all hereby placed in the public domain.
@ -1449,7 +1449,7 @@ To get a non-cryptographic hash of an \texttt{mp\_int} use the following functio
\index{mp\_hash} \index{mp\_hash}
\begin{alltt} \begin{alltt}
mp_err mp_hash (mp_int *a, mp_hval *hash); mp_err mp_hash (const mp_int *a, mp_hval *hash);
\end{alltt} \end{alltt}
This will create the hash of $a$ following the \mbox{FNV-1a} algorithm as described on This will create the hash of $a$ following the \mbox{FNV-1a} algorithm as described on
@ -2004,7 +2004,7 @@ int main(int argc, char **argv)
mp_error_to_string(e)); mp_error_to_string(e));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("%d\n",output); printf("%d\textbackslash{}n",output);
mp_clear(&x); mp_clear(&x);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -2658,6 +2658,12 @@ bool mp_iszero(mp_int *a)
\end{alltt} \end{alltt}
Checks if $a = 0$. It does not check if the amount of memory allocated for $a$ is also minimal. Checks if $a = 0$. It does not check if the amount of memory allocated for $a$ is also minimal.
\index{mp\_isone}
\begin{alltt}
bool mp_isone(mp_int *a)
\end{alltt}
Checks if $a = 1$.
Other macros which are either shortcuts to normal functions or just other names for them do have Other macros which are either shortcuts to normal functions or just other names for them do have
their place in a programmer's life, too! their place in a programmer's life, too!

1744
deps/libtommath/doc/tommath.3 vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -105,6 +105,7 @@ MARKER
sub check_doc { sub check_doc {
my $fails = 0; my $fails = 0;
my $man = read_file('doc/tommath.3');
my $tex = read_file('doc/bn.tex'); my $tex = read_file('doc/bn.tex');
my $tmh = read_file('tommath.h'); my $tmh = read_file('tommath.h');
my @functions = $tmh =~ /\n\s*[a-zA-Z0-9_* ]+?(mp_[a-z0-9_]+)\s*\([^\)]+\)\s*[MP_WUR]+?;/sg; my @functions = $tmh =~ /\n\s*[a-zA-Z0-9_* ]+?(mp_[a-z0-9_]+)\s*\([^\)]+\)\s*[MP_WUR]+?;/sg;
@ -123,6 +124,18 @@ sub check_doc {
$fails++ $fails++
} }
} }
for my $n (sort @functions) {
if ($man !~ /.BI.*$n/) {
warn "[missing_man_entry_for_function] $n\n";
$fails++
}
}
for my $n (sort @macros) {
if ($man !~ /.BI.*$n/) {
warn "[missing_man_entry_for_macro] $n\n";
$fails++
}
}
warn( $fails > 0 ? "check_doc: FAIL $fails\n" : "check-doc: PASS\n" ); warn( $fails > 0 ? "check_doc: FAIL $fails\n" : "check-doc: PASS\n" );
return $fails; return $fails;
} }

View File

@ -79,9 +79,7 @@ profiled_single: amalgamated_timing
$(CC) $(LTM_CFLAGS) -fbranch-probabilities -c pre_gen/tommath_amalgam.c -o tommath_amalgam.o $(CC) $(LTM_CFLAGS) -fbranch-probabilities -c pre_gen/tommath_amalgam.c -o tommath_amalgam.o
$(AR) $(ARFLAGS) $(LIBNAME) tommath_amalgam.o $(AR) $(ARFLAGS) $(LIBNAME) tommath_amalgam.o
install: $(LIBNAME) install: $(LIBNAME) .install_common
install -d $(DESTDIR)$(LIBPATH)
install -d $(DESTDIR)$(INCPATH)
install -m 644 $(LIBNAME) $(DESTDIR)$(LIBPATH) install -m 644 $(LIBNAME) $(DESTDIR)$(LIBPATH)
install -m 644 $(HEADERS_PUB) $(DESTDIR)$(INCPATH) install -m 644 $(HEADERS_PUB) $(DESTDIR)$(INCPATH)
@ -114,9 +112,6 @@ tune: $(LIBNAME)
coveralls: lcov coveralls: lcov
coveralls-lcov coveralls-lcov
docs manual:
$(MAKE) -C doc/ $@ V=$(V)
.PHONY: pre_gen cmp .PHONY: pre_gen cmp
pre_gen: pre_gen:
mkdir -p pre_gen mkdir -p pre_gen
@ -127,6 +122,7 @@ cmp: profiled_single
./timing ./timing
$(MAKE) -C logs/ cmp $(MAKE) -C logs/ cmp
TODAY=$(shell date -I)
zipup: clean astyle new_file docs zipup: clean astyle new_file docs
@# Update the index, so diff-index won't fail in case the pdf has been created. @# Update the index, so diff-index won't fail in case the pdf has been created.
@# As the pdf creation modifies the tex files, git sometimes detects the @# As the pdf creation modifies the tex files, git sometimes detects the
@ -140,6 +136,7 @@ zipup: clean astyle new_file docs
-@(find libtommath-$(VERSION)/ -type f | xargs grep 'FIXM[E]') && echo '############## BEWARE: the "fixme" marker was found !!! ##############' || true -@(find libtommath-$(VERSION)/ -type f | xargs grep 'FIXM[E]') && echo '############## BEWARE: the "fixme" marker was found !!! ##############' || true
mkdir -p libtommath-$(VERSION)/doc mkdir -p libtommath-$(VERSION)/doc
cp doc/bn.pdf libtommath-$(VERSION)/doc/ cp doc/bn.pdf libtommath-$(VERSION)/doc/
sed -e "s,^Version.*,Version $(VERSION)," -e "s,2003-28-02,$(TODAY)," doc/tommath.3 > libtommath-$(VERSION)/doc/tommath.3
$(MAKE) -C libtommath-$(VERSION)/ pre_gen $(MAKE) -C libtommath-$(VERSION)/ pre_gen
tar -c libtommath-$(VERSION)/ | xz -6e -c - > ltm-$(VERSION).tar.xz tar -c libtommath-$(VERSION)/ | xz -6e -c - > ltm-$(VERSION).tar.xz
zip -9rq ltm-$(VERSION).zip libtommath-$(VERSION) zip -9rq ltm-$(VERSION).zip libtommath-$(VERSION)

View File

@ -60,9 +60,7 @@ LOBJECTS = $(OBJECTS:.o=.lo)
$(LIBNAME): $(OBJECTS) $(LIBNAME): $(OBJECTS)
$(LTLINK) $(LTM_LDFLAGS) $(LOBJECTS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION_SO) $(LTM_LIBTOOLFLAGS) $(LTLINK) $(LTM_LDFLAGS) $(LOBJECTS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION_SO) $(LTM_LIBTOOLFLAGS)
install: $(LIBNAME) install: $(LIBNAME) .install_common
install -d $(DESTDIR)$(LIBPATH)
install -d $(DESTDIR)$(INCPATH)
$(LIBTOOL) --mode=install install -m 644 $(LIBNAME) $(DESTDIR)$(LIBPATH)/$(LIBNAME) $(LIBTOOL) --mode=install install -m 644 $(LIBNAME) $(DESTDIR)$(LIBPATH)/$(LIBNAME)
install -m 644 $(HEADERS_PUB) $(DESTDIR)$(INCPATH) install -m 644 $(HEADERS_PUB) $(DESTDIR)$(INCPATH)
sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,@CMAKE_INSTALL_LIBDIR@,lib,' \ sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,@CMAKE_INSTALL_LIBDIR@,lib,' \

View File

@ -20,7 +20,7 @@ ARFLAGS = rcs
CFLAGS = -O2 CFLAGS = -O2
LDFLAGS = LDFLAGS =
VERSION = 1.2.0 VERSION = 1.2.1
#Compilation flags #Compilation flags
LTM_CFLAGS = -I. $(CFLAGS) LTM_CFLAGS = -I. $(CFLAGS)

View File

@ -3,9 +3,9 @@
# #
#version of library #version of library
VERSION=1.2.0-develop VERSION=1.2.1-develop
VERSION_PC=1.2.0 VERSION_PC=1.2.1
VERSION_SO=3:0:2 VERSION_SO=3:1:2
PLATFORM := $(shell uname | sed -e 's/_.*//') PLATFORM := $(shell uname | sed -e 's/_.*//')
@ -86,8 +86,11 @@ LTM_CFLAGS += -fomit-frame-pointer
endif endif
ifdef COMPILE_LTO ifdef COMPILE_LTO
LTM_CFLAGS += -flto ifeq ($(findstring clang,$(CC)),)
LTM_LDFLAGS += -flto LTO_ARG = "=auto"
endif
LTM_CFLAGS += -flto$(LTO_ARG)
LTM_LDFLAGS += -flto$(LTO_ARG)
AR = $(subst clang,llvm-ar,$(subst gcc,gcc-ar,$(CC))) AR = $(subst clang,llvm-ar,$(subst gcc,gcc-ar,$(CC)))
endif endif
@ -138,11 +141,27 @@ HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h
#LIBPATH The directory for libtommath to be installed to. #LIBPATH The directory for libtommath to be installed to.
#INCPATH The directory to install the header files for libtommath. #INCPATH The directory to install the header files for libtommath.
#DATAPATH The directory to install the pdf docs. #DATAPATH The directory to install the pdf docs.
#MANPATH The directory to install the manfile.
DESTDIR ?= DESTDIR ?=
PREFIX ?= /usr/local PREFIX ?= /usr/local
LIBPATH ?= $(PREFIX)/lib LIBPATH ?= $(PREFIX)/lib
INCPATH ?= $(PREFIX)/include INCPATH ?= $(PREFIX)/include
DATAPATH ?= $(PREFIX)/share/doc/libtommath/pdf DATAPATH ?= $(PREFIX)/share/doc/libtommath/pdf
MANPATH ?= $(PREFIX)/share/man
.install_common:
install -d $(DESTDIR)$(LIBPATH)
install -d $(DESTDIR)$(INCPATH)
install_docs: manual
install -d $(DESTDIR)$(DATAPATH)
install -p -m 644 doc/bn.pdf $(DESTDIR)$(DATAPATH)
install -d $(DESTDIR)$(MANPATH)
install -p -m 644 doc/tommath.3 $(DESTDIR)$(MANPATH)/man3
docs manual:
$(MAKE) -C doc/ $@ V=$(V)
# build & run test-suite # build & run test-suite
check: test check: test

View File

@ -12,6 +12,10 @@ mp_err mp_2expt(mp_int *a, int b)
{ {
mp_err err; mp_err err;
if (b < 0) {
return MP_VAL;
}
/* zero a as per default */ /* zero a as per default */
mp_zero(a); mp_zero(a);

View File

@ -6,6 +6,10 @@
/* grow as required */ /* grow as required */
mp_err mp_grow(mp_int *a, int size) mp_err mp_grow(mp_int *a, int size)
{ {
if (size < 0) {
return MP_VAL;
}
/* if the alloc size is smaller alloc more ram */ /* if the alloc size is smaller alloc more ram */
if (a->alloc < size) { if (a->alloc < size) {
mp_digit *dp; mp_digit *dp;

View File

@ -12,7 +12,7 @@
#endif #endif
/* computes hash of mp_int. */ /* computes hash of mp_int. */
mp_err mp_hash(mp_int *a, mp_hval *hash) mp_err mp_hash(const mp_int *a, mp_hval *hash)
{ {
int x; int x;
mp_hval hval = FNV_1A_INIT; mp_hval hval = FNV_1A_INIT;

View File

@ -6,6 +6,10 @@
/* init an mp_init for a given size */ /* init an mp_init for a given size */
mp_err mp_init_size(mp_int *a, int size) mp_err mp_init_size(mp_int *a, int size)
{ {
if (size < 0) {
return MP_VAL;
}
size = MP_MAX(MP_MIN_DIGIT_COUNT, size); size = MP_MAX(MP_MIN_DIGIT_COUNT, size);
if (size > MP_MAX_DIGIT_COUNT) { if (size > MP_MAX_DIGIT_COUNT) {

View File

@ -13,6 +13,10 @@ mp_err s_mp_mul(const mp_int *a, const mp_int *b, mp_int *c, int digs)
mp_err err; mp_err err;
int pa, ix; int pa, ix;
if (digs < 0) {
return MP_VAL;
}
/* can we use the fast multiplier? */ /* can we use the fast multiplier? */
if ((digs < MP_WARRAY) && if ((digs < MP_WARRAY) &&
(MP_MIN(a->used, b->used) < MP_MAX_COMBA)) { (MP_MIN(a->used, b->used) < MP_MAX_COMBA)) {

View File

@ -26,6 +26,10 @@ mp_err s_mp_mul_comba(const mp_int *a, const mp_int *b, mp_int *c, int digs)
mp_digit W[MP_WARRAY]; mp_digit W[MP_WARRAY];
mp_word _W; mp_word _W;
if (digs < 0) {
return MP_VAL;
}
/* grow the destination as required */ /* grow the destination as required */
if ((err = mp_grow(c, digs)) != MP_OKAY) { if ((err = mp_grow(c, digs)) != MP_OKAY) {
return err; return err;

View File

@ -12,6 +12,10 @@ mp_err s_mp_mul_high(const mp_int *a, const mp_int *b, mp_int *c, int digs)
int pa, pb, ix; int pa, pb, ix;
mp_err err; mp_err err;
if (digs < 0) {
return MP_VAL;
}
/* can we use the fast multiplier? */ /* can we use the fast multiplier? */
if (MP_HAS(S_MP_MUL_HIGH_COMBA) if (MP_HAS(S_MP_MUL_HIGH_COMBA)
&& ((a->used + b->used + 1) < MP_WARRAY) && ((a->used + b->used + 1) < MP_WARRAY)

View File

@ -19,6 +19,10 @@ mp_err s_mp_mul_high_comba(const mp_int *a, const mp_int *b, mp_int *c, int digs
mp_digit W[MP_WARRAY]; mp_digit W[MP_WARRAY];
mp_word _W; mp_word _W;
if (digs < 0) {
return MP_VAL;
}
/* grow the destination as required */ /* grow the destination as required */
pa = a->used + b->used; pa = a->used + b->used;
if ((err = mp_grow(c, pa)) != MP_OKAY) { if ((err = mp_grow(c, pa)) != MP_OKAY) {

View File

@ -208,6 +208,7 @@ mp_err mp_init_size(mp_int *a, int size) MP_WUR;
/* ---> Basic Manipulations <--- */ /* ---> Basic Manipulations <--- */
#define mp_iszero(a) ((a)->used == 0) #define mp_iszero(a) ((a)->used == 0)
#define mp_isone(a) ( ((a)->sign == MP_ZPOS) && ((a)->used == 1u) && ((a)->dp[0] == 1u) )
#define mp_isneg(a) ((a)->sign == MP_NEG) #define mp_isneg(a) ((a)->sign == MP_NEG)
#define mp_iseven(a) (((a)->used == 0) || (((a)->dp[0] & 1u) == 0u)) #define mp_iseven(a) (((a)->used == 0) || (((a)->dp[0] & 1u) == 0u))
#define mp_isodd(a) (!mp_iseven(a)) #define mp_isodd(a) (!mp_iseven(a))
@ -498,7 +499,7 @@ typedef uint64_t mp_hval;
#endif #endif
/* computes hash */ /* computes hash */
mp_err mp_hash(mp_int *a, mp_hval *hash) MP_WUR; mp_err mp_hash(const mp_int *a, mp_hval *hash) MP_WUR;
/* ---> Primes <--- */ /* ---> Primes <--- */

View File

@ -20,3 +20,7 @@ trim_trailing_whitespace = true
# UTF-8 with BOM # UTF-8 with BOM
[*.{c,h,def,txt}] [*.{c,h,def,txt}]
charset=utf-8-bom charset=utf-8-bom
# C/C++ code formatting
[*.{c,h}]
cpp_space_pointer_reference_alignment = right

View File

@ -880,7 +880,7 @@ MH_STATUS WINAPI MH_CreateHookApiEx(
if (pTarget == NULL) if (pTarget == NULL)
return MH_ERROR_FUNCTION_NOT_FOUND; return MH_ERROR_FUNCTION_NOT_FOUND;
if(ppTarget != NULL) if (ppTarget != NULL)
*ppTarget = pTarget; *ppTarget = pTarget;
return MH_CreateHook(pTarget, pDetour, ppOriginal); return MH_CreateHook(pTarget, pDetour, ppOriginal);
@ -890,11 +890,11 @@ MH_STATUS WINAPI MH_CreateHookApiEx(
MH_STATUS WINAPI MH_CreateHookApi( MH_STATUS WINAPI MH_CreateHookApi(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal) LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal)
{ {
return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL); return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
const char * WINAPI MH_StatusToString(MH_STATUS status) const char *WINAPI MH_StatusToString(MH_STATUS status)
{ {
#define MH_ST2STR(x) \ #define MH_ST2STR(x) \
case x: \ case x: \

View File

@ -285,8 +285,7 @@ BOOL CreateTrampolineFunction(PTRAMPOLINE ct)
#endif #endif
newPos += copySize; newPos += copySize;
oldPos += hs.len; oldPos += hs.len;
} } while (!finished);
while (!finished);
// Is there enough place for a long jump? // Is there enough place for a long jump?
if (oldPos < sizeof(JMP_REL) if (oldPos < sizeof(JMP_REL)

View File

@ -195,6 +195,11 @@ install(FILES readme.md
DESTINATION "${DOC_INSTALL_DIR}" DESTINATION "${DOC_INSTALL_DIR}"
COMPONENT doc) COMPONENT doc)
# Add an interface target to export it
add_library(RapidJSON INTERFACE)
target_include_directories(RapidJSON INTERFACE $<INSTALL_INTERFACE:include/rapidjson>)
install(DIRECTORY include/rapidjson install(DIRECTORY include/rapidjson
DESTINATION "${INCLUDE_INSTALL_DIR}" DESTINATION "${INCLUDE_INSTALL_DIR}"
COMPONENT dev) COMPONENT dev)
@ -221,6 +226,7 @@ SET( CONFIG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
SET( CONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR}) SET( CONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR})
SET( ${PROJECT_NAME}_INCLUDE_DIR "\${${PROJECT_NAME}_SOURCE_DIR}/include" ) SET( ${PROJECT_NAME}_INCLUDE_DIR "\${${PROJECT_NAME}_SOURCE_DIR}/include" )
INCLUDE(CMakePackageConfigHelpers)
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY ) ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY )
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}ConfigVersion.cmake.in CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}ConfigVersion.cmake.in
@ -243,9 +249,12 @@ INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAM
# Install files # Install files
IF(CMAKE_INSTALL_DIR) IF(CMAKE_INSTALL_DIR)
INSTALL(FILES INSTALL(FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION "${CMAKE_INSTALL_DIR}" DESTINATION "${CMAKE_INSTALL_DIR}"
COMPONENT dev) COMPONENT dev)
INSTALL(TARGETS RapidJSON EXPORT RapidJSON-targets)
INSTALL(EXPORT RapidJSON-targets DESTINATION ${CMAKE_INSTALL_DIR})
ENDIF() ENDIF()

View File

@ -1,6 +1,6 @@
################################################################################ @PACKAGE_INIT@
# CMake minimum version required
cmake_minimum_required(VERSION 3.0) include ("${CMAKE_CURRENT_LIST_DIR}/RapidJSON-targets.cmake")
################################################################################ ################################################################################
# RapidJSON source dir # RapidJSON source dir
@ -14,12 +14,6 @@ set( RapidJSON_DIR "@CONFIG_DIR@")
# Compute paths # Compute paths
get_filename_component(RapidJSON_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(RapidJSON_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set( RapidJSON_INCLUDE_DIR "@RapidJSON_INCLUDE_DIR@" ) get_target_property(RapidJSON_INCLUDE_DIR RapidJSON INTERFACE_INCLUDE_DIRECTORIES)
set( RapidJSON_INCLUDE_DIRS "@RapidJSON_INCLUDE_DIR@" )
message(STATUS "RapidJSON found. Headers: ${RapidJSON_INCLUDE_DIRS}")
if(NOT TARGET rapidjson) set( RapidJSON_INCLUDE_DIRS ${RapidJSON_INCLUDE_DIR} )
add_library(rapidjson INTERFACE IMPORTED)
set_property(TARGET rapidjson PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${RapidJSON_INCLUDE_DIRS})
endif()

Some files were not shown because too many files have changed in this diff Show More