forked from qt-creator/qt-creator
Merge "Merge remote-tracking branch 'origin/4.8' into master"
This commit is contained in:
@@ -37,7 +37,8 @@
|
|||||||
\title Connecting Android Devices
|
\title Connecting Android Devices
|
||||||
|
|
||||||
You can connect Android devices to the development PC to run, debug,
|
You can connect Android devices to the development PC to run, debug,
|
||||||
and analyze applications built for them from \QC.
|
and analyze applications built for them from \QC. Devices with Android
|
||||||
|
version 4.1 (API level 16) or later are supported.
|
||||||
|
|
||||||
If you have a tool chain for building applications for Android devices
|
If you have a tool chain for building applications for Android devices
|
||||||
installed on the development PC, you can add it to \QC. You can then add a
|
installed on the development PC, you can add it to \QC. You can then add a
|
||||||
@@ -59,7 +60,10 @@
|
|||||||
\list
|
\list
|
||||||
|
|
||||||
\li \l{http://www.oracle.com/technetwork/java/javase/downloads/index.html}
|
\li \l{http://www.oracle.com/technetwork/java/javase/downloads/index.html}
|
||||||
{Java SE Development Kit (JDK)} version 6, or later
|
{Java SE Development Kit (JDK)} version 6, or later.
|
||||||
|
You can also use \l{http://openjdk.java.net/}{OpenJDK} on Linux.
|
||||||
|
|
||||||
|
\note Android SDK Tools have issues with JDK versions later than 8.
|
||||||
|
|
||||||
\li \l{http://www.gradle.org}{Gradle} for building application packages
|
\li \l{http://www.gradle.org}{Gradle} for building application packages
|
||||||
for Android devices (APK). Gradle is delivered with Qt 5.9, and
|
for Android devices (APK). Gradle is delivered with Qt 5.9, and
|
||||||
@@ -71,7 +75,7 @@
|
|||||||
|
|
||||||
\li A tool chain for building applications for Android devices provided
|
\li A tool chain for building applications for Android devices provided
|
||||||
by the \l{http://developer.android.com/tools/sdk/ndk/index.html}
|
by the \l{http://developer.android.com/tools/sdk/ndk/index.html}
|
||||||
{Android NDK} from Google.
|
{Android NDK} from Google. The recommended version is 10e.
|
||||||
|
|
||||||
\li \l{http://developer.android.com/sdk/index.html}{Android SDK Tools}
|
\li \l{http://developer.android.com/sdk/index.html}{Android SDK Tools}
|
||||||
|
|
||||||
@@ -106,9 +110,12 @@
|
|||||||
\section1 Setting Up the Development Environment
|
\section1 Setting Up the Development Environment
|
||||||
|
|
||||||
You must download and install the latest Android NDK and SDK, and then
|
You must download and install the latest Android NDK and SDK, and then
|
||||||
update or install the tools and packages needed for development. The SDK
|
update or install the tools and packages needed for development. However,
|
||||||
tool used to update and install the other SDK tools and packages depends on
|
if your Qt version is earlier than v5.9, use the SDK tools package v25.2.5
|
||||||
the Android SDK Tools version that you have installed:
|
or earlier.
|
||||||
|
|
||||||
|
The SDK tool used to update and install the other SDK tools and packages
|
||||||
|
depends on the Android SDK Tools version that you have installed:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
|
||||||
@@ -135,6 +142,10 @@
|
|||||||
|
|
||||||
In addition, you must install Qt for Android as part of Qt 5.2, or later.
|
In addition, you must install Qt for Android as part of Qt 5.2, or later.
|
||||||
|
|
||||||
|
\note You can build a 64-bit version of Qt for Android yourself. However,
|
||||||
|
for such a Qt version, the minimum required Android version on devices
|
||||||
|
is 5.0 (API level 21).
|
||||||
|
|
||||||
For more information, see \l{Qt for Android}.
|
For more information, see \l{Qt for Android}.
|
||||||
|
|
||||||
\section2 Specifying Android Device Settings
|
\section2 Specifying Android Device Settings
|
||||||
@@ -287,22 +298,11 @@
|
|||||||
|
|
||||||
\section1 Debugging on Android Devices
|
\section1 Debugging on Android Devices
|
||||||
|
|
||||||
Android devices support debugging multi-thread applications in version
|
Select a \l{glossary-build-config}{debug build configuration} to build
|
||||||
2.2.1 and later. If you use AVD, select Android 2.3, or later. For more
|
|
||||||
information, see the Android documentation.
|
|
||||||
|
|
||||||
In addition, debugging is supported at android-10 API level, or higher. In
|
|
||||||
the run settings for the project, in the \uicontrol {Android build SDK} field,
|
|
||||||
select android-10, or higher. For more information about Android API levels,
|
|
||||||
see \l{http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels}
|
|
||||||
{What is API Level?}.
|
|
||||||
|
|
||||||
\note Select a \l{glossary-build-config}{debug build configuration} to build
|
|
||||||
the application for debugging.
|
the application for debugging.
|
||||||
|
|
||||||
\note \QC cannot debug applications on Android devices if Android Studio is
|
\note \QC cannot debug applications on Android devices if Android Studio is
|
||||||
running. If the following message is displayed in the \uicontrol Output
|
running. If the following message is displayed in the \uicontrol Output
|
||||||
pane, close Android Studio and try again: \e {Ignoring second debugger -
|
pane, close Android Studio and try again: \e {Ignoring second debugger -
|
||||||
accepting and dropping.}
|
accepting and dropping.}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@@ -60,7 +60,7 @@
|
|||||||
first-letter case-sensitivity, select \uicontrol Full or
|
first-letter case-sensitivity, select \uicontrol Full or
|
||||||
\uicontrol {First Letter} in the \uicontrol {Case-sensitivity} field.
|
\uicontrol {First Letter} in the \uicontrol {Case-sensitivity} field.
|
||||||
|
|
||||||
\section2 Summary of Available Types
|
\section1 Summary of Available Types
|
||||||
|
|
||||||
The following table lists available types for code completion and icon used
|
The following table lists available types for code completion and icon used
|
||||||
for each.
|
for each.
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
\endif
|
\endif
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
\section2 Completing Code Snippets
|
\section1 Completing Code Snippets
|
||||||
|
|
||||||
Code snippets can consist of multiple variables that you specify values for.
|
Code snippets can consist of multiple variables that you specify values for.
|
||||||
Select an item in the list and press \key Tab or \key Enter to complete the
|
Select an item in the list and press \key Tab or \key Enter to complete the
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\section3 Adding and Editing Snippets
|
\section2 Adding and Editing Snippets
|
||||||
|
|
||||||
Select a snippet in the list to edit it in the snippet editor. To add a new
|
Select a snippet in the list to edit it in the snippet editor. To add a new
|
||||||
snippet, select \uicontrol Add. Specify a trigger and, if the trigger is
|
snippet, select \uicontrol Add. Specify a trigger and, if the trigger is
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
To discard the changes you made to a built-in snippet, select
|
To discard the changes you made to a built-in snippet, select
|
||||||
\uicontrol {Revert Built-in}.
|
\uicontrol {Revert Built-in}.
|
||||||
|
|
||||||
\section3 Removing Snippets
|
\section2 Removing Snippets
|
||||||
|
|
||||||
Several similar built-in snippets might be provided for different use cases.
|
Several similar built-in snippets might be provided for different use cases.
|
||||||
To make the list of suggestions shorter when you write code, remove the
|
To make the list of suggestions shorter when you write code, remove the
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
\uicontrol Remove. To restore the removed snippets, select
|
\uicontrol Remove. To restore the removed snippets, select
|
||||||
\uicontrol {Restore Removed Built-ins}.
|
\uicontrol {Restore Removed Built-ins}.
|
||||||
|
|
||||||
\section3 Resetting Snippets
|
\section2 Resetting Snippets
|
||||||
|
|
||||||
To remove all added snippets and to restore all removed snippets, select
|
To remove all added snippets and to restore all removed snippets, select
|
||||||
\uicontrol {Reset All}.
|
\uicontrol {Reset All}.
|
||||||
|
@@ -56,8 +56,9 @@
|
|||||||
This is totally transparent to users. As Qt is composed of libraries
|
This is totally transparent to users. As Qt is composed of libraries
|
||||||
referencing each other, Qt 4 applications are only supported on
|
referencing each other, Qt 4 applications are only supported on
|
||||||
Android version 1.6, or later, and Qt 5 applications on version
|
Android version 1.6, or later, and Qt 5 applications on version
|
||||||
2.3.3, or later. You must install a Qt version targeting Android and
|
4.1 (API level 16), or later. You must install a Qt version
|
||||||
the Android SDK and NDK to develop for Android devices.
|
targeting Android and the Android SDK and NDK to develop for
|
||||||
|
Android devices.
|
||||||
|
|
||||||
\if defined(qtcreator)
|
\if defined(qtcreator)
|
||||||
\li \l{Connecting Bare Metal Devices}
|
\li \l{Connecting Bare Metal Devices}
|
||||||
|
@@ -4,16 +4,16 @@ import qbs.FileInfo
|
|||||||
import "qtc.js" as HelperFunctions
|
import "qtc.js" as HelperFunctions
|
||||||
|
|
||||||
Module {
|
Module {
|
||||||
property string qtcreator_display_version: '4.8.0-beta1'
|
property string qtcreator_display_version: '4.8.0-beta2'
|
||||||
property string ide_version_major: '4'
|
property string ide_version_major: '4'
|
||||||
property string ide_version_minor: '7'
|
property string ide_version_minor: '7'
|
||||||
property string ide_version_release: '82'
|
property string ide_version_release: '83'
|
||||||
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
|
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
|
||||||
+ ide_version_release
|
+ ide_version_release
|
||||||
|
|
||||||
property string ide_compat_version_major: '4'
|
property string ide_compat_version_major: '4'
|
||||||
property string ide_compat_version_minor: '7'
|
property string ide_compat_version_minor: '7'
|
||||||
property string ide_compat_version_release: '82'
|
property string ide_compat_version_release: '83'
|
||||||
property string qtcreator_compat_version: ide_compat_version_major + '.'
|
property string qtcreator_compat_version: ide_compat_version_major + '.'
|
||||||
+ ide_compat_version_minor + '.' + ide_compat_version_release
|
+ ide_compat_version_minor + '.' + ide_compat_version_release
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
|
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
|
||||||
QTCREATOR_PRI_INCLUDED = 1
|
QTCREATOR_PRI_INCLUDED = 1
|
||||||
|
|
||||||
QTCREATOR_VERSION = 4.7.82
|
QTCREATOR_VERSION = 4.7.83
|
||||||
QTCREATOR_COMPAT_VERSION = 4.7.82
|
QTCREATOR_COMPAT_VERSION = 4.7.83
|
||||||
VERSION = $$QTCREATOR_VERSION
|
VERSION = $$QTCREATOR_VERSION
|
||||||
QTCREATOR_DISPLAY_VERSION = 4.8.0-beta1
|
QTCREATOR_DISPLAY_VERSION = 4.8.0-beta2
|
||||||
QTCREATOR_COPYRIGHT_YEAR = 2018
|
QTCREATOR_COPYRIGHT_YEAR = 2018
|
||||||
BINARY_ARTIFACTS_BRANCH = master
|
BINARY_ARTIFACTS_BRANCH = master
|
||||||
|
|
||||||
|
@@ -2795,7 +2795,7 @@ def qdump__qfloat16(d, value):
|
|||||||
elif exp == 0b11111:
|
elif exp == 0b11111:
|
||||||
res = ('-inf' if sign else 'inf') if fraction == 0 else 'nan'
|
res = ('-inf' if sign else 'inf') if fraction == 0 else 'nan'
|
||||||
else:
|
else:
|
||||||
res = (-1)**sign * (1 + fraction / 2**10) * 2**(exp - 15)
|
res = (-1)**sign * (1 + 1. * fraction / 2**10) * 2**(exp - 15)
|
||||||
d.putValue(res)
|
d.putValue(res)
|
||||||
d.putNumChild(1)
|
d.putNumChild(1)
|
||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
<style name="Function"/>
|
<style name="Function"/>
|
||||||
<style name="Keyword" foreground="#45c6d6" italic="true"/>
|
<style name="Keyword" foreground="#45c6d6" italic="true"/>
|
||||||
<style name="PrimitiveType" foreground="#d69aa7"/>
|
<style name="PrimitiveType" foreground="#d69aa7"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator" foreground="#d6bb9a"/>
|
<style name="Operator" foreground="#d6bb9a"/>
|
||||||
|
<style name="Overloaded Operator"/>
|
||||||
<style name="Preprocessor" foreground="#ff6aad"/>
|
<style name="Preprocessor" foreground="#ff6aad"/>
|
||||||
<style name="Label" foreground="#d6c540"/>
|
<style name="Label" foreground="#d6c540"/>
|
||||||
<style name="Comment" foreground="#a8abb0" italic="true"/>
|
<style name="Comment" foreground="#a8abb0" italic="true"/>
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
<style name="Number" foreground="#ff55ff"/>
|
<style name="Number" foreground="#ff55ff"/>
|
||||||
<style name="Occurrences" background="#363636"/>
|
<style name="Occurrences" background="#363636"/>
|
||||||
<style name="Occurrences.Rename" foreground="#ffaaaa" background="#553636"/>
|
<style name="Occurrences.Rename" foreground="#ffaaaa" background="#553636"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator" foreground="#aaaaaa"/>
|
<style name="Operator" foreground="#aaaaaa"/>
|
||||||
|
<style name="Overloaded Operator"/>
|
||||||
<style name="Parentheses" foreground="#ff5555" background="#333333"/>
|
<style name="Parentheses" foreground="#ff5555" background="#333333"/>
|
||||||
<style name="ParenthesesMismatch" background="#800080"/>
|
<style name="ParenthesesMismatch" background="#800080"/>
|
||||||
<style name="AutoComplete" foreground="#a0a0ff" background="#333333"/>
|
<style name="AutoComplete" foreground="#a0a0ff" background="#333333"/>
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
<style name="Function" background="#ffffff"/>
|
<style name="Function" background="#ffffff"/>
|
||||||
<style name="Keyword" foreground="#808000"/>
|
<style name="Keyword" foreground="#808000"/>
|
||||||
<style name="PrimitiveType" foreground="#808000"/>
|
<style name="PrimitiveType" foreground="#808000"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator"/>
|
<style name="Operator"/>
|
||||||
|
<style name="Overloaded Operator" background="#ffffff"/>
|
||||||
<style name="Preprocessor" foreground="#000080"/>
|
<style name="Preprocessor" foreground="#000080"/>
|
||||||
<style name="Label" foreground="#800000"/>
|
<style name="Label" foreground="#800000"/>
|
||||||
<style name="Comment" foreground="#008000"/>
|
<style name="Comment" foreground="#008000"/>
|
||||||
|
@@ -22,7 +22,9 @@
|
|||||||
<style name="Link" foreground="#0000ff"/>
|
<style name="Link" foreground="#0000ff"/>
|
||||||
<style name="Local"/>
|
<style name="Local"/>
|
||||||
<style name="Number" foreground="#3f3f3f"/>
|
<style name="Number" foreground="#3f3f3f"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator"/>
|
<style name="Operator"/>
|
||||||
|
<style name="Overloaded Operator"/>
|
||||||
<style name="Parentheses" background="#e3e3e3" bold="true"/>
|
<style name="Parentheses" background="#e3e3e3" bold="true"/>
|
||||||
<style name="ParenthesesMismatch" background="#808080"/>
|
<style name="ParenthesesMismatch" background="#808080"/>
|
||||||
<style name="AutoComplete" foreground="#303030" background="#d0d0d0"/>
|
<style name="AutoComplete" foreground="#303030" background="#d0d0d0"/>
|
||||||
|
@@ -31,7 +31,9 @@
|
|||||||
<style name="Occurrences" foreground="#000000" background="#616161"/>
|
<style name="Occurrences" foreground="#000000" background="#616161"/>
|
||||||
<style name="Occurrences.Rename" foreground="#000000" background="#ff6464"/>
|
<style name="Occurrences.Rename" foreground="#000000" background="#ff6464"/>
|
||||||
<style name="Occurrences.Unused" foreground="#808000"/>
|
<style name="Occurrences.Unused" foreground="#808000"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator" foreground="#cfbfad"/>
|
<style name="Operator" foreground="#cfbfad"/>
|
||||||
|
<style name="Overloaded Operator"/>
|
||||||
<style name="Parentheses" foreground="#ffff00" background="#4e4e8f"/>
|
<style name="Parentheses" foreground="#ffff00" background="#4e4e8f"/>
|
||||||
<style name="ParenthesesMismatch" background="#404040"/>
|
<style name="ParenthesesMismatch" background="#404040"/>
|
||||||
<style name="AutoComplete" foreground="#ffff00" background="#4e4e8f"/>
|
<style name="AutoComplete" foreground="#ffff00" background="#4e4e8f"/>
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
<style name="Local" foreground="#000000"/>
|
<style name="Local" foreground="#000000"/>
|
||||||
<style name="Number" foreground="#0000ff"/>
|
<style name="Number" foreground="#0000ff"/>
|
||||||
<style name="Operator" foreground="#000000"/>
|
<style name="Operator" foreground="#000000"/>
|
||||||
|
<style name="Overloaded Operator" foreground="#000000"/>
|
||||||
<style name="Parentheses" foreground="#ff0000" background="#c3e1ff"/>
|
<style name="Parentheses" foreground="#ff0000" background="#c3e1ff"/>
|
||||||
<style name="ParenthesesMismatch" background="#ff00ff"/>
|
<style name="ParenthesesMismatch" background="#ff00ff"/>
|
||||||
<style name="AutoComplete" foreground="#ff0000" background="#c3e1ff"/>
|
<style name="AutoComplete" foreground="#ff0000" background="#c3e1ff"/>
|
||||||
|
@@ -31,7 +31,9 @@
|
|||||||
<style name="Function"/>
|
<style name="Function"/>
|
||||||
<style name="Keyword" foreground="#78d7ec" italic="true"/>
|
<style name="Keyword" foreground="#78d7ec" italic="true"/>
|
||||||
<style name="PrimitiveType" foreground="#ff8080"/>
|
<style name="PrimitiveType" foreground="#ff8080"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator" foreground="#a6e22e"/>
|
<style name="Operator" foreground="#a6e22e"/>
|
||||||
|
<style name="Overloaded Operator"/>
|
||||||
<style name="Preprocessor" foreground="#f92672"/>
|
<style name="Preprocessor" foreground="#f92672"/>
|
||||||
<style name="Label" foreground="#ffff55"/>
|
<style name="Label" foreground="#ffff55"/>
|
||||||
<style name="Comment" foreground="#75715e" italic="true"/>
|
<style name="Comment" foreground="#75715e" italic="true"/>
|
||||||
|
@@ -31,7 +31,9 @@
|
|||||||
<style name="Function" foreground="#839496"/>
|
<style name="Function" foreground="#839496"/>
|
||||||
<style name="Keyword" foreground="#709d06"/>
|
<style name="Keyword" foreground="#709d06"/>
|
||||||
<style name="PrimitiveType" foreground="#808000"/>
|
<style name="PrimitiveType" foreground="#808000"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator" foreground="#839496"/>
|
<style name="Operator" foreground="#839496"/>
|
||||||
|
<style name="Overloaded Operator" foreground="#839496"/>
|
||||||
<style name="Preprocessor" foreground="#cb4b16"/>
|
<style name="Preprocessor" foreground="#cb4b16"/>
|
||||||
<style name="Label" foreground="#268bd2" bold="true"/>
|
<style name="Label" foreground="#268bd2" bold="true"/>
|
||||||
<style name="Comment" foreground="#586e75" italic="true"/>
|
<style name="Comment" foreground="#586e75" italic="true"/>
|
||||||
|
@@ -31,7 +31,9 @@
|
|||||||
<style name="Function" foreground="#657b83"/>
|
<style name="Function" foreground="#657b83"/>
|
||||||
<style name="Keyword" foreground="#709d06"/>
|
<style name="Keyword" foreground="#709d06"/>
|
||||||
<style name="PrimitiveType" foreground="#808000"/>
|
<style name="PrimitiveType" foreground="#808000"/>
|
||||||
|
<style name="Punctuation"/>
|
||||||
<style name="Operator" foreground="#657b83"/>
|
<style name="Operator" foreground="#657b83"/>
|
||||||
|
<style name="Overloaded Operator" foreground="#657b83"/>
|
||||||
<style name="Preprocessor" foreground="#cb4b16"/>
|
<style name="Preprocessor" foreground="#cb4b16"/>
|
||||||
<style name="Label" foreground="#268bd2" bold="true"/>
|
<style name="Label" foreground="#268bd2" bold="true"/>
|
||||||
<style name="Comment" foreground="#93a1a1" italic="true"/>
|
<style name="Comment" foreground="#93a1a1" italic="true"/>
|
||||||
|
@@ -1757,6 +1757,10 @@ Install an SDK of at least API version %1.</source>
|
|||||||
<source>Alt+Shift+T,Alt+A</source>
|
<source>Alt+Shift+T,Alt+A</source>
|
||||||
<translation>Alt+Shift+T,Alt+A</translation>
|
<translation>Alt+Shift+T,Alt+A</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ctrl+Meta+T, Ctrl+Meta+A</source>
|
||||||
|
<translation>Ctrl+Meta+T, Ctrl+Meta+A</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>&Run Selected Tests</source>
|
<source>&Run Selected Tests</source>
|
||||||
<translation>&Запустить выбранные</translation>
|
<translation>&Запустить выбранные</translation>
|
||||||
@@ -1769,6 +1773,10 @@ Install an SDK of at least API version %1.</source>
|
|||||||
<source>Alt+Shift+T,Alt+R</source>
|
<source>Alt+Shift+T,Alt+R</source>
|
||||||
<translation>Alt+Shift+T,Alt+R</translation>
|
<translation>Alt+Shift+T,Alt+R</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ctrl+Meta+T, Ctrl+Meta+R</source>
|
||||||
|
<translation>Ctrl+Meta+T, Ctrl+Meta+R</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Run Tests for Current &File</source>
|
<source>Run Tests for Current &File</source>
|
||||||
<translation>Запустить тесты для текущего &файла</translation>
|
<translation>Запустить тесты для текущего &файла</translation>
|
||||||
@@ -1781,6 +1789,10 @@ Install an SDK of at least API version %1.</source>
|
|||||||
<source>Alt+Shift+T,Alt+F</source>
|
<source>Alt+Shift+T,Alt+F</source>
|
||||||
<translation>Alt+Shift+T,Alt+F</translation>
|
<translation>Alt+Shift+T,Alt+F</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ctrl+Meta+T, Ctrl+Meta+F</source>
|
||||||
|
<translation>Ctrl+Meta+T, Ctrl+Meta+F</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Re&scan Tests</source>
|
<source>Re&scan Tests</source>
|
||||||
<translation>&Пересканировать</translation>
|
<translation>&Пересканировать</translation>
|
||||||
@@ -1789,6 +1801,10 @@ Install an SDK of at least API version %1.</source>
|
|||||||
<source>Alt+Shift+T,Alt+S</source>
|
<source>Alt+Shift+T,Alt+S</source>
|
||||||
<translation>Alt+Shift+T,Alt+S</translation>
|
<translation>Alt+Shift+T,Alt+S</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ctrl+Meta+T, Ctrl+Meta+S</source>
|
||||||
|
<translation>Ctrl+Meta+T, Ctrl+Meta+S</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>&Run Test Under Cursor</source>
|
<source>&Run Test Under Cursor</source>
|
||||||
<translation>&Запустить тест под курсором</translation>
|
<translation>&Запустить тест под курсором</translation>
|
||||||
@@ -11195,7 +11211,7 @@ Flags: %3</source>
|
|||||||
<name>CppTools::TidyChecksTreeModel</name>
|
<name>CppTools::TidyChecksTreeModel</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Web Page</source>
|
<source>Web Page</source>
|
||||||
<translation>Вэб-страница</translation>
|
<translation>Веб-страница</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -13312,7 +13328,7 @@ Affected are breakpoints %1</source>
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Start Debugging Without Deployment</source>
|
<source>Start Debugging Without Deployment</source>
|
||||||
<translation>Начать отладку с установкой</translation>
|
<translation>Начать отладку без установки</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Start and Debug External Application...</source>
|
<source>Start and Debug External Application...</source>
|
||||||
@@ -26820,6 +26836,10 @@ to project "%2".</source>
|
|||||||
<source>Alt+Shift+L</source>
|
<source>Alt+Shift+L</source>
|
||||||
<translation>Alt+Shift+L</translation>
|
<translation>Alt+Shift+L</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Meta+Shift+L</source>
|
||||||
|
<translation>Meta+Shift+L</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Hide Empty Directories</source>
|
<source>Hide Empty Directories</source>
|
||||||
<translation>Скрывать пустые каталоги</translation>
|
<translation>Скрывать пустые каталоги</translation>
|
||||||
@@ -36383,7 +36403,7 @@ For more details, see /etc/sysctl.d/10-ptrace.conf
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Classes for displaying and editing Web content</source>
|
<source>Classes for displaying and editing Web content</source>
|
||||||
<translation>Классы для отображения и правки вэб-страниц</translation>
|
<translation>Классы для отображения и правки веб-страниц</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>WebKit1 and QWidget-based classes from Qt 4 (Qt 5)</source>
|
<source>WebKit1 and QWidget-based classes from Qt 4 (Qt 5)</source>
|
||||||
@@ -45318,6 +45338,10 @@ should a repository require SSH-authentication (see documentation on SSH and the
|
|||||||
<source>No executable to deploy found in %1.</source>
|
<source>No executable to deploy found in %1.</source>
|
||||||
<translation>В %1 не обнаружен исполняемый файл для установки.</translation>
|
<translation>В %1 не обнаружен исполняемый файл для установки.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Cannot find windeployqt.exe in "%1".</source>
|
||||||
|
<translation>Не удалось найти windeployqt.exe в «%1».</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Cannot parse manifest file %1.</source>
|
<source>Cannot parse manifest file %1.</source>
|
||||||
<translation>Не удалось разобрать файл манифеста %1.</translation>
|
<translation>Не удалось разобрать файл манифеста %1.</translation>
|
||||||
|
142
src/libs/3rdparty/botan/configure.py
vendored
142
src/libs/3rdparty/botan/configure.py
vendored
@@ -276,7 +276,7 @@ class BuildPaths(object): # pylint: disable=too-many-instance-attributes
|
|||||||
else:
|
else:
|
||||||
raise InternalError("Unknown src info type '%s'" % (typ))
|
raise InternalError("Unknown src info type '%s'" % (typ))
|
||||||
|
|
||||||
def process_command_line(args): # pylint: disable=too-many-locals
|
def process_command_line(args): # pylint: disable=too-many-locals,too-many-statements
|
||||||
"""
|
"""
|
||||||
Handle command line options
|
Handle command line options
|
||||||
Do not use logging in this method as command line options need to be
|
Do not use logging in this method as command line options need to be
|
||||||
@@ -469,6 +469,9 @@ def process_command_line(args): # pylint: disable=too-many-locals
|
|||||||
build_group.add_option('--with-debug-asserts', action='store_true', default=False,
|
build_group.add_option('--with-debug-asserts', action='store_true', default=False,
|
||||||
help=optparse.SUPPRESS_HELP)
|
help=optparse.SUPPRESS_HELP)
|
||||||
|
|
||||||
|
build_group.add_option('--ack-vc2013-deprecated', action='store_true', default=False,
|
||||||
|
help=optparse.SUPPRESS_HELP)
|
||||||
|
|
||||||
docs_group = optparse.OptionGroup(parser, 'Documentation Options')
|
docs_group = optparse.OptionGroup(parser, 'Documentation Options')
|
||||||
|
|
||||||
docs_group.add_option('--with-documentation', action='store_true',
|
docs_group.add_option('--with-documentation', action='store_true',
|
||||||
@@ -520,7 +523,7 @@ def process_command_line(args): # pylint: disable=too-many-locals
|
|||||||
help='minimize build')
|
help='minimize build')
|
||||||
|
|
||||||
# Should be derived from info.txt but this runs too early
|
# Should be derived from info.txt but this runs too early
|
||||||
third_party = ['bearssl', 'boost', 'bzip2', 'lzma', 'openssl', 'sqlite3', 'zlib', 'tpm']
|
third_party = ['bearssl', 'boost', 'bzip2', 'lzma', 'openssl', 'commoncrypto', 'sqlite3', 'zlib', 'tpm']
|
||||||
|
|
||||||
for mod in third_party:
|
for mod in third_party:
|
||||||
mods_group.add_option('--with-%s' % (mod),
|
mods_group.add_option('--with-%s' % (mod),
|
||||||
@@ -754,6 +757,7 @@ class ModuleInfo(InfoObject):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, infofile):
|
def __init__(self, infofile):
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
super(ModuleInfo, self).__init__(infofile)
|
super(ModuleInfo, self).__init__(infofile)
|
||||||
lex = lex_me_harder(
|
lex = lex_me_harder(
|
||||||
infofile,
|
infofile,
|
||||||
@@ -850,7 +854,7 @@ class ModuleInfo(InfoObject):
|
|||||||
for key, value in defines.items():
|
for key, value in defines.items():
|
||||||
if not re.match('^[0-9A-Za-z_]{3,30}$', key):
|
if not re.match('^[0-9A-Za-z_]{3,30}$', key):
|
||||||
raise InternalError('Module defines key has invalid format: "%s"' % key)
|
raise InternalError('Module defines key has invalid format: "%s"' % key)
|
||||||
if not re.match('^[0-9]{8}$', value):
|
if not re.match('^20[0-9]{6}$', value):
|
||||||
raise InternalError('Module defines value has invalid format: "%s"' % value)
|
raise InternalError('Module defines value has invalid format: "%s"' % value)
|
||||||
|
|
||||||
def cross_check(self, arch_info, cc_info, all_os_features):
|
def cross_check(self, arch_info, cc_info, all_os_features):
|
||||||
@@ -959,7 +963,7 @@ class ModuleInfo(InfoObject):
|
|||||||
def dependencies(self, osinfo):
|
def dependencies(self, osinfo):
|
||||||
# base is an implicit dep for all submodules
|
# base is an implicit dep for all submodules
|
||||||
deps = ['base']
|
deps = ['base']
|
||||||
if self.parent_module != None:
|
if self.parent_module is not None:
|
||||||
deps.append(self.parent_module)
|
deps.append(self.parent_module)
|
||||||
|
|
||||||
for req in self.requires:
|
for req in self.requires:
|
||||||
@@ -1173,22 +1177,22 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
|
|||||||
return self.visibility_attribute
|
return self.visibility_attribute
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def mach_abi_link_flags(self, options, with_debug_info=None):
|
def mach_abi_link_flags(self, options, debug_mode=None):
|
||||||
#pylint: disable=too-many-branches
|
#pylint: disable=too-many-branches
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Return the machine specific ABI flags
|
Return the machine specific ABI flags
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if with_debug_info is None:
|
if debug_mode is None:
|
||||||
with_debug_info = options.with_debug_info
|
debug_mode = options.debug_mode
|
||||||
|
|
||||||
def mach_abi_groups():
|
def mach_abi_groups():
|
||||||
|
|
||||||
yield 'all'
|
yield 'all'
|
||||||
|
|
||||||
if options.msvc_runtime is None:
|
if options.msvc_runtime is None:
|
||||||
if with_debug_info:
|
if debug_mode:
|
||||||
yield 'rt-debug'
|
yield 'rt-debug'
|
||||||
else:
|
else:
|
||||||
yield 'rt'
|
yield 'rt'
|
||||||
@@ -1205,7 +1209,7 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
|
|||||||
for what in mach_abi_groups():
|
for what in mach_abi_groups():
|
||||||
if what in self.mach_abi_linking:
|
if what in self.mach_abi_linking:
|
||||||
flag = self.mach_abi_linking.get(what)
|
flag = self.mach_abi_linking.get(what)
|
||||||
if flag != None and flag != '' and flag not in abi_link:
|
if flag is not None and flag != '' and flag not in abi_link:
|
||||||
abi_link.add(flag)
|
abi_link.add(flag)
|
||||||
|
|
||||||
if options.msvc_runtime:
|
if options.msvc_runtime:
|
||||||
@@ -1418,7 +1422,7 @@ class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def building_shared_supported(self):
|
def building_shared_supported(self):
|
||||||
return self.soname_pattern_base != None
|
return self.soname_pattern_base is not None
|
||||||
|
|
||||||
def enabled_features(self, options):
|
def enabled_features(self, options):
|
||||||
feats = []
|
feats = []
|
||||||
@@ -1466,7 +1470,7 @@ def guess_processor(archinfo):
|
|||||||
for info_part in system_cpu_info():
|
for info_part in system_cpu_info():
|
||||||
if info_part:
|
if info_part:
|
||||||
match = canon_processor(archinfo, info_part)
|
match = canon_processor(archinfo, info_part)
|
||||||
if match != None:
|
if match is not None:
|
||||||
logging.debug("Matched '%s' to processor '%s'" % (info_part, match))
|
logging.debug("Matched '%s' to processor '%s'" % (info_part, match))
|
||||||
return match, info_part
|
return match, info_part
|
||||||
else:
|
else:
|
||||||
@@ -1727,13 +1731,13 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
|
|||||||
"""
|
"""
|
||||||
Figure out what external libraries/frameworks are needed based on selected modules
|
Figure out what external libraries/frameworks are needed based on selected modules
|
||||||
"""
|
"""
|
||||||
if not (module_member_name == 'libs' or module_member_name == 'frameworks'):
|
if module_member_name not in ['libs', 'frameworks']:
|
||||||
raise InternalError("Invalid argument")
|
raise InternalError("Invalid argument")
|
||||||
|
|
||||||
libs = set()
|
libs = set()
|
||||||
for module in modules:
|
for module in modules:
|
||||||
for (osname, module_link_to) in getattr(module, module_member_name).items():
|
for (osname, module_link_to) in getattr(module, module_member_name).items():
|
||||||
if osname == 'all' or osname == osinfo.basename:
|
if osname in ['all', osinfo.basename]:
|
||||||
libs |= set(module_link_to)
|
libs |= set(module_link_to)
|
||||||
else:
|
else:
|
||||||
match = re.match('^all!(.*)', osname)
|
match = re.match('^all!(.*)', osname)
|
||||||
@@ -1787,7 +1791,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
|
|||||||
return osinfo.ar_command
|
return osinfo.ar_command
|
||||||
|
|
||||||
def choose_endian(arch_info, options):
|
def choose_endian(arch_info, options):
|
||||||
if options.with_endian != None:
|
if options.with_endian is not None:
|
||||||
return options.with_endian
|
return options.with_endian
|
||||||
|
|
||||||
if options.cpu.endswith('eb') or options.cpu.endswith('be'):
|
if options.cpu.endswith('eb') or options.cpu.endswith('be'):
|
||||||
@@ -1795,7 +1799,8 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
|
|||||||
elif options.cpu.endswith('el') or options.cpu.endswith('le'):
|
elif options.cpu.endswith('el') or options.cpu.endswith('le'):
|
||||||
return 'little'
|
return 'little'
|
||||||
|
|
||||||
logging.info('Defaulting to assuming %s endian', arch_info.endian)
|
if arch_info.endian:
|
||||||
|
logging.info('Defaulting to assuming %s endian', arch_info.endian)
|
||||||
return arch_info.endian
|
return arch_info.endian
|
||||||
|
|
||||||
build_dir = options.with_build_dir or os.path.curdir
|
build_dir = options.with_build_dir or os.path.curdir
|
||||||
@@ -1863,6 +1868,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
|
|||||||
'with_rst2man': options.with_rst2man,
|
'with_rst2man': options.with_rst2man,
|
||||||
'sphinx_config_dir': source_paths.sphinx_config_dir,
|
'sphinx_config_dir': source_paths.sphinx_config_dir,
|
||||||
'with_doxygen': options.with_doxygen,
|
'with_doxygen': options.with_doxygen,
|
||||||
|
'maintainer_mode': options.maintainer_mode,
|
||||||
|
|
||||||
'out_dir': build_dir,
|
'out_dir': build_dir,
|
||||||
'build_dir': build_paths.build_dir,
|
'build_dir': build_paths.build_dir,
|
||||||
@@ -1968,6 +1974,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
|
|||||||
'with_openmp': options.with_openmp,
|
'with_openmp': options.with_openmp,
|
||||||
'with_debug_asserts': options.with_debug_asserts,
|
'with_debug_asserts': options.with_debug_asserts,
|
||||||
'test_mode': options.test_mode,
|
'test_mode': options.test_mode,
|
||||||
|
'optimize_for_size': options.optimize_for_size,
|
||||||
|
|
||||||
'mod_list': sorted([m.basename for m in modules])
|
'mod_list': sorted([m.basename for m in modules])
|
||||||
}
|
}
|
||||||
@@ -1980,15 +1987,15 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
|
|||||||
variables['static_suffix'])
|
variables['static_suffix'])
|
||||||
|
|
||||||
if options.build_shared_lib:
|
if options.build_shared_lib:
|
||||||
if osinfo.soname_pattern_base != None:
|
if osinfo.soname_pattern_base is not None:
|
||||||
variables['soname_base'] = osinfo.soname_pattern_base.format(**variables)
|
variables['soname_base'] = osinfo.soname_pattern_base.format(**variables)
|
||||||
variables['shared_lib_name'] = variables['soname_base']
|
variables['shared_lib_name'] = variables['soname_base']
|
||||||
|
|
||||||
if osinfo.soname_pattern_abi != None:
|
if osinfo.soname_pattern_abi is not None:
|
||||||
variables['soname_abi'] = osinfo.soname_pattern_abi.format(**variables)
|
variables['soname_abi'] = osinfo.soname_pattern_abi.format(**variables)
|
||||||
variables['shared_lib_name'] = variables['soname_abi']
|
variables['shared_lib_name'] = variables['soname_abi']
|
||||||
|
|
||||||
if osinfo.soname_pattern_patch != None:
|
if osinfo.soname_pattern_patch is not None:
|
||||||
variables['soname_patch'] = osinfo.soname_pattern_patch.format(**variables)
|
variables['soname_patch'] = osinfo.soname_pattern_patch.format(**variables)
|
||||||
|
|
||||||
variables['lib_link_cmd'] = variables['lib_link_cmd'].format(**variables)
|
variables['lib_link_cmd'] = variables['lib_link_cmd'].format(**variables)
|
||||||
@@ -2035,15 +2042,15 @@ class ModulesChooser(object):
|
|||||||
self._modules, self._options.enabled_modules, self._options.disabled_modules)
|
self._modules, self._options.enabled_modules, self._options.disabled_modules)
|
||||||
|
|
||||||
def _check_usable(self, module, modname):
|
def _check_usable(self, module, modname):
|
||||||
if not module.compatible_os(self._osinfo, self._options):
|
if not module.compatible_cpu(self._archinfo, self._options):
|
||||||
|
self._not_using_because['incompatible CPU'].add(modname)
|
||||||
|
return False
|
||||||
|
elif not module.compatible_os(self._osinfo, self._options):
|
||||||
self._not_using_because['incompatible OS'].add(modname)
|
self._not_using_because['incompatible OS'].add(modname)
|
||||||
return False
|
return False
|
||||||
elif not module.compatible_compiler(self._ccinfo, self._cc_min_version, self._archinfo.basename):
|
elif not module.compatible_compiler(self._ccinfo, self._cc_min_version, self._archinfo.basename):
|
||||||
self._not_using_because['incompatible compiler'].add(modname)
|
self._not_using_because['incompatible compiler'].add(modname)
|
||||||
return False
|
return False
|
||||||
elif not module.compatible_cpu(self._archinfo, self._options):
|
|
||||||
self._not_using_because['incompatible CPU'].add(modname)
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -2265,11 +2272,13 @@ def choose_link_method(options):
|
|||||||
# Symbolic link support on Windows was introduced in Windows 6.0 (Vista) and Python 3.2
|
# Symbolic link support on Windows was introduced in Windows 6.0 (Vista) and Python 3.2
|
||||||
# Furthermore the SeCreateSymbolicLinkPrivilege is required in order to successfully create symlinks
|
# Furthermore the SeCreateSymbolicLinkPrivilege is required in order to successfully create symlinks
|
||||||
# So only try to use symlinks on Windows if explicitly requested
|
# So only try to use symlinks on Windows if explicitly requested
|
||||||
if req == 'symlink' and options.os == 'windows':
|
|
||||||
yield 'symlink'
|
if options.os in ['windows', 'mingw', 'cygwin']:
|
||||||
# otherwise keep old conservative behavior
|
if req == 'symlink':
|
||||||
if 'symlink' in os.__dict__ and options.os != 'windows':
|
yield 'symlink'
|
||||||
|
elif 'symlink' in os.__dict__:
|
||||||
yield 'symlink'
|
yield 'symlink'
|
||||||
|
|
||||||
if 'link' in os.__dict__:
|
if 'link' in os.__dict__:
|
||||||
yield 'hardlink'
|
yield 'hardlink'
|
||||||
yield 'copy'
|
yield 'copy'
|
||||||
@@ -2352,16 +2361,10 @@ class AmalgamationHeader(object):
|
|||||||
self.included_already = set()
|
self.included_already = set()
|
||||||
self.all_std_includes = set()
|
self.all_std_includes = set()
|
||||||
|
|
||||||
encoding_kwords = {}
|
|
||||||
if sys.version_info[0] == 3:
|
|
||||||
encoding_kwords['encoding'] = 'utf8'
|
|
||||||
|
|
||||||
self.file_contents = {}
|
self.file_contents = {}
|
||||||
for filepath in sorted(input_filepaths):
|
for filepath in sorted(input_filepaths):
|
||||||
try:
|
try:
|
||||||
with open(filepath, **encoding_kwords) as f:
|
contents = AmalgamationGenerator.read_header(filepath)
|
||||||
raw_content = f.readlines()
|
|
||||||
contents = AmalgamationGenerator.strip_header_goop(filepath, raw_content)
|
|
||||||
self.file_contents[os.path.basename(filepath)] = contents
|
self.file_contents[os.path.basename(filepath)] = contents
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
logging.error('Error processing file %s for amalgamation: %s' % (filepath, e))
|
logging.error('Error processing file %s for amalgamation: %s' % (filepath, e))
|
||||||
@@ -2438,6 +2441,15 @@ class AmalgamationGenerator(object):
|
|||||||
|
|
||||||
_header_guard_pattern = re.compile('^#define BOTAN_.*_H_$')
|
_header_guard_pattern = re.compile('^#define BOTAN_.*_H_$')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def read_header(filepath):
|
||||||
|
encoding_kwords = {}
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
|
encoding_kwords['encoding'] = 'utf8'
|
||||||
|
with open(filepath, **encoding_kwords) as f:
|
||||||
|
raw_content = f.readlines()
|
||||||
|
return AmalgamationGenerator.strip_header_goop(filepath, raw_content)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def strip_header_goop(header_name, header_lines):
|
def strip_header_goop(header_name, header_lines):
|
||||||
lines = copy.copy(header_lines) # defensive copy
|
lines = copy.copy(header_lines) # defensive copy
|
||||||
@@ -2505,16 +2517,32 @@ class AmalgamationGenerator(object):
|
|||||||
logging.info('Writing amalgamation header to %s' % (header_name))
|
logging.info('Writing amalgamation header to %s' % (header_name))
|
||||||
pub_header_amalag.write_to_file(header_name, "BOTAN_AMALGAMATION_H_")
|
pub_header_amalag.write_to_file(header_name, "BOTAN_AMALGAMATION_H_")
|
||||||
|
|
||||||
internal_headers = AmalgamationHeader(self._build_paths.internal_headers)
|
isa_headers = {}
|
||||||
|
internal_headers = []
|
||||||
|
|
||||||
|
def known_isa_header(hdr):
|
||||||
|
if hdr == 'simd_avx2.h':
|
||||||
|
return 'avx2'
|
||||||
|
return None
|
||||||
|
|
||||||
|
for hdr in self._build_paths.internal_headers:
|
||||||
|
isa = known_isa_header(os.path.basename(hdr))
|
||||||
|
if isa:
|
||||||
|
isa_headers[isa] = ''.join(AmalgamationGenerator.read_header(hdr))
|
||||||
|
else:
|
||||||
|
internal_headers.append(hdr)
|
||||||
|
|
||||||
|
internal_headers = AmalgamationHeader(internal_headers)
|
||||||
header_int_name = '%s_internal.h' % (AmalgamationGenerator.filename_prefix)
|
header_int_name = '%s_internal.h' % (AmalgamationGenerator.filename_prefix)
|
||||||
logging.info('Writing amalgamation header to %s' % (header_int_name))
|
logging.info('Writing amalgamation header to %s' % (header_int_name))
|
||||||
internal_headers.write_to_file(header_int_name, "BOTAN_AMALGAMATION_INTERNAL_H_")
|
internal_headers.write_to_file(header_int_name, "BOTAN_AMALGAMATION_INTERNAL_H_")
|
||||||
|
|
||||||
header_files = [header_name, header_int_name]
|
header_files = [header_name, header_int_name]
|
||||||
included_in_headers = pub_header_amalag.all_std_includes | internal_headers.all_std_includes
|
included_in_headers = pub_header_amalag.all_std_includes | internal_headers.all_std_includes
|
||||||
return header_files, included_in_headers
|
return header_files, included_in_headers, isa_headers
|
||||||
|
|
||||||
def _generate_sources(self, amalgamation_headers, included_in_headers): #pylint: disable=too-many-locals,too-many-branches
|
def _generate_sources(self, amalgamation_headers, included_in_headers, isa_headers):
|
||||||
|
#pylint: disable=too-many-locals,too-many-branches
|
||||||
encoding_kwords = {}
|
encoding_kwords = {}
|
||||||
if sys.version_info[0] == 3:
|
if sys.version_info[0] == 3:
|
||||||
encoding_kwords['encoding'] = 'utf8'
|
encoding_kwords['encoding'] = 'utf8'
|
||||||
@@ -2533,6 +2561,14 @@ class AmalgamationGenerator(object):
|
|||||||
logging.info('Writing amalgamation source to %s' % (filepath))
|
logging.info('Writing amalgamation source to %s' % (filepath))
|
||||||
amalgamation_files[target] = open(filepath, 'w', **encoding_kwords)
|
amalgamation_files[target] = open(filepath, 'w', **encoding_kwords)
|
||||||
|
|
||||||
|
def gcc_isa(isa):
|
||||||
|
if isa == 'sse41':
|
||||||
|
return 'sse4.1'
|
||||||
|
elif isa == 'sse42':
|
||||||
|
return 'ssse4.2'
|
||||||
|
else:
|
||||||
|
return isa
|
||||||
|
|
||||||
for target, f in amalgamation_files.items():
|
for target, f in amalgamation_files.items():
|
||||||
AmalgamationHeader.write_banner(f)
|
AmalgamationHeader.write_banner(f)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
@@ -2542,13 +2578,11 @@ class AmalgamationGenerator(object):
|
|||||||
|
|
||||||
for isa in self._isas_for_target(target):
|
for isa in self._isas_for_target(target):
|
||||||
|
|
||||||
if isa == 'sse41':
|
if isa in isa_headers:
|
||||||
isa = 'sse4.1'
|
f.write(isa_headers[isa])
|
||||||
elif isa == 'sse42':
|
|
||||||
isa = 'ssse4.2'
|
|
||||||
|
|
||||||
f.write('#if defined(__GNUG__) && !defined(__clang__)\n')
|
f.write('#if defined(__GNUG__) && !defined(__clang__)\n')
|
||||||
f.write('#pragma GCC target ("%s")\n' % (isa))
|
f.write('#pragma GCC target ("%s")\n' % (gcc_isa(isa)))
|
||||||
f.write('#endif\n')
|
f.write('#endif\n')
|
||||||
|
|
||||||
# target to include header map
|
# target to include header map
|
||||||
@@ -2580,8 +2614,8 @@ class AmalgamationGenerator(object):
|
|||||||
return set(amalgamation_sources.values())
|
return set(amalgamation_sources.values())
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
amalgamation_headers, included_in_headers = self._generate_headers()
|
amalgamation_headers, included_in_headers, isa_headers = self._generate_headers()
|
||||||
amalgamation_sources = self._generate_sources(amalgamation_headers, included_in_headers)
|
amalgamation_sources = self._generate_sources(amalgamation_headers, included_in_headers, isa_headers)
|
||||||
return (sorted(amalgamation_sources), sorted(amalgamation_headers))
|
return (sorted(amalgamation_sources), sorted(amalgamation_headers))
|
||||||
|
|
||||||
|
|
||||||
@@ -2712,7 +2746,7 @@ def set_defaults_for_unset_options(options, info_arch, info_cc): # pylint: disab
|
|||||||
return 'gcc'
|
return 'gcc'
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if options.compiler is None and options.compiler_binary != None:
|
if options.compiler is None and options.compiler_binary is not None:
|
||||||
options.compiler = deduce_compiler_type_from_cc_bin(options.compiler_binary)
|
options.compiler = deduce_compiler_type_from_cc_bin(options.compiler_binary)
|
||||||
|
|
||||||
if options.compiler is None:
|
if options.compiler is None:
|
||||||
@@ -2836,7 +2870,7 @@ def validate_options(options, info_os, info_cc, available_module_policies):
|
|||||||
if options.os != options.cpu:
|
if options.os != options.cpu:
|
||||||
raise UserError('LLVM target requires both CPU and OS be set to llvm')
|
raise UserError('LLVM target requires both CPU and OS be set to llvm')
|
||||||
|
|
||||||
if options.build_fuzzers != None:
|
if options.build_fuzzers is not None:
|
||||||
if options.build_fuzzers not in ['libfuzzer', 'afl', 'klee', 'test']:
|
if options.build_fuzzers not in ['libfuzzer', 'afl', 'klee', 'test']:
|
||||||
raise UserError('Bad value to --build-fuzzers')
|
raise UserError('Bad value to --build-fuzzers')
|
||||||
|
|
||||||
@@ -2932,7 +2966,10 @@ def calculate_cc_min_version(options, ccinfo, source_paths):
|
|||||||
|
|
||||||
if ccinfo.basename == 'msvc':
|
if ccinfo.basename == 'msvc':
|
||||||
if major_version == 18:
|
if major_version == 18:
|
||||||
logging.warning('MSVC 2013 support is deprecated and will be removed in a future release')
|
logging.warning('MSVC 2013 support is deprecated, and will be removed in Jan 2019')
|
||||||
|
if not options.ack_vc2013_deprecated:
|
||||||
|
logging.error('Acknowledge this deprecation by adding flag --ack-vc2013-deprecated')
|
||||||
|
|
||||||
return cc_version
|
return cc_version
|
||||||
|
|
||||||
def check_compiler_arch(options, ccinfo, archinfo, source_paths):
|
def check_compiler_arch(options, ccinfo, archinfo, source_paths):
|
||||||
@@ -2941,7 +2978,10 @@ def check_compiler_arch(options, ccinfo, archinfo, source_paths):
|
|||||||
abi_flags = ccinfo.mach_abi_link_flags(options).split(' ')
|
abi_flags = ccinfo.mach_abi_link_flags(options).split(' ')
|
||||||
cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, 'UNKNOWN', abi_flags).lower()
|
cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, 'UNKNOWN', abi_flags).lower()
|
||||||
|
|
||||||
if cc_output in ['', 'unknown']:
|
if cc_output == '':
|
||||||
|
cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, 'UNKNOWN').lower()
|
||||||
|
|
||||||
|
if cc_output == 'unknown':
|
||||||
logging.warning('Unable to detect target architecture via compiler macro checks')
|
logging.warning('Unable to detect target architecture via compiler macro checks')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -2954,7 +2994,7 @@ def check_compiler_arch(options, ccinfo, archinfo, source_paths):
|
|||||||
return cc_output
|
return cc_output
|
||||||
|
|
||||||
def do_io_for_build(cc, arch, osinfo, using_mods, build_paths, source_paths, template_vars, options):
|
def do_io_for_build(cc, arch, osinfo, using_mods, build_paths, source_paths, template_vars, options):
|
||||||
# pylint: disable=too-many-locals,too-many-branches
|
# pylint: disable=too-many-locals,too-many-branches,too-many-statements
|
||||||
|
|
||||||
try:
|
try:
|
||||||
robust_rmtree(build_paths.build_dir)
|
robust_rmtree(build_paths.build_dir)
|
||||||
@@ -3165,10 +3205,8 @@ if __name__ == '__main__':
|
|||||||
logging.error("""%s
|
logging.error("""%s
|
||||||
An internal error occurred.
|
An internal error occurred.
|
||||||
|
|
||||||
Don't panic, this is probably not your fault!
|
Don't panic, this is probably not your fault! Please open an issue
|
||||||
|
with the entire output at https://github.com/randombit/botan
|
||||||
Please report the entire output at https://github.com/randombit/botan or email
|
|
||||||
to the mailing list https://lists.randombit.net/mailman/listinfo/botan-devel
|
|
||||||
|
|
||||||
You'll meet friendly people happy to help!""" % traceback.format_exc())
|
You'll meet friendly people happy to help!""" % traceback.format_exc())
|
||||||
|
|
||||||
|
134
src/libs/3rdparty/botan/readme.rst
vendored
134
src/libs/3rdparty/botan/readme.rst
vendored
@@ -1,50 +1,36 @@
|
|||||||
Botan: Crypto and TLS for C++11
|
Botan: Crypto and TLS for Modern C++
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
Botan (Japanese for peony) is a cryptography library written in C++11
|
Botan (Japanese for peony flower) is a C++ cryptography library released under the
|
||||||
and released under the permissive `Simplified BSD
|
permissive `Simplified BSD <https://botan.randombit.net/license.txt>`_ license.
|
||||||
<https://botan.randombit.net/license.txt>`_ license.
|
|
||||||
|
|
||||||
Botan's goal is to be the best option for cryptography in C++ by offering the
|
Botan's goal is to be the best option for cryptography in C++ by offering the
|
||||||
tools necessary to implement a range of practical systems, such as TLS/DTLS,
|
tools necessary to implement a range of practical systems, such as TLS protocol,
|
||||||
X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support,
|
X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support,
|
||||||
password hashing, and post quantum crypto schemes. Botan also has a C89 API
|
password hashing, and post quantum crypto schemes.
|
||||||
specifically designed to be easy to call from other languages. A Python binding
|
See the `documentation <https://botan.randombit.net/manual>`_ for more information.
|
||||||
using ctypes is included, and several other `language bindings
|
|
||||||
|
A Python binding is included, and several other `language bindings
|
||||||
<https://github.com/randombit/botan/wiki/Language-Bindings>`_ are available.
|
<https://github.com/randombit/botan/wiki/Language-Bindings>`_ are available.
|
||||||
Find the full feature list below.
|
|
||||||
|
|
||||||
Development is coordinated on `GitHub <https://github.com/randombit/botan>`_
|
Development is coordinated on `GitHub <https://github.com/randombit/botan>`_
|
||||||
and contributions are welcome (read `doc/contributing.rst` for more info).
|
and contributions are welcome. If you need help, please open an issue on
|
||||||
|
`GitHub <https://github.com/randombit/botan/issues>`_ or email the
|
||||||
If you need help with a problem, please open an `issue on GitHub
|
`botan-devel mailing list <https://lists.randombit.net/mailman/listinfo/botan-devel/>`_.
|
||||||
<https://github.com/randombit/botan/issues>`_ or email the
|
New releases are announced on the `botan-announce mailing list
|
||||||
`botan-devel mailing list
|
|
||||||
<https://lists.randombit.net/mailman/listinfo/botan-devel/>`_.
|
|
||||||
|
|
||||||
New releases are announced on the
|
|
||||||
`botan-announce mailing list
|
|
||||||
<https://lists.randombit.net/mailman/listinfo/botan-announce/>`_.
|
<https://lists.randombit.net/mailman/listinfo/botan-announce/>`_.
|
||||||
|
If you think you have found a security issue, see the `security page
|
||||||
|
<https://botan.randombit.net/security.html>`_ for contact information.
|
||||||
|
|
||||||
If you think you have found a security bug in Botan please contact
|
The latest release is
|
||||||
Jack Lloyd by emailing jack@randombit.net. His PGP public key with
|
`2.8.0 <https://botan.randombit.net/releases/Botan-2.8.0.tgz>`_
|
||||||
fingerprint 4E60C73551AF2188DF0A5A6278E9804357123B60 can can be found
|
`(sig) <https://botan.randombit.net/releases/Botan-2.8.0.tgz.asc>`_,
|
||||||
in ``doc/pgpkey.txt`` in the distribution,
|
released on 2018-10-01.
|
||||||
https://keybase.io/jacklloyd, and some public PGP key servers.
|
All releases are signed with a `PGP key <https://botan.randombit.net/pgpkey.txt>`_.
|
||||||
|
See the `release notes <https://botan.randombit.net/news.html>`_ for
|
||||||
.. highlight:: none
|
what is new. Botan is also available through most
|
||||||
|
`distributions <https://github.com/randombit/botan/wiki/Distros>`_
|
||||||
For all the details on building the library, read the
|
such as Fedora, Debian, Arch and Homebrew.
|
||||||
`users manual <https://botan.randombit.net/manual>`_, but basically::
|
|
||||||
|
|
||||||
$ ./configure.py
|
|
||||||
$ make
|
|
||||||
$ ./botan-test
|
|
||||||
...
|
|
||||||
$ make install
|
|
||||||
|
|
||||||
Botan can also be built into a single-file amalgamation for easy inclusion into
|
|
||||||
external build systems, see the manual for details.
|
|
||||||
|
|
||||||
.. image:: https://travis-ci.org/randombit/botan.svg?branch=master
|
.. image:: https://travis-ci.org/randombit/botan.svg?branch=master
|
||||||
:target: https://travis-ci.org/randombit/botan
|
:target: https://travis-ci.org/randombit/botan
|
||||||
@@ -66,55 +52,10 @@ external build systems, see the manual for details.
|
|||||||
:target: https://scan.coverity.com/projects/624
|
:target: https://scan.coverity.com/projects/624
|
||||||
:alt: Coverity results
|
:alt: Coverity results
|
||||||
|
|
||||||
.. image:: https://sonarcloud.io/api/project_badges/measure?project=botan&metric=ncloc
|
|
||||||
:target: https://sonarcloud.io/dashboard/index/botan
|
|
||||||
:alt: Sonarcloud analysis
|
|
||||||
|
|
||||||
.. image:: https://bestpractices.coreinfrastructure.org/projects/531/badge
|
.. image:: https://bestpractices.coreinfrastructure.org/projects/531/badge
|
||||||
:target: https://bestpractices.coreinfrastructure.org/projects/531
|
:target: https://bestpractices.coreinfrastructure.org/projects/531
|
||||||
:alt: CII Best Practices statement
|
:alt: CII Best Practices statement
|
||||||
|
|
||||||
Release Downloads
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
See the `release notes <https://botan.randombit.net/news.html>`_ and
|
|
||||||
`security advisories <https://botan.randombit.net/security.html>`_
|
|
||||||
|
|
||||||
All releases are signed with a
|
|
||||||
`PGP key <https://botan.randombit.net/pgpkey.txt>`_::
|
|
||||||
|
|
||||||
pub 2048R/EFBADFBC 2004-10-30
|
|
||||||
Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC
|
|
||||||
uid Botan Distribution Key
|
|
||||||
|
|
||||||
Some `distributions <https://github.com/randombit/botan/wiki/Distros>`_
|
|
||||||
such as Arch, Fedora and Debian include packages for Botan. However
|
|
||||||
these are often out of date; using the latest source release is recommended.
|
|
||||||
|
|
||||||
Current Stable Release
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
Version 2 requires a C++11 compiler; GCC 4.8 and later, Clang 3.8 and later, and
|
|
||||||
MSVC 2015/2017 are regularly tested. New releases of Botan 2 are made on a
|
|
||||||
quarterly basis.
|
|
||||||
|
|
||||||
The latest 2.x release is
|
|
||||||
`2.7.0 <https://botan.randombit.net/releases/Botan-2.7.0.tgz>`_
|
|
||||||
`(sig) <https://botan.randombit.net/releases/Botan-2.7.0.tgz.asc>`_
|
|
||||||
released on 2018-07-02
|
|
||||||
|
|
||||||
Old Release
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
The 1.10 branch is the last version of the library written in C++98. It is no
|
|
||||||
longer supported except for critical security updates (with all support ending
|
|
||||||
in December 2018), and the developers do not recommend its use anymore.
|
|
||||||
|
|
||||||
The latest 1.10 release is
|
|
||||||
`1.10.17 <https://botan.randombit.net/releases/Botan-1.10.17.tgz>`_
|
|
||||||
`(sig) <https://botan.randombit.net/releases/Botan-1.10.17.tgz.asc>`_
|
|
||||||
released on 2017-10-02
|
|
||||||
|
|
||||||
Find Enclosed
|
Find Enclosed
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -123,8 +64,8 @@ Transport Layer Security (TLS) Protocol
|
|||||||
|
|
||||||
* TLS v1.0, v1.1, and v1.2. The broken SSLv3 protocol is no longer supported.
|
* TLS v1.0, v1.1, and v1.2. The broken SSLv3 protocol is no longer supported.
|
||||||
* DTLS v1.0 and v1.2 are adaptations of TLS to datagram operation.
|
* DTLS v1.0 and v1.2 are adaptations of TLS to datagram operation.
|
||||||
* Extensions include session tickets, SNI, ALPN, OCSP staple requests (client
|
* Supported extensions include session tickets, SNI, ALPN, OCSP stapling,
|
||||||
side only right now), encrypt-then-mac CBC, and extended master secret.
|
encrypt-then-mac CBC, and extended master secret.
|
||||||
* Supports authentication using preshared keys (PSK) or passwords (SRP)
|
* Supports authentication using preshared keys (PSK) or passwords (SRP)
|
||||||
* Supports record encryption with ChaCha20Poly1305, AES/OCB, AES/GCM, AES/CCM,
|
* Supports record encryption with ChaCha20Poly1305, AES/OCB, AES/GCM, AES/CCM,
|
||||||
Camellia/GCM as well as legacy CBC ciphersuites.
|
Camellia/GCM as well as legacy CBC ciphersuites.
|
||||||
@@ -144,7 +85,7 @@ Public Key Cryptography
|
|||||||
|
|
||||||
* RSA signatures and encryption
|
* RSA signatures and encryption
|
||||||
* DH and ECDH key agreement
|
* DH and ECDH key agreement
|
||||||
* Signature schemes ECDSA, DSA, Ed25519, ECGDSA, ECKCDSA, SM2, and GOST 34.10-2001
|
* Signature schemes ECDSA, DSA, Ed25519, ECGDSA, ECKCDSA, SM2, GOST 34.10-2001
|
||||||
* Post-quantum signature scheme XMSS
|
* Post-quantum signature scheme XMSS
|
||||||
* Post-quantum key agreement schemes McEliece and NewHope
|
* Post-quantum key agreement schemes McEliece and NewHope
|
||||||
* ElGamal encryption
|
* ElGamal encryption
|
||||||
@@ -153,17 +94,15 @@ Public Key Cryptography
|
|||||||
Ciphers, hashes, MACs, and checksums
|
Ciphers, hashes, MACs, and checksums
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
* Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, and ChaCha20Poly1305
|
* Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, (X)ChaCha20Poly1305
|
||||||
* Cipher modes CTR, CBC, XTS, CFB, and OFB
|
* Cipher modes CTR, CBC, XTS, CFB, OFB
|
||||||
* Block ciphers AES, ARIA, Blowfish, Camellia, CAST-128, CAST-256,
|
* Block ciphers AES, ARIA, Blowfish, Camellia, CAST-128, DES/3DES, GOST 28147,
|
||||||
DES/3DES, GOST 28147, IDEA, KASUMI, Lion, MISTY1, Noekeon, SEED,
|
IDEA, Lion, Noekeon, SEED, Serpent, SHACAL2, SM4, Threefish-512, Twofish, XTEA
|
||||||
Serpent, SHACAL2, SM4, Threefish-512, Twofish, XTEA
|
* Stream ciphers (X)ChaCha20, (X)Salsa20, SHAKE-128, RC4
|
||||||
* Stream ciphers ChaCha20, Salsa20/XSalsa20, SHAKE-128, and RC4
|
* Hash functions SHA-1, SHA-2, SHA-3, MD4, MD5, RIPEMD-160, BLAKE2b,
|
||||||
* Hash functions SHA-1, SHA-2, SHA-3, RIPEMD-160, Skein-512,
|
Skein-512, SM3, Tiger, Whirlpool, GOST 34.11
|
||||||
BLAKE2b, SM3, Tiger, Whirlpool, GOST 34.11, MD5, MD4
|
* Authentication codes HMAC, CMAC, Poly1305, SipHash, GMAC, X9.19 DES-MAC
|
||||||
* Hash function combiners Parallel and Comb4P
|
* Non-cryptographic checksums Adler32, CRC24, CRC32
|
||||||
* Authentication codes HMAC, CMAC, Poly1305, SipHash, GMAC, CBC-MAC, X9.19 DES-MAC
|
|
||||||
* Non-cryptographic checksums Adler32, CRC24, and CRC32
|
|
||||||
|
|
||||||
Other Useful Things
|
Other Useful Things
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
@@ -173,8 +112,7 @@ Other Useful Things
|
|||||||
* Simple compression API wrapping zlib, bzip2, and lzma libraries
|
* Simple compression API wrapping zlib, bzip2, and lzma libraries
|
||||||
* RNG wrappers for system RNG and hardware RNGs
|
* RNG wrappers for system RNG and hardware RNGs
|
||||||
* HMAC_DRBG and entropy collection system for userspace RNGs
|
* HMAC_DRBG and entropy collection system for userspace RNGs
|
||||||
* Password based key derivation functions PBKDF2 and Scrypt
|
* Password hashing schemes PBKDF2, Scrypt, bcrypt
|
||||||
* Password hashing function bcrypt and passhash9 (custom PBKDF scheme)
|
|
||||||
* SRP-6a password authenticated key exchange
|
* SRP-6a password authenticated key exchange
|
||||||
* Key derivation functions including HKDF, KDF2, SP 800-108, SP 800-56A, SP 800-56C
|
* Key derivation functions including HKDF, KDF2, SP 800-108, SP 800-56A, SP 800-56C
|
||||||
* HOTP and TOTP algorithms
|
* HOTP and TOTP algorithms
|
||||||
|
@@ -12,4 +12,8 @@ armv8-a
|
|||||||
<isa_extensions>
|
<isa_extensions>
|
||||||
neon
|
neon
|
||||||
armv8crypto
|
armv8crypto
|
||||||
|
armv8sm3
|
||||||
|
armv8sm4
|
||||||
|
armv8sha3
|
||||||
|
armv8sha512
|
||||||
</isa_extensions>
|
</isa_extensions>
|
||||||
|
@@ -6,6 +6,7 @@ wordsize 64
|
|||||||
<aliases>
|
<aliases>
|
||||||
powerpc64
|
powerpc64
|
||||||
ppc64le
|
ppc64le
|
||||||
|
ppc64el
|
||||||
</aliases>
|
</aliases>
|
||||||
|
|
||||||
<isa_extensions>
|
<isa_extensions>
|
||||||
|
@@ -1 +1,2 @@
|
|||||||
family riscv
|
family riscv
|
||||||
|
endian little
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
family sparc
|
family sparc
|
||||||
wordsize 64
|
wordsize 64
|
||||||
|
endian big
|
||||||
|
@@ -12,6 +12,7 @@ x86pc # for QNX
|
|||||||
bepc # for Haiku
|
bepc # for Haiku
|
||||||
|
|
||||||
i686
|
i686
|
||||||
|
i586
|
||||||
i386
|
i386
|
||||||
</aliases>
|
</aliases>
|
||||||
|
|
||||||
|
@@ -74,7 +74,10 @@ WARN_IF_DOC_ERROR = YES
|
|||||||
WARN_NO_PARAMDOC = YES
|
WARN_NO_PARAMDOC = YES
|
||||||
WARN_FORMAT = "$file:$line: $text"
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
WARN_LOGFILE =
|
WARN_LOGFILE =
|
||||||
|
|
||||||
|
%{if maintainer_mode}
|
||||||
WARN_AS_ERROR = YES
|
WARN_AS_ERROR = YES
|
||||||
|
%{endif}
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the input files
|
# configuration options related to the input files
|
||||||
@@ -154,14 +157,17 @@ PREDEFINED = BOTAN_HAS_AES_ARMV8 \
|
|||||||
BOTAN_HAS_AES_POWER8 \
|
BOTAN_HAS_AES_POWER8 \
|
||||||
BOTAN_HAS_AES_SSSE3 \
|
BOTAN_HAS_AES_SSSE3 \
|
||||||
BOTAN_HAS_CHACHA_SSE2 \
|
BOTAN_HAS_CHACHA_SSE2 \
|
||||||
|
BOTAN_HAS_CHACHA_AVX2 \
|
||||||
BOTAN_HAS_IDEA_SSE2 \
|
BOTAN_HAS_IDEA_SSE2 \
|
||||||
BOTAN_HAS_NOEKEON_SIMD \
|
BOTAN_HAS_NOEKEON_SIMD \
|
||||||
BOTAN_HAS_SERPENT_SIMD \
|
BOTAN_HAS_SERPENT_SIMD \
|
||||||
|
BOTAN_HAS_SERPENT_AVX2 \
|
||||||
BOTAN_HAS_SHA1_SSE2 \
|
BOTAN_HAS_SHA1_SSE2 \
|
||||||
BOTAN_HAS_SHA2_32_X86 \
|
BOTAN_HAS_SHA2_32_X86 \
|
||||||
BOTAN_HAS_SHA2_32_X86_BMI2 \
|
BOTAN_HAS_SHA2_32_X86_BMI2 \
|
||||||
BOTAN_HAS_SHACAL2_SIMD \
|
BOTAN_HAS_SHACAL2_SIMD \
|
||||||
BOTAN_HAS_SHACAL2_X86 \
|
BOTAN_HAS_SHACAL2_X86 \
|
||||||
|
BOTAN_HAS_SM4_ARMV8 \
|
||||||
BOTAN_HAS_THREEFISH_512_AVX2 \
|
BOTAN_HAS_THREEFISH_512_AVX2 \
|
||||||
BOTAN_DEPRECATED(msg)= \
|
BOTAN_DEPRECATED(msg)= \
|
||||||
BOTAN_PUBLIC_API(maj,min)=
|
BOTAN_PUBLIC_API(maj,min)=
|
||||||
|
10
src/libs/3rdparty/botan/src/build-data/buildh.in
vendored
10
src/libs/3rdparty/botan/src/build-data/buildh.in
vendored
@@ -87,6 +87,10 @@
|
|||||||
#define BOTAN_ENABLE_DEBUG_ASSERTS
|
#define BOTAN_ENABLE_DEBUG_ASSERTS
|
||||||
%{endif}
|
%{endif}
|
||||||
|
|
||||||
|
%{if optimize_for_size}
|
||||||
|
#define BOTAN_OPTIMIZE_FOR_SIZE
|
||||||
|
%{endif}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Module availability definitions
|
* Module availability definitions
|
||||||
*/
|
*/
|
||||||
@@ -166,8 +170,8 @@
|
|||||||
* broken system RNG.
|
* broken system RNG.
|
||||||
*/
|
*/
|
||||||
#define BOTAN_ENTROPY_DEFAULT_SOURCES \
|
#define BOTAN_ENTROPY_DEFAULT_SOURCES \
|
||||||
{ "rdseed", "rdrand", "darwin_secrandom", "getentropy", \
|
{ "rdseed", "rdrand", "getentropy", "dev_random", \
|
||||||
"dev_random", "system_rng", "proc_walk", "system_stats" }
|
"system_rng", "proc_walk", "system_stats" }
|
||||||
|
|
||||||
/* Multiplier on a block cipher's native parallelism */
|
/* Multiplier on a block cipher's native parallelism */
|
||||||
#define BOTAN_BLOCK_CIPHER_PAR_MULT 4
|
#define BOTAN_BLOCK_CIPHER_PAR_MULT 4
|
||||||
@@ -176,7 +180,7 @@
|
|||||||
* These control the RNG used by the system RNG interface
|
* These control the RNG used by the system RNG interface
|
||||||
*/
|
*/
|
||||||
#define BOTAN_SYSTEM_RNG_DEVICE "/dev/urandom"
|
#define BOTAN_SYSTEM_RNG_DEVICE "/dev/urandom"
|
||||||
#define BOTAN_SYSTEM_RNG_POLL_DEVICES { "/dev/urandom", "/dev/random", "/dev/srandom" }
|
#define BOTAN_SYSTEM_RNG_POLL_DEVICES { "/dev/urandom", "/dev/random" }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This directory will be monitored by ProcWalking_EntropySource and
|
* This directory will be monitored by ProcWalking_EntropySource and
|
||||||
|
@@ -18,7 +18,7 @@ default -> address,undefined
|
|||||||
|
|
||||||
address -> "-fsanitize=address"
|
address -> "-fsanitize=address"
|
||||||
undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined"
|
undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined"
|
||||||
coverage -> "-fsanitize-coverage=edge,indirect-calls,8bit-counters"
|
coverage -> "-fsanitize-coverage=edge,indirect-calls,trace-pc-guard,trace-cmp,trace-gep"
|
||||||
memory -> "-fsanitize=memory"
|
memory -> "-fsanitize=memory"
|
||||||
</sanitizers>
|
</sanitizers>
|
||||||
|
|
||||||
|
@@ -65,6 +65,10 @@ altivec -> "-maltivec"
|
|||||||
ppccrypto -> "-mcrypto"
|
ppccrypto -> "-mcrypto"
|
||||||
|
|
||||||
arm64:armv8crypto -> ""
|
arm64:armv8crypto -> ""
|
||||||
|
arm64:armv8sm3 -> "-march=armv8.2-a+sm4"
|
||||||
|
arm64:armv8sm4 -> "-march=armv8.2-a+sm4"
|
||||||
|
arm64:armv8sha512 -> "-march=armv8.2-a+sha3"
|
||||||
|
arm64:armv8sha3 -> "-march=armv8.2-a+sha3"
|
||||||
|
|
||||||
# For Aarch32 -mfpu=neon is required
|
# For Aarch32 -mfpu=neon is required
|
||||||
# For Aarch64 NEON is enabled by default
|
# For Aarch64 NEON is enabled by default
|
||||||
|
@@ -23,7 +23,7 @@ debug_info_flags "/Zi /FS"
|
|||||||
|
|
||||||
preproc_flags "/nologo /EP"
|
preproc_flags "/nologo /EP"
|
||||||
|
|
||||||
lang_flags "/EHs /GR"
|
lang_flags "/EHs /GR /D_ENABLE_EXTENDED_ALIGNED_STORAGE"
|
||||||
warning_flags "/W4 /wd4250 /wd4251 /wd4275"
|
warning_flags "/W4 /wd4250 /wd4251 /wd4275"
|
||||||
|
|
||||||
visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)"
|
visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)"
|
||||||
@@ -38,7 +38,7 @@ sse2 -> ""
|
|||||||
ssse3 -> ""
|
ssse3 -> ""
|
||||||
sse41 -> ""
|
sse41 -> ""
|
||||||
sse42 -> ""
|
sse42 -> ""
|
||||||
x86_64:avx2 -> ""
|
x86_64:avx2 -> "/arch:AVX"
|
||||||
bmi2 -> ""
|
bmi2 -> ""
|
||||||
aesni -> ""
|
aesni -> ""
|
||||||
clmul -> ""
|
clmul -> ""
|
||||||
|
@@ -5,8 +5,8 @@ binary_name CC
|
|||||||
optimization_flags "-xO2"
|
optimization_flags "-xO2"
|
||||||
|
|
||||||
shared_flags "-KPIC"
|
shared_flags "-KPIC"
|
||||||
warning_flags "+w -erroff=truncwarn,wnoretvalue"
|
warning_flags "+w -erroff=truncwarn,wnoretvalue,wlessrestrictedthrow"
|
||||||
lang_flags "-std=c++11 +p -features=extensions -D__FUNCTION__=__func__"
|
lang_flags "-std=c++11 +p -features=extensions"
|
||||||
|
|
||||||
ar_command CC
|
ar_command CC
|
||||||
ar_options "-xar -o"
|
ar_options "-xar -o"
|
||||||
@@ -19,7 +19,7 @@ default -> "$(CXX) -G -h{soname_abi}"
|
|||||||
# Needed on some Linux distros
|
# Needed on some Linux distros
|
||||||
linux -> "-library=stlport4"
|
linux -> "-library=stlport4"
|
||||||
|
|
||||||
sparc64 -> "-xarch=v9"
|
sparc64 -> "-m64 -xarch=sparc"
|
||||||
x86_64 -> "-m64"
|
x86_64 -> "-m64"
|
||||||
</mach_abi_linking>
|
</mach_abi_linking>
|
||||||
|
|
||||||
|
@@ -57,6 +57,14 @@
|
|||||||
#elif defined(__s390__)
|
#elif defined(__s390__)
|
||||||
S390
|
S390
|
||||||
|
|
||||||
|
#elif defined(__riscv)
|
||||||
|
|
||||||
|
#if defined(__LP64__)
|
||||||
|
RISCV64
|
||||||
|
#else
|
||||||
|
RISCV32
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
|
|
||||||
|
@@ -54,7 +54,7 @@ distclean:
|
|||||||
$(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" --distclean
|
$(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" --distclean
|
||||||
|
|
||||||
install: libs cli docs
|
install: libs cli docs
|
||||||
$(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix=%{prefix} --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir}
|
$(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix="%{prefix}" --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir}
|
||||||
|
|
||||||
# Object Files
|
# Object Files
|
||||||
LIBOBJS = %{join lib_objs}
|
LIBOBJS = %{join lib_objs}
|
||||||
|
25
src/libs/3rdparty/botan/src/build-data/oids.txt
vendored
25
src/libs/3rdparty/botan/src/build-data/oids.txt
vendored
@@ -21,6 +21,7 @@
|
|||||||
1.3.132.1.12 = ECDH
|
1.3.132.1.12 = ECDH
|
||||||
|
|
||||||
1.2.156.10197.1.301.1 = SM2_Sig
|
1.2.156.10197.1.301.1 = SM2_Sig
|
||||||
|
1.2.156.10197.1.301.1 = SM2
|
||||||
1.2.156.10197.1.301.2 = SM2_Kex
|
1.2.156.10197.1.301.2 = SM2_Kex
|
||||||
1.2.156.10197.1.301.3 = SM2_Enc
|
1.2.156.10197.1.301.3 = SM2_Enc
|
||||||
|
|
||||||
@@ -40,7 +41,6 @@
|
|||||||
# Cipher modes
|
# Cipher modes
|
||||||
1.3.14.3.2.7 = DES/CBC
|
1.3.14.3.2.7 = DES/CBC
|
||||||
1.2.840.113549.3.7 = TripleDES/CBC
|
1.2.840.113549.3.7 = TripleDES/CBC
|
||||||
1.2.840.113549.3.2 = RC2/CBC
|
|
||||||
1.2.840.113533.7.66.10 = CAST-128/CBC
|
1.2.840.113533.7.66.10 = CAST-128/CBC
|
||||||
2.16.840.1.101.3.4.1.2 = AES-128/CBC
|
2.16.840.1.101.3.4.1.2 = AES-128/CBC
|
||||||
2.16.840.1.101.3.4.1.22 = AES-192/CBC
|
2.16.840.1.101.3.4.1.22 = AES-192/CBC
|
||||||
@@ -80,6 +80,21 @@
|
|||||||
1.3.6.1.4.1.25258.3.2.3 = AES-256/OCB
|
1.3.6.1.4.1.25258.3.2.3 = AES-256/OCB
|
||||||
1.3.6.1.4.1.25258.3.2.4 = Serpent/OCB
|
1.3.6.1.4.1.25258.3.2.4 = Serpent/OCB
|
||||||
1.3.6.1.4.1.25258.3.2.5 = Twofish/OCB
|
1.3.6.1.4.1.25258.3.2.5 = Twofish/OCB
|
||||||
|
1.3.6.1.4.1.25258.3.2.6 = Camellia-128/OCB
|
||||||
|
1.3.6.1.4.1.25258.3.2.7 = Camellia-192/OCB
|
||||||
|
1.3.6.1.4.1.25258.3.2.8 = Camellia-256/OCB
|
||||||
|
|
||||||
|
1.2.156.10197.1.104.100 = SM4/OCB
|
||||||
|
|
||||||
|
1.3.6.1.4.1.25258.3.4.1 = AES-128/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.2 = AES-192/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.3 = AES-256/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.4 = Serpent/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.5 = Twofish/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.6 = Camellia-128/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.7 = Camellia-192/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.8 = Camellia-256/SIV
|
||||||
|
1.3.6.1.4.1.25258.3.4.9 = SM4/SIV
|
||||||
|
|
||||||
[hash]
|
[hash]
|
||||||
# Hash functions
|
# Hash functions
|
||||||
@@ -115,11 +130,11 @@
|
|||||||
1.2.840.113549.2.9 = HMAC(SHA-256)
|
1.2.840.113549.2.9 = HMAC(SHA-256)
|
||||||
1.2.840.113549.2.10 = HMAC(SHA-384)
|
1.2.840.113549.2.10 = HMAC(SHA-384)
|
||||||
1.2.840.113549.2.11 = HMAC(SHA-512)
|
1.2.840.113549.2.11 = HMAC(SHA-512)
|
||||||
|
1.2.840.113549.2.13 = HMAC(SHA-512-256)
|
||||||
|
|
||||||
[keywrap]
|
[keywrap]
|
||||||
# Keywrap algorithms
|
# Keywrap algorithms
|
||||||
1.2.840.113549.1.9.16.3.6 = KeyWrap.TripleDES
|
1.2.840.113549.1.9.16.3.6 = KeyWrap.TripleDES
|
||||||
1.2.840.113549.1.9.16.3.7 = KeyWrap.RC2
|
|
||||||
1.2.840.113533.7.66.15 = KeyWrap.CAST-128
|
1.2.840.113533.7.66.15 = KeyWrap.CAST-128
|
||||||
2.16.840.1.101.3.4.1.5 = KeyWrap.AES-128
|
2.16.840.1.101.3.4.1.5 = KeyWrap.AES-128
|
||||||
2.16.840.1.101.3.4.1.25 = KeyWrap.AES-192
|
2.16.840.1.101.3.4.1.25 = KeyWrap.AES-192
|
||||||
@@ -140,6 +155,8 @@
|
|||||||
1.2.840.113549.1.1.14 = RSA/EMSA3(SHA-224)
|
1.2.840.113549.1.1.14 = RSA/EMSA3(SHA-224)
|
||||||
1.2.840.113549.1.1.16 = RSA/EMSA3(SHA-512-256)
|
1.2.840.113549.1.1.16 = RSA/EMSA3(SHA-512-256)
|
||||||
1.3.36.3.3.1.2 = RSA/EMSA3(RIPEMD-160)
|
1.3.36.3.3.1.2 = RSA/EMSA3(RIPEMD-160)
|
||||||
|
|
||||||
|
1.2.156.10197.1.501 = SM2_Sig/SM3
|
||||||
1.2.156.10197.1.504 = RSA/EMSA3(SM3)
|
1.2.156.10197.1.504 = RSA/EMSA3(SM3)
|
||||||
|
|
||||||
1.2.840.10040.4.3 = DSA/EMSA1(SHA-160)
|
1.2.840.10040.4.3 = DSA/EMSA1(SHA-160)
|
||||||
@@ -208,6 +225,7 @@
|
|||||||
|
|
||||||
[pbe]
|
[pbe]
|
||||||
1.2.840.113549.1.5.12 = PKCS5.PBKDF2
|
1.2.840.113549.1.5.12 = PKCS5.PBKDF2
|
||||||
|
1.2.840.113549.1.5.13 = PBES2
|
||||||
1.2.840.113549.1.5.13 = PBE-PKCS5v20
|
1.2.840.113549.1.5.13 = PBE-PKCS5v20
|
||||||
|
|
||||||
1.3.6.1.4.1.11591.4.11 = Scrypt
|
1.3.6.1.4.1.11591.4.11 = Scrypt
|
||||||
@@ -258,6 +276,9 @@
|
|||||||
1.3.6.1.5.5.7.48.2 = PKIX.CertificateAuthorityIssuers
|
1.3.6.1.5.5.7.48.2 = PKIX.CertificateAuthorityIssuers
|
||||||
|
|
||||||
1.3.6.1.4.1.311.20.2.2 = Microsoft SmartcardLogon
|
1.3.6.1.4.1.311.20.2.2 = Microsoft SmartcardLogon
|
||||||
|
1.3.6.1.4.1.311.20.2.3 = Microsoft UPN
|
||||||
|
|
||||||
|
2.16.840.1.113730.1.13 = Certificate Comment
|
||||||
|
|
||||||
# ECC param sets
|
# ECC param sets
|
||||||
[ecc_param]
|
[ecc_param]
|
||||||
|
@@ -14,8 +14,8 @@ posix1
|
|||||||
posix_mlock
|
posix_mlock
|
||||||
arc4random
|
arc4random
|
||||||
dev_random
|
dev_random
|
||||||
security_framework
|
|
||||||
|
|
||||||
|
commoncrypto
|
||||||
sockets
|
sockets
|
||||||
threads
|
threads
|
||||||
filesystem
|
filesystem
|
||||||
|
@@ -10,6 +10,7 @@ posix1
|
|||||||
posix_mlock
|
posix_mlock
|
||||||
arc4random
|
arc4random
|
||||||
|
|
||||||
|
commoncrypto
|
||||||
sockets
|
sockets
|
||||||
threads
|
threads
|
||||||
filesystem
|
filesystem
|
||||||
|
@@ -10,6 +10,9 @@ proc_fs
|
|||||||
clock_gettime
|
clock_gettime
|
||||||
getauxval
|
getauxval
|
||||||
|
|
||||||
|
# not enabled by default as only available in newer kernel/glibc
|
||||||
|
#getrandom
|
||||||
|
|
||||||
sockets
|
sockets
|
||||||
threads
|
threads
|
||||||
filesystem
|
filesystem
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
release_major = 2
|
release_major = 2
|
||||||
release_minor = 7
|
release_minor = 8
|
||||||
release_patch = 0
|
release_patch = 0
|
||||||
release_so_abi_rev = 7
|
release_so_abi_rev = 8
|
||||||
|
|
||||||
# These are set by the distribution script
|
# These are set by the distribution script
|
||||||
release_vc_rev = 'git:5874000d42c338ec95a7ff24cdc0c64e70f967b5'
|
release_vc_rev = 'git:a792728e8941b62761052f5e0d288ba13a016c77'
|
||||||
release_datestamp = 20180702
|
release_datestamp = 20181001
|
||||||
release_type = 'release'
|
release_type = 'release'
|
||||||
|
@@ -174,7 +174,7 @@ void ASN1_Formatter::decode(std::ostream& output,
|
|||||||
data.decode(number, ENUMERATED, class_tag);
|
data.decode(number, ENUMERATED, class_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> rep = BigInt::encode(number, BigInt::Binary);
|
std::vector<uint8_t> rep = BigInt::encode(number);
|
||||||
if(rep.empty()) // if zero
|
if(rep.empty()) // if zero
|
||||||
rep.resize(1);
|
rep.resize(1);
|
||||||
|
|
||||||
|
@@ -262,6 +262,12 @@ std::chrono::system_clock::time_point X509_Time::to_std_timepoint() const
|
|||||||
return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint();
|
return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t X509_Time::time_since_epoch() const
|
||||||
|
{
|
||||||
|
auto tp = this->to_std_timepoint();
|
||||||
|
return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare two X509_Times for in various ways
|
* Compare two X509_Times for in various ways
|
||||||
*/
|
*/
|
||||||
|
@@ -49,6 +49,9 @@ class BOTAN_PUBLIC_API(2,0) X509_Time final : public ASN1_Object
|
|||||||
/// Returns a STL timepoint object
|
/// Returns a STL timepoint object
|
||||||
std::chrono::system_clock::time_point to_std_timepoint() const;
|
std::chrono::system_clock::time_point to_std_timepoint() const;
|
||||||
|
|
||||||
|
/// Return time since epoch
|
||||||
|
uint64_t time_since_epoch() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_to(const std::string& t_spec, ASN1_Tag);
|
void set_to(const std::string& t_spec, ASN1_Tag);
|
||||||
bool passes_sanity_check() const;
|
bool passes_sanity_check() const;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* OID maps
|
* OID maps
|
||||||
*
|
*
|
||||||
* This file was automatically generated by ./src/scripts/oids.py on 2018-07-01
|
* This file was automatically generated by ./src/scripts/oids.py on 2018-08-23
|
||||||
*
|
*
|
||||||
* All manual edits to this file will be lost. Edit the script
|
* All manual edits to this file will be lost. Edit the script
|
||||||
* then regenerate this source file.
|
* then regenerate this source file.
|
||||||
@@ -21,13 +21,15 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map()
|
|||||||
{ "0.3.4401.5.3.1.9.46", "Camellia-256/GCM" },
|
{ "0.3.4401.5.3.1.9.46", "Camellia-256/GCM" },
|
||||||
{ "0.3.4401.5.3.1.9.6", "Camellia-128/GCM" },
|
{ "0.3.4401.5.3.1.9.6", "Camellia-128/GCM" },
|
||||||
{ "1.0.14888.3.0.5", "ECKCDSA" },
|
{ "1.0.14888.3.0.5", "ECKCDSA" },
|
||||||
|
{ "1.2.156.10197.1.104.100", "SM4/OCB" },
|
||||||
{ "1.2.156.10197.1.104.2", "SM4/CBC" },
|
{ "1.2.156.10197.1.104.2", "SM4/CBC" },
|
||||||
{ "1.2.156.10197.1.104.8", "SM4/GCM" },
|
{ "1.2.156.10197.1.104.8", "SM4/GCM" },
|
||||||
{ "1.2.156.10197.1.301", "sm2p256v1" },
|
{ "1.2.156.10197.1.301", "sm2p256v1" },
|
||||||
{ "1.2.156.10197.1.301.1", "SM2_Sig" },
|
{ "1.2.156.10197.1.301.1", "SM2" },
|
||||||
{ "1.2.156.10197.1.301.2", "SM2_Kex" },
|
{ "1.2.156.10197.1.301.2", "SM2_Kex" },
|
||||||
{ "1.2.156.10197.1.301.3", "SM2_Enc" },
|
{ "1.2.156.10197.1.301.3", "SM2_Enc" },
|
||||||
{ "1.2.156.10197.1.401", "SM3" },
|
{ "1.2.156.10197.1.401", "SM3" },
|
||||||
|
{ "1.2.156.10197.1.501", "SM2_Sig/SM3" },
|
||||||
{ "1.2.156.10197.1.504", "RSA/EMSA3(SM3)" },
|
{ "1.2.156.10197.1.504", "RSA/EMSA3(SM3)" },
|
||||||
{ "1.2.250.1.223.101.256.1", "frp256v1" },
|
{ "1.2.250.1.223.101.256.1", "frp256v1" },
|
||||||
{ "1.2.392.200011.61.1.1.1.2", "Camellia-128/CBC" },
|
{ "1.2.392.200011.61.1.1.1.2", "Camellia-128/CBC" },
|
||||||
@@ -78,7 +80,6 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map()
|
|||||||
{ "1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest" },
|
{ "1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest" },
|
||||||
{ "1.2.840.113549.1.9.16.3.18", "ChaCha20Poly1305" },
|
{ "1.2.840.113549.1.9.16.3.18", "ChaCha20Poly1305" },
|
||||||
{ "1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES" },
|
{ "1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES" },
|
||||||
{ "1.2.840.113549.1.9.16.3.7", "KeyWrap.RC2" },
|
|
||||||
{ "1.2.840.113549.1.9.16.3.8", "Compression.Zlib" },
|
{ "1.2.840.113549.1.9.16.3.8", "Compression.Zlib" },
|
||||||
{ "1.2.840.113549.1.9.2", "PKCS9.UnstructuredName" },
|
{ "1.2.840.113549.1.9.2", "PKCS9.UnstructuredName" },
|
||||||
{ "1.2.840.113549.1.9.3", "PKCS9.ContentType" },
|
{ "1.2.840.113549.1.9.3", "PKCS9.ContentType" },
|
||||||
@@ -86,11 +87,11 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map()
|
|||||||
{ "1.2.840.113549.1.9.7", "PKCS9.ChallengePassword" },
|
{ "1.2.840.113549.1.9.7", "PKCS9.ChallengePassword" },
|
||||||
{ "1.2.840.113549.2.10", "HMAC(SHA-384)" },
|
{ "1.2.840.113549.2.10", "HMAC(SHA-384)" },
|
||||||
{ "1.2.840.113549.2.11", "HMAC(SHA-512)" },
|
{ "1.2.840.113549.2.11", "HMAC(SHA-512)" },
|
||||||
|
{ "1.2.840.113549.2.13", "HMAC(SHA-512-256)" },
|
||||||
{ "1.2.840.113549.2.5", "MD5" },
|
{ "1.2.840.113549.2.5", "MD5" },
|
||||||
{ "1.2.840.113549.2.7", "HMAC(SHA-160)" },
|
{ "1.2.840.113549.2.7", "HMAC(SHA-160)" },
|
||||||
{ "1.2.840.113549.2.8", "HMAC(SHA-224)" },
|
{ "1.2.840.113549.2.8", "HMAC(SHA-224)" },
|
||||||
{ "1.2.840.113549.2.9", "HMAC(SHA-256)" },
|
{ "1.2.840.113549.2.9", "HMAC(SHA-256)" },
|
||||||
{ "1.2.840.113549.3.2", "RC2/CBC" },
|
|
||||||
{ "1.2.840.113549.3.7", "TripleDES/CBC" },
|
{ "1.2.840.113549.3.7", "TripleDES/CBC" },
|
||||||
{ "1.3.101.110", "Curve25519" },
|
{ "1.3.101.110", "Curve25519" },
|
||||||
{ "1.3.101.112", "Ed25519" },
|
{ "1.3.101.112", "Ed25519" },
|
||||||
@@ -137,10 +138,23 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map()
|
|||||||
{ "1.3.6.1.4.1.25258.3.2.3", "AES-256/OCB" },
|
{ "1.3.6.1.4.1.25258.3.2.3", "AES-256/OCB" },
|
||||||
{ "1.3.6.1.4.1.25258.3.2.4", "Serpent/OCB" },
|
{ "1.3.6.1.4.1.25258.3.2.4", "Serpent/OCB" },
|
||||||
{ "1.3.6.1.4.1.25258.3.2.5", "Twofish/OCB" },
|
{ "1.3.6.1.4.1.25258.3.2.5", "Twofish/OCB" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.2.6", "Camellia-128/OCB" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.2.7", "Camellia-192/OCB" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.2.8", "Camellia-256/OCB" },
|
||||||
{ "1.3.6.1.4.1.25258.3.3", "Twofish/CBC" },
|
{ "1.3.6.1.4.1.25258.3.3", "Twofish/CBC" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.1", "AES-128/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.2", "AES-192/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.3", "AES-256/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.4", "Serpent/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.5", "Twofish/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.6", "Camellia-128/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.7", "Camellia-192/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.8", "Camellia-256/SIV" },
|
||||||
|
{ "1.3.6.1.4.1.25258.3.4.9", "SM4/SIV" },
|
||||||
{ "1.3.6.1.4.1.3029.1.2.1", "ElGamal" },
|
{ "1.3.6.1.4.1.3029.1.2.1", "ElGamal" },
|
||||||
{ "1.3.6.1.4.1.3029.1.5.1", "OpenPGP.Curve25519" },
|
{ "1.3.6.1.4.1.3029.1.5.1", "OpenPGP.Curve25519" },
|
||||||
{ "1.3.6.1.4.1.311.20.2.2", "Microsoft SmartcardLogon" },
|
{ "1.3.6.1.4.1.311.20.2.2", "Microsoft SmartcardLogon" },
|
||||||
|
{ "1.3.6.1.4.1.311.20.2.3", "Microsoft UPN" },
|
||||||
{ "1.3.6.1.4.1.8301.3.1.2.9.0.38", "secp521r1" },
|
{ "1.3.6.1.4.1.8301.3.1.2.9.0.38", "secp521r1" },
|
||||||
{ "1.3.6.1.5.5.7.1.1", "PKIX.AuthorityInformationAccess" },
|
{ "1.3.6.1.5.5.7.1.1", "PKIX.AuthorityInformationAccess" },
|
||||||
{ "1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth" },
|
{ "1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth" },
|
||||||
@@ -195,6 +209,7 @@ std::unordered_map<std::string, std::string> OIDS::load_oid2str_map()
|
|||||||
{ "2.16.840.1.101.3.4.3.7", "DSA/EMSA1(SHA-3(384))" },
|
{ "2.16.840.1.101.3.4.3.7", "DSA/EMSA1(SHA-3(384))" },
|
||||||
{ "2.16.840.1.101.3.4.3.8", "DSA/EMSA1(SHA-3(512))" },
|
{ "2.16.840.1.101.3.4.3.8", "DSA/EMSA1(SHA-3(512))" },
|
||||||
{ "2.16.840.1.101.3.4.3.9", "ECDSA/EMSA1(SHA-3(224))" },
|
{ "2.16.840.1.101.3.4.3.9", "ECDSA/EMSA1(SHA-3(224))" },
|
||||||
|
{ "2.16.840.1.113730.1.13", "Certificate Comment" },
|
||||||
{ "2.5.29.14", "X509v3.SubjectKeyIdentifier" },
|
{ "2.5.29.14", "X509v3.SubjectKeyIdentifier" },
|
||||||
{ "2.5.29.15", "X509v3.KeyUsage" },
|
{ "2.5.29.15", "X509v3.KeyUsage" },
|
||||||
{ "2.5.29.17", "X509v3.SubjectAlternativeName" },
|
{ "2.5.29.17", "X509v3.SubjectAlternativeName" },
|
||||||
@@ -237,21 +252,31 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map()
|
|||||||
{ "AES-128/CCM", OID({2,16,840,1,101,3,4,1,7}) },
|
{ "AES-128/CCM", OID({2,16,840,1,101,3,4,1,7}) },
|
||||||
{ "AES-128/GCM", OID({2,16,840,1,101,3,4,1,6}) },
|
{ "AES-128/GCM", OID({2,16,840,1,101,3,4,1,6}) },
|
||||||
{ "AES-128/OCB", OID({1,3,6,1,4,1,25258,3,2,1}) },
|
{ "AES-128/OCB", OID({1,3,6,1,4,1,25258,3,2,1}) },
|
||||||
|
{ "AES-128/SIV", OID({1,3,6,1,4,1,25258,3,4,1}) },
|
||||||
{ "AES-192/CBC", OID({2,16,840,1,101,3,4,1,22}) },
|
{ "AES-192/CBC", OID({2,16,840,1,101,3,4,1,22}) },
|
||||||
{ "AES-192/CCM", OID({2,16,840,1,101,3,4,1,27}) },
|
{ "AES-192/CCM", OID({2,16,840,1,101,3,4,1,27}) },
|
||||||
{ "AES-192/GCM", OID({2,16,840,1,101,3,4,1,26}) },
|
{ "AES-192/GCM", OID({2,16,840,1,101,3,4,1,26}) },
|
||||||
{ "AES-192/OCB", OID({1,3,6,1,4,1,25258,3,2,2}) },
|
{ "AES-192/OCB", OID({1,3,6,1,4,1,25258,3,2,2}) },
|
||||||
|
{ "AES-192/SIV", OID({1,3,6,1,4,1,25258,3,4,2}) },
|
||||||
{ "AES-256/CBC", OID({2,16,840,1,101,3,4,1,42}) },
|
{ "AES-256/CBC", OID({2,16,840,1,101,3,4,1,42}) },
|
||||||
{ "AES-256/CCM", OID({2,16,840,1,101,3,4,1,47}) },
|
{ "AES-256/CCM", OID({2,16,840,1,101,3,4,1,47}) },
|
||||||
{ "AES-256/GCM", OID({2,16,840,1,101,3,4,1,46}) },
|
{ "AES-256/GCM", OID({2,16,840,1,101,3,4,1,46}) },
|
||||||
{ "AES-256/OCB", OID({1,3,6,1,4,1,25258,3,2,3}) },
|
{ "AES-256/OCB", OID({1,3,6,1,4,1,25258,3,2,3}) },
|
||||||
|
{ "AES-256/SIV", OID({1,3,6,1,4,1,25258,3,4,3}) },
|
||||||
{ "CAST-128/CBC", OID({1,2,840,113533,7,66,10}) },
|
{ "CAST-128/CBC", OID({1,2,840,113533,7,66,10}) },
|
||||||
{ "Camellia-128/CBC", OID({1,2,392,200011,61,1,1,1,2}) },
|
{ "Camellia-128/CBC", OID({1,2,392,200011,61,1,1,1,2}) },
|
||||||
{ "Camellia-128/GCM", OID({0,3,4401,5,3,1,9,6}) },
|
{ "Camellia-128/GCM", OID({0,3,4401,5,3,1,9,6}) },
|
||||||
|
{ "Camellia-128/OCB", OID({1,3,6,1,4,1,25258,3,2,6}) },
|
||||||
|
{ "Camellia-128/SIV", OID({1,3,6,1,4,1,25258,3,4,6}) },
|
||||||
{ "Camellia-192/CBC", OID({1,2,392,200011,61,1,1,1,3}) },
|
{ "Camellia-192/CBC", OID({1,2,392,200011,61,1,1,1,3}) },
|
||||||
{ "Camellia-192/GCM", OID({0,3,4401,5,3,1,9,26}) },
|
{ "Camellia-192/GCM", OID({0,3,4401,5,3,1,9,26}) },
|
||||||
|
{ "Camellia-192/OCB", OID({1,3,6,1,4,1,25258,3,2,7}) },
|
||||||
|
{ "Camellia-192/SIV", OID({1,3,6,1,4,1,25258,3,4,7}) },
|
||||||
{ "Camellia-256/CBC", OID({1,2,392,200011,61,1,1,1,4}) },
|
{ "Camellia-256/CBC", OID({1,2,392,200011,61,1,1,1,4}) },
|
||||||
{ "Camellia-256/GCM", OID({0,3,4401,5,3,1,9,46}) },
|
{ "Camellia-256/GCM", OID({0,3,4401,5,3,1,9,46}) },
|
||||||
|
{ "Camellia-256/OCB", OID({1,3,6,1,4,1,25258,3,2,8}) },
|
||||||
|
{ "Camellia-256/SIV", OID({1,3,6,1,4,1,25258,3,4,8}) },
|
||||||
|
{ "Certificate Comment", OID({2,16,840,1,113730,1,13}) },
|
||||||
{ "ChaCha20Poly1305", OID({1,2,840,113549,1,9,16,3,18}) },
|
{ "ChaCha20Poly1305", OID({1,2,840,113549,1,9,16,3,18}) },
|
||||||
{ "Compression.Zlib", OID({1,2,840,113549,1,9,16,3,8}) },
|
{ "Compression.Zlib", OID({1,2,840,113549,1,9,16,3,8}) },
|
||||||
{ "Curve25519", OID({1,3,101,110}) },
|
{ "Curve25519", OID({1,3,101,110}) },
|
||||||
@@ -299,19 +324,21 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map()
|
|||||||
{ "HMAC(SHA-256)", OID({1,2,840,113549,2,9}) },
|
{ "HMAC(SHA-256)", OID({1,2,840,113549,2,9}) },
|
||||||
{ "HMAC(SHA-384)", OID({1,2,840,113549,2,10}) },
|
{ "HMAC(SHA-384)", OID({1,2,840,113549,2,10}) },
|
||||||
{ "HMAC(SHA-512)", OID({1,2,840,113549,2,11}) },
|
{ "HMAC(SHA-512)", OID({1,2,840,113549,2,11}) },
|
||||||
|
{ "HMAC(SHA-512-256)", OID({1,2,840,113549,2,13}) },
|
||||||
{ "KeyWrap.AES-128", OID({2,16,840,1,101,3,4,1,5}) },
|
{ "KeyWrap.AES-128", OID({2,16,840,1,101,3,4,1,5}) },
|
||||||
{ "KeyWrap.AES-192", OID({2,16,840,1,101,3,4,1,25}) },
|
{ "KeyWrap.AES-192", OID({2,16,840,1,101,3,4,1,25}) },
|
||||||
{ "KeyWrap.AES-256", OID({2,16,840,1,101,3,4,1,45}) },
|
{ "KeyWrap.AES-256", OID({2,16,840,1,101,3,4,1,45}) },
|
||||||
{ "KeyWrap.CAST-128", OID({1,2,840,113533,7,66,15}) },
|
{ "KeyWrap.CAST-128", OID({1,2,840,113533,7,66,15}) },
|
||||||
{ "KeyWrap.RC2", OID({1,2,840,113549,1,9,16,3,7}) },
|
|
||||||
{ "KeyWrap.TripleDES", OID({1,2,840,113549,1,9,16,3,6}) },
|
{ "KeyWrap.TripleDES", OID({1,2,840,113549,1,9,16,3,6}) },
|
||||||
{ "MD5", OID({1,2,840,113549,2,5}) },
|
{ "MD5", OID({1,2,840,113549,2,5}) },
|
||||||
{ "MGF1", OID({1,2,840,113549,1,1,8}) },
|
{ "MGF1", OID({1,2,840,113549,1,1,8}) },
|
||||||
{ "McEliece", OID({1,3,6,1,4,1,25258,1,3}) },
|
{ "McEliece", OID({1,3,6,1,4,1,25258,1,3}) },
|
||||||
{ "Microsoft SmartcardLogon", OID({1,3,6,1,4,1,311,20,2,2}) },
|
{ "Microsoft SmartcardLogon", OID({1,3,6,1,4,1,311,20,2,2}) },
|
||||||
|
{ "Microsoft UPN", OID({1,3,6,1,4,1,311,20,2,3}) },
|
||||||
{ "OpenPGP.Curve25519", OID({1,3,6,1,4,1,3029,1,5,1}) },
|
{ "OpenPGP.Curve25519", OID({1,3,6,1,4,1,3029,1,5,1}) },
|
||||||
{ "OpenPGP.Ed25519", OID({1,3,6,1,4,1,11591,15,1}) },
|
{ "OpenPGP.Ed25519", OID({1,3,6,1,4,1,11591,15,1}) },
|
||||||
{ "PBE-PKCS5v20", OID({1,2,840,113549,1,5,13}) },
|
{ "PBE-PKCS5v20", OID({1,2,840,113549,1,5,13}) },
|
||||||
|
{ "PBES2", OID({1,2,840,113549,1,5,13}) },
|
||||||
{ "PKCS5.PBKDF2", OID({1,2,840,113549,1,5,12}) },
|
{ "PKCS5.PBKDF2", OID({1,2,840,113549,1,5,12}) },
|
||||||
{ "PKCS9.ChallengePassword", OID({1,2,840,113549,1,9,7}) },
|
{ "PKCS9.ChallengePassword", OID({1,2,840,113549,1,9,7}) },
|
||||||
{ "PKCS9.ContentType", OID({1,2,840,113549,1,9,3}) },
|
{ "PKCS9.ContentType", OID({1,2,840,113549,1,9,3}) },
|
||||||
@@ -333,7 +360,6 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map()
|
|||||||
{ "PKIX.ServerAuth", OID({1,3,6,1,5,5,7,3,1}) },
|
{ "PKIX.ServerAuth", OID({1,3,6,1,5,5,7,3,1}) },
|
||||||
{ "PKIX.TimeStamping", OID({1,3,6,1,5,5,7,3,8}) },
|
{ "PKIX.TimeStamping", OID({1,3,6,1,5,5,7,3,8}) },
|
||||||
{ "PKIX.XMPPAddr", OID({1,3,6,1,5,5,7,8,5}) },
|
{ "PKIX.XMPPAddr", OID({1,3,6,1,5,5,7,8,5}) },
|
||||||
{ "RC2/CBC", OID({1,2,840,113549,3,2}) },
|
|
||||||
{ "RIPEMD-160", OID({1,3,36,3,2,1}) },
|
{ "RIPEMD-160", OID({1,3,36,3,2,1}) },
|
||||||
{ "RSA", OID({1,2,840,113549,1,1,1}) },
|
{ "RSA", OID({1,2,840,113549,1,1,1}) },
|
||||||
{ "RSA/EMSA3(MD5)", OID({1,2,840,113549,1,1,4}) },
|
{ "RSA/EMSA3(MD5)", OID({1,2,840,113549,1,1,4}) },
|
||||||
@@ -364,16 +390,21 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map()
|
|||||||
{ "SHA-512-256", OID({2,16,840,1,101,3,4,2,6}) },
|
{ "SHA-512-256", OID({2,16,840,1,101,3,4,2,6}) },
|
||||||
{ "SHAKE-128", OID({2,16,840,1,101,3,4,2,11}) },
|
{ "SHAKE-128", OID({2,16,840,1,101,3,4,2,11}) },
|
||||||
{ "SHAKE-256", OID({2,16,840,1,101,3,4,2,12}) },
|
{ "SHAKE-256", OID({2,16,840,1,101,3,4,2,12}) },
|
||||||
|
{ "SM2", OID({1,2,156,10197,1,301,1}) },
|
||||||
{ "SM2_Enc", OID({1,2,156,10197,1,301,3}) },
|
{ "SM2_Enc", OID({1,2,156,10197,1,301,3}) },
|
||||||
{ "SM2_Kex", OID({1,2,156,10197,1,301,2}) },
|
{ "SM2_Kex", OID({1,2,156,10197,1,301,2}) },
|
||||||
{ "SM2_Sig", OID({1,2,156,10197,1,301,1}) },
|
{ "SM2_Sig", OID({1,2,156,10197,1,301,1}) },
|
||||||
|
{ "SM2_Sig/SM3", OID({1,2,156,10197,1,501}) },
|
||||||
{ "SM3", OID({1,2,156,10197,1,401}) },
|
{ "SM3", OID({1,2,156,10197,1,401}) },
|
||||||
{ "SM4/CBC", OID({1,2,156,10197,1,104,2}) },
|
{ "SM4/CBC", OID({1,2,156,10197,1,104,2}) },
|
||||||
{ "SM4/GCM", OID({1,2,156,10197,1,104,8}) },
|
{ "SM4/GCM", OID({1,2,156,10197,1,104,8}) },
|
||||||
|
{ "SM4/OCB", OID({1,2,156,10197,1,104,100}) },
|
||||||
|
{ "SM4/SIV", OID({1,3,6,1,4,1,25258,3,4,9}) },
|
||||||
{ "Scrypt", OID({1,3,6,1,4,1,11591,4,11}) },
|
{ "Scrypt", OID({1,3,6,1,4,1,11591,4,11}) },
|
||||||
{ "Serpent/CBC", OID({1,3,6,1,4,1,25258,3,1}) },
|
{ "Serpent/CBC", OID({1,3,6,1,4,1,25258,3,1}) },
|
||||||
{ "Serpent/GCM", OID({1,3,6,1,4,1,25258,3,101}) },
|
{ "Serpent/GCM", OID({1,3,6,1,4,1,25258,3,101}) },
|
||||||
{ "Serpent/OCB", OID({1,3,6,1,4,1,25258,3,2,4}) },
|
{ "Serpent/OCB", OID({1,3,6,1,4,1,25258,3,2,4}) },
|
||||||
|
{ "Serpent/SIV", OID({1,3,6,1,4,1,25258,3,4,4}) },
|
||||||
{ "Streebog-256", OID({1,2,643,7,1,1,2,2}) },
|
{ "Streebog-256", OID({1,2,643,7,1,1,2,2}) },
|
||||||
{ "Streebog-512", OID({1,2,643,7,1,1,2,3}) },
|
{ "Streebog-512", OID({1,2,643,7,1,1,2,3}) },
|
||||||
{ "Threefish-512/CBC", OID({1,3,6,1,4,1,25258,3,2}) },
|
{ "Threefish-512/CBC", OID({1,3,6,1,4,1,25258,3,2}) },
|
||||||
@@ -382,6 +413,7 @@ std::unordered_map<std::string, OID> OIDS::load_str2oid_map()
|
|||||||
{ "Twofish/CBC", OID({1,3,6,1,4,1,25258,3,3}) },
|
{ "Twofish/CBC", OID({1,3,6,1,4,1,25258,3,3}) },
|
||||||
{ "Twofish/GCM", OID({1,3,6,1,4,1,25258,3,102}) },
|
{ "Twofish/GCM", OID({1,3,6,1,4,1,25258,3,102}) },
|
||||||
{ "Twofish/OCB", OID({1,3,6,1,4,1,25258,3,2,5}) },
|
{ "Twofish/OCB", OID({1,3,6,1,4,1,25258,3,2,5}) },
|
||||||
|
{ "Twofish/SIV", OID({1,3,6,1,4,1,25258,3,4,5}) },
|
||||||
{ "X509v3.AnyPolicy", OID({2,5,29,32,0}) },
|
{ "X509v3.AnyPolicy", OID({2,5,29,32,0}) },
|
||||||
{ "X509v3.AuthorityKeyIdentifier", OID({2,5,29,35}) },
|
{ "X509v3.AuthorityKeyIdentifier", OID({2,5,29,35}) },
|
||||||
{ "X509v3.BasicConstraints", OID({2,5,29,19}) },
|
{ "X509v3.BasicConstraints", OID({2,5,29,19}) },
|
||||||
|
@@ -14,7 +14,7 @@ namespace OIDS {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class OID_Map
|
class OID_Map final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void add_oid(const OID& oid, const std::string& str)
|
void add_oid(const OID& oid, const std::string& str)
|
||||||
|
@@ -88,7 +88,7 @@ operator!=(const secure_allocator<T>&, const secure_allocator<U>&)
|
|||||||
template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>;
|
template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>;
|
||||||
template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>;
|
template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>;
|
||||||
|
|
||||||
// For better compatability with 1.10 API
|
// For better compatibility with 1.10 API
|
||||||
template<typename T> using SecureVector = secure_vector<T>;
|
template<typename T> using SecureVector = secure_vector<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* AES
|
* AES
|
||||||
* (C) 1999-2010,2015,2017 Jack Lloyd
|
* (C) 1999-2010,2015,2017,2018 Jack Lloyd
|
||||||
*
|
*
|
||||||
* Based on the public domain reference implementation by Paulo Baretto
|
* Based on the public domain reference implementation by Paulo Baretto
|
||||||
*
|
*
|
||||||
@@ -18,14 +18,14 @@
|
|||||||
* countermeasures are used which may be helpful in some situations:
|
* countermeasures are used which may be helpful in some situations:
|
||||||
*
|
*
|
||||||
* - Only a single 256-word T-table is used, with rotations applied.
|
* - Only a single 256-word T-table is used, with rotations applied.
|
||||||
* Most implementations use 4 T-tables which leaks much more
|
* Most implementations use 4 (or sometimes 5) T-tables, which leaks
|
||||||
* information via cache usage.
|
* much more information via cache usage.
|
||||||
*
|
*
|
||||||
* - The TE and TD tables are computed at runtime to avoid flush+reload
|
* - The TE and TD tables are computed at runtime to avoid flush+reload
|
||||||
* attacks using clflush. As different processes will not share the
|
* attacks using clflush. As different processes will not share the
|
||||||
* same underlying table data, an attacker can't manipulate another
|
* same underlying table data, an attacker can't manipulate another
|
||||||
* processes cache lines via their shared reference to the library
|
* processes cache lines via their shared reference to the library
|
||||||
* read only segment.
|
* read only segment. (However, prime+probe attacks are still possible.)
|
||||||
*
|
*
|
||||||
* - Each cache line of the lookup tables is accessed at the beginning
|
* - Each cache line of the lookup tables is accessed at the beginning
|
||||||
* of each call to encrypt or decrypt. (See the Z variable below)
|
* of each call to encrypt or decrypt. (See the Z variable below)
|
||||||
@@ -188,7 +188,6 @@ void aes_encrypt_n(const uint8_t in[], uint8_t out[],
|
|||||||
BOTAN_ASSERT(EK.size() && ME.size() == 16, "Key was set");
|
BOTAN_ASSERT(EK.size() && ME.size() == 16, "Key was set");
|
||||||
|
|
||||||
const size_t cache_line_size = CPUID::cache_line_size();
|
const size_t cache_line_size = CPUID::cache_line_size();
|
||||||
|
|
||||||
const uint32_t* TE = AES_TE();
|
const uint32_t* TE = AES_TE();
|
||||||
|
|
||||||
// Hit every cache line of TE
|
// Hit every cache line of TE
|
||||||
@@ -269,6 +268,10 @@ void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks,
|
|||||||
{
|
{
|
||||||
Z |= TD[i];
|
Z |= TD[i];
|
||||||
}
|
}
|
||||||
|
for(size_t i = 0; i < 256; i += cache_line_size)
|
||||||
|
{
|
||||||
|
Z |= SD[i];
|
||||||
|
}
|
||||||
Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce
|
Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce
|
||||||
|
|
||||||
for(size_t i = 0; i != blocks; ++i)
|
for(size_t i = 0; i != blocks; ++i)
|
||||||
@@ -339,8 +342,24 @@ void aes_key_schedule(const uint8_t key[], size_t length,
|
|||||||
// Can't happen, but make static analyzers happy
|
// Can't happen, but make static analyzers happy
|
||||||
BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size");
|
BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size");
|
||||||
|
|
||||||
|
const uint32_t* TD = AES_TD();
|
||||||
|
|
||||||
|
// Prefetch TD and SE which are used later on in this function
|
||||||
|
volatile uint32_t Z = 0;
|
||||||
|
const size_t cache_line_size = CPUID::cache_line_size();
|
||||||
|
|
||||||
|
for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t))
|
||||||
|
{
|
||||||
|
Z |= TD[i];
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < 256; i += cache_line_size)
|
||||||
|
{
|
||||||
|
Z |= SE[i];
|
||||||
|
}
|
||||||
|
Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce
|
||||||
|
|
||||||
for(size_t i = 0; i != X; ++i)
|
for(size_t i = 0; i != X; ++i)
|
||||||
XEK[i] = load_be<uint32_t>(key, i);
|
XEK[i] = Z ^ load_be<uint32_t>(key, i);
|
||||||
|
|
||||||
for(size_t i = X; i < 4*(rounds+1); i += X)
|
for(size_t i = X; i < 4*(rounds+1); i += X)
|
||||||
{
|
{
|
||||||
@@ -367,8 +386,8 @@ void aes_key_schedule(const uint8_t key[], size_t length,
|
|||||||
|
|
||||||
for(size_t i = 4; i != length + 24; ++i)
|
for(size_t i = 4; i != length + 24; ++i)
|
||||||
{
|
{
|
||||||
XDK[i] = SE_word(XDK[i]);
|
XDK[i] = Z ^ SE_word(XDK[i]);
|
||||||
XDK[i] = AES_T(AES_TD(), 0, XDK[i], XDK[i], XDK[i], XDK[i]);
|
XDK[i] = AES_T(TD, 0, XDK[i], XDK[i], XDK[i], XDK[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ME.resize(16);
|
ME.resize(16);
|
||||||
|
@@ -2,6 +2,4 @@
|
|||||||
AES_NI -> 20131128
|
AES_NI -> 20131128
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
load_on auto
|
|
||||||
|
|
||||||
need_isa aesni
|
need_isa aesni
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
AES_SSSE3 -> 20131128
|
AES_SSSE3 -> 20131128
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
load_on auto
|
|
||||||
|
|
||||||
need_isa ssse3
|
need_isa ssse3
|
||||||
|
|
||||||
# Intel C++ can't deal with syntax for defining constants :(
|
# Intel C++ can't deal with syntax for defining constants :(
|
||||||
|
@@ -98,12 +98,27 @@
|
|||||||
#include <botan/internal/openssl.h>
|
#include <botan/internal/openssl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_COMMONCRYPTO)
|
||||||
|
#include <botan/internal/commoncrypto.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
std::unique_ptr<BlockCipher>
|
std::unique_ptr<BlockCipher>
|
||||||
BlockCipher::create(const std::string& algo,
|
BlockCipher::create(const std::string& algo,
|
||||||
const std::string& provider)
|
const std::string& provider)
|
||||||
{
|
{
|
||||||
|
#if defined(BOTAN_HAS_COMMONCRYPTO)
|
||||||
|
if(provider.empty() || provider == "commoncrypto")
|
||||||
|
{
|
||||||
|
if(auto bc = make_commoncrypto_block_cipher(algo))
|
||||||
|
return bc;
|
||||||
|
|
||||||
|
if(!provider.empty())
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_OPENSSL)
|
#if defined(BOTAN_HAS_OPENSSL)
|
||||||
if(provider.empty() || provider == "openssl")
|
if(provider.empty() || provider == "openssl")
|
||||||
{
|
{
|
||||||
@@ -115,7 +130,6 @@ BlockCipher::create(const std::string& algo,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: CommonCrypto
|
|
||||||
// TODO: CryptoAPI
|
// TODO: CryptoAPI
|
||||||
// TODO: /dev/crypto
|
// TODO: /dev/crypto
|
||||||
|
|
||||||
@@ -343,7 +357,7 @@ BlockCipher::create_or_throw(const std::string& algo,
|
|||||||
|
|
||||||
std::vector<std::string> BlockCipher::providers(const std::string& algo)
|
std::vector<std::string> BlockCipher::providers(const std::string& algo)
|
||||||
{
|
{
|
||||||
return probe_providers_of<BlockCipher>(algo, { "base", "openssl" });
|
return probe_providers_of<BlockCipher>(algo, { "base", "openssl", "commoncrypto" });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -197,36 +197,52 @@ class BOTAN_PUBLIC_API(2,0) BlockCipher : public SymmetricAlgorithm
|
|||||||
virtual ~BlockCipher() = default;
|
virtual ~BlockCipher() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tweakable block ciphers allow setting a tweak which is a non-keyed
|
||||||
|
* value which affects the encryption/decryption operation.
|
||||||
|
*/
|
||||||
|
class BOTAN_PUBLIC_API(2,8) Tweakable_Block_Cipher : public BlockCipher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Set the tweak value. This must be called after setting a key. The value
|
||||||
|
* persists until either set_tweak, set_key, or clear is called.
|
||||||
|
* Different algorithms support different tweak length(s). If called with
|
||||||
|
* an unsupported length, Invalid_Argument will be thrown.
|
||||||
|
*/
|
||||||
|
virtual void set_tweak(const uint8_t tweak[], size_t len) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a block cipher with a single fixed block size
|
* Represents a block cipher with a single fixed block size
|
||||||
*/
|
*/
|
||||||
template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1>
|
template<size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1, typename BaseClass = BlockCipher>
|
||||||
class Block_Cipher_Fixed_Params : public BlockCipher
|
class Block_Cipher_Fixed_Params : public BaseClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { BLOCK_SIZE = BS };
|
enum { BLOCK_SIZE = BS };
|
||||||
size_t block_size() const override { return BS; }
|
size_t block_size() const final override { return BS; }
|
||||||
|
|
||||||
// override to take advantage of compile time constant block size
|
// override to take advantage of compile time constant block size
|
||||||
void encrypt_n_xex(uint8_t data[],
|
void encrypt_n_xex(uint8_t data[],
|
||||||
const uint8_t mask[],
|
const uint8_t mask[],
|
||||||
size_t blocks) const override
|
size_t blocks) const final override
|
||||||
{
|
{
|
||||||
xor_buf(data, mask, blocks * BS);
|
xor_buf(data, mask, blocks * BS);
|
||||||
encrypt_n(data, data, blocks);
|
this->encrypt_n(data, data, blocks);
|
||||||
xor_buf(data, mask, blocks * BS);
|
xor_buf(data, mask, blocks * BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void decrypt_n_xex(uint8_t data[],
|
void decrypt_n_xex(uint8_t data[],
|
||||||
const uint8_t mask[],
|
const uint8_t mask[],
|
||||||
size_t blocks) const override
|
size_t blocks) const final override
|
||||||
{
|
{
|
||||||
xor_buf(data, mask, blocks * BS);
|
xor_buf(data, mask, blocks * BS);
|
||||||
decrypt_n(data, data, blocks);
|
this->decrypt_n(data, data, blocks);
|
||||||
xor_buf(data, mask, blocks * BS);
|
xor_buf(data, mask, blocks * BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Key_Length_Specification key_spec() const override
|
Key_Length_Specification key_spec() const final override
|
||||||
{
|
{
|
||||||
return Key_Length_Specification(KMIN, KMAX, KMOD);
|
return Key_Length_Specification(KMIN, KMAX, KMOD);
|
||||||
}
|
}
|
||||||
|
@@ -6,30 +6,156 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <botan/base64.h>
|
#include <botan/base64.h>
|
||||||
|
#include <botan/internal/codec_base.h>
|
||||||
#include <botan/exceptn.h>
|
#include <botan/exceptn.h>
|
||||||
#include <botan/mem_ops.h>
|
|
||||||
#include <botan/internal/rounding.h>
|
#include <botan/internal/rounding.h>
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const uint8_t BIN_TO_BASE64[64] = {
|
class Base64 final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline size_t encoding_bytes_in() BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return m_encoding_bytes_in;
|
||||||
|
}
|
||||||
|
static inline size_t encoding_bytes_out() BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return m_encoding_bytes_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t decoding_bytes_in() BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return m_encoding_bytes_out;
|
||||||
|
}
|
||||||
|
static inline size_t decoding_bytes_out() BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return m_encoding_bytes_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t bits_consumed() BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return m_encoding_bits;
|
||||||
|
}
|
||||||
|
static inline size_t remaining_bits_before_padding() BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return m_remaining_bits_before_padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t encode_max_output(size_t input_length)
|
||||||
|
{
|
||||||
|
return (round_up(input_length, m_encoding_bytes_in) / m_encoding_bytes_in) * m_encoding_bytes_out;
|
||||||
|
}
|
||||||
|
static inline size_t decode_max_output(size_t input_length)
|
||||||
|
{
|
||||||
|
return (round_up(input_length, m_encoding_bytes_out) * m_encoding_bytes_in) / m_encoding_bytes_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void encode(char out[8], const uint8_t in[5]) BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
out[0] = Base64::m_bin_to_base64[(in[0] & 0xFC) >> 2];
|
||||||
|
out[1] = Base64::m_bin_to_base64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
||||||
|
out[2] = Base64::m_bin_to_base64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
|
||||||
|
out[3] = Base64::m_bin_to_base64[in[2] & 0x3F];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t lookup_binary_value(char input) BOTAN_NOEXCEPT
|
||||||
|
{
|
||||||
|
return Base64::m_base64_to_bin[static_cast<uint8_t>(input)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool check_bad_char(uint8_t bin, char input, bool ignore_ws)
|
||||||
|
{
|
||||||
|
if(bin <= 0x3F)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
|
||||||
|
{
|
||||||
|
std::string bad_char(1, input);
|
||||||
|
if(bad_char == "\t")
|
||||||
|
{ bad_char = "\\t"; }
|
||||||
|
else if(bad_char == "\n")
|
||||||
|
{ bad_char = "\\n"; }
|
||||||
|
else if(bad_char == "\r")
|
||||||
|
{ bad_char = "\\r"; }
|
||||||
|
|
||||||
|
throw Invalid_Argument(
|
||||||
|
std::string("base64_decode: invalid base64 character '") +
|
||||||
|
bad_char + "'");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void decode(uint8_t* out_ptr, const uint8_t decode_buf[4])
|
||||||
|
{
|
||||||
|
out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
|
||||||
|
out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
|
||||||
|
out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t bytes_to_remove(size_t final_truncate)
|
||||||
|
{
|
||||||
|
return final_truncate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const size_t m_encoding_bits = 6;
|
||||||
|
static const size_t m_remaining_bits_before_padding = 8;
|
||||||
|
|
||||||
|
|
||||||
|
static const size_t m_encoding_bytes_in = 3;
|
||||||
|
static const size_t m_encoding_bytes_out = 4;
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t m_bin_to_base64[64];
|
||||||
|
static const uint8_t m_base64_to_bin[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t Base64::m_bin_to_base64[64] =
|
||||||
|
{
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||||
};
|
};
|
||||||
|
|
||||||
void do_base64_encode(char out[4], const uint8_t in[3])
|
/*
|
||||||
|
* base64 Decoder Lookup Table
|
||||||
|
* Warning: assumes ASCII encodings
|
||||||
|
*/
|
||||||
|
const uint8_t Base64::m_base64_to_bin[256] =
|
||||||
{
|
{
|
||||||
out[0] = BIN_TO_BASE64[(in[0] & 0xFC) >> 2];
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
|
||||||
out[1] = BIN_TO_BASE64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
out[2] = BIN_TO_BASE64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
out[3] = BIN_TO_BASE64[in[2] & 0x3F];
|
0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
}
|
0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
|
||||||
|
0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
|
||||||
|
0xFF, 0x81, 0xFF, 0xFF, 0xFF, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
|
||||||
|
0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
|
||||||
|
0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
||||||
|
0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base64_encode(char out[],
|
size_t base64_encode(char out[],
|
||||||
@@ -38,58 +164,24 @@ size_t base64_encode(char out[],
|
|||||||
size_t& input_consumed,
|
size_t& input_consumed,
|
||||||
bool final_inputs)
|
bool final_inputs)
|
||||||
{
|
{
|
||||||
input_consumed = 0;
|
return base_encode(Base64(), out, in, input_length, input_consumed, final_inputs);
|
||||||
|
|
||||||
size_t input_remaining = input_length;
|
|
||||||
size_t output_produced = 0;
|
|
||||||
|
|
||||||
while(input_remaining >= 3)
|
|
||||||
{
|
|
||||||
do_base64_encode(out + output_produced, in + input_consumed);
|
|
||||||
|
|
||||||
input_consumed += 3;
|
|
||||||
output_produced += 4;
|
|
||||||
input_remaining -= 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(final_inputs && input_remaining)
|
|
||||||
{
|
|
||||||
uint8_t remainder[3] = { 0 };
|
|
||||||
for(size_t i = 0; i != input_remaining; ++i)
|
|
||||||
remainder[i] = in[input_consumed + i];
|
|
||||||
|
|
||||||
do_base64_encode(out + output_produced, remainder);
|
|
||||||
|
|
||||||
size_t empty_bits = 8 * (3 - input_remaining);
|
|
||||||
size_t index = output_produced + 4 - 1;
|
|
||||||
while(empty_bits >= 8)
|
|
||||||
{
|
|
||||||
out[index--] = '=';
|
|
||||||
empty_bits -= 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
input_consumed += input_remaining;
|
|
||||||
output_produced += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output_produced;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string base64_encode(const uint8_t input[],
|
std::string base64_encode(const uint8_t input[],
|
||||||
size_t input_length)
|
size_t input_length)
|
||||||
{
|
{
|
||||||
const size_t output_length = base64_encode_max_output(input_length);
|
const size_t output_length = Base64::encode_max_output(input_length);
|
||||||
std::string output(output_length, 0);
|
std::string output(output_length, 0);
|
||||||
|
|
||||||
size_t consumed = 0;
|
size_t consumed = 0;
|
||||||
size_t produced = 0;
|
size_t produced = 0;
|
||||||
|
|
||||||
if (output_length > 0)
|
if(output_length > 0)
|
||||||
{
|
{
|
||||||
produced = base64_encode(&output.front(),
|
produced = base64_encode(&output.front(),
|
||||||
input, input_length,
|
input, input_length,
|
||||||
consumed, true);
|
consumed, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOTAN_ASSERT_EQUAL(consumed, input_length, "Consumed the entire input");
|
BOTAN_ASSERT_EQUAL(consumed, input_length, "Consumed the entire input");
|
||||||
BOTAN_ASSERT_EQUAL(produced, output.size(), "Produced expected size");
|
BOTAN_ASSERT_EQUAL(produced, output.size(), "Produced expected size");
|
||||||
@@ -97,111 +189,14 @@ std::string base64_encode(const uint8_t input[],
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base64_decode(uint8_t output[],
|
size_t base64_decode(uint8_t out[],
|
||||||
const char input[],
|
const char in[],
|
||||||
size_t input_length,
|
size_t input_length,
|
||||||
size_t& input_consumed,
|
size_t& input_consumed,
|
||||||
bool final_inputs,
|
bool final_inputs,
|
||||||
bool ignore_ws)
|
bool ignore_ws)
|
||||||
{
|
{
|
||||||
/*
|
return base_decode(Base64(), out, in, input_length, input_consumed, final_inputs, ignore_ws);
|
||||||
* Base64 Decoder Lookup Table
|
|
||||||
* Warning: assumes ASCII encodings
|
|
||||||
*/
|
|
||||||
static const uint8_t BASE64_TO_BIN[256] = {
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
|
|
||||||
0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
|
|
||||||
0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
|
|
||||||
0xFF, 0x81, 0xFF, 0xFF, 0xFF, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
|
|
||||||
0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
|
|
||||||
0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
|
||||||
0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
|
||||||
|
|
||||||
uint8_t* out_ptr = output;
|
|
||||||
uint8_t decode_buf[4];
|
|
||||||
size_t decode_buf_pos = 0;
|
|
||||||
size_t final_truncate = 0;
|
|
||||||
|
|
||||||
clear_mem(output, input_length * 3 / 4);
|
|
||||||
|
|
||||||
for(size_t i = 0; i != input_length; ++i)
|
|
||||||
{
|
|
||||||
const uint8_t bin = BASE64_TO_BIN[static_cast<uint8_t>(input[i])];
|
|
||||||
|
|
||||||
if(bin <= 0x3F)
|
|
||||||
{
|
|
||||||
decode_buf[decode_buf_pos] = bin;
|
|
||||||
decode_buf_pos += 1;
|
|
||||||
}
|
|
||||||
else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
|
|
||||||
{
|
|
||||||
std::string bad_char(1, input[i]);
|
|
||||||
if(bad_char == "\t")
|
|
||||||
bad_char = "\\t";
|
|
||||||
else if(bad_char == "\n")
|
|
||||||
bad_char = "\\n";
|
|
||||||
else if(bad_char == "\r")
|
|
||||||
bad_char = "\\r";
|
|
||||||
|
|
||||||
throw Invalid_Argument(
|
|
||||||
std::string("base64_decode: invalid base64 character '") +
|
|
||||||
bad_char + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're at the end of the input, pad with 0s and truncate
|
|
||||||
*/
|
|
||||||
if(final_inputs && (i == input_length - 1))
|
|
||||||
{
|
|
||||||
if(decode_buf_pos)
|
|
||||||
{
|
|
||||||
for(size_t j = decode_buf_pos; j != 4; ++j)
|
|
||||||
decode_buf[j] = 0;
|
|
||||||
final_truncate = (4 - decode_buf_pos);
|
|
||||||
decode_buf_pos = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(decode_buf_pos == 4)
|
|
||||||
{
|
|
||||||
out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
|
|
||||||
out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
|
|
||||||
out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
|
|
||||||
|
|
||||||
out_ptr += 3;
|
|
||||||
decode_buf_pos = 0;
|
|
||||||
input_consumed = i+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(input_consumed < input_length &&
|
|
||||||
BASE64_TO_BIN[static_cast<uint8_t>(input[input_consumed])] == 0x80)
|
|
||||||
{
|
|
||||||
++input_consumed;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t written = (out_ptr - output) - final_truncate;
|
|
||||||
|
|
||||||
return written;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base64_decode(uint8_t output[],
|
size_t base64_decode(uint8_t output[],
|
||||||
@@ -214,7 +209,7 @@ size_t base64_decode(uint8_t output[],
|
|||||||
consumed, true, ignore_ws);
|
consumed, true, ignore_ws);
|
||||||
|
|
||||||
if(consumed != input_length)
|
if(consumed != input_length)
|
||||||
throw Invalid_Argument("base64_decode: input did not have full bytes");
|
{ throw Invalid_Argument("base64_decode: input did not have full bytes"); }
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
@@ -227,10 +222,10 @@ size_t base64_decode(uint8_t output[],
|
|||||||
}
|
}
|
||||||
|
|
||||||
secure_vector<uint8_t> base64_decode(const char input[],
|
secure_vector<uint8_t> base64_decode(const char input[],
|
||||||
size_t input_length,
|
size_t input_length,
|
||||||
bool ignore_ws)
|
bool ignore_ws)
|
||||||
{
|
{
|
||||||
const size_t output_length = base64_decode_max_output(input_length);
|
const size_t output_length = Base64::decode_max_output(input_length);
|
||||||
secure_vector<uint8_t> bin(output_length);
|
secure_vector<uint8_t> bin(output_length);
|
||||||
|
|
||||||
size_t written = base64_decode(bin.data(),
|
size_t written = base64_decode(bin.data(),
|
||||||
@@ -243,19 +238,19 @@ secure_vector<uint8_t> base64_decode(const char input[],
|
|||||||
}
|
}
|
||||||
|
|
||||||
secure_vector<uint8_t> base64_decode(const std::string& input,
|
secure_vector<uint8_t> base64_decode(const std::string& input,
|
||||||
bool ignore_ws)
|
bool ignore_ws)
|
||||||
{
|
{
|
||||||
return base64_decode(input.data(), input.size(), ignore_ws);
|
return base64_decode(input.data(), input.size(), ignore_ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base64_encode_max_output(size_t input_length)
|
size_t base64_encode_max_output(size_t input_length)
|
||||||
{
|
{
|
||||||
return (round_up(input_length, 3) / 3) * 4;
|
return Base64::encode_max_output(input_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base64_decode_max_output(size_t input_length)
|
size_t base64_decode_max_output(size_t input_length)
|
||||||
{
|
{
|
||||||
return (round_up(input_length, 4) * 3) / 4;
|
return Base64::decode_max_output(input_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Darwin SecRandomCopyBytes EntropySource
|
|
||||||
* (C) 2015 Daniel Seither (Kullo GmbH)
|
|
||||||
*
|
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <botan/internal/darwin_secrandom.h>
|
|
||||||
#include <Security/Security.h>
|
|
||||||
#include <Security/SecRandom.h>
|
|
||||||
|
|
||||||
namespace Botan {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gather entropy from SecRandomCopyBytes
|
|
||||||
*/
|
|
||||||
size_t Darwin_SecRandom::poll(RandomNumberGenerator& rng)
|
|
||||||
{
|
|
||||||
secure_vector<uint8_t> buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
|
|
||||||
|
|
||||||
if(0 == SecRandomCopyBytes(kSecRandomDefault, buf.size(), buf.data()))
|
|
||||||
{
|
|
||||||
rng.add_entropy(buf.data(), buf.size());
|
|
||||||
return buf.size() * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Darwin SecRandomCopyBytes EntropySource
|
|
||||||
* (C) 2015 Daniel Seither (Kullo GmbH)
|
|
||||||
*
|
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOTAN_ENTROPY_SRC_DARWIN_SECRANDOM_H_
|
|
||||||
#define BOTAN_ENTROPY_SRC_DARWIN_SECRANDOM_H_
|
|
||||||
|
|
||||||
#include <botan/entropy_src.h>
|
|
||||||
|
|
||||||
namespace Botan {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entropy source using SecRandomCopyBytes from Darwin's Security.framework
|
|
||||||
*/
|
|
||||||
class Darwin_SecRandom final : public Entropy_Source
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string name() const override { return "darwin_secrandom"; }
|
|
||||||
|
|
||||||
size_t poll(RandomNumberGenerator& rng) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,16 +0,0 @@
|
|||||||
<defines>
|
|
||||||
ENTROPY_SRC_DARWIN_SECRANDOM -> 20150925
|
|
||||||
</defines>
|
|
||||||
|
|
||||||
<header:internal>
|
|
||||||
darwin_secrandom.h
|
|
||||||
</header:internal>
|
|
||||||
|
|
||||||
<os_features>
|
|
||||||
security_framework
|
|
||||||
</os_features>
|
|
||||||
|
|
||||||
<frameworks>
|
|
||||||
darwin -> Security
|
|
||||||
ios -> Security
|
|
||||||
</frameworks>
|
|
@@ -30,10 +30,7 @@
|
|||||||
|
|
||||||
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
|
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
|
||||||
#include <botan/internal/proc_walk.h>
|
#include <botan/internal/proc_walk.h>
|
||||||
#endif
|
#include <botan/internal/os_utils.h>
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
|
|
||||||
#include <botan/internal/darwin_secrandom.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
|
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
|
||||||
@@ -86,13 +83,6 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
|
|
||||||
if(name == "darwin_secrandom")
|
|
||||||
{
|
|
||||||
return std::unique_ptr<Entropy_Source>(new Darwin_SecRandom);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
|
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
|
||||||
if(name == "getentropy")
|
if(name == "getentropy")
|
||||||
{
|
{
|
||||||
@@ -108,7 +98,7 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
|
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
|
||||||
if(name == "proc_walk")
|
if(name == "proc_walk" && OS::running_in_privileged_state() == false)
|
||||||
{
|
{
|
||||||
const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
|
const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
|
||||||
if(!root_dir.empty())
|
if(!root_dir.empty())
|
||||||
|
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
#include <botan/internal/rdrand.h>
|
#include <botan/internal/rdrand.h>
|
||||||
#include <botan/rdrand_rng.h>
|
#include <botan/rdrand_rng.h>
|
||||||
#include <botan/cpuid.h>
|
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
size_t Intel_Rdrand::poll(RandomNumberGenerator& rng) {
|
size_t Intel_Rdrand::poll(RandomNumberGenerator& rng)
|
||||||
if(CPUID::has_rdrand() && BOTAN_ENTROPY_INTEL_RNG_POLLS > 0)
|
{
|
||||||
|
if(BOTAN_ENTROPY_INTEL_RNG_POLLS > 0 && RDRAND_RNG::available())
|
||||||
{
|
{
|
||||||
RDRAND_RNG rdrand_rng;
|
RDRAND_RNG rdrand_rng;
|
||||||
secure_vector<uint8_t> buf(4 * BOTAN_ENTROPY_INTEL_RNG_POLLS);
|
secure_vector<uint8_t> buf(4 * BOTAN_ENTROPY_INTEL_RNG_POLLS);
|
||||||
|
@@ -15,7 +15,8 @@
|
|||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
BOTAN_FUNC_ISA("rdseed")
|
BOTAN_FUNC_ISA("rdseed")
|
||||||
size_t Intel_Rdseed::poll(RandomNumberGenerator& rng) {
|
size_t Intel_Rdseed::poll(RandomNumberGenerator& rng)
|
||||||
|
{
|
||||||
if(CPUID::has_rdseed())
|
if(CPUID::has_rdseed())
|
||||||
{
|
{
|
||||||
for(size_t p = 0; p != BOTAN_ENTROPY_INTEL_RNG_POLLS; ++p)
|
for(size_t p = 0; p != BOTAN_ENTROPY_INTEL_RNG_POLLS; ++p)
|
||||||
|
20
src/libs/3rdparty/botan/src/lib/filters/filter.h
vendored
20
src/libs/3rdparty/botan/src/lib/filters/filter.h
vendored
@@ -67,28 +67,20 @@ class BOTAN_PUBLIC_API(2,0) Filter
|
|||||||
/**
|
/**
|
||||||
* @param in some input for the filter
|
* @param in some input for the filter
|
||||||
*/
|
*/
|
||||||
void send(const secure_vector<uint8_t>& in) { send(in.data(), in.size()); }
|
template<typename Alloc>
|
||||||
|
void send(const std::vector<uint8_t, Alloc>& in)
|
||||||
/**
|
|
||||||
* @param in some input for the filter
|
|
||||||
*/
|
|
||||||
void send(const std::vector<uint8_t>& in) { send(in.data(), in.size()); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param in some input for the filter
|
|
||||||
* @param length the number of bytes of in to send
|
|
||||||
*/
|
|
||||||
void send(const secure_vector<uint8_t>& in, size_t length)
|
|
||||||
{
|
{
|
||||||
send(in.data(), length);
|
send(in.data(), in.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param in some input for the filter
|
* @param in some input for the filter
|
||||||
* @param length the number of bytes of in to send
|
* @param length the number of bytes of in to send
|
||||||
*/
|
*/
|
||||||
void send(const std::vector<uint8_t>& in, size_t length)
|
template<typename Alloc>
|
||||||
|
void send(const std::vector<uint8_t, Alloc>& in, size_t length)
|
||||||
{
|
{
|
||||||
|
BOTAN_ASSERT_NOMSG(length <= in.size());
|
||||||
send(in.data(), length);
|
send(in.data(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/libs/3rdparty/botan/src/lib/hash/hash.cpp
vendored
20
src/libs/3rdparty/botan/src/lib/hash/hash.cpp
vendored
@@ -101,11 +101,27 @@
|
|||||||
#include <botan/internal/openssl.h>
|
#include <botan/internal/openssl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_COMMONCRYPTO)
|
||||||
|
#include <botan/internal/commoncrypto.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
|
std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
|
||||||
const std::string& provider)
|
const std::string& provider)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_COMMONCRYPTO)
|
||||||
|
if(provider.empty() || provider == "commoncrypto")
|
||||||
|
{
|
||||||
|
if(auto hash = make_commoncrypto_hash(algo_spec))
|
||||||
|
return hash;
|
||||||
|
|
||||||
|
if(!provider.empty())
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_OPENSSL)
|
#if defined(BOTAN_HAS_OPENSSL)
|
||||||
if(provider.empty() || provider == "openssl")
|
if(provider.empty() || provider == "openssl")
|
||||||
{
|
{
|
||||||
@@ -128,8 +144,6 @@ std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: CommonCrypto hashes
|
|
||||||
|
|
||||||
if(provider.empty() == false && provider != "base")
|
if(provider.empty() == false && provider != "base")
|
||||||
return nullptr; // unknown provider
|
return nullptr; // unknown provider
|
||||||
|
|
||||||
@@ -354,7 +368,7 @@ HashFunction::create_or_throw(const std::string& algo,
|
|||||||
|
|
||||||
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
|
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
|
||||||
{
|
{
|
||||||
return probe_providers_of<HashFunction>(algo_spec, {"base", "bearssl", "openssl"});
|
return probe_providers_of<HashFunction>(algo_spec, {"base", "bearssl", "openssl", "commoncrypto"});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -20,15 +20,14 @@ namespace Botan {
|
|||||||
BOTAN_FUNC_ISA("+crypto")
|
BOTAN_FUNC_ISA("+crypto")
|
||||||
void SHA_160::sha1_armv8_compress_n(secure_vector<uint32_t>& digest, const uint8_t input8[], size_t blocks)
|
void SHA_160::sha1_armv8_compress_n(secure_vector<uint32_t>& digest, const uint8_t input8[], size_t blocks)
|
||||||
{
|
{
|
||||||
uint32x4_t C0, C1, C2, C3;
|
uint32x4_t ABCD;
|
||||||
uint32x4_t ABCD, ABCD_SAVED;
|
uint32_t E0;
|
||||||
uint32_t E0, E0_SAVED, E1;
|
|
||||||
|
|
||||||
// Load initial values
|
// Load magic constants
|
||||||
C0 = vdupq_n_u32(0x5A827999);
|
const uint32x4_t C0 = vdupq_n_u32(0x5A827999);
|
||||||
C1 = vdupq_n_u32(0x6ED9EBA1);
|
const uint32x4_t C1 = vdupq_n_u32(0x6ED9EBA1);
|
||||||
C2 = vdupq_n_u32(0x8F1BBCDC);
|
const uint32x4_t C2 = vdupq_n_u32(0x8F1BBCDC);
|
||||||
C3 = vdupq_n_u32(0xCA62C1D6);
|
const uint32x4_t C3 = vdupq_n_u32(0xCA62C1D6);
|
||||||
|
|
||||||
ABCD = vld1q_u32(&digest[0]);
|
ABCD = vld1q_u32(&digest[0]);
|
||||||
E0 = digest[4];
|
E0 = digest[4];
|
||||||
@@ -38,12 +37,13 @@ void SHA_160::sha1_armv8_compress_n(secure_vector<uint32_t>& digest, const uint8
|
|||||||
|
|
||||||
while (blocks)
|
while (blocks)
|
||||||
{
|
{
|
||||||
|
// Save current hash
|
||||||
|
const uint32x4_t ABCD_SAVED = ABCD;
|
||||||
|
const uint32_t E0_SAVED = E0;
|
||||||
|
|
||||||
uint32x4_t MSG0, MSG1, MSG2, MSG3;
|
uint32x4_t MSG0, MSG1, MSG2, MSG3;
|
||||||
uint32x4_t TMP0, TMP1;
|
uint32x4_t TMP0, TMP1;
|
||||||
|
uint32_t E1;
|
||||||
// Save current hash
|
|
||||||
ABCD_SAVED = ABCD;
|
|
||||||
E0_SAVED = E0;
|
|
||||||
|
|
||||||
MSG0 = vld1q_u32(input32 + 0);
|
MSG0 = vld1q_u32(input32 + 0);
|
||||||
MSG1 = vld1q_u32(input32 + 4);
|
MSG1 = vld1q_u32(input32 + 4);
|
||||||
|
@@ -12,6 +12,42 @@
|
|||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
|
std::string BigInt::to_dec_string() const
|
||||||
|
{
|
||||||
|
BigInt copy = *this;
|
||||||
|
copy.set_sign(Positive);
|
||||||
|
|
||||||
|
BigInt remainder;
|
||||||
|
std::vector<uint8_t> digits;
|
||||||
|
|
||||||
|
while(copy > 0)
|
||||||
|
{
|
||||||
|
divide(copy, 10, copy, remainder);
|
||||||
|
digits.push_back(static_cast<uint8_t>(remainder.word_at(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
|
||||||
|
for(auto i = digits.rbegin(); i != digits.rend(); ++i)
|
||||||
|
{
|
||||||
|
s.push_back(Charset::digit2char(*i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s.empty())
|
||||||
|
s += "0";
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BigInt::to_hex_string() const
|
||||||
|
{
|
||||||
|
const std::vector<uint8_t> bits = BigInt::encode(*this);
|
||||||
|
if(bits.empty())
|
||||||
|
return "00";
|
||||||
|
else
|
||||||
|
return hex_encode(bits);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encode a BigInt
|
* Encode a BigInt
|
||||||
*/
|
*/
|
||||||
@@ -53,12 +89,15 @@ void BigInt::encode(uint8_t output[], const BigInt& n, Base base)
|
|||||||
*/
|
*/
|
||||||
std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base)
|
std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base)
|
||||||
{
|
{
|
||||||
|
if(base == Binary)
|
||||||
|
return BigInt::encode(n);
|
||||||
|
|
||||||
std::vector<uint8_t> output(n.encoded_size(base));
|
std::vector<uint8_t> output(n.encoded_size(base));
|
||||||
encode(output.data(), n, base);
|
encode(output.data(), n, base);
|
||||||
if(base != Binary)
|
for(size_t j = 0; j != output.size(); ++j)
|
||||||
for(size_t j = 0; j != output.size(); ++j)
|
if(output[j] == 0)
|
||||||
if(output[j] == 0)
|
output[j] = '0';
|
||||||
output[j] = '0';
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,12 +106,15 @@ std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base)
|
|||||||
*/
|
*/
|
||||||
secure_vector<uint8_t> BigInt::encode_locked(const BigInt& n, Base base)
|
secure_vector<uint8_t> BigInt::encode_locked(const BigInt& n, Base base)
|
||||||
{
|
{
|
||||||
|
if(base == Binary)
|
||||||
|
return BigInt::encode_locked(n);
|
||||||
|
|
||||||
secure_vector<uint8_t> output(n.encoded_size(base));
|
secure_vector<uint8_t> output(n.encoded_size(base));
|
||||||
encode(output.data(), n, base);
|
encode(output.data(), n, base);
|
||||||
if(base != Binary)
|
for(size_t j = 0; j != output.size(); ++j)
|
||||||
for(size_t j = 0; j != output.size(); ++j)
|
if(output[j] == 0)
|
||||||
if(output[j] == 0)
|
output[j] = '0';
|
||||||
output[j] = '0';
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -125,6 +125,24 @@ BigInt operator*(const BigInt& x, const BigInt& y)
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiplication Operator
|
||||||
|
*/
|
||||||
|
BigInt operator*(const BigInt& x, word y)
|
||||||
|
{
|
||||||
|
const size_t x_sw = x.sig_words();
|
||||||
|
|
||||||
|
BigInt z(BigInt::Positive, x_sw + 1);
|
||||||
|
|
||||||
|
if(x_sw && y)
|
||||||
|
{
|
||||||
|
bigint_linmul3(z.mutable_data(), x.data(), x_sw, y);
|
||||||
|
z.set_sign(x.sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Division Operator
|
* Division Operator
|
||||||
*/
|
*/
|
||||||
|
@@ -96,7 +96,7 @@ BigInt::BigInt(const uint8_t input[], size_t length, Base base)
|
|||||||
BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits)
|
BigInt::BigInt(const uint8_t buf[], size_t length, size_t max_bits)
|
||||||
{
|
{
|
||||||
const size_t max_bytes = std::min(length, (max_bits + 7) / 8);
|
const size_t max_bytes = std::min(length, (max_bits + 7) / 8);
|
||||||
*this = decode(buf, max_bytes);
|
binary_decode(buf, max_bytes);
|
||||||
|
|
||||||
const size_t b = this->bits();
|
const size_t b = this->bits();
|
||||||
if(b > max_bits)
|
if(b > max_bits)
|
||||||
@@ -163,18 +163,19 @@ void BigInt::encode_words(word out[], size_t size) const
|
|||||||
*/
|
*/
|
||||||
uint32_t BigInt::get_substring(size_t offset, size_t length) const
|
uint32_t BigInt::get_substring(size_t offset, size_t length) const
|
||||||
{
|
{
|
||||||
if(length > 32)
|
if(length == 0 || length > 32)
|
||||||
throw Invalid_Argument("BigInt::get_substring: Substring size " + std::to_string(length) + " too big");
|
throw Invalid_Argument("BigInt::get_substring invalid substring length");
|
||||||
|
|
||||||
uint64_t piece = 0;
|
const size_t byte_offset = offset / 8;
|
||||||
for(size_t i = 0; i != 8; ++i)
|
|
||||||
{
|
|
||||||
const uint8_t part = byte_at((offset / 8) + (7-i));
|
|
||||||
piece = (piece << 8) | part;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t mask = (static_cast<uint64_t>(1) << length) - 1;
|
|
||||||
const size_t shift = (offset % 8);
|
const size_t shift = (offset % 8);
|
||||||
|
const uint32_t mask = 0xFFFFFFFF >> (32 - length);
|
||||||
|
|
||||||
|
const uint8_t b0 = byte_at(byte_offset);
|
||||||
|
const uint8_t b1 = byte_at(byte_offset + 1);
|
||||||
|
const uint8_t b2 = byte_at(byte_offset + 2);
|
||||||
|
const uint8_t b3 = byte_at(byte_offset + 3);
|
||||||
|
const uint8_t b4 = byte_at(byte_offset + 4);
|
||||||
|
const uint64_t piece = make_uint64(0, 0, 0, b4, b3, b2, b1, b0);
|
||||||
|
|
||||||
return static_cast<uint32_t>((piece >> shift) & mask);
|
return static_cast<uint32_t>((piece >> shift) & mask);
|
||||||
}
|
}
|
||||||
@@ -341,6 +342,21 @@ void BigInt::binary_decode(const uint8_t buf[], size_t length)
|
|||||||
m_reg[length / WORD_BYTES] = (m_reg[length / WORD_BYTES] << 8) | buf[i];
|
m_reg[length / WORD_BYTES] = (m_reg[length / WORD_BYTES] << 8) | buf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BigInt::ct_cond_assign(bool predicate, BigInt& other)
|
||||||
|
{
|
||||||
|
const size_t t_words = size();
|
||||||
|
const size_t o_words = other.size();
|
||||||
|
|
||||||
|
const size_t r_words = std::max(t_words, o_words);
|
||||||
|
|
||||||
|
const word mask = CT::expand_mask<word>(predicate);
|
||||||
|
|
||||||
|
for(size_t i = 0; i != r_words; ++i)
|
||||||
|
{
|
||||||
|
this->set_word_at(i, CT::select<word>(mask, other.word_at(i), this->word_at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_VALGRIND)
|
#if defined(BOTAN_HAS_VALGRIND)
|
||||||
void BigInt::const_time_poison() const
|
void BigInt::const_time_poison() const
|
||||||
{
|
{
|
||||||
|
109
src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h
vendored
109
src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h
vendored
@@ -77,6 +77,13 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
*/
|
*/
|
||||||
BigInt(const uint8_t buf[], size_t length);
|
BigInt(const uint8_t buf[], size_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a BigInt from an integer in a byte array
|
||||||
|
* @param vec the byte vector holding the value
|
||||||
|
*/
|
||||||
|
template<typename Alloc>
|
||||||
|
explicit BigInt(const std::vector<uint8_t, Alloc>& vec) : BigInt(vec.data(), vec.size()) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a BigInt from an integer in a byte array
|
* Create a BigInt from an integer in a byte array
|
||||||
* @param buf the byte array holding the value
|
* @param buf the byte array holding the value
|
||||||
@@ -422,6 +429,17 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
*/
|
*/
|
||||||
uint32_t to_u32bit() const;
|
uint32_t to_u32bit() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert this value to a decimal string.
|
||||||
|
* Warning: decimal conversions are relatively slow
|
||||||
|
*/
|
||||||
|
std::string to_dec_string() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert this value to a hexadecimal string.
|
||||||
|
*/
|
||||||
|
std::string to_hex_string() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param n the offset to get a byte from
|
* @param n the offset to get a byte from
|
||||||
* @result byte at offset n
|
* @result byte at offset n
|
||||||
@@ -616,6 +634,12 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
*/
|
*/
|
||||||
void encode_words(word out[], size_t size) const;
|
void encode_words(word out[], size_t size) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If predicate is true assign other to *this
|
||||||
|
* Uses a masked operation to avoid side channels
|
||||||
|
*/
|
||||||
|
void ct_cond_assign(bool predicate, BigInt& other);
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_VALGRIND)
|
#if defined(BOTAN_HAS_VALGRIND)
|
||||||
void const_time_poison() const;
|
void const_time_poison() const;
|
||||||
void const_time_unpoison() const;
|
void const_time_unpoison() const;
|
||||||
@@ -646,13 +670,78 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the integer value from a BigInt to a std::vector of bytes
|
||||||
|
* @param n the BigInt to use as integer source
|
||||||
|
* @result secure_vector of bytes containing the bytes of the integer
|
||||||
|
*/
|
||||||
|
static std::vector<uint8_t> encode(const BigInt& n)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> output(n.bytes());
|
||||||
|
n.binary_encode(output.data());
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the integer value from a BigInt to a secure_vector of bytes
|
||||||
|
* @param n the BigInt to use as integer source
|
||||||
|
* @result secure_vector of bytes containing the bytes of the integer
|
||||||
|
*/
|
||||||
|
static secure_vector<uint8_t> encode_locked(const BigInt& n)
|
||||||
|
{
|
||||||
|
secure_vector<uint8_t> output(n.bytes());
|
||||||
|
n.binary_encode(output.data());
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the integer value from a BigInt to a byte array
|
||||||
|
* @param buf destination byte array for the encoded integer
|
||||||
|
* @param n the BigInt to use as integer source
|
||||||
|
*/
|
||||||
|
static void encode(uint8_t buf[], const BigInt& n)
|
||||||
|
{
|
||||||
|
n.binary_encode(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a BigInt from an integer in a byte array
|
||||||
|
* @param buf the binary value to load
|
||||||
|
* @param length size of buf
|
||||||
|
* @result BigInt representing the integer in the byte array
|
||||||
|
*/
|
||||||
|
static BigInt decode(const uint8_t buf[], size_t length)
|
||||||
|
{
|
||||||
|
return BigInt(buf, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a BigInt from an integer in a byte array
|
||||||
|
* @param buf the binary value to load
|
||||||
|
* @result BigInt representing the integer in the byte array
|
||||||
|
*/
|
||||||
|
static BigInt decode(const secure_vector<uint8_t>& buf)
|
||||||
|
{
|
||||||
|
return BigInt(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a BigInt from an integer in a byte array
|
||||||
|
* @param buf the binary value to load
|
||||||
|
* @result BigInt representing the integer in the byte array
|
||||||
|
*/
|
||||||
|
static BigInt decode(const std::vector<uint8_t>& buf)
|
||||||
|
{
|
||||||
|
return BigInt(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the integer value from a BigInt to a std::vector of bytes
|
* Encode the integer value from a BigInt to a std::vector of bytes
|
||||||
* @param n the BigInt to use as integer source
|
* @param n the BigInt to use as integer source
|
||||||
* @param base number-base of resulting byte array representation
|
* @param base number-base of resulting byte array representation
|
||||||
* @result secure_vector of bytes containing the integer with given base
|
* @result secure_vector of bytes containing the integer with given base
|
||||||
*/
|
*/
|
||||||
static std::vector<uint8_t> encode(const BigInt& n, Base base = Binary);
|
static std::vector<uint8_t> encode(const BigInt& n, Base base);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the integer value from a BigInt to a secure_vector of bytes
|
* Encode the integer value from a BigInt to a secure_vector of bytes
|
||||||
@@ -661,7 +750,7 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
* @result secure_vector of bytes containing the integer with given base
|
* @result secure_vector of bytes containing the integer with given base
|
||||||
*/
|
*/
|
||||||
static secure_vector<uint8_t> encode_locked(const BigInt& n,
|
static secure_vector<uint8_t> encode_locked(const BigInt& n,
|
||||||
Base base = Binary);
|
Base base);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the integer value from a BigInt to a byte array
|
* Encode the integer value from a BigInt to a byte array
|
||||||
@@ -670,7 +759,7 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
* @param n the BigInt to use as integer source
|
* @param n the BigInt to use as integer source
|
||||||
* @param base number-base of resulting byte array representation
|
* @param base number-base of resulting byte array representation
|
||||||
*/
|
*/
|
||||||
static void encode(uint8_t buf[], const BigInt& n, Base base = Binary);
|
static void encode(uint8_t buf[], const BigInt& n, Base base);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a BigInt from an integer in a byte array
|
* Create a BigInt from an integer in a byte array
|
||||||
@@ -680,7 +769,7 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
* @result BigInt representing the integer in the byte array
|
* @result BigInt representing the integer in the byte array
|
||||||
*/
|
*/
|
||||||
static BigInt decode(const uint8_t buf[], size_t length,
|
static BigInt decode(const uint8_t buf[], size_t length,
|
||||||
Base base = Binary);
|
Base base);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a BigInt from an integer in a byte array
|
* Create a BigInt from an integer in a byte array
|
||||||
@@ -689,8 +778,10 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
* @result BigInt representing the integer in the byte array
|
* @result BigInt representing the integer in the byte array
|
||||||
*/
|
*/
|
||||||
static BigInt decode(const secure_vector<uint8_t>& buf,
|
static BigInt decode(const secure_vector<uint8_t>& buf,
|
||||||
Base base = Binary)
|
Base base)
|
||||||
{
|
{
|
||||||
|
if(base == Binary)
|
||||||
|
return BigInt(buf);
|
||||||
return BigInt::decode(buf.data(), buf.size(), base);
|
return BigInt::decode(buf.data(), buf.size(), base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,9 +791,10 @@ class BOTAN_PUBLIC_API(2,0) BigInt final
|
|||||||
* @param base number-base of the integer in buf
|
* @param base number-base of the integer in buf
|
||||||
* @result BigInt representing the integer in the byte array
|
* @result BigInt representing the integer in the byte array
|
||||||
*/
|
*/
|
||||||
static BigInt decode(const std::vector<uint8_t>& buf,
|
static BigInt decode(const std::vector<uint8_t>& buf, Base base)
|
||||||
Base base = Binary)
|
|
||||||
{
|
{
|
||||||
|
if(base == Binary)
|
||||||
|
return BigInt(buf);
|
||||||
return BigInt::decode(buf.data(), buf.size(), base);
|
return BigInt::decode(buf.data(), buf.size(), base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,6 +842,9 @@ BigInt BOTAN_PUBLIC_API(2,0) operator-(const BigInt& x, const BigInt& y);
|
|||||||
BigInt BOTAN_PUBLIC_API(2,7) operator-(const BigInt& x, word y);
|
BigInt BOTAN_PUBLIC_API(2,7) operator-(const BigInt& x, word y);
|
||||||
|
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) operator*(const BigInt& x, const BigInt& y);
|
BigInt BOTAN_PUBLIC_API(2,0) operator*(const BigInt& x, const BigInt& y);
|
||||||
|
BigInt BOTAN_PUBLIC_API(2,8) operator*(const BigInt& x, word y);
|
||||||
|
inline BigInt operator*(word x, const BigInt& y) { return y*x; }
|
||||||
|
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) operator/(const BigInt& x, const BigInt& d);
|
BigInt BOTAN_PUBLIC_API(2,0) operator/(const BigInt& x, const BigInt& d);
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, const BigInt& m);
|
BigInt BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, const BigInt& m);
|
||||||
word BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, word m);
|
word BOTAN_PUBLIC_API(2,0) operator%(const BigInt& x, word m);
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
BIGINT -> 20131128
|
BIGINT -> 20131128
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
load_on auto
|
|
||||||
|
|
||||||
<header:public>
|
<header:public>
|
||||||
bigint.h
|
bigint.h
|
||||||
divide.h
|
divide.h
|
||||||
|
@@ -353,11 +353,33 @@ void bigint_shl1(word x[], size_t x_size, size_t word_shift, size_t bit_shift)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void bigint_shift_right_1(word x[], size_t x_size)
|
||||||
|
{
|
||||||
|
word carry = 0;
|
||||||
|
size_t top = x_size;
|
||||||
|
|
||||||
|
while(top)
|
||||||
|
{
|
||||||
|
word w = x[top-1];
|
||||||
|
x[top-1] = (w >> 1) | carry;
|
||||||
|
carry = (w << (BOTAN_MP_WORD_BITS - 1));
|
||||||
|
|
||||||
|
top--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Single Operand Right Shift
|
* Single Operand Right Shift
|
||||||
*/
|
*/
|
||||||
void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift)
|
void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift)
|
||||||
{
|
{
|
||||||
|
if(word_shift == 0 && bit_shift == 1)
|
||||||
|
return bigint_shift_right_1(x, x_size);
|
||||||
|
|
||||||
if(x_size < word_shift)
|
if(x_size < word_shift)
|
||||||
{
|
{
|
||||||
clear_mem(x, x_size);
|
clear_mem(x, x_size);
|
||||||
|
@@ -14,15 +14,10 @@
|
|||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
#if (BOTAN_MP_WORD_BITS == 8)
|
#if (BOTAN_MP_WORD_BITS == 32)
|
||||||
typedef uint16_t dword;
|
|
||||||
#define BOTAN_HAS_MP_DWORD
|
|
||||||
#elif (BOTAN_MP_WORD_BITS == 16)
|
|
||||||
typedef uint32_t dword;
|
|
||||||
#define BOTAN_HAS_MP_DWORD
|
|
||||||
#elif (BOTAN_MP_WORD_BITS == 32)
|
|
||||||
typedef uint64_t dword;
|
typedef uint64_t dword;
|
||||||
#define BOTAN_HAS_MP_DWORD
|
#define BOTAN_HAS_MP_DWORD
|
||||||
|
|
||||||
#elif (BOTAN_MP_WORD_BITS == 64)
|
#elif (BOTAN_MP_WORD_BITS == 64)
|
||||||
#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
|
#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
|
||||||
typedef uint128_t dword;
|
typedef uint128_t dword;
|
||||||
@@ -32,21 +27,19 @@ namespace Botan {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64
|
#error BOTAN_MP_WORD_BITS must be 32 or 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_TARGET_ARCH_IS_X86_32) && (BOTAN_MP_WORD_BITS == 32)
|
#if defined(BOTAN_TARGET_ARCH_IS_X86_32) && (BOTAN_MP_WORD_BITS == 32)
|
||||||
|
|
||||||
#if defined(BOTAN_USE_GCC_INLINE_ASM)
|
#if defined(BOTAN_USE_GCC_INLINE_ASM)
|
||||||
#define BOTAN_MP_USE_X86_32_ASM
|
#define BOTAN_MP_USE_X86_32_ASM
|
||||||
#define ASM(x) x "\n\t"
|
|
||||||
#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
|
#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
|
||||||
#define BOTAN_MP_USE_X86_32_MSVC_ASM
|
#define BOTAN_MP_USE_X86_32_MSVC_ASM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64) && (BOTAN_USE_GCC_INLINE_ASM)
|
#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64) && (BOTAN_USE_GCC_INLINE_ASM)
|
||||||
#define BOTAN_MP_USE_X86_64_ASM
|
#define BOTAN_MP_USE_X86_64_ASM
|
||||||
#define ASM(x) x "\n\t"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_MP_USE_X86_32_ASM) || defined(BOTAN_MP_USE_X86_64_ASM)
|
#if defined(BOTAN_MP_USE_X86_32_ASM) || defined(BOTAN_MP_USE_X86_64_ASM)
|
||||||
|
@@ -23,8 +23,6 @@ namespace Botan {
|
|||||||
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p521();
|
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p521();
|
||||||
BOTAN_PUBLIC_API(2,0) void redc_p521(BigInt& x, secure_vector<word>& ws);
|
BOTAN_PUBLIC_API(2,0) void redc_p521(BigInt& x, secure_vector<word>& ws);
|
||||||
|
|
||||||
#if (BOTAN_MP_WORD_BITS == 32) || (BOTAN_MP_WORD_BITS == 64)
|
|
||||||
|
|
||||||
#define BOTAN_HAS_NIST_PRIME_REDUCERS_W32
|
#define BOTAN_HAS_NIST_PRIME_REDUCERS_W32
|
||||||
|
|
||||||
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p384();
|
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p384();
|
||||||
@@ -39,8 +37,6 @@ BOTAN_PUBLIC_API(2,0) void redc_p224(BigInt& x, secure_vector<word>& ws);
|
|||||||
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p192();
|
BOTAN_PUBLIC_API(2,0) const BigInt& prime_p192();
|
||||||
BOTAN_PUBLIC_API(2,0) void redc_p192(BigInt& x, secure_vector<word>& ws);
|
BOTAN_PUBLIC_API(2,0) void redc_p192(BigInt& x, secure_vector<word>& ws);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
NUMBERTHEORY -> 20131128
|
NUMBERTHEORY -> 20131128
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
load_on auto
|
|
||||||
|
|
||||||
<header:public>
|
<header:public>
|
||||||
curve_nistp.h
|
curve_nistp.h
|
||||||
numthry.h
|
numthry.h
|
||||||
@@ -13,6 +11,7 @@ monty.h
|
|||||||
</header:public>
|
</header:public>
|
||||||
|
|
||||||
<header:internal>
|
<header:internal>
|
||||||
|
primality.h
|
||||||
def_powm.h
|
def_powm.h
|
||||||
monty_exp.h
|
monty_exp.h
|
||||||
</header:internal>
|
</header:internal>
|
||||||
|
@@ -14,12 +14,11 @@ namespace Botan {
|
|||||||
*/
|
*/
|
||||||
int32_t jacobi(const BigInt& a, const BigInt& n)
|
int32_t jacobi(const BigInt& a, const BigInt& n)
|
||||||
{
|
{
|
||||||
if(a.is_negative())
|
|
||||||
throw Invalid_Argument("jacobi: first argument must be non-negative");
|
|
||||||
if(n.is_even() || n < 2)
|
if(n.is_even() || n < 2)
|
||||||
throw Invalid_Argument("jacobi: second argument must be odd and > 1");
|
throw Invalid_Argument("jacobi: second argument must be odd and > 1");
|
||||||
|
|
||||||
BigInt x = a, y = n;
|
BigInt x = a % n;
|
||||||
|
BigInt y = n;
|
||||||
int32_t J = 1;
|
int32_t J = 1;
|
||||||
|
|
||||||
while(y > 1)
|
while(y > 1)
|
||||||
|
@@ -14,7 +14,7 @@ namespace Botan {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class Prime_Sieve
|
class Prime_Sieve final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Prime_Sieve(const BigInt& init_value) : m_sieve(PRIME_TABLE_SIZE)
|
Prime_Sieve(const BigInt& init_value) : m_sieve(PRIME_TABLE_SIZE)
|
||||||
|
@@ -13,7 +13,7 @@ namespace Botan {
|
|||||||
Montgomery_Params::Montgomery_Params(const BigInt& p,
|
Montgomery_Params::Montgomery_Params(const BigInt& p,
|
||||||
const Modular_Reducer& mod_p)
|
const Modular_Reducer& mod_p)
|
||||||
{
|
{
|
||||||
if(p.is_negative() || p.is_even())
|
if(p.is_even() || p < 3)
|
||||||
throw Invalid_Argument("Montgomery_Params invalid modulus");
|
throw Invalid_Argument("Montgomery_Params invalid modulus");
|
||||||
|
|
||||||
m_p = p;
|
m_p = p;
|
||||||
|
@@ -44,7 +44,7 @@ Montgomery_Exponentation_State::Montgomery_Exponentation_State(std::shared_ptr<c
|
|||||||
if(m_window_bits < 1 || m_window_bits > 12) // really even 8 is too large ...
|
if(m_window_bits < 1 || m_window_bits > 12) // really even 8 is too large ...
|
||||||
throw Invalid_Argument("Invalid window bits for Montgomery exponentiation");
|
throw Invalid_Argument("Invalid window bits for Montgomery exponentiation");
|
||||||
|
|
||||||
const size_t window_size = (1U << m_window_bits);
|
const size_t window_size = (static_cast<size_t>(1) << m_window_bits);
|
||||||
|
|
||||||
m_g.reserve(window_size);
|
m_g.reserve(window_size);
|
||||||
|
|
||||||
@@ -233,10 +233,10 @@ BigInt monty_multi_exp(std::shared_ptr<const Montgomery_Params> params_p,
|
|||||||
H.square_this(ws);
|
H.square_this(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2);
|
const uint32_t z1_b = z1.get_substring(z_bits - i - 2, 2);
|
||||||
const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2);
|
const uint32_t z2_b = z2.get_substring(z_bits - i - 2, 2);
|
||||||
|
|
||||||
const uint8_t z12 = (4*z2_b) + z1_b;
|
const uint32_t z12 = (4*z2_b) + z1_b;
|
||||||
|
|
||||||
H.mul_by(*M[z12], ws);
|
H.mul_by(*M[z12], ws);
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,7 @@ void redc_p521(BigInt& x, secure_vector<word>& ws)
|
|||||||
BOTAN_ASSERT_EQUAL(carry, 0, "Final carry in P-521 reduction");
|
BOTAN_ASSERT_EQUAL(carry, 0, "Final carry in P-521 reduction");
|
||||||
|
|
||||||
// Now find the actual carry in bit 522
|
// Now find the actual carry in bit 522
|
||||||
const uint8_t bit_522_set = x.word_at(p_full_words) >> (p_top_bits);
|
const word bit_522_set = x.word_at(p_full_words) >> p_top_bits;
|
||||||
|
|
||||||
#if (BOTAN_MP_WORD_BITS == 64)
|
#if (BOTAN_MP_WORD_BITS == 64)
|
||||||
static const word p521_words[9] = {
|
static const word p521_words[9] = {
|
||||||
@@ -91,10 +91,8 @@ inline uint32_t get_uint32_t(const BigInt& x, size_t i)
|
|||||||
{
|
{
|
||||||
#if (BOTAN_MP_WORD_BITS == 32)
|
#if (BOTAN_MP_WORD_BITS == 32)
|
||||||
return x.word_at(i);
|
return x.word_at(i);
|
||||||
#elif (BOTAN_MP_WORD_BITS == 64)
|
|
||||||
return static_cast<uint32_t>(x.word_at(i/2) >> ((i % 2)*32));
|
|
||||||
#else
|
#else
|
||||||
#error "Not implemented"
|
return static_cast<uint32_t>(x.word_at(i/2) >> ((i % 2)*32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,10 +101,8 @@ inline void set_words(BigInt& x, size_t i, uint32_t R0, uint32_t R1)
|
|||||||
#if (BOTAN_MP_WORD_BITS == 32)
|
#if (BOTAN_MP_WORD_BITS == 32)
|
||||||
x.set_word_at(i, R0);
|
x.set_word_at(i, R0);
|
||||||
x.set_word_at(i+1, R1);
|
x.set_word_at(i+1, R1);
|
||||||
#elif (BOTAN_MP_WORD_BITS == 64)
|
|
||||||
x.set_word_at(i/2, (static_cast<uint64_t>(R1) << 32) | R0);
|
|
||||||
#else
|
#else
|
||||||
#error "Not implemented"
|
x.set_word_at(i/2, (static_cast<uint64_t>(R1) << 32) | R0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <botan/internal/mp_core.h>
|
#include <botan/internal/mp_core.h>
|
||||||
#include <botan/internal/ct_utils.h>
|
#include <botan/internal/ct_utils.h>
|
||||||
#include <botan/internal/monty_exp.h>
|
#include <botan/internal/monty_exp.h>
|
||||||
|
#include <botan/internal/primality.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
@@ -434,78 +435,43 @@ BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
bool mr_witness(BigInt&& y,
|
BigInt is_perfect_square(const BigInt& C)
|
||||||
const Modular_Reducer& reducer_n,
|
|
||||||
const BigInt& n_minus_1, size_t s)
|
|
||||||
{
|
{
|
||||||
if(y == 1 || y == n_minus_1)
|
if(C < 1)
|
||||||
return false;
|
throw Invalid_Argument("is_perfect_square requires C >= 1");
|
||||||
|
if(C == 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
for(size_t i = 1; i != s; ++i)
|
const size_t n = C.bits();
|
||||||
|
const size_t m = (n + 1) / 2;
|
||||||
|
const BigInt B = C + BigInt::power_of_2(m);
|
||||||
|
|
||||||
|
BigInt X = BigInt::power_of_2(m) - 1;
|
||||||
|
BigInt X2 = (X*X);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
{
|
{
|
||||||
y = reducer_n.square(y);
|
X = (X2 + C) / (2*X);
|
||||||
|
X2 = (X*X);
|
||||||
|
|
||||||
if(y == 1) // found a non-trivial square root
|
if(X2 < B)
|
||||||
return true;
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
-1 is the trivial square root of unity, so ``a`` is not a
|
|
||||||
witness for this number - give up
|
|
||||||
*/
|
|
||||||
if(y == n_minus_1)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true; // is a witness
|
if(X2 == C)
|
||||||
|
return X;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mr_test_iterations(size_t n_bits, size_t prob, bool random)
|
|
||||||
{
|
|
||||||
const size_t base = (prob + 2) / 2; // worst case 4^-t error rate
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the candidate prime was maliciously constructed, we can't rely
|
|
||||||
* on arguments based on p being random.
|
|
||||||
*/
|
|
||||||
if(random == false)
|
|
||||||
return base;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For randomly chosen numbers we can use the estimates from
|
|
||||||
* http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
|
|
||||||
*
|
|
||||||
* These values are derived from the inequality for p(k,t) given on
|
|
||||||
* the second page.
|
|
||||||
*/
|
|
||||||
if(prob <= 128)
|
|
||||||
{
|
|
||||||
if(n_bits >= 1536)
|
|
||||||
return 4; // < 2^-133
|
|
||||||
if(n_bits >= 1024)
|
|
||||||
return 6; // < 2^-133
|
|
||||||
if(n_bits >= 512)
|
|
||||||
return 12; // < 2^-129
|
|
||||||
if(n_bits >= 256)
|
|
||||||
return 29; // < 2^-128
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
If the user desires a smaller error probability than we have
|
|
||||||
precomputed error estimates for, just fall back to using the worst
|
|
||||||
case error rate.
|
|
||||||
*/
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test for primality using Miller-Rabin
|
* Test for primality using Miller-Rabin
|
||||||
*/
|
*/
|
||||||
bool is_prime(const BigInt& n, RandomNumberGenerator& rng,
|
bool is_prime(const BigInt& n,
|
||||||
size_t prob, bool is_random)
|
RandomNumberGenerator& rng,
|
||||||
|
size_t prob,
|
||||||
|
bool is_random)
|
||||||
{
|
{
|
||||||
if(n == 2)
|
if(n == 2)
|
||||||
return true;
|
return true;
|
||||||
@@ -520,47 +486,21 @@ bool is_prime(const BigInt& n, RandomNumberGenerator& rng,
|
|||||||
return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
|
return std::binary_search(PRIMES, PRIMES + PRIME_TABLE_SIZE, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t test_iterations =
|
const size_t t = miller_rabin_test_iterations(n.bits(), prob, is_random);
|
||||||
mr_test_iterations(n.bits(), prob, is_random && rng.is_seeded());
|
|
||||||
|
|
||||||
const BigInt n_minus_1 = n - 1;
|
Modular_Reducer mod_n(n);
|
||||||
const size_t s = low_zero_bits(n_minus_1);
|
|
||||||
const BigInt nm1_s = n_minus_1 >> s;
|
|
||||||
const size_t n_bits = n.bits();
|
|
||||||
|
|
||||||
const Modular_Reducer mod_n(n);
|
if(rng.is_seeded())
|
||||||
auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
|
|
||||||
|
|
||||||
const size_t powm_window = 4;
|
|
||||||
|
|
||||||
for(size_t i = 0; i != test_iterations; ++i)
|
|
||||||
{
|
{
|
||||||
BigInt a;
|
if(is_miller_rabin_probable_prime(n, mod_n, rng, t) == false)
|
||||||
|
|
||||||
if(rng.is_seeded())
|
|
||||||
{
|
|
||||||
a = BigInt::random_integer(rng, 2, n_minus_1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If passed a null RNG just use 2,3,5, ... as bases
|
|
||||||
*
|
|
||||||
* This is not ideal but in certain circumstances we need to
|
|
||||||
* test for primality but have no RNG available.
|
|
||||||
*/
|
|
||||||
a = PRIMES[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
auto powm_a_n = monty_precompute(monty_n, a, powm_window);
|
|
||||||
|
|
||||||
BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits);
|
|
||||||
|
|
||||||
if(mr_witness(std::move(y), mod_n, n_minus_1, s))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return is_lucas_probable_prime(n, mod_n);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return is_bailie_psw_probable_prime(n, mod_n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Number Theory Functions
|
* Number Theory Functions
|
||||||
* (C) 1999-2007 Jack Lloyd
|
* (C) 1999-2007,2018 Jack Lloyd
|
||||||
*
|
*
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
*/
|
*/
|
||||||
@@ -22,8 +22,8 @@ class RandomNumberGenerator;
|
|||||||
* @return (a*b)+c
|
* @return (a*b)+c
|
||||||
*/
|
*/
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a,
|
BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a,
|
||||||
const BigInt& b,
|
const BigInt& b,
|
||||||
const BigInt& c);
|
const BigInt& c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fused subtract-multiply
|
* Fused subtract-multiply
|
||||||
@@ -33,8 +33,8 @@ BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a,
|
|||||||
* @return (a-b)*c
|
* @return (a-b)*c
|
||||||
*/
|
*/
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a,
|
BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a,
|
||||||
const BigInt& b,
|
const BigInt& b,
|
||||||
const BigInt& c);
|
const BigInt& c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fused multiply-subtract
|
* Fused multiply-subtract
|
||||||
@@ -44,8 +44,8 @@ BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a,
|
|||||||
* @return (a*b)-c
|
* @return (a*b)-c
|
||||||
*/
|
*/
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) mul_sub(const BigInt& a,
|
BigInt BOTAN_PUBLIC_API(2,0) mul_sub(const BigInt& a,
|
||||||
const BigInt& b,
|
const BigInt& b,
|
||||||
const BigInt& c);
|
const BigInt& c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the absolute value
|
* Return the absolute value
|
||||||
@@ -108,8 +108,8 @@ BigInt BOTAN_PUBLIC_API(2,0) ct_inverse_mod_odd_modulus(const BigInt& n, const B
|
|||||||
* Not const time
|
* Not const time
|
||||||
*/
|
*/
|
||||||
size_t BOTAN_PUBLIC_API(2,0) almost_montgomery_inverse(BigInt& result,
|
size_t BOTAN_PUBLIC_API(2,0) almost_montgomery_inverse(BigInt& result,
|
||||||
const BigInt& a,
|
const BigInt& a,
|
||||||
const BigInt& b);
|
const BigInt& b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call almost_montgomery_inverse and correct the result to a^-1 mod b
|
* Call almost_montgomery_inverse and correct the result to a^-1 mod b
|
||||||
@@ -126,8 +126,7 @@ BigInt BOTAN_PUBLIC_API(2,0) normalized_montgomery_inverse(const BigInt& a, cons
|
|||||||
* @param n is an odd integer > 1
|
* @param n is an odd integer > 1
|
||||||
* @return (n / m)
|
* @return (n / m)
|
||||||
*/
|
*/
|
||||||
int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a,
|
int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a, const BigInt& n);
|
||||||
const BigInt& n);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modular exponentation
|
* Modular exponentation
|
||||||
@@ -137,8 +136,8 @@ int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a,
|
|||||||
* @return (b^x) % m
|
* @return (b^x) % m
|
||||||
*/
|
*/
|
||||||
BigInt BOTAN_PUBLIC_API(2,0) power_mod(const BigInt& b,
|
BigInt BOTAN_PUBLIC_API(2,0) power_mod(const BigInt& b,
|
||||||
const BigInt& x,
|
const BigInt& x,
|
||||||
const BigInt& m);
|
const BigInt& m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the square root of x modulo a prime using the
|
* Compute the square root of x modulo a prime using the
|
||||||
@@ -175,9 +174,18 @@ size_t BOTAN_PUBLIC_API(2,0) low_zero_bits(const BigInt& x);
|
|||||||
*/
|
*/
|
||||||
bool BOTAN_PUBLIC_API(2,0) is_prime(const BigInt& n,
|
bool BOTAN_PUBLIC_API(2,0) is_prime(const BigInt& n,
|
||||||
RandomNumberGenerator& rng,
|
RandomNumberGenerator& rng,
|
||||||
size_t prob = 56,
|
size_t prob = 64,
|
||||||
bool is_random = false);
|
bool is_random = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if the positive integer x is a perfect square ie if there
|
||||||
|
* exists some positive integer y st y*y == x
|
||||||
|
* See FIPS 186-4 sec C.4
|
||||||
|
* @return 0 if the integer is not a perfect square, otherwise
|
||||||
|
* returns the positive y st y*y == x
|
||||||
|
*/
|
||||||
|
BigInt BOTAN_PUBLIC_API(2,8) is_perfect_square(const BigInt& x);
|
||||||
|
|
||||||
inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng)
|
inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng)
|
||||||
{ return is_prime(n, rng, 32); }
|
{ return is_prime(n, rng, 32); }
|
||||||
|
|
||||||
@@ -187,7 +195,6 @@ inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng)
|
|||||||
inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng)
|
inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng)
|
||||||
{ return is_prime(n, rng, 80); }
|
{ return is_prime(n, rng, 80); }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Randomly generate a prime suitable for discrete logarithm parameters
|
* Randomly generate a prime suitable for discrete logarithm parameters
|
||||||
* @param rng a random number generator
|
* @param rng a random number generator
|
||||||
|
@@ -25,7 +25,7 @@ void Fixed_Window_Exponentiator::set_base(const BigInt& base)
|
|||||||
{
|
{
|
||||||
m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints);
|
m_window_bits = Power_Mod::window_bits(m_exp.bits(), base.bits(), m_hints);
|
||||||
|
|
||||||
m_g.resize(1U << m_window_bits);
|
m_g.resize(static_cast<size_t>(1) << m_window_bits);
|
||||||
m_g[0] = 1;
|
m_g[0] = 1;
|
||||||
m_g[1] = base;
|
m_g[1] = base;
|
||||||
|
|
||||||
|
206
src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.cpp
vendored
Normal file
206
src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.cpp
vendored
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* (C) 2016,2018 Jack Lloyd
|
||||||
|
*
|
||||||
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <botan/internal/primality.h>
|
||||||
|
#include <botan/internal/monty_exp.h>
|
||||||
|
#include <botan/bigint.h>
|
||||||
|
#include <botan/monty.h>
|
||||||
|
#include <botan/reducer.h>
|
||||||
|
#include <botan/rng.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Botan {
|
||||||
|
|
||||||
|
bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C)
|
||||||
|
{
|
||||||
|
if(C <= 1)
|
||||||
|
return false;
|
||||||
|
else if(C == 2)
|
||||||
|
return true;
|
||||||
|
else if(C.is_even())
|
||||||
|
return false;
|
||||||
|
else if(C == 3 || C == 5 || C == 7 || C == 11 || C == 13)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
BigInt D = 5;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
int32_t j = jacobi(D, C);
|
||||||
|
if(j == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(j == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check 5, -7, 9, -11, 13, -15, 17, ...
|
||||||
|
if(D.is_negative())
|
||||||
|
{
|
||||||
|
D.flip_sign();
|
||||||
|
D += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D += 2;
|
||||||
|
D.flip_sign();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(D == 17 && is_perfect_square(C).is_nonzero())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BigInt K = C + 1;
|
||||||
|
const size_t K_bits = K.bits() - 1;
|
||||||
|
|
||||||
|
BigInt U = 1;
|
||||||
|
BigInt V = 1;
|
||||||
|
|
||||||
|
BigInt Ut, Vt, U2, V2;
|
||||||
|
|
||||||
|
for(size_t i = 0; i != K_bits; ++i)
|
||||||
|
{
|
||||||
|
const uint8_t k_bit = K.get_bit(K_bits - 1 - i);
|
||||||
|
|
||||||
|
Ut = mod_C.multiply(U, V);
|
||||||
|
|
||||||
|
Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U)));
|
||||||
|
if(Vt.is_odd())
|
||||||
|
Vt += C;
|
||||||
|
Vt >>= 1;
|
||||||
|
Vt = mod_C.reduce(Vt);
|
||||||
|
|
||||||
|
U = Ut;
|
||||||
|
V = Vt;
|
||||||
|
|
||||||
|
U2 = mod_C.reduce(Ut + Vt);
|
||||||
|
if(U2.is_odd())
|
||||||
|
U2 += C;
|
||||||
|
U2 >>= 1;
|
||||||
|
|
||||||
|
V2 = mod_C.reduce(Vt + Ut*D);
|
||||||
|
if(V2.is_odd())
|
||||||
|
V2 += C;
|
||||||
|
V2 >>= 1;
|
||||||
|
|
||||||
|
U.ct_cond_assign(k_bit, U2);
|
||||||
|
V.ct_cond_assign(k_bit, V2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (U == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n)
|
||||||
|
{
|
||||||
|
auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
|
||||||
|
return passes_miller_rabin_test(n, mod_n, monty_n, 2) && is_lucas_probable_prime(n, mod_n);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_bailie_psw_probable_prime(const BigInt& n)
|
||||||
|
{
|
||||||
|
Modular_Reducer mod_n(n);
|
||||||
|
return is_bailie_psw_probable_prime(n, mod_n);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool passes_miller_rabin_test(const BigInt& n,
|
||||||
|
const Modular_Reducer& mod_n,
|
||||||
|
const std::shared_ptr<Montgomery_Params>& monty_n,
|
||||||
|
const BigInt& a)
|
||||||
|
{
|
||||||
|
BOTAN_ASSERT_NOMSG(n > 1);
|
||||||
|
|
||||||
|
const BigInt n_minus_1 = n - 1;
|
||||||
|
const size_t s = low_zero_bits(n_minus_1);
|
||||||
|
const BigInt nm1_s = n_minus_1 >> s;
|
||||||
|
const size_t n_bits = n.bits();
|
||||||
|
|
||||||
|
const size_t powm_window = 4;
|
||||||
|
|
||||||
|
auto powm_a_n = monty_precompute(monty_n, a, powm_window);
|
||||||
|
|
||||||
|
BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits);
|
||||||
|
|
||||||
|
if(y == 1 || y == n_minus_1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for(size_t i = 1; i != s; ++i)
|
||||||
|
{
|
||||||
|
y = mod_n.square(y);
|
||||||
|
|
||||||
|
if(y == 1) // found a non-trivial square root
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
-1 is the trivial square root of unity, so ``a`` is not a
|
||||||
|
witness for this number - give up
|
||||||
|
*/
|
||||||
|
if(y == n_minus_1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_miller_rabin_probable_prime(const BigInt& n,
|
||||||
|
const Modular_Reducer& mod_n,
|
||||||
|
RandomNumberGenerator& rng,
|
||||||
|
size_t test_iterations)
|
||||||
|
{
|
||||||
|
BOTAN_ASSERT_NOMSG(n > 1);
|
||||||
|
|
||||||
|
auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
|
||||||
|
|
||||||
|
for(size_t i = 0; i != test_iterations; ++i)
|
||||||
|
{
|
||||||
|
const BigInt a = BigInt::random_integer(rng, 2, n);
|
||||||
|
|
||||||
|
if(!passes_miller_rabin_test(n, mod_n, monty_n, a))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to find a counterexample
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random)
|
||||||
|
{
|
||||||
|
const size_t base = (prob + 2) / 2; // worst case 4^-t error rate
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the candidate prime was maliciously constructed, we can't rely
|
||||||
|
* on arguments based on p being random.
|
||||||
|
*/
|
||||||
|
if(random == false)
|
||||||
|
return base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For randomly chosen numbers we can use the estimates from
|
||||||
|
* http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
|
||||||
|
*
|
||||||
|
* These values are derived from the inequality for p(k,t) given on
|
||||||
|
* the second page.
|
||||||
|
*/
|
||||||
|
if(prob <= 128)
|
||||||
|
{
|
||||||
|
if(n_bits >= 1536)
|
||||||
|
return 4; // < 2^-133
|
||||||
|
if(n_bits >= 1024)
|
||||||
|
return 6; // < 2^-133
|
||||||
|
if(n_bits >= 512)
|
||||||
|
return 12; // < 2^-129
|
||||||
|
if(n_bits >= 256)
|
||||||
|
return 29; // < 2^-128
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the user desires a smaller error probability than we have
|
||||||
|
precomputed error estimates for, just fall back to using the worst
|
||||||
|
case error rate.
|
||||||
|
*/
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
100
src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.h
vendored
Normal file
100
src/libs/3rdparty/botan/src/lib/math/numbertheory/primality.h
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* (C) 2018 Jack Lloyd
|
||||||
|
*
|
||||||
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOTAN_PRIMALITY_TEST_H_
|
||||||
|
#define BOTAN_PRIMALITY_TEST_H_
|
||||||
|
|
||||||
|
#include <botan/types.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Botan {
|
||||||
|
|
||||||
|
class BigInt;
|
||||||
|
class Modular_Reducer;
|
||||||
|
class Montgomery_Params;
|
||||||
|
class RandomNumberGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform Lucas primality test
|
||||||
|
* @see FIPS 186-4 C.3.3
|
||||||
|
*
|
||||||
|
* @warning it is possible to construct composite integers which pass
|
||||||
|
* this test alone.
|
||||||
|
*
|
||||||
|
* @param n the positive integer to test
|
||||||
|
* @param mod_n a pre-created Modular_Reducer for n
|
||||||
|
* @return true if n seems probably prime, false if n is composite
|
||||||
|
*/
|
||||||
|
bool BOTAN_TEST_API is_lucas_probable_prime(const BigInt& n, const Modular_Reducer& mod_n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform Bailie-PSW primality test
|
||||||
|
*
|
||||||
|
* This is a combination of Miller-Rabin with base 2 and a Lucas test. No known
|
||||||
|
* composite integer passes both tests, though it is conjectured that infinitely
|
||||||
|
* many composite counterexamples exist.
|
||||||
|
*
|
||||||
|
* @param n the positive integer to test
|
||||||
|
* @param mod_n a pre-created Modular_Reducer for n
|
||||||
|
* @return true if n seems probably prime, false if n is composite
|
||||||
|
*/
|
||||||
|
bool BOTAN_TEST_API is_bailie_psw_probable_prime(const BigInt& n, const Modular_Reducer& mod_n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform Bailie-PSW primality test
|
||||||
|
*
|
||||||
|
* This is a combination of Miller-Rabin with base 2 and a Lucas test. No known
|
||||||
|
* composite integer passes both tests, though it is conjectured that infinitely
|
||||||
|
* many composite counterexamples exist.
|
||||||
|
*
|
||||||
|
* @param n the positive integer to test
|
||||||
|
* @return true if n seems probably prime, false if n is composite
|
||||||
|
*/
|
||||||
|
bool is_bailie_psw_probable_prime(const BigInt& n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return required number of Miller-Rabin tests in order to
|
||||||
|
* reach the specified probability of error.
|
||||||
|
*
|
||||||
|
* @param n_bits the bit-length of the integer being tested
|
||||||
|
* @param prob chance of false positive is bounded by 1/2**prob
|
||||||
|
* @param random is set if (and only if) the integer was randomly generated by us
|
||||||
|
* and thus cannot have been maliciously constructed.
|
||||||
|
*/
|
||||||
|
size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a single Miller-Rabin test with specified base
|
||||||
|
*
|
||||||
|
* @param n the positive integer to test
|
||||||
|
* @param mod_n a pre-created Modular_Reducer for n
|
||||||
|
* @param monty_n Montgomery parameters for n
|
||||||
|
* @param a the base to check
|
||||||
|
* @return result of primality test
|
||||||
|
*/
|
||||||
|
bool passes_miller_rabin_test(const BigInt& n,
|
||||||
|
const Modular_Reducer& mod_n,
|
||||||
|
const std::shared_ptr<Montgomery_Params>& monty_n,
|
||||||
|
const BigInt& a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform t iterations of a Miller-Rabin primality test with random bases
|
||||||
|
*
|
||||||
|
* @param n the positive integer to test
|
||||||
|
* @param mod_n a pre-created Modular_Reducer for n
|
||||||
|
* @param rng a random number generator
|
||||||
|
* @param t number of tests to perform
|
||||||
|
*
|
||||||
|
* @return result of primality test
|
||||||
|
*/
|
||||||
|
bool BOTAN_TEST_API is_miller_rabin_probable_prime(const BigInt& n,
|
||||||
|
const Modular_Reducer& mod_n,
|
||||||
|
RandomNumberGenerator& rng,
|
||||||
|
size_t t);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -32,11 +32,18 @@ Modular_Reducer::Modular_Reducer(const BigInt& mod)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Barrett Reduction
|
|
||||||
*/
|
|
||||||
BigInt Modular_Reducer::reduce(const BigInt& x) const
|
BigInt Modular_Reducer::reduce(const BigInt& x) const
|
||||||
{
|
{
|
||||||
|
BigInt r;
|
||||||
|
secure_vector<word> ws;
|
||||||
|
reduce(r, x, ws);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector<word>& ws) const
|
||||||
|
{
|
||||||
|
if(&t1 == &x)
|
||||||
|
throw Invalid_State("Modular_Reducer arguments cannot alias");
|
||||||
if(m_mod_words == 0)
|
if(m_mod_words == 0)
|
||||||
throw Invalid_State("Modular_Reducer: Never initalized");
|
throw Invalid_State("Modular_Reducer: Never initalized");
|
||||||
|
|
||||||
@@ -45,12 +52,11 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const
|
|||||||
if(x_sw >= (2*m_mod_words - 1) && x.cmp(m_modulus_2, false) >= 0)
|
if(x_sw >= (2*m_mod_words - 1) && x.cmp(m_modulus_2, false) >= 0)
|
||||||
{
|
{
|
||||||
// too big, fall back to normal division
|
// too big, fall back to normal division
|
||||||
return (x % m_modulus);
|
t1 = x % m_modulus;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
secure_vector<word> ws;
|
t1 = x;
|
||||||
|
|
||||||
BigInt t1 = x;
|
|
||||||
t1.set_sign(BigInt::Positive);
|
t1.set_sign(BigInt::Positive);
|
||||||
t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1));
|
t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1));
|
||||||
|
|
||||||
@@ -83,8 +89,6 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const
|
|||||||
{
|
{
|
||||||
t1.rev_sub(m_modulus.data(), m_modulus.size(), ws);
|
t1.rev_sub(m_modulus.data(), m_modulus.size(), ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
return t1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,8 @@ class BOTAN_PUBLIC_API(2,0) Modular_Reducer
|
|||||||
BigInt cube(const BigInt& x) const
|
BigInt cube(const BigInt& x) const
|
||||||
{ return multiply(x, this->square(x)); }
|
{ return multiply(x, this->square(x)); }
|
||||||
|
|
||||||
|
void reduce(BigInt& out, const BigInt& x, secure_vector<word>& ws) const;
|
||||||
|
|
||||||
bool initialized() const { return (m_mod_words != 0); }
|
bool initialized() const { return (m_mod_words != 0); }
|
||||||
|
|
||||||
Modular_Reducer() { m_mod_words = 0; }
|
Modular_Reducer() { m_mod_words = 0; }
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
* CBC Mode
|
* CBC Mode
|
||||||
* (C) 1999-2007,2013,2017 Jack Lloyd
|
* (C) 1999-2007,2013,2017 Jack Lloyd
|
||||||
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
|
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
|
||||||
|
* (C) 2018 Ribose Inc
|
||||||
*
|
*
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
*/
|
*/
|
||||||
@@ -15,9 +16,9 @@ namespace Botan {
|
|||||||
CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
|
CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
|
||||||
m_cipher(cipher),
|
m_cipher(cipher),
|
||||||
m_padding(padding),
|
m_padding(padding),
|
||||||
m_state(m_cipher->block_size())
|
m_block_size(cipher->block_size())
|
||||||
{
|
{
|
||||||
if(m_padding && !m_padding->valid_blocksize(cipher->block_size()))
|
if(m_padding && !m_padding->valid_blocksize(m_block_size))
|
||||||
throw Invalid_Argument("Padding " + m_padding->name() +
|
throw Invalid_Argument("Padding " + m_padding->name() +
|
||||||
" cannot be used with " +
|
" cannot be used with " +
|
||||||
cipher->name() + "/CBC");
|
cipher->name() + "/CBC");
|
||||||
@@ -31,7 +32,7 @@ void CBC_Mode::clear()
|
|||||||
|
|
||||||
void CBC_Mode::reset()
|
void CBC_Mode::reset()
|
||||||
{
|
{
|
||||||
zeroise(m_state);
|
m_state.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CBC_Mode::name() const
|
std::string CBC_Mode::name() const
|
||||||
@@ -65,6 +66,7 @@ bool CBC_Mode::valid_nonce_length(size_t n) const
|
|||||||
void CBC_Mode::key_schedule(const uint8_t key[], size_t length)
|
void CBC_Mode::key_schedule(const uint8_t key[], size_t length)
|
||||||
{
|
{
|
||||||
m_cipher->set_key(key, length);
|
m_cipher->set_key(key, length);
|
||||||
|
m_state.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
|
void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
|
||||||
@@ -79,6 +81,9 @@ void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
|
|||||||
*/
|
*/
|
||||||
if(nonce_len)
|
if(nonce_len)
|
||||||
m_state.assign(nonce, nonce + nonce_len);
|
m_state.assign(nonce, nonce + nonce_len);
|
||||||
|
else if(m_state.empty())
|
||||||
|
m_state.resize(m_cipher->block_size());
|
||||||
|
// else leave the state alone
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CBC_Encryption::minimum_final_size() const
|
size_t CBC_Encryption::minimum_final_size() const
|
||||||
@@ -96,6 +101,7 @@ size_t CBC_Encryption::output_length(size_t input_length) const
|
|||||||
|
|
||||||
size_t CBC_Encryption::process(uint8_t buf[], size_t sz)
|
size_t CBC_Encryption::process(uint8_t buf[], size_t sz)
|
||||||
{
|
{
|
||||||
|
BOTAN_STATE_CHECK(state().empty() == false);
|
||||||
const size_t BS = block_size();
|
const size_t BS = block_size();
|
||||||
|
|
||||||
BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks");
|
BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks");
|
||||||
@@ -120,6 +126,7 @@ size_t CBC_Encryption::process(uint8_t buf[], size_t sz)
|
|||||||
|
|
||||||
void CBC_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
void CBC_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
||||||
{
|
{
|
||||||
|
BOTAN_STATE_CHECK(state().empty() == false);
|
||||||
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
||||||
|
|
||||||
const size_t BS = block_size();
|
const size_t BS = block_size();
|
||||||
@@ -151,6 +158,7 @@ size_t CTS_Encryption::output_length(size_t input_length) const
|
|||||||
|
|
||||||
void CTS_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
void CTS_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
||||||
{
|
{
|
||||||
|
BOTAN_STATE_CHECK(state().empty() == false);
|
||||||
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
||||||
uint8_t* buf = buffer.data() + offset;
|
uint8_t* buf = buffer.data() + offset;
|
||||||
const size_t sz = buffer.size() - offset;
|
const size_t sz = buffer.size() - offset;
|
||||||
@@ -205,6 +213,8 @@ size_t CBC_Decryption::minimum_final_size() const
|
|||||||
|
|
||||||
size_t CBC_Decryption::process(uint8_t buf[], size_t sz)
|
size_t CBC_Decryption::process(uint8_t buf[], size_t sz)
|
||||||
{
|
{
|
||||||
|
BOTAN_STATE_CHECK(state().empty() == false);
|
||||||
|
|
||||||
const size_t BS = block_size();
|
const size_t BS = block_size();
|
||||||
|
|
||||||
BOTAN_ASSERT(sz % BS == 0, "Input is full blocks");
|
BOTAN_ASSERT(sz % BS == 0, "Input is full blocks");
|
||||||
@@ -231,6 +241,7 @@ size_t CBC_Decryption::process(uint8_t buf[], size_t sz)
|
|||||||
|
|
||||||
void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
||||||
{
|
{
|
||||||
|
BOTAN_STATE_CHECK(state().empty() == false);
|
||||||
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
||||||
const size_t sz = buffer.size() - offset;
|
const size_t sz = buffer.size() - offset;
|
||||||
|
|
||||||
@@ -251,7 +262,7 @@ void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
|||||||
|
|
||||||
void CBC_Decryption::reset()
|
void CBC_Decryption::reset()
|
||||||
{
|
{
|
||||||
zeroise(state());
|
CBC_Mode::reset();
|
||||||
zeroise(m_tempbuf);
|
zeroise(m_tempbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,6 +278,7 @@ size_t CTS_Decryption::minimum_final_size() const
|
|||||||
|
|
||||||
void CTS_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
void CTS_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
|
||||||
{
|
{
|
||||||
|
BOTAN_STATE_CHECK(state().empty() == false);
|
||||||
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
|
||||||
const size_t sz = buffer.size() - offset;
|
const size_t sz = buffer.size() - offset;
|
||||||
uint8_t* buf = buffer.data() + offset;
|
uint8_t* buf = buffer.data() + offset;
|
||||||
|
@@ -46,9 +46,9 @@ class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode
|
|||||||
return *m_padding;
|
return *m_padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
secure_vector<uint8_t>& state() { return m_state; }
|
size_t block_size() const { return m_block_size; }
|
||||||
|
|
||||||
size_t block_size() const { return m_state.size(); }
|
secure_vector<uint8_t>& state() { return m_state; }
|
||||||
|
|
||||||
uint8_t* state_ptr() { return m_state.data(); }
|
uint8_t* state_ptr() { return m_state.data(); }
|
||||||
|
|
||||||
@@ -60,6 +60,7 @@ class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode
|
|||||||
std::unique_ptr<BlockCipher> m_cipher;
|
std::unique_ptr<BlockCipher> m_cipher;
|
||||||
std::unique_ptr<BlockCipherModePaddingMethod> m_padding;
|
std::unique_ptr<BlockCipherModePaddingMethod> m_padding;
|
||||||
secure_vector<uint8_t> m_state;
|
secure_vector<uint8_t> m_state;
|
||||||
|
size_t m_block_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -35,6 +35,10 @@
|
|||||||
#include <botan/internal/openssl.h>
|
#include <botan/internal/openssl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_COMMONCRYPTO)
|
||||||
|
#include <botan/internal/commoncrypto.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(const std::string& algo,
|
std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(const std::string& algo,
|
||||||
@@ -51,6 +55,19 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo,
|
|||||||
Cipher_Dir direction,
|
Cipher_Dir direction,
|
||||||
const std::string& provider)
|
const std::string& provider)
|
||||||
{
|
{
|
||||||
|
#if defined(BOTAN_HAS_COMMONCRYPTO)
|
||||||
|
if(provider.empty() || provider == "commoncrypto")
|
||||||
|
{
|
||||||
|
std::unique_ptr<Cipher_Mode> commoncrypto_cipher(make_commoncrypto_cipher_mode(algo, direction));
|
||||||
|
|
||||||
|
if(commoncrypto_cipher)
|
||||||
|
return commoncrypto_cipher;
|
||||||
|
|
||||||
|
if(!provider.empty())
|
||||||
|
return std::unique_ptr<Cipher_Mode>();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_OPENSSL)
|
#if defined(BOTAN_HAS_OPENSSL)
|
||||||
if(provider.empty() || provider == "openssl")
|
if(provider.empty() || provider == "openssl")
|
||||||
{
|
{
|
||||||
@@ -172,7 +189,7 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo,
|
|||||||
//static
|
//static
|
||||||
std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec)
|
std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec)
|
||||||
{
|
{
|
||||||
const std::vector<std::string>& possible = { "base", "openssl" };
|
const std::vector<std::string>& possible = { "base", "openssl", "commoncrypto" };
|
||||||
std::vector<std::string> providers;
|
std::vector<std::string> providers;
|
||||||
for(auto&& prov : possible)
|
for(auto&& prov : possible)
|
||||||
{
|
{
|
||||||
|
@@ -9,9 +9,8 @@
|
|||||||
#define BOTAN_CIPHER_MODE_H_
|
#define BOTAN_CIPHER_MODE_H_
|
||||||
|
|
||||||
#include <botan/secmem.h>
|
#include <botan/secmem.h>
|
||||||
#include <botan/key_spec.h>
|
#include <botan/sym_algo.h>
|
||||||
#include <botan/exceptn.h>
|
#include <botan/exceptn.h>
|
||||||
#include <botan/symkey.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -26,11 +25,9 @@ enum Cipher_Dir : int { ENCRYPTION, DECRYPTION };
|
|||||||
/**
|
/**
|
||||||
* Interface for cipher modes
|
* Interface for cipher modes
|
||||||
*/
|
*/
|
||||||
class BOTAN_PUBLIC_API(2,0) Cipher_Mode
|
class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Cipher_Mode() = default;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of available providers for this algorithm, empty if not available
|
* @return list of available providers for this algorithm, empty if not available
|
||||||
* @param algo_spec algorithm name
|
* @param algo_spec algorithm name
|
||||||
@@ -133,8 +130,9 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the size of the output if this transform is used to process a
|
* Returns the size of the output if this transform is used to process a
|
||||||
* message with input_length bytes. Will throw if unable to give a precise
|
* message with input_length bytes. In most cases the answer is precise.
|
||||||
* answer.
|
* If it is not possible to precise (namely for CBC decryption) instead a
|
||||||
|
* lower bound is returned.
|
||||||
*/
|
*/
|
||||||
virtual size_t output_length(size_t input_length) const = 0;
|
virtual size_t output_length(size_t input_length) const = 0;
|
||||||
|
|
||||||
@@ -159,14 +157,6 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode
|
|||||||
*/
|
*/
|
||||||
virtual bool valid_nonce_length(size_t nonce_len) const = 0;
|
virtual bool valid_nonce_length(size_t nonce_len) const = 0;
|
||||||
|
|
||||||
virtual std::string name() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zeroise all state
|
|
||||||
* See also reset_msg()
|
|
||||||
*/
|
|
||||||
virtual void clear() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets just the message specific state and allows encrypting again under the existing key
|
* Resets just the message specific state and allows encrypting again under the existing key
|
||||||
*/
|
*/
|
||||||
@@ -183,60 +173,11 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode
|
|||||||
*/
|
*/
|
||||||
virtual size_t tag_size() const { return 0; }
|
virtual size_t tag_size() const { return 0; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @return object describing limits on key size
|
|
||||||
*/
|
|
||||||
virtual Key_Length_Specification key_spec() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a given key length is valid for this algorithm.
|
|
||||||
* @param length the key length to be checked.
|
|
||||||
* @return true if the key length is valid.
|
|
||||||
*/
|
|
||||||
bool valid_keylength(size_t length) const
|
|
||||||
{
|
|
||||||
return key_spec().valid_keylength(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the symmetric key of this transform
|
|
||||||
* @param key contains the key material
|
|
||||||
*/
|
|
||||||
template<typename Alloc>
|
|
||||||
void set_key(const std::vector<uint8_t, Alloc>& key)
|
|
||||||
{
|
|
||||||
set_key(key.data(), key.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the symmetric key of this transform
|
|
||||||
* @param key contains the key material
|
|
||||||
*/
|
|
||||||
void set_key(const SymmetricKey& key)
|
|
||||||
{
|
|
||||||
set_key(key.begin(), key.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the symmetric key of this transform
|
|
||||||
* @param key contains the key material
|
|
||||||
* @param length in bytes of key param
|
|
||||||
*/
|
|
||||||
void set_key(const uint8_t key[], size_t length)
|
|
||||||
{
|
|
||||||
if(!valid_keylength(length))
|
|
||||||
throw Invalid_Key_Length(name(), length);
|
|
||||||
key_schedule(key, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return provider information about this implementation. Default is "base",
|
* @return provider information about this implementation. Default is "base",
|
||||||
* might also return "sse2", "avx2", "openssl", or some other arbitrary string.
|
* might also return "sse2", "avx2", "openssl", or some other arbitrary string.
|
||||||
*/
|
*/
|
||||||
virtual std::string provider() const { return "base"; }
|
virtual std::string provider() const { return "base"; }
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void key_schedule(const uint8_t key[], size_t length) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* CBC Padding Methods
|
* CBC Padding Methods
|
||||||
* (C) 1999-2007,2013 Jack Lloyd
|
* (C) 1999-2007,2013,2018 Jack Lloyd
|
||||||
* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
|
* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
|
||||||
*
|
*
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
@@ -51,26 +51,27 @@ void PKCS7_Padding::add_padding(secure_vector<uint8_t>& buffer,
|
|||||||
/*
|
/*
|
||||||
* Unpad with PKCS #7 Method
|
* Unpad with PKCS #7 Method
|
||||||
*/
|
*/
|
||||||
size_t PKCS7_Padding::unpad(const uint8_t block[], size_t size) const
|
size_t PKCS7_Padding::unpad(const uint8_t input[], size_t input_length) const
|
||||||
{
|
{
|
||||||
CT::poison(block,size);
|
if(input_length <= 2)
|
||||||
|
return input_length;
|
||||||
|
|
||||||
|
CT::poison(input, input_length);
|
||||||
size_t bad_input = 0;
|
size_t bad_input = 0;
|
||||||
const uint8_t last_byte = block[size-1];
|
const uint8_t last_byte = input[input_length-1];
|
||||||
|
|
||||||
bad_input |= CT::expand_mask<size_t>(last_byte > size);
|
bad_input |= CT::expand_mask<size_t>(last_byte > input_length);
|
||||||
|
|
||||||
size_t pad_pos = size - last_byte;
|
const size_t pad_pos = input_length - last_byte;
|
||||||
size_t i = size - 2;
|
|
||||||
while(i)
|
for(size_t i = 0; i != input_length - 1; ++i)
|
||||||
{
|
{
|
||||||
bad_input |= (~CT::is_equal(block[i],last_byte)) & CT::expand_mask<uint8_t>(i >= pad_pos);
|
const uint8_t in_range = CT::expand_mask<uint8_t>(i >= pad_pos);
|
||||||
--i;
|
bad_input |= in_range & (~CT::is_equal(input[i], last_byte));
|
||||||
}
|
}
|
||||||
|
|
||||||
CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1);
|
CT::unpoison(input, input_length);
|
||||||
CT::unpoison(block,size);
|
return CT::conditional_return(bad_input, input_length, pad_pos);
|
||||||
CT::unpoison(pad_pos);
|
|
||||||
return pad_pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -92,25 +93,27 @@ void ANSI_X923_Padding::add_padding(secure_vector<uint8_t>& buffer,
|
|||||||
/*
|
/*
|
||||||
* Unpad with ANSI X9.23 Method
|
* Unpad with ANSI X9.23 Method
|
||||||
*/
|
*/
|
||||||
size_t ANSI_X923_Padding::unpad(const uint8_t block[], size_t size) const
|
size_t ANSI_X923_Padding::unpad(const uint8_t input[], size_t input_length) const
|
||||||
{
|
{
|
||||||
CT::poison(block,size);
|
if(input_length <= 2)
|
||||||
size_t bad_input = 0;
|
return input_length;
|
||||||
const size_t last_byte = block[size-1];
|
|
||||||
|
|
||||||
bad_input |= CT::expand_mask<size_t>(last_byte > size);
|
CT::poison(input, input_length);
|
||||||
|
const size_t last_byte = input[input_length-1];
|
||||||
|
|
||||||
size_t pad_pos = size - last_byte;
|
uint8_t bad_input = 0;
|
||||||
size_t i = size - 2;
|
bad_input |= CT::expand_mask<uint8_t>(last_byte > input_length);
|
||||||
while(i)
|
|
||||||
|
const size_t pad_pos = input_length - last_byte;
|
||||||
|
|
||||||
|
for(size_t i = 0; i != input_length - 1; ++i)
|
||||||
{
|
{
|
||||||
bad_input |= (~CT::is_zero(block[i])) & CT::expand_mask<uint8_t>(i >= pad_pos);
|
const uint8_t in_range = CT::expand_mask<uint8_t>(i >= pad_pos);
|
||||||
--i;
|
bad_input |= CT::expand_mask(input[i]) & in_range;
|
||||||
}
|
}
|
||||||
CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1);
|
|
||||||
CT::unpoison(block,size);
|
CT::unpoison(input, input_length);
|
||||||
CT::unpoison(pad_pos);
|
return CT::conditional_return(bad_input, input_length, pad_pos);
|
||||||
return pad_pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -129,28 +132,29 @@ void OneAndZeros_Padding::add_padding(secure_vector<uint8_t>& buffer,
|
|||||||
/*
|
/*
|
||||||
* Unpad with One and Zeros Method
|
* Unpad with One and Zeros Method
|
||||||
*/
|
*/
|
||||||
size_t OneAndZeros_Padding::unpad(const uint8_t block[], size_t size) const
|
size_t OneAndZeros_Padding::unpad(const uint8_t input[], size_t input_length) const
|
||||||
{
|
{
|
||||||
CT::poison(block, size);
|
if(input_length <= 2)
|
||||||
|
return input_length;
|
||||||
|
|
||||||
|
CT::poison(input, input_length);
|
||||||
|
|
||||||
uint8_t bad_input = 0;
|
uint8_t bad_input = 0;
|
||||||
uint8_t seen_one = 0;
|
uint8_t seen_one = 0;
|
||||||
size_t pad_pos = size - 1;
|
size_t pad_pos = input_length - 1;
|
||||||
size_t i = size;
|
size_t i = input_length;
|
||||||
|
|
||||||
while(i)
|
while(i)
|
||||||
{
|
{
|
||||||
seen_one |= CT::is_equal<uint8_t>(block[i-1],0x80);
|
seen_one |= CT::is_equal<uint8_t>(input[i-1], 0x80);
|
||||||
pad_pos -= CT::select<uint8_t>(~seen_one, 1, 0);
|
pad_pos -= CT::select<uint8_t>(~seen_one, 1, 0);
|
||||||
bad_input |= ~CT::is_zero<uint8_t>(block[i-1]) & ~seen_one;
|
bad_input |= ~CT::is_zero<uint8_t>(input[i-1]) & ~seen_one;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
bad_input |= ~seen_one;
|
bad_input |= ~seen_one;
|
||||||
|
|
||||||
CT::conditional_copy_mem(size_t(bad_input),&pad_pos,&size,&pad_pos,1);
|
CT::unpoison(input, input_length);
|
||||||
CT::unpoison(block, size);
|
return CT::conditional_return(bad_input, input_length, pad_pos);
|
||||||
CT::unpoison(pad_pos);
|
|
||||||
|
|
||||||
return pad_pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -171,25 +175,28 @@ void ESP_Padding::add_padding(secure_vector<uint8_t>& buffer,
|
|||||||
/*
|
/*
|
||||||
* Unpad with ESP Padding Method
|
* Unpad with ESP Padding Method
|
||||||
*/
|
*/
|
||||||
size_t ESP_Padding::unpad(const uint8_t block[], size_t size) const
|
size_t ESP_Padding::unpad(const uint8_t input[], size_t input_length) const
|
||||||
{
|
{
|
||||||
CT::poison(block,size);
|
if(input_length <= 2)
|
||||||
|
return input_length;
|
||||||
|
|
||||||
const size_t last_byte = block[size-1];
|
CT::poison(input, input_length);
|
||||||
size_t bad_input = 0;
|
|
||||||
bad_input |= CT::expand_mask<size_t>(last_byte > size);
|
|
||||||
|
|
||||||
size_t pad_pos = size - last_byte;
|
const size_t last_byte = input[input_length-1];
|
||||||
size_t i = size - 1;
|
uint8_t bad_input = 0;
|
||||||
|
bad_input |= CT::is_zero(last_byte) | CT::expand_mask<uint8_t>(last_byte > input_length);
|
||||||
|
|
||||||
|
const size_t pad_pos = input_length - last_byte;
|
||||||
|
size_t i = input_length - 1;
|
||||||
while(i)
|
while(i)
|
||||||
{
|
{
|
||||||
bad_input |= ~CT::is_equal<uint8_t>(size_t(block[i-1]),size_t(block[i])-1) & CT::expand_mask<uint8_t>(i > pad_pos);
|
const uint8_t in_range = CT::expand_mask<uint8_t>(i > pad_pos);
|
||||||
|
bad_input |= (~CT::is_equal<uint8_t>(input[i-1], input[i]-1)) & in_range;
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1);
|
|
||||||
CT::unpoison(block, size);
|
CT::unpoison(input, input_length);
|
||||||
CT::unpoison(pad_pos);
|
return CT::conditional_return(bad_input, input_length, pad_pos);
|
||||||
return pad_pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -39,11 +39,10 @@ class BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod
|
|||||||
/**
|
/**
|
||||||
* Remove padding bytes from block
|
* Remove padding bytes from block
|
||||||
* @param block the last block
|
* @param block the last block
|
||||||
* @param size the size of the block in bytes
|
* @param len the size of the block in bytes
|
||||||
* @return number of padding bytes
|
* @return number of data bytes, or if the padding is invalid returns len
|
||||||
*/
|
*/
|
||||||
virtual size_t unpad(const uint8_t block[],
|
virtual size_t unpad(const uint8_t block[], size_t len) const = 0;
|
||||||
size_t size) const = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param block_size of the cipher
|
* @param block_size of the cipher
|
||||||
@@ -74,7 +73,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS7_Padding final : public BlockCipherModePaddingM
|
|||||||
|
|
||||||
size_t unpad(const uint8_t[], size_t) const override;
|
size_t unpad(const uint8_t[], size_t) const override;
|
||||||
|
|
||||||
bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); }
|
bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
|
||||||
|
|
||||||
std::string name() const override { return "PKCS7"; }
|
std::string name() const override { return "PKCS7"; }
|
||||||
};
|
};
|
||||||
@@ -91,7 +90,7 @@ class BOTAN_PUBLIC_API(2,0) ANSI_X923_Padding final : public BlockCipherModePadd
|
|||||||
|
|
||||||
size_t unpad(const uint8_t[], size_t) const override;
|
size_t unpad(const uint8_t[], size_t) const override;
|
||||||
|
|
||||||
bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); }
|
bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
|
||||||
|
|
||||||
std::string name() const override { return "X9.23"; }
|
std::string name() const override { return "X9.23"; }
|
||||||
};
|
};
|
||||||
@@ -108,7 +107,7 @@ class BOTAN_PUBLIC_API(2,0) OneAndZeros_Padding final : public BlockCipherModePa
|
|||||||
|
|
||||||
size_t unpad(const uint8_t[], size_t) const override;
|
size_t unpad(const uint8_t[], size_t) const override;
|
||||||
|
|
||||||
bool valid_blocksize(size_t bs) const override { return (bs > 0); }
|
bool valid_blocksize(size_t bs) const override { return (bs > 2); }
|
||||||
|
|
||||||
std::string name() const override { return "OneAndZeros"; }
|
std::string name() const override { return "OneAndZeros"; }
|
||||||
};
|
};
|
||||||
@@ -125,7 +124,7 @@ class BOTAN_PUBLIC_API(2,0) ESP_Padding final : public BlockCipherModePaddingMet
|
|||||||
|
|
||||||
size_t unpad(const uint8_t[], size_t) const override;
|
size_t unpad(const uint8_t[], size_t) const override;
|
||||||
|
|
||||||
bool valid_blocksize(size_t bs) const override { return (bs > 0); }
|
bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
|
||||||
|
|
||||||
std::string name() const override { return "ESP"; }
|
std::string name() const override { return "ESP"; }
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<defines>
|
<defines>
|
||||||
PBKDF -> 20150626
|
PBKDF -> 20180902
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
<requires>
|
<requires>
|
||||||
@@ -8,5 +8,6 @@ hash
|
|||||||
</requires>
|
</requires>
|
||||||
|
|
||||||
<header:public>
|
<header:public>
|
||||||
|
pwdhash.h
|
||||||
pbkdf.h
|
pbkdf.h
|
||||||
</header:public>
|
</header:public>
|
||||||
|
@@ -17,6 +17,9 @@ namespace Botan {
|
|||||||
* Base class for PBKDF (password based key derivation function)
|
* Base class for PBKDF (password based key derivation function)
|
||||||
* implementations. Converts a password into a key using a salt
|
* implementations. Converts a password into a key using a salt
|
||||||
* and iterated hashing to make brute force attacks harder.
|
* and iterated hashing to make brute force attacks harder.
|
||||||
|
*
|
||||||
|
* Starting in 2.8 this functionality is also offered by PasswordHash.
|
||||||
|
* The PBKDF interface may be removed in a future release.
|
||||||
*/
|
*/
|
||||||
class BOTAN_PUBLIC_API(2,0) PBKDF
|
class BOTAN_PUBLIC_API(2,0) PBKDF
|
||||||
{
|
{
|
||||||
@@ -216,7 +219,7 @@ class BOTAN_PUBLIC_API(2,0) PBKDF
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compatability typedef
|
* Compatibility typedef
|
||||||
*/
|
*/
|
||||||
typedef PBKDF S2K;
|
typedef PBKDF S2K;
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<defines>
|
<defines>
|
||||||
PBKDF2 -> 20131128
|
PBKDF2 -> 20180902
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
<requires>
|
<requires>
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* PBKDF2
|
* PBKDF2
|
||||||
* (C) 1999-2007 Jack Lloyd
|
* (C) 1999-2007 Jack Lloyd
|
||||||
|
* (C) 2018 Ribose Inc
|
||||||
*
|
*
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
*/
|
*/
|
||||||
@@ -8,42 +9,116 @@
|
|||||||
#include <botan/pbkdf2.h>
|
#include <botan/pbkdf2.h>
|
||||||
#include <botan/exceptn.h>
|
#include <botan/exceptn.h>
|
||||||
#include <botan/internal/rounding.h>
|
#include <botan/internal/rounding.h>
|
||||||
|
#include <botan/internal/timer.h>
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void pbkdf2_set_key(MessageAuthenticationCode& prf,
|
||||||
|
const char* password,
|
||||||
|
size_t password_len)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
prf.set_key(cast_char_ptr_to_uint8(password), password_len);
|
||||||
|
}
|
||||||
|
catch(Invalid_Key_Length&)
|
||||||
|
{
|
||||||
|
throw Exception("PBKDF2 cannot accept passphrase of the given size");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
pbkdf2(MessageAuthenticationCode& prf,
|
pbkdf2(MessageAuthenticationCode& prf,
|
||||||
uint8_t out[],
|
uint8_t out[],
|
||||||
size_t out_len,
|
size_t out_len,
|
||||||
const std::string& passphrase,
|
const std::string& password,
|
||||||
const uint8_t salt[], size_t salt_len,
|
const uint8_t salt[], size_t salt_len,
|
||||||
size_t iterations,
|
size_t iterations,
|
||||||
std::chrono::milliseconds msec)
|
std::chrono::milliseconds msec)
|
||||||
{
|
{
|
||||||
|
if(iterations == 0)
|
||||||
|
{
|
||||||
|
iterations = PBKDF2(prf, out_len, msec).iterations();
|
||||||
|
}
|
||||||
|
|
||||||
|
PBKDF2 pbkdf2(prf, iterations);
|
||||||
|
|
||||||
|
pbkdf2.derive_key(out, out_len,
|
||||||
|
password.c_str(), password.size(),
|
||||||
|
salt, salt_len);
|
||||||
|
|
||||||
|
return iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
size_t tune_pbkdf2(MessageAuthenticationCode& prf,
|
||||||
|
size_t output_length,
|
||||||
|
uint32_t msec)
|
||||||
|
{
|
||||||
|
const size_t prf_sz = prf.output_length();
|
||||||
|
BOTAN_ASSERT_NOMSG(prf_sz > 0);
|
||||||
|
secure_vector<uint8_t> U(prf_sz);
|
||||||
|
|
||||||
|
const size_t trial_iterations = 10000;
|
||||||
|
|
||||||
|
// Short output ensures we only need a single PBKDF2 block
|
||||||
|
|
||||||
|
Timer timer("PBKDF2");
|
||||||
|
|
||||||
|
const std::chrono::milliseconds tune_msec(30);
|
||||||
|
|
||||||
|
prf.set_key(nullptr, 0);
|
||||||
|
|
||||||
|
timer.run_until_elapsed(tune_msec, [&]() {
|
||||||
|
uint8_t out[16] = { 0 };
|
||||||
|
uint8_t salt[16] = { 0 };
|
||||||
|
pbkdf2(prf, out, sizeof(out), salt, sizeof(salt), trial_iterations);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(timer.events() == 0)
|
||||||
|
return trial_iterations;
|
||||||
|
|
||||||
|
const uint64_t duration_nsec = timer.value() / timer.events();
|
||||||
|
|
||||||
|
const uint64_t desired_nsec = static_cast<uint64_t>(msec) * 1000000;
|
||||||
|
|
||||||
|
if(duration_nsec > desired_nsec)
|
||||||
|
return trial_iterations;
|
||||||
|
|
||||||
|
const size_t blocks_needed = (output_length + prf_sz - 1) / prf_sz;
|
||||||
|
|
||||||
|
const size_t multiplier = (desired_nsec / duration_nsec / blocks_needed);
|
||||||
|
|
||||||
|
if(multiplier == 0)
|
||||||
|
return trial_iterations;
|
||||||
|
else
|
||||||
|
return trial_iterations * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void pbkdf2(MessageAuthenticationCode& prf,
|
||||||
|
uint8_t out[],
|
||||||
|
size_t out_len,
|
||||||
|
const uint8_t salt[],
|
||||||
|
size_t salt_len,
|
||||||
|
size_t iterations)
|
||||||
|
{
|
||||||
clear_mem(out, out_len);
|
clear_mem(out, out_len);
|
||||||
|
|
||||||
if(out_len == 0)
|
if(out_len == 0)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
prf.set_key(cast_char_ptr_to_uint8(passphrase.data()), passphrase.size());
|
|
||||||
}
|
|
||||||
catch(Invalid_Key_Length&)
|
|
||||||
{
|
|
||||||
throw Exception("PBKDF2 with " + prf.name() +
|
|
||||||
" cannot accept passphrases of length " +
|
|
||||||
std::to_string(passphrase.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t prf_sz = prf.output_length();
|
const size_t prf_sz = prf.output_length();
|
||||||
|
BOTAN_ASSERT_NOMSG(prf_sz > 0);
|
||||||
|
|
||||||
secure_vector<uint8_t> U(prf_sz);
|
secure_vector<uint8_t> U(prf_sz);
|
||||||
|
|
||||||
const size_t blocks_needed = round_up(out_len, prf_sz) / prf_sz;
|
|
||||||
|
|
||||||
std::chrono::microseconds usec_per_block =
|
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(msec) / blocks_needed;
|
|
||||||
|
|
||||||
uint32_t counter = 1;
|
uint32_t counter = 1;
|
||||||
while(out_len)
|
while(out_len)
|
||||||
{
|
{
|
||||||
@@ -55,64 +130,93 @@ pbkdf2(MessageAuthenticationCode& prf,
|
|||||||
|
|
||||||
xor_buf(out, U.data(), prf_output);
|
xor_buf(out, U.data(), prf_output);
|
||||||
|
|
||||||
if(iterations == 0)
|
for(size_t i = 1; i != iterations; ++i)
|
||||||
{
|
{
|
||||||
/*
|
prf.update(U);
|
||||||
If no iterations set, run the first block to calibrate based
|
prf.final(U.data());
|
||||||
on how long hashing takes on whatever machine we're running on.
|
xor_buf(out, U.data(), prf_output);
|
||||||
*/
|
|
||||||
|
|
||||||
const auto start = std::chrono::high_resolution_clock::now();
|
|
||||||
|
|
||||||
iterations = 1; // the first iteration we did above
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
prf.update(U);
|
|
||||||
prf.final(U.data());
|
|
||||||
xor_buf(out, U.data(), prf_output);
|
|
||||||
iterations++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Only break on relatively 'even' iterations. For one it
|
|
||||||
avoids confusion, and likely some broken implementations
|
|
||||||
break on getting completely randomly distributed values
|
|
||||||
*/
|
|
||||||
if(iterations % 10000 == 0)
|
|
||||||
{
|
|
||||||
auto time_taken = std::chrono::high_resolution_clock::now() - start;
|
|
||||||
auto usec_taken = std::chrono::duration_cast<std::chrono::microseconds>(time_taken);
|
|
||||||
if(usec_taken > usec_per_block)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(size_t i = 1; i != iterations; ++i)
|
|
||||||
{
|
|
||||||
prf.update(U);
|
|
||||||
prf.final(U.data());
|
|
||||||
xor_buf(out, U.data(), prf_output);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out_len -= prf_output;
|
out_len -= prf_output;
|
||||||
out += prf_output;
|
out += prf_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterations;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PBKDF interface
|
||||||
size_t
|
size_t
|
||||||
PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len,
|
PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len,
|
||||||
const std::string& passphrase,
|
const std::string& password,
|
||||||
const uint8_t salt[], size_t salt_len,
|
const uint8_t salt[], size_t salt_len,
|
||||||
size_t iterations,
|
size_t iterations,
|
||||||
std::chrono::milliseconds msec) const
|
std::chrono::milliseconds msec) const
|
||||||
{
|
{
|
||||||
return pbkdf2(*m_mac.get(), key, key_len, passphrase, salt, salt_len, iterations, msec);
|
if(iterations == 0)
|
||||||
|
{
|
||||||
|
iterations = PBKDF2(*m_mac, key_len, msec).iterations();
|
||||||
|
}
|
||||||
|
|
||||||
|
PBKDF2 pbkdf2(*m_mac, iterations);
|
||||||
|
|
||||||
|
pbkdf2.derive_key(key, key_len,
|
||||||
|
password.c_str(), password.size(),
|
||||||
|
salt, salt_len);
|
||||||
|
|
||||||
|
return iterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PKCS5_PBKDF2::name() const
|
||||||
|
{
|
||||||
|
return "PBKDF2(" + m_mac->name() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
PBKDF* PKCS5_PBKDF2::clone() const
|
||||||
|
{
|
||||||
|
return new PKCS5_PBKDF2(m_mac->clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordHash interface
|
||||||
|
|
||||||
|
PBKDF2::PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec) :
|
||||||
|
m_prf(prf.clone()),
|
||||||
|
m_iterations(tune_pbkdf2(*m_prf, olen, static_cast<uint32_t>(msec.count())))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string PBKDF2::to_string() const
|
||||||
|
{
|
||||||
|
return "PBKDF2(" + m_prf->name() + "," + std::to_string(m_iterations) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PBKDF2::derive_key(uint8_t out[], size_t out_len,
|
||||||
|
const char* password, const size_t password_len,
|
||||||
|
const uint8_t salt[], size_t salt_len) const
|
||||||
|
{
|
||||||
|
pbkdf2_set_key(*m_prf, password, password_len);
|
||||||
|
pbkdf2(*m_prf, out, out_len, salt, salt_len, m_iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PBKDF2_Family::name() const
|
||||||
|
{
|
||||||
|
return "PBKDF2(" + m_prf->name() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> PBKDF2_Family::tune(size_t output_len, std::chrono::milliseconds msec, size_t) const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, output_len, msec));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> PBKDF2_Family::default_params() const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, 150000));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> PBKDF2_Family::from_params(size_t iter, size_t, size_t) const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, iter));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> PBKDF2_Family::from_iterations(size_t iter) const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, iter));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* PBKDF2
|
* PBKDF2
|
||||||
* (C) 1999-2007,2012 Jack Lloyd
|
* (C) 1999-2007,2012 Jack Lloyd
|
||||||
|
* (C) 2018 Ribose Inc
|
||||||
*
|
*
|
||||||
* Botan is released under the Simplified BSD License (see license.txt)
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
*/
|
*/
|
||||||
@@ -9,6 +10,7 @@
|
|||||||
#define BOTAN_PBKDF2_H_
|
#define BOTAN_PBKDF2_H_
|
||||||
|
|
||||||
#include <botan/pbkdf.h>
|
#include <botan/pbkdf.h>
|
||||||
|
#include <botan/pwdhash.h>
|
||||||
#include <botan/mac.h>
|
#include <botan/mac.h>
|
||||||
|
|
||||||
namespace Botan {
|
namespace Botan {
|
||||||
@@ -22,20 +24,76 @@ BOTAN_PUBLIC_API(2,0) size_t pbkdf2(MessageAuthenticationCode& prf,
|
|||||||
std::chrono::milliseconds msec);
|
std::chrono::milliseconds msec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PKCS #5 PBKDF2
|
* Perform PBKDF2. The prf is assumed to be keyed already.
|
||||||
|
*/
|
||||||
|
BOTAN_PUBLIC_API(2,8) void pbkdf2(MessageAuthenticationCode& prf,
|
||||||
|
uint8_t out[], size_t out_len,
|
||||||
|
const uint8_t salt[], size_t salt_len,
|
||||||
|
size_t iterations);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PBKDF2
|
||||||
|
*/
|
||||||
|
class BOTAN_PUBLIC_API(2,8) PBKDF2 final : public PasswordHash
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PBKDF2(const MessageAuthenticationCode& prf, size_t iter) :
|
||||||
|
m_prf(prf.clone()),
|
||||||
|
m_iterations(iter)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec);
|
||||||
|
|
||||||
|
size_t iterations() const override { return m_iterations; }
|
||||||
|
|
||||||
|
std::string to_string() const override;
|
||||||
|
|
||||||
|
void derive_key(uint8_t out[], size_t out_len,
|
||||||
|
const char* password, size_t password_len,
|
||||||
|
const uint8_t salt[], size_t salt_len) const override;
|
||||||
|
private:
|
||||||
|
std::unique_ptr<MessageAuthenticationCode> m_prf;
|
||||||
|
size_t m_iterations;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Family of PKCS #5 PBKDF2 operations
|
||||||
|
*/
|
||||||
|
class BOTAN_PUBLIC_API(2,8) PBKDF2_Family final : public PasswordHashFamily
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PBKDF2_Family(MessageAuthenticationCode* prf) : m_prf(prf) {}
|
||||||
|
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> tune(size_t output_len,
|
||||||
|
std::chrono::milliseconds msec,
|
||||||
|
size_t max_memory) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return some default parameter set for this PBKDF that should be good
|
||||||
|
* enough for most users. The value returned may change over time as
|
||||||
|
* processing power and attacks improve.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<PasswordHash> default_params() const override;
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHash> from_params(
|
||||||
|
size_t iter, size_t, size_t) const override;
|
||||||
|
private:
|
||||||
|
std::unique_ptr<MessageAuthenticationCode> m_prf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PKCS #5 PBKDF2 (old interface)
|
||||||
*/
|
*/
|
||||||
class BOTAN_PUBLIC_API(2,0) PKCS5_PBKDF2 final : public PBKDF
|
class BOTAN_PUBLIC_API(2,0) PKCS5_PBKDF2 final : public PBKDF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string name() const override
|
std::string name() const override;
|
||||||
{
|
|
||||||
return "PBKDF2(" + m_mac->name() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
PBKDF* clone() const override
|
PBKDF* clone() const override;
|
||||||
{
|
|
||||||
return new PKCS5_PBKDF2(m_mac->clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t pbkdf(uint8_t output_buf[], size_t output_len,
|
size_t pbkdf(uint8_t output_buf[], size_t output_len,
|
||||||
const std::string& passphrase,
|
const std::string& passphrase,
|
||||||
|
88
src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.cpp
vendored
Normal file
88
src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.cpp
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* (C) 2018 Ribose Inc
|
||||||
|
*
|
||||||
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <botan/pbkdf.h>
|
||||||
|
#include <botan/exceptn.h>
|
||||||
|
#include <botan/scan_name.h>
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_PBKDF2)
|
||||||
|
#include <botan/pbkdf2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_PGP_S2K)
|
||||||
|
#include <botan/pgp_s2k.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_SCRYPT)
|
||||||
|
#include <botan/scrypt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Botan {
|
||||||
|
|
||||||
|
std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(const std::string& algo_spec,
|
||||||
|
const std::string& provider)
|
||||||
|
{
|
||||||
|
const SCAN_Name req(algo_spec);
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_PBKDF2)
|
||||||
|
if(req.algo_name() == "PBKDF2")
|
||||||
|
{
|
||||||
|
// TODO OpenSSL
|
||||||
|
|
||||||
|
if(provider.empty() || provider == "base")
|
||||||
|
{
|
||||||
|
if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
|
||||||
|
return std::unique_ptr<PasswordHashFamily>(new PBKDF2_Family(mac.release()));
|
||||||
|
|
||||||
|
if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
|
||||||
|
return std::unique_ptr<PasswordHashFamily>(new PBKDF2_Family(mac.release()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_SCRYPT)
|
||||||
|
if(req.algo_name() == "Scrypt")
|
||||||
|
{
|
||||||
|
return std::unique_ptr<PasswordHashFamily>(new Scrypt_Family);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOTAN_HAS_PGP_S2K)
|
||||||
|
if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1)
|
||||||
|
{
|
||||||
|
if(auto hash = HashFunction::create(req.arg(0)))
|
||||||
|
{
|
||||||
|
return std::unique_ptr<PasswordHashFamily>(new RFC4880_S2K_Family(hash.release()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOTAN_UNUSED(req);
|
||||||
|
BOTAN_UNUSED(provider);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
std::unique_ptr<PasswordHashFamily>
|
||||||
|
PasswordHashFamily::create_or_throw(const std::string& algo,
|
||||||
|
const std::string& provider)
|
||||||
|
{
|
||||||
|
if(auto pbkdf = PasswordHashFamily::create(algo, provider))
|
||||||
|
{
|
||||||
|
return pbkdf;
|
||||||
|
}
|
||||||
|
throw Lookup_Error("PasswordHashFamily", algo, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PasswordHashFamily::providers(const std::string& algo_spec)
|
||||||
|
{
|
||||||
|
return probe_providers_of<PasswordHashFamily>(algo_spec, { "base", "openssl" });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
162
src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.h
vendored
Normal file
162
src/libs/3rdparty/botan/src/lib/pbkdf/pwdhash.h
vendored
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* (C) 2018 Ribose Inc
|
||||||
|
*
|
||||||
|
* Botan is released under the Simplified BSD License (see license.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOTAN_PWDHASH_H_
|
||||||
|
#define BOTAN_PWDHASH_H_
|
||||||
|
|
||||||
|
#include <botan/types.h>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
namespace Botan {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for password based key derivation functions.
|
||||||
|
*
|
||||||
|
* Converts a password into a key using a salt and iterated hashing to
|
||||||
|
* make brute force attacks harder.
|
||||||
|
*/
|
||||||
|
class BOTAN_PUBLIC_API(2,8) PasswordHash
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~PasswordHash() = default;
|
||||||
|
|
||||||
|
virtual std::string to_string() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most password hashes have some notion of iterations.
|
||||||
|
*/
|
||||||
|
virtual size_t iterations() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some password hashing algorithms have a parameter which controls how
|
||||||
|
* much memory is used. If not supported by some algorithm, returns 0.
|
||||||
|
*/
|
||||||
|
virtual size_t memory_param() const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some password hashing algorithms have a parallelism parameter.
|
||||||
|
* If the algorithm does not support this notion, then the
|
||||||
|
* function returns zero. This allows distinguishing between a
|
||||||
|
* password hash which just does not support parallel operation,
|
||||||
|
* vs one that does support parallel operation but which has been
|
||||||
|
* configured to use a single lane.
|
||||||
|
*/
|
||||||
|
virtual size_t parallelism() const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an estimate of the total memory usage required to perform this
|
||||||
|
* key derivation.
|
||||||
|
*
|
||||||
|
* If this algorithm uses a small and constant amount of memory, with no
|
||||||
|
* effort made towards being memory hard, this function returns 0.
|
||||||
|
*/
|
||||||
|
virtual size_t total_memory_usage() const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive a key from a password
|
||||||
|
*
|
||||||
|
* @param out buffer to store the derived key, must be of out_len bytes
|
||||||
|
* @param out_len the desired length of the key to produce
|
||||||
|
* @param password the password to derive the key from
|
||||||
|
* @param password_len the length of password in bytes
|
||||||
|
* @param salt a randomly chosen salt
|
||||||
|
* @param salt_len length of salt in bytes
|
||||||
|
*
|
||||||
|
* This function is const, but is not thread safe. Different threads should
|
||||||
|
* either use unique objects, or serialize all access.
|
||||||
|
*/
|
||||||
|
virtual void derive_key(uint8_t out[], size_t out_len,
|
||||||
|
const char* password, size_t password_len,
|
||||||
|
const uint8_t salt[], size_t salt_len) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BOTAN_PUBLIC_API(2,8) PasswordHashFamily
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Create an instance based on a name
|
||||||
|
* If provider is empty then best available is chosen.
|
||||||
|
* @param algo_spec algorithm name
|
||||||
|
* @param provider provider implementation to choose
|
||||||
|
* @return a null pointer if the algo/provider combination cannot be found
|
||||||
|
*/
|
||||||
|
static std::unique_ptr<PasswordHashFamily> create(const std::string& algo_spec,
|
||||||
|
const std::string& provider = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance based on a name, or throw if the
|
||||||
|
* algo/provider combination cannot be found. If provider is
|
||||||
|
* empty then best available is chosen.
|
||||||
|
*/
|
||||||
|
static std::unique_ptr<PasswordHashFamily>
|
||||||
|
create_or_throw(const std::string& algo_spec,
|
||||||
|
const std::string& provider = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list of available providers for this algorithm, empty if not available
|
||||||
|
*/
|
||||||
|
static std::vector<std::string> providers(const std::string& algo_spec);
|
||||||
|
|
||||||
|
virtual ~PasswordHashFamily() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return name of this PasswordHash
|
||||||
|
*/
|
||||||
|
virtual std::string name() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new parameter set tuned for this machine
|
||||||
|
* @param output_length how long the output length will be
|
||||||
|
* @param msec the desired execution time in milliseconds
|
||||||
|
*
|
||||||
|
* @param max_memory_usage_mb some password hash functions can use a tunable
|
||||||
|
* amount of memory, in this case max_memory_usage limits the amount of RAM
|
||||||
|
* the returned parameters will require, in mebibytes (2**20 bytes). It may
|
||||||
|
* require some small amount above the request. Set to zero to place no
|
||||||
|
* limit at all.
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<PasswordHash> tune(size_t output_length,
|
||||||
|
std::chrono::milliseconds msec,
|
||||||
|
size_t max_memory_usage_mb = 0) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return some default parameter set for this PBKDF that should be good
|
||||||
|
* enough for most users. The value returned may change over time as
|
||||||
|
* processing power and attacks improve.
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<PasswordHash> default_params() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a parameter chosen based on a rough approximation with the
|
||||||
|
* specified iteration count. The exact value this returns for a particular
|
||||||
|
* algorithm may change from over time. Think of it as an alternative to
|
||||||
|
* tune, where time is expressed in terms of PBKDF2 iterations rather than
|
||||||
|
* milliseconds.
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a password hash using some scheme specific format.
|
||||||
|
* Eg PBKDF2 and PGP-S2K set iterations in i1
|
||||||
|
* Scrypt uses N,r,p in i{1-3}
|
||||||
|
* Bcrypt-PBKDF just has iterations
|
||||||
|
* Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3},
|
||||||
|
* and Argon2 type is part of the family.
|
||||||
|
*
|
||||||
|
* Values not needed should be set to 0
|
||||||
|
*/
|
||||||
|
virtual std::unique_ptr<PasswordHash> from_params(
|
||||||
|
size_t i1,
|
||||||
|
size_t i2 = 0,
|
||||||
|
size_t i3 = 0) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
47
src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp
vendored
47
src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp
vendored
@@ -55,8 +55,9 @@ EMSA* get_emsa(const std::string& algo_spec)
|
|||||||
|
|
||||||
#if defined(BOTAN_HAS_EMSA_PKCS1)
|
#if defined(BOTAN_HAS_EMSA_PKCS1)
|
||||||
if(req.algo_name() == "EMSA_PKCS1" ||
|
if(req.algo_name() == "EMSA_PKCS1" ||
|
||||||
req.algo_name() == "EMSA-PKCS1-v1_5" ||
|
req.algo_name() == "PKCS1v15" ||
|
||||||
req.algo_name() == "EMSA3")
|
req.algo_name() == "EMSA-PKCS1-v1_5" ||
|
||||||
|
req.algo_name() == "EMSA3")
|
||||||
{
|
{
|
||||||
if(req.arg_count() == 2 && req.arg(0) == "Raw")
|
if(req.arg_count() == 2 && req.arg(0) == "Raw")
|
||||||
{
|
{
|
||||||
@@ -80,25 +81,45 @@ EMSA* get_emsa(const std::string& algo_spec)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOTAN_HAS_EMSA_PSSR)
|
#if defined(BOTAN_HAS_EMSA_PSSR)
|
||||||
if(req.algo_name() == "PSSR" ||
|
if(req.algo_name() == "PSS_Raw" ||
|
||||||
req.algo_name() == "EMSA-PSS" ||
|
|
||||||
req.algo_name() == "PSS-MGF1" ||
|
|
||||||
req.algo_name() == "EMSA4" ||
|
|
||||||
req.algo_name() == "PSSR_Raw")
|
req.algo_name() == "PSSR_Raw")
|
||||||
{
|
{
|
||||||
if(req.arg_count_between(1, 3))
|
if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
|
||||||
{
|
{
|
||||||
if(req.arg(1, "MGF1") != "MGF1")
|
|
||||||
return nullptr; // not supported
|
|
||||||
|
|
||||||
if(auto h = HashFunction::create(req.arg(0)))
|
if(auto h = HashFunction::create(req.arg(0)))
|
||||||
{
|
{
|
||||||
const size_t salt_size = req.arg_as_integer(2, h->output_length());
|
if(req.arg_count() == 3)
|
||||||
|
{
|
||||||
if(req.algo_name() == "PSSR_Raw")
|
const size_t salt_size = req.arg_as_integer(2, 0);
|
||||||
return new PSSR_Raw(h.release(), salt_size);
|
return new PSSR_Raw(h.release(), salt_size);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
return new PSSR_Raw(h.release());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(req.algo_name() == "PSS" ||
|
||||||
|
req.algo_name() == "PSSR" ||
|
||||||
|
req.algo_name() == "EMSA-PSS" ||
|
||||||
|
req.algo_name() == "PSS-MGF1" ||
|
||||||
|
req.algo_name() == "EMSA4")
|
||||||
|
{
|
||||||
|
if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
|
||||||
|
{
|
||||||
|
if(auto h = HashFunction::create(req.arg(0)))
|
||||||
|
{
|
||||||
|
if(req.arg_count() == 3)
|
||||||
|
{
|
||||||
|
const size_t salt_size = req.arg_as_integer(2, 0);
|
||||||
return new PSSR(h.release(), salt_size);
|
return new PSSR(h.release(), salt_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new PSSR(h.release());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,9 +55,10 @@ secure_vector<uint8_t> pss_encode(HashFunction& hash,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool pss_verify(HashFunction& hash,
|
bool pss_verify(HashFunction& hash,
|
||||||
const secure_vector<uint8_t>& const_coded,
|
const secure_vector<uint8_t>& pss_repr,
|
||||||
const secure_vector<uint8_t>& raw,
|
const secure_vector<uint8_t>& message_hash,
|
||||||
size_t key_bits)
|
size_t key_bits,
|
||||||
|
size_t* out_salt_size)
|
||||||
{
|
{
|
||||||
const size_t HASH_SIZE = hash.output_length();
|
const size_t HASH_SIZE = hash.output_length();
|
||||||
const size_t KEY_BYTES = (key_bits + 7) / 8;
|
const size_t KEY_BYTES = (key_bits + 7) / 8;
|
||||||
@@ -65,16 +66,16 @@ bool pss_verify(HashFunction& hash,
|
|||||||
if(key_bits < 8*HASH_SIZE + 9)
|
if(key_bits < 8*HASH_SIZE + 9)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(raw.size() != HASH_SIZE)
|
if(message_hash.size() != HASH_SIZE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(const_coded.size() > KEY_BYTES || const_coded.size() <= 1)
|
if(pss_repr.size() > KEY_BYTES || pss_repr.size() <= 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(const_coded[const_coded.size()-1] != 0xBC)
|
if(pss_repr[pss_repr.size()-1] != 0xBC)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
secure_vector<uint8_t> coded = const_coded;
|
secure_vector<uint8_t> coded = pss_repr;
|
||||||
if(coded.size() < KEY_BYTES)
|
if(coded.size() < KEY_BYTES)
|
||||||
{
|
{
|
||||||
secure_vector<uint8_t> temp(KEY_BYTES);
|
secure_vector<uint8_t> temp(KEY_BYTES);
|
||||||
@@ -110,23 +111,32 @@ bool pss_verify(HashFunction& hash,
|
|||||||
|
|
||||||
for(size_t j = 0; j != 8; ++j)
|
for(size_t j = 0; j != 8; ++j)
|
||||||
hash.update(0);
|
hash.update(0);
|
||||||
hash.update(raw);
|
hash.update(message_hash);
|
||||||
hash.update(&DB[salt_offset], salt_size);
|
hash.update(&DB[salt_offset], salt_size);
|
||||||
|
|
||||||
secure_vector<uint8_t> H2 = hash.final();
|
const secure_vector<uint8_t> H2 = hash.final();
|
||||||
|
|
||||||
return constant_time_compare(H, H2.data(), HASH_SIZE);
|
const bool ok = constant_time_compare(H, H2.data(), HASH_SIZE);
|
||||||
|
|
||||||
|
if(out_salt_size && ok)
|
||||||
|
*out_salt_size = salt_size;
|
||||||
|
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PSSR::PSSR(HashFunction* h) :
|
PSSR::PSSR(HashFunction* h) :
|
||||||
m_hash(h), m_SALT_SIZE(m_hash->output_length())
|
m_hash(h),
|
||||||
|
m_salt_size(m_hash->output_length()),
|
||||||
|
m_required_salt_len(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PSSR::PSSR(HashFunction* h, size_t salt_size) :
|
PSSR::PSSR(HashFunction* h, size_t salt_size) :
|
||||||
m_hash(h), m_SALT_SIZE(salt_size)
|
m_hash(h),
|
||||||
|
m_salt_size(salt_size),
|
||||||
|
m_required_salt_len(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +160,7 @@ secure_vector<uint8_t> PSSR::encoding_of(const secure_vector<uint8_t>& msg,
|
|||||||
size_t output_bits,
|
size_t output_bits,
|
||||||
RandomNumberGenerator& rng)
|
RandomNumberGenerator& rng)
|
||||||
{
|
{
|
||||||
secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE);
|
const secure_vector<uint8_t> salt = rng.random_vec(m_salt_size);
|
||||||
return pss_encode(*m_hash, msg, salt, output_bits);
|
return pss_encode(*m_hash, msg, salt, output_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,12 +171,23 @@ bool PSSR::verify(const secure_vector<uint8_t>& coded,
|
|||||||
const secure_vector<uint8_t>& raw,
|
const secure_vector<uint8_t>& raw,
|
||||||
size_t key_bits)
|
size_t key_bits)
|
||||||
{
|
{
|
||||||
return pss_verify(*m_hash, coded, raw, key_bits);
|
size_t salt_size = 0;
|
||||||
|
const bool ok = pss_verify(*m_hash, coded, raw, key_bits, &salt_size);
|
||||||
|
|
||||||
|
if(m_required_salt_len && salt_size != m_salt_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSA* PSSR::clone()
|
||||||
|
{
|
||||||
|
return new PSSR(m_hash->clone(), m_salt_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PSSR::name() const
|
std::string PSSR::name() const
|
||||||
{
|
{
|
||||||
return "EMSA4(" + m_hash->name() + ",MGF1," + std::to_string(m_SALT_SIZE) + ")";
|
return "EMSA4(" + m_hash->name() + ",MGF1," + std::to_string(m_salt_size) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key,
|
AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key,
|
||||||
@@ -193,7 +214,7 @@ AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key,
|
|||||||
.start_cons(SEQUENCE)
|
.start_cons(SEQUENCE)
|
||||||
.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).encode(hash_id).end_cons()
|
.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).encode(hash_id).end_cons()
|
||||||
.start_cons(ASN1_Tag(1), CONTEXT_SPECIFIC).encode(mgf_id).end_cons()
|
.start_cons(ASN1_Tag(1), CONTEXT_SPECIFIC).encode(mgf_id).end_cons()
|
||||||
.start_cons(ASN1_Tag(2), CONTEXT_SPECIFIC).encode(m_SALT_SIZE).end_cons()
|
.start_cons(ASN1_Tag(2), CONTEXT_SPECIFIC).encode(m_salt_size).end_cons()
|
||||||
.start_cons(ASN1_Tag(3), CONTEXT_SPECIFIC).encode(size_t(1)).end_cons() // trailer field
|
.start_cons(ASN1_Tag(3), CONTEXT_SPECIFIC).encode(size_t(1)).end_cons() // trailer field
|
||||||
.end_cons();
|
.end_cons();
|
||||||
|
|
||||||
@@ -201,12 +222,16 @@ AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PSSR_Raw::PSSR_Raw(HashFunction* h) :
|
PSSR_Raw::PSSR_Raw(HashFunction* h) :
|
||||||
m_hash(h), m_SALT_SIZE(m_hash->output_length())
|
m_hash(h),
|
||||||
|
m_salt_size(m_hash->output_length()),
|
||||||
|
m_required_salt_len(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PSSR_Raw::PSSR_Raw(HashFunction* h, size_t salt_size) :
|
PSSR_Raw::PSSR_Raw(HashFunction* h, size_t salt_size) :
|
||||||
m_hash(h), m_SALT_SIZE(salt_size)
|
m_hash(h),
|
||||||
|
m_salt_size(salt_size),
|
||||||
|
m_required_salt_len(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +261,7 @@ secure_vector<uint8_t> PSSR_Raw::encoding_of(const secure_vector<uint8_t>& msg,
|
|||||||
size_t output_bits,
|
size_t output_bits,
|
||||||
RandomNumberGenerator& rng)
|
RandomNumberGenerator& rng)
|
||||||
{
|
{
|
||||||
secure_vector<uint8_t> salt = rng.random_vec(m_SALT_SIZE);
|
secure_vector<uint8_t> salt = rng.random_vec(m_salt_size);
|
||||||
return pss_encode(*m_hash, msg, salt, output_bits);
|
return pss_encode(*m_hash, msg, salt, output_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,12 +272,23 @@ bool PSSR_Raw::verify(const secure_vector<uint8_t>& coded,
|
|||||||
const secure_vector<uint8_t>& raw,
|
const secure_vector<uint8_t>& raw,
|
||||||
size_t key_bits)
|
size_t key_bits)
|
||||||
{
|
{
|
||||||
return pss_verify(*m_hash, coded, raw, key_bits);
|
size_t salt_size = 0;
|
||||||
|
const bool ok = pss_verify(*m_hash, coded, raw, key_bits, &salt_size);
|
||||||
|
|
||||||
|
if(m_required_salt_len && salt_size != m_salt_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSA* PSSR_Raw::clone()
|
||||||
|
{
|
||||||
|
return new PSSR_Raw(m_hash->clone(), m_salt_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PSSR_Raw::name() const
|
std::string PSSR_Raw::name() const
|
||||||
{
|
{
|
||||||
return "PSSR_Raw(" + m_hash->name() + ",MGF1," + std::to_string(m_SALT_SIZE) + ")";
|
return "PSSR_Raw(" + m_hash->name() + ",MGF1," + std::to_string(m_salt_size) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ class BOTAN_PUBLIC_API(2,0) PSSR final : public EMSA
|
|||||||
*/
|
*/
|
||||||
PSSR(HashFunction* hash, size_t salt_size);
|
PSSR(HashFunction* hash, size_t salt_size);
|
||||||
|
|
||||||
EMSA* clone() override { return new PSSR(m_hash->clone(), m_SALT_SIZE); }
|
EMSA* clone() override;
|
||||||
|
|
||||||
std::string name() const override;
|
std::string name() const override;
|
||||||
|
|
||||||
@@ -51,7 +51,8 @@ class BOTAN_PUBLIC_API(2,0) PSSR final : public EMSA
|
|||||||
size_t key_bits) override;
|
size_t key_bits) override;
|
||||||
|
|
||||||
std::unique_ptr<HashFunction> m_hash;
|
std::unique_ptr<HashFunction> m_hash;
|
||||||
size_t m_SALT_SIZE;
|
size_t m_salt_size;
|
||||||
|
bool m_required_salt_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,7 +74,7 @@ class BOTAN_PUBLIC_API(2,3) PSSR_Raw final : public EMSA
|
|||||||
*/
|
*/
|
||||||
PSSR_Raw(HashFunction* hash, size_t salt_size);
|
PSSR_Raw(HashFunction* hash, size_t salt_size);
|
||||||
|
|
||||||
EMSA* clone() override { return new PSSR_Raw(m_hash->clone(), m_SALT_SIZE); }
|
EMSA* clone() override;
|
||||||
|
|
||||||
std::string name() const override;
|
std::string name() const override;
|
||||||
private:
|
private:
|
||||||
@@ -90,8 +91,9 @@ class BOTAN_PUBLIC_API(2,3) PSSR_Raw final : public EMSA
|
|||||||
size_t key_bits) override;
|
size_t key_bits) override;
|
||||||
|
|
||||||
std::unique_ptr<HashFunction> m_hash;
|
std::unique_ptr<HashFunction> m_hash;
|
||||||
size_t m_SALT_SIZE;
|
|
||||||
secure_vector<uint8_t> m_msg;
|
secure_vector<uint8_t> m_msg;
|
||||||
|
size_t m_salt_size;
|
||||||
|
bool m_required_salt_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
PK_PADDING -> 20131128
|
PK_PADDING -> 20131128
|
||||||
</defines>
|
</defines>
|
||||||
|
|
||||||
load_on auto
|
|
||||||
|
|
||||||
<requires>
|
<requires>
|
||||||
asn1
|
asn1
|
||||||
rng
|
rng
|
||||||
|
@@ -17,13 +17,14 @@ void mgf1_mask(HashFunction& hash,
|
|||||||
{
|
{
|
||||||
uint32_t counter = 0;
|
uint32_t counter = 0;
|
||||||
|
|
||||||
|
secure_vector<uint8_t> buffer(hash.output_length());
|
||||||
while(out_len)
|
while(out_len)
|
||||||
{
|
{
|
||||||
hash.update(in, in_len);
|
hash.update(in, in_len);
|
||||||
hash.update_be(counter);
|
hash.update_be(counter);
|
||||||
secure_vector<uint8_t> buffer = hash.final();
|
hash.final(buffer.data());
|
||||||
|
|
||||||
size_t xored = std::min<size_t>(buffer.size(), out_len);
|
const size_t xored = std::min<size_t>(buffer.size(), out_len);
|
||||||
xor_buf(out, buffer.data(), xored);
|
xor_buf(out, buffer.data(), xored);
|
||||||
out += xored;
|
out += xored;
|
||||||
out_len -= xored;
|
out_len -= xored;
|
||||||
|
@@ -93,6 +93,8 @@ class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
|
|||||||
[this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); })
|
[this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); })
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
size_t agreed_value_size() const override { return m_p.bytes(); }
|
||||||
|
|
||||||
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
|
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
|
||||||
private:
|
private:
|
||||||
const BigInt& m_p;
|
const BigInt& m_p;
|
||||||
|
@@ -67,6 +67,7 @@ class DL_Group_Data final
|
|||||||
size_t p_bits() const { return m_p_bits; }
|
size_t p_bits() const { return m_p_bits; }
|
||||||
size_t q_bits() const { return m_q_bits; }
|
size_t q_bits() const { return m_q_bits; }
|
||||||
size_t p_bytes() const { return (m_p_bits + 7) / 8; }
|
size_t p_bytes() const { return (m_p_bits + 7) / 8; }
|
||||||
|
size_t q_bytes() const { return (m_q_bits + 7) / 8; }
|
||||||
|
|
||||||
size_t estimated_strength() const { return m_estimated_strength; }
|
size_t estimated_strength() const { return m_estimated_strength; }
|
||||||
|
|
||||||
@@ -448,6 +449,12 @@ size_t DL_Group::q_bits() const
|
|||||||
return data().q_bits();
|
return data().q_bits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t DL_Group::q_bytes() const
|
||||||
|
{
|
||||||
|
data().assert_q_is_set("q_bytes");
|
||||||
|
return data().q_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
size_t DL_Group::estimated_strength() const
|
size_t DL_Group::estimated_strength() const
|
||||||
{
|
{
|
||||||
return data().estimated_strength();
|
return data().estimated_strength();
|
||||||
|
@@ -268,6 +268,13 @@ class BOTAN_PUBLIC_API(2,0) DL_Group final
|
|||||||
*/
|
*/
|
||||||
size_t q_bits() const;
|
size_t q_bits() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the size of q in bytes
|
||||||
|
* Same as get_q().bytes()
|
||||||
|
* Throws if q is unset
|
||||||
|
*/
|
||||||
|
size_t q_bytes() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return size in bits of a secret exponent
|
* Return size in bits of a secret exponent
|
||||||
*
|
*
|
||||||
|
@@ -89,7 +89,8 @@ class DSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
|
|||||||
m_b_inv = m_group.inverse_mod_q(m_b);
|
m_b_inv = m_group.inverse_mod_q(m_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t max_input_bits() const override { return m_group.get_q().bits(); }
|
size_t signature_length() const override { return 2*m_group.q_bytes(); }
|
||||||
|
size_t max_input_bits() const override { return m_group.q_bits(); }
|
||||||
|
|
||||||
secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
|
secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
|
||||||
RandomNumberGenerator& rng) override;
|
RandomNumberGenerator& rng) override;
|
||||||
@@ -157,7 +158,7 @@ class DSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t max_input_bits() const override { return m_group.get_q().bits(); }
|
size_t max_input_bits() const override { return m_group.q_bits(); }
|
||||||
|
|
||||||
bool with_recovery() const override { return false; }
|
bool with_recovery() const override { return false; }
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user