8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22:43:03 +01:00
This commit is contained in:
Paul Reeves 2017-08-23 16:30:54 +02:00
commit 53e9f73c57
111 changed files with 7517 additions and 982 deletions

View File

@ -58,12 +58,23 @@
Reference(s): [doc/sql.extensions/README.identity_columns](https://github.com/FirebirdSQL/firebird/raw/master/doc/sql.extensions/README.identity_columns.txt)
Contributor(s): Adriano dos Santos Fernandes
* [CORE-5380](http://tracker.firebirdsql.org/browse/CORE-5380): Allow subroutines to call others subroutines and themself recursively
Reference(s): [doc/sql.extensions/README.subroutines.txt](https://github.com/FirebirdSQL/firebird/raw/master/doc/sql.extensions/README.subroutines.txt)
Contributor(s): Adriano dos Santos Fernandes
* [CORE-5238](http://tracker.firebirdsql.org/browse/CORE-5238): Replace xinetd support with the native listener
Contributor(s): Alex Peshkoff
* [CORE-5119](http://tracker.firebirdsql.org/browse/CORE-5119): Support autocommit mode in SET TRANSACTION statement
Contributor(s): Dmitry Yemanov
* [CORE-5064](http://tracker.firebirdsql.org/browse/CORE-5064): Add datatypes (VAR)BINARY(n) and BINARY VARYING(n) as aliases for (VAR)CHAR(n) CHARACTER SET OCTETS
Contributor(s): Dimitry Sibiryakov
* [CORE-4436](http://tracker.firebirdsql.org/browse/CORE-4436): Support for different hash algorithms in HASH system function
Reference(s): [doc/sql.extensions/README.builtin_functions.txt](https://github.com/FirebirdSQL/firebird/raw/master/doc/sql.extensions/README.builtin_functions.txt)
Contributor(s): Adriano dos Santos Fernandes
* [CORE-2557](http://tracker.firebirdsql.org/browse/CORE-2557): Grants on MON$ tables
Contributor(s): Alex Peshkoff

View File

@ -1,4 +1,4 @@
Firebird 3 Server for Linux
Firebird 4 Server for Linux
More information can be found about the Firebird

View File

@ -1,10 +0,0 @@
[Unit]
Description=Firebird Database Server ( Classic )
After=local-fs.target
[Service]
User=firebird
Group=firebird
ExecStart=@FB_SBINDIR@/firebird
StandardInput=socket
StandardError=syslog

View File

@ -1,11 +0,0 @@
[Unit]
Description=Firebird Classic Activation Socket
Conflicts=firebird-superserver.service
[Socket]
ListenStream=3050
Accept=true
MaxConnections=2048
[Install]
WantedBy=sockets.target

View File

@ -2,7 +2,7 @@
#
# /etc/rc.d/rc.firebirdss
#
# Start/stop/restart the firebird super server.
# Start/stop/restart the firebird server.
#
fb_install_prefix=@prefix@

View File

@ -9,7 +9,7 @@
#
# /usr/sbin/rcfirebird
#
# System startup script for the Firebird SuperServer
# System startup script for the Firebird Server
#
### BEGIN INIT INFO
# Provides: firebird

View File

@ -1,7 +1,6 @@
[Unit]
Description=Firebird Database Server ( SuperServer )
Description=Firebird Database Server
After=syslog.target network.target
Conflicts=firebird-classic.socket
[Service]
User=firebird

View File

@ -1,17 +0,0 @@
# default: on
# description: FirebirdSQL server
#
service @FB_SERVICE_NAME@
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
# These lines cause problems with Windows XP SP2 clients
# using default firewall configuration (SF#1065511)
# log_on_success += USERID
# log_on_failure += USERID
server = @FB_SBINDIR@/firebird
}

View File

@ -111,8 +111,7 @@ getInitScriptLocation() {
# register/start/stop server using systemd
SYSTEMCTL=systemctl
CLASSIC_CTRL=${fb_startup_name}-classic.socket
SUPER_CTRL=${fb_startup_name}-superserver.service
CTRL=${fb_startup_name}.service
SYSTEMD_DIR=/usr/lib/systemd/system
[ -d $SYSTEMD_DIR ] || SYSTEMD_DIR=/lib/systemd/system
TMPFILE_CONF=/usr/lib/tmpfiles.d/firebird.conf
@ -140,13 +139,9 @@ installSystemdCtrlFiles() {
exit 1
fi
editFile "@FB_MISCDIR@/firebird-superserver.service" ExecStart "ExecStart=${fb_install_prefix}/bin/fbguard -pidfile $PidDir/${fb_startup_name}.pid -daemon -forever"
editFile "@FB_MISCDIR@/firebird-superserver.service" PIDFile "PIDFile=$PidDir/${fb_startup_name}.pid"
editFile "@FB_MISCDIR@/firebird-classic@.service" ExecStart "ExecStart=${fb_install_prefix}/bin/firebird"
cp @FB_MISCDIR@/firebird-superserver.service "${SYSTEMD_DIR}/${fb_startup_name}-superserver.service"
cp @FB_MISCDIR@/firebird-classic@.service "${SYSTEMD_DIR}/${fb_startup_name}-classic@.service"
cp @FB_MISCDIR@/firebird-classic.socket "${SYSTEMD_DIR}/${fb_startup_name}-classic.socket"
editFile "@FB_MISCDIR@/firebird.service" ExecStart "ExecStart=${fb_install_prefix}/bin/fbguard -pidfile $PidDir/${fb_startup_name}.pid -daemon -forever"
editFile "@FB_MISCDIR@/firebird.service" PIDFile "PIDFile=$PidDir/${fb_startup_name}.pid"
cp @FB_MISCDIR@/firebird.service "${SYSTEMD_DIR}/${fb_startup_name}.service"
mkdir -p ${PidDir}
chown $RunUser:$RunGroup ${PidDir}
@ -156,7 +151,7 @@ installSystemdCtrlFiles() {
}
osRemoveStartupFiles() {
rm -f ${SYSTEMD_DIR}/${fb_startup_name}-*
rm -f ${SYSTEMD_DIR}/${fb_startup_name}.*
rm -f ${TMPFILE_CONF}
}
@ -180,33 +175,10 @@ systemdSrv() {
return 1
}
classicSrv() {
op=${1}
systemdSrv ${op} ${CLASSIC_CTRL}
}
superSrv() {
op=${1}
systemdSrv ${op} ${SUPER_CTRL}
}
osRegisterClassicServer() {
installSystemdCtrlFiles
classicSrv enable
}
osUnregisterClassicServer() {
classicSrv disable
}
osStartClassicServer() {
classicSrv start
}
osStopClassicServer() {
classicSrv stop
systemdSrv ${op} ${CTRL}
}
registerSuperServer() {
@ -236,9 +208,6 @@ stopSuperServer() {
}
# Additional OS settings
systemdPresent && OS_Has_Specific_Classic_Startup=yes
#------------------------------------------------------------------------
# stop super server if it is running
@ -493,7 +462,7 @@ removeServiceAutostart() {
standaloneServerInstalled() {
if systemdPresent; then
${SYSTEMCTL} --quiet is-enabled ${SUPER_CTRL} && return 0
${SYSTEMCTL} --quiet is-enabled ${CTRL} && return 0
return 1
fi

View File

@ -285,10 +285,9 @@ copyFiles() {
#misc
cp $BuildRootDir/src/misc/intl.sql ${TargetDir}@FB_MISCDIR@
cp $BuildRootDir/src/misc/upgrade/v3.0/security_database* ${TargetDir}@FB_MISCDIR@/upgrade/security
cp $BuildRootDir/gen/install/misc/firebird.xinetd ${TargetDir}@FB_MISCDIR@
cp $BuildRootDir/gen/install/misc/firebird.init.d.* ${TargetDir}@FB_MISCDIR@
cp $BuildRootDir/gen/install/misc/rc.config.firebird ${TargetDir}@FB_MISCDIR@
cp $BuildRootDir/gen/install/misc/firebird-* ${TargetDir}@FB_MISCDIR@
cp $BuildRootDir/gen/install/misc/firebird.service ${TargetDir}@FB_MISCDIR@
chmod -R go-rwx ${TargetDir}@FB_MISCDIR@

View File

@ -382,7 +382,7 @@ for /R %FB_OUTPUT_DIR%\doc %%v in (.) do (
:: This requires WiX 3.0 to be installed
::============
:: This is only relevent if we are shipping packages built with Visual Studio 2010 (MSVC10)
:: for Firebird 3.0 there are no plans to ship oficial builds with other MSVC runtimes. But we could.
:: for Firebird 3.0 there are no plans to ship official builds with other MSVC runtimes. But we could.
if %MSVC_VERSION% EQU 10 (
if not exist %FB_OUTPUT_DIR%\system32\vccrt%MSVC_VERSION%_%FB_TARGET_PLATFORM%.msi (
"%WIX%\bin\candle.exe" -v -sw1091 %FB_ROOT_PATH%\builds\win32\msvc%MSVC_VERSION%\VCCRT_%FB_TARGET_PLATFORM%.wxs -out %FB_GEN_DIR%\vccrt_%FB_TARGET_PLATFORM%.wixobj

View File

@ -666,8 +666,7 @@ begin
{ Create a page to grab the new SYSDBA password }
AdminUserPage := CreateInputQueryPage(wpSelectTasks,
'Create a password for the Database System Administrator'
, 'Or click through to use the default password of ''masterkey''. ' + #13#10
' *** Note - in Firebird 3 masterkey and masterke are different passwords. ***'
, 'Or click through to use the default password of ''masterkey''. '
, ''
);
AdminUserPage.Add('SYSDBA Name:', False);

View File

@ -1,5 +1,5 @@
Firebird Database Server $MAJOR.$MINOR.$RELEASE (Release Candidate 2)
========================================================
Firebird Database Server $MAJOR.$MINOR.$RELEASE
===============================================
Ovaj dokument je vodic za instalaciju ovog paketa
Firebird-a $MAJOR.$MINOR za Windows platformu. Ovaj tekst
@ -21,7 +21,7 @@ Sadrzaj
o Prije instalacije
o Deployment gds32.dll
o Instalacija Guardian-a
o Re-instalacija Firebird-a 3
o Re-instalacija Firebird-a
o Poznati problemi u vezi s instalacijom
o Deinstalacija
o Instalacija batch datotekom
@ -37,8 +37,8 @@ fbclient.dll i gds32.dll uklonjeni iz <system32>.
Pogledajte UNINSTALL sekciju ispod za vise informacija o ovome.
Ako ste instalirali beta ili alpha verziju
firebird-a 3, instalacija ce preimenovati firebid.conf i
security3.fdb jer ove datoteke vise nisu kompatibilne.
firebird-a, instalacija ce preimenovati firebird.conf i
security4.fdb jer ove datoteke vise nisu kompatibilne.
Deployment gds32.dll
@ -64,12 +64,12 @@ SuperServer ili SuperClassic, onda je ponudjen
ali nije izabran po default-u.
Re-instalacija Firebird-a 3
-----------------------------
Re-instalacija Firebird-a
-------------------------
Instalacioni program radi sve sto moze da detektuje i
sacuva prethodnu instalaciju. Ako instalacija detektuje
firebird.conf ili security3.fdb onda nece ponuditi
firebird.conf ili security4.fdb onda nece ponuditi
opciju da instalira legacy_auth. Niti ce ponuditi
opciju da postavi SYSDBA username i password.
@ -127,7 +127,7 @@ o Deinstalacija ostavlja 5 datoteka u install
- firebird.conf
- fbtrace.conf
- firebird.log
- security3.fdb
- security4.fdb
Ovo je uradjeno namjerno. Ove datoteke su sve
potencijalno modifikovane od strane korisnika i mogu

View File

@ -28,7 +28,7 @@ Contenu
o Avant l'installation
o Déployement de gds32.dll
o Installation du Guardian
o Réinstallation de Firebird 3
o Réinstallation de Firebird
o Problèmes connus d'installation
o Desinstallation
o Installation depuis un fichier batch
@ -44,7 +44,7 @@ Il est particulièrement important de vérifier que
fbclient.dll et gds32.dll ont été retirés de <system32>.
Si vous avez installé une version beta ou alpha de Firebird $MAJOR.$MINOR,
l'installeur va renommer firebird.conf et security3.fdb, car ces
l'installeur va renommer firebird.conf et security4.fdb, car ces
fichiers ne sont plus compatibles avec la version actuelle.
@ -131,7 +131,7 @@ o La désinstallation laisse cinq fichiers dans le
- firebird.conf
- fbtrace.conf
- firebird.log
- security3.fdb
- security4.fdb
Ceci est intentionnel. Ces fichiers sont tous
potentiellement modifiables par les utilisateurs et peuvent

View File

@ -40,9 +40,8 @@ an existing translation. The steps to follow are these:
o The Win32 install files are located in install\arch-specific\win32.
This sub-directory is located as follows:
Firebird 1.5 - firebird2\src
Firebird 2.n - firebird2\builds
Firebird 3.n - firebird2\builds
Firebird 1.5 - firebird2\src
Firebird 2.n and newer - firebird2\builds
o You can use a tool such as TortoiseSVN to checkout the Win32 install
kit. Just open the SVN checkout dialogue and enter something similar

View File

@ -1,5 +1,5 @@
Firebird Database Server $MAJOR.$MINOR.$RELEASE (Release Candidate 2)
========================================================
Firebird Database Server $MAJOR.$MINOR.$RELEASE
===============================================
This document is a guide to installing this package of
@ -10,9 +10,9 @@ primarily aimed at users of the binary installer.
It is assumed that readers of this document are already
familiar with Firebird. If you are evaluating Firebird $MAJOR.$MINOR
as part of a migration from Firebird 2.5 you are advised to
review the Firebird $MAJOR.$MINOR documentation to understand
the changes made between 2.5 and $MAJOR.$MINOR.
as part of a migration from some older Firebird version you are advised
to review the Firebird $MAJOR.$MINOR documentation to understand
the changes made between your version and $MAJOR.$MINOR.
Contents
@ -37,7 +37,7 @@ fbclient.dll and gds32.dll are removed from <system32>.
See the UNINSTALL section below for more info on this.
If you have installed a beta or alpha version of Firebird $MAJOR.$MINOR
the installer will rename firebird.conf and security3.fdb as
the installer will rename firebird.conf and security4.fdb as
these files are no longer compatible.
@ -64,12 +64,12 @@ chosen. If SuperServer or SuperClassic are chosen
it is offered but not selected by default.
Re-installation of Firebird 3
-----------------------------
Re-installation of Firebird
---------------------------
The binary installer does its best to detect and
preserve a previous install. If the installer detects
firebird.conf or security3.fdb it will not offer the
firebird.conf or security4.fdb it will not offer the
option to install legacy_auth. Neither will it offer
the option to set the SYSDBA username and password.
@ -129,7 +129,7 @@ o Uninstallation leaves five files in the install
- firebird.conf
- fbtrace.conf
- firebird.log
- security3.fdb
- security4.fdb
This is intentional. These files are all
potentially modifiable by users and may be required

View File

@ -175,7 +175,7 @@ Parameters specific to Firebird uninstalls
firebird.conf
databases.conf
firebird.log
security3.fdb
security4.fdb
fbtrace.conf
The assumption is that these files will be useful to users

View File

@ -9,10 +9,10 @@
Предполагается, что читатели данного документа уже
знакомы с Firebird. Если же вы знакомитесь
с Firebird $MAJOR.$MINOR в процессе миграции с версии
2.5, то рекомендуем вам обратиться к документации по
версии $MAJOR.$MINOR с целью ознакомиться с основными
отличиями между версиями 2.5 и $MAJOR.$MINOR.
с Firebird $MAJOR.$MINOR в процессе миграции с
предыдущей версии, то рекомендуем вам обратиться к документации
по версии $MAJOR.$MINOR с целью ознакомиться с основными
отличиями между вашей версией и $MAJOR.$MINOR.
Содержание
@ -36,7 +36,7 @@ o Установка из пакетного (bat) файла
каталога <system32>.
Если у вас установлена Альфа или Бета версия Firebird $MAJOR.$MINOR,
то программа установки переименует файлы firebird.conf и security3.fdb
то программа установки переименует файлы firebird.conf и security4.fdb
из-за их несовместимости с устанавливаемой версией.
@ -67,7 +67,7 @@ MS VC runtime версии 10.0 установлены в системе.
Программа установки пытается обнаружить и сохранить ранее установленную
версию Firebird. Если программа установки обнаруживает файлы firebird.conf
или security3.fdb, то некоторые настройки авторизации могут быть недоступны,
или security4.fdb, то некоторые настройки авторизации могут быть недоступны,
в частности возможность установить пароль пользователя SYSDBA.
@ -123,7 +123,7 @@ o Деинсталлятор оставляет четыре файла в ка
- firebird.conf
- fbtrace.conf
- firebird.log
- security3.fdb
- security4.fdb
Это происходит намеренно. Эти файлы потенциально
могут быть изменены пользователем и могут

View File

@ -69,7 +69,6 @@ done
removeLinksForBackCompatibility
removeServiceAutostart
removeInetdServiceEntry
if [ -d $PidDir ]
then
@ -82,9 +81,4 @@ removeInstalledFiles # Remove installed files
removeUninstallFiles # Remove the 'uninstall' utility files
removeEmptyDirs # Remove empty directories
if [ "$OS_Has_Specific_Classic_Startup" ]
then
osRemoveStartupFiles
fi
displayMessage "Uninstall completed"

View File

@ -27,6 +27,11 @@ cat <<EOF
Firebird server may run in 2 different modes - super and classic.
Super server provides better performance, classic - better availability.
*******************************************************
* This script is deprecated and will be removed soon: *
* edit firebird.conf directly instead. *
*******************************************************
EOF
AskQuestion "Which option would you like to choose: (super|classic) [super] " "super"
@ -51,8 +56,6 @@ esac
echo "Stopping currently running engine..."
checkIfServerRunning
removeInetdServiceEntry
removeServiceAutostart
sc=Starting
[ ${fb_install_prefix} = ${default_prefix} ] || sc=Configure
@ -60,13 +63,10 @@ echo "$sc firebird in $multiAnswer server mode..."
fbconf="@FB_CONFDIR@/firebird.conf"
if [ $multiAnswer = classic ]; then
replaceLineInFile $fbconf "ServerMode = Classic" "^ServerMode"
updateInetdServiceEntry
else
replaceLineInFile $fbconf "ServerMode = Super" "^ServerMode"
installInitdScript
fi
startFirebird
echo "Done."

View File

@ -226,64 +226,6 @@ checkLibraries() {
}
#------------------------------------------------------------------------
# resetInetdServer
# Works for both inetd and xinetd
resetInetdServer() {
pid=`grepProcess "inetd|xinetd" | awk '{print $2}'`
if [ "$pid" ]
then
kill -HUP $pid
fi
}
#------------------------------------------------------------------------
# remove the xinetd config file(s)
removeXinetdEntry() {
file="${XINETD}${fb_startup_name}"
[ -f $file ] && rm -f $file
}
#------------------------------------------------------------------------
# remove the line from inetd file
removeInetdEntry() {
FileName=/etc/inetd.conf
oldLine=`grep "^@FB_SERVICE_NAME@" $FileName`
removeLineFromFile "$FileName" "$oldLine"
}
#------------------------------------------------------------------------
# Remove (x)inetd service entry and restart the service.
# Check to see if we have xinetd installed or plain inetd.
# Install differs for each of them.
removeInetdServiceEntry() {
if [ "$OS_Has_Specific_Classic_Startup" ]
then
osStopClassicServer
osUnregisterClassicServer
return
fi
if [ -d /etc/xinetd.d ]
then
removeXinetdEntry
elif [ -f /etc/inetd.conf ]
then
removeInetdEntry
fi
# make [x]inetd reload configuration
resetInetdServer
}
#------------------------------------------------------------------------
# grep process by name
@ -359,12 +301,6 @@ checkIfServerRunning() {
echo "Please quit all Firebird applications and then proceed."
exit 1
fi
# have to be root to modify (x)inetd
if [ "$1" != "install-embedded" ]
then
removeInetdServiceEntry
fi
}
@ -1006,64 +942,6 @@ fixFilePermissions() {
}
#------------------------------------------------------------------------
# Update inetd service entry
# This just adds/replaces the service entry line
updateInetdEntry() {
newLine="@FB_SERVICE_NAME@ stream tcp nowait.30000 $RunUser @FB_SBINDIR@/firebird firebird # Firebird Database Remote Server"
replaceLineInFile /etc/inetd.conf "$newLine" "^@FB_SERVICE_NAME@"
}
#------------------------------------------------------------------------
# Update xinetd service entry
updateXinetdEntry() {
InitFile="${XINETD}${fb_startup_name}"
cp @FB_MISCDIR@/firebird.xinetd $InitFile
if [ -f $InitFile ]
then
editFile $InitFile user "\tuser\t\t\t= $RunUser"
editFile $InitFile server "\tserver\t\t= ${fb_install_prefix}/bin/firebird"
yesno=yes
[ ${fb_install_prefix} = ${default_prefix} ] && yesno=no
editFile $InitFile disable "\tdisable\t\t= ${yesno}"
fi
}
#------------------------------------------------------------------------
# Update inetd service entry
# Check to see if we have xinetd installed or plain inetd.
# Install differs for each of them.
updateInetdServiceEntry() {
if ! standaloneServerInstalled
then
if [ "$OS_Has_Specific_Classic_Startup" ]
then
osRegisterClassicServer
return
fi
if [ -d /etc/xinetd.d ]
then
updateXinetdEntry
else
if [ ${fb_install_prefix} = ${default_prefix} ]
then
updateInetdEntry
else
echo "Install of classic server in non-default path is not supported with inetd - xinetd needed"
exit 1
fi
fi
fi
}
fbUsage() {
pf=""
if [ "@CHANGE_PATH_SUPPORT@" = "yes" ]
@ -1172,21 +1050,11 @@ extractBuildroot() {
#---------------------------------------------------------------------------
# depending upon presence of startup script starts super or classic server
# starts firebird server
startFirebird() {
if [ "${fb_install_prefix}" = "${default_prefix}" ]
then
if standaloneServerInstalled; then
startService
else
if [ "$OS_Has_Specific_Classic_Startup" ]
then
osStartClassicServer
return
fi
resetInetdServer
fi
startService
fi
}

View File

@ -729,7 +729,7 @@ clean_dependancies:
# leave the directories to make dependacies work still
clean_build:
$(RM) `find $(GEN_ROOT)/*/firebird \( -type f -o -type l \) -print`
$(RM) `find $(GEN_ROOT)/*/firebird \( -type f -o -type l \) \( \! -name '*.conf' -o -name 'udr_engine.conf' \) \! -name 'fb_config' \! -name '*.sh' -print`
clean_makefiles:
$(RM) $(GEN_ROOT)/Make*

View File

@ -194,14 +194,6 @@ SHRLIB_FOREIGN_EXT= $(SHRLIB_EXT)
# Include file with version variable definitions
include $(ROOT)/gen/Make.Version
#MajorVer = 2
#MinorVer = 5
#RevNo = 0
#BuildNum = 28678
#BuildType = T
#BuildSuffix = Firebird 3.0 Unstable
#PackageVersion = Unstable
#FirebirdVersion = 2.5.0
# Add windows dll to library patterns

View File

@ -27,10 +27,11 @@ AllObjects=
CO1:= $(call dirObjects,common)
CO2:= $(call dirObjects,common/classes)
CO3:= $(call dirObjects,common/config)
#CO4:= $(call dirObjects,common/exceptions)
#CO5:= $(call dirObjects,common/sync)
Common_Objects:= $(CO1) $(CO2) $(CO3)
# $(CO4) $(CO5)
CO4:= $(call dirObjects,common/tomcrypt)
#CO5:= $(call dirObjects,common/exceptions)
#CO6:= $(call dirObjects,common/sync)
Common_Objects:= $(CO1) $(CO2) $(CO3) $(CO4)
# $(CO5) $(CO6)
AllObjects += $(Common_Objects)

View File

@ -45,6 +45,7 @@
<ClCompile Include="..\..\..\src\common\classes\SyncObject.cpp" />
<ClCompile Include="..\..\..\src\common\classes\TempFile.cpp" />
<ClCompile Include="..\..\..\src\common\classes\timestamp.cpp" />
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp" />
<ClCompile Include="..\..\..\src\common\classes\UserBlob.cpp" />
<ClCompile Include="..\..\..\src\common\config\config.cpp" />
<ClCompile Include="..\..\..\src\common\config\ConfigCache.cpp" />
@ -62,6 +63,7 @@
</ClCompile>
<ClCompile Include="..\..\..\src\common\cvt.cpp" />
<ClCompile Include="..\..\..\src\common\db_alias.cpp" />
<ClCompile Include="..\..\..\src\common\DecFloat.cpp" />
<ClCompile Include="..\..\..\src\common\dllinst.cpp" />
<ClCompile Include="..\..\..\src\common\dsc.cpp" />
<ClCompile Include="..\..\..\src\common\DynamicStrings.cpp" />
@ -91,6 +93,11 @@
<ClCompile Include="..\..\..\src\common\ThreadData.cpp" />
<ClCompile Include="..\..\..\src\common\ThreadStart.cpp" />
<ClCompile Include="..\..\..\src\common\Tokens.cpp" />
<ClCompile Include="..\..\..\src\common\tomcrypt\crypt_argchk.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\md5.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha1.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha256.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha512.c" />
<ClCompile Include="..\..\..\src\common\unicode_util.cpp" />
<ClCompile Include="..\..\..\src\common\utils.cpp" />
<ClCompile Include="..\..\..\src\common\UtilSvc.cpp" />
@ -158,6 +165,7 @@
<ClInclude Include="..\..\..\src\common\CsConvert.h" />
<ClInclude Include="..\..\..\src\common\cvt.h" />
<ClInclude Include="..\..\..\src\common\db_alias.h" />
<ClInclude Include="..\..\..\src\common\DecFloat.h" />
<ClInclude Include="..\..\..\src\common\dllinst.h" />
<ClInclude Include="..\..\..\src\common\dsc.h" />
<ClInclude Include="..\..\..\src\common\dsc_proto.h" />
@ -196,6 +204,19 @@
<ClInclude Include="..\..\..\src\common\ThreadData.h" />
<ClInclude Include="..\..\..\src\common\ThreadStart.h" />
<ClInclude Include="..\..\..\src\common\Tokens.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_argchk.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cfg.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cipher.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_custom.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_hash.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_mac.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_macros.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_math.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_misc.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pk.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pkcs.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_prng.h" />
<ClInclude Include="..\..\..\src\common\unicode_util.h" />
<ClInclude Include="..\..\..\src\common\UtilSvc.h" />
<ClInclude Include="..\..\..\src\common\utils_proto.h" />
@ -283,7 +304,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Release\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -299,7 +320,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Debug\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -318,7 +339,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Release\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -336,7 +357,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Debug\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -13,6 +13,9 @@
<Filter Include="headers">
<UniqueIdentifier>{03f83331-723e-4ba5-9ebb-348f0554a088}</UniqueIdentifier>
</Filter>
<Filter Include="tomcrypt">
<UniqueIdentifier>{dd0bb92e-0a1e-4406-96ff-5265e8d28258}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\common\xdr.cpp">
@ -214,6 +217,27 @@
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\CRC32C.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\DecFloat.cpp">
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\crypt_argchk.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\md5.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha1.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha256.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha512.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
<Filter>classes</Filter>
</ClCompile>
</ItemGroup>
@ -530,5 +554,47 @@
<ClInclude Include="..\..\..\src\common\Tokens.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\DecFloat.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_argchk.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cfg.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cipher.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_custom.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_hash.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_mac.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_macros.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_math.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_misc.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pk.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pkcs.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_prng.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -45,6 +45,7 @@
<ClCompile Include="..\..\..\src\common\classes\SyncObject.cpp" />
<ClCompile Include="..\..\..\src\common\classes\TempFile.cpp" />
<ClCompile Include="..\..\..\src\common\classes\timestamp.cpp" />
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp" />
<ClCompile Include="..\..\..\src\common\classes\UserBlob.cpp" />
<ClCompile Include="..\..\..\src\common\config\config.cpp" />
<ClCompile Include="..\..\..\src\common\config\ConfigCache.cpp" />
@ -88,6 +89,11 @@
<ClCompile Include="..\..\..\src\common\ThreadData.cpp" />
<ClCompile Include="..\..\..\src\common\ThreadStart.cpp" />
<ClCompile Include="..\..\..\src\common\Tokens.cpp" />
<ClCompile Include="..\..\..\src\common\tomcrypt\crypt_argchk.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\md5.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha1.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha256.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha512.c" />
<ClCompile Include="..\..\..\src\common\unicode_util.cpp" />
<ClCompile Include="..\..\..\src\common\utils.cpp" />
<ClCompile Include="..\..\..\src\common\UtilSvc.cpp" />
@ -194,6 +200,19 @@
<ClInclude Include="..\..\..\src\common\ThreadData.h" />
<ClInclude Include="..\..\..\src\common\ThreadStart.h" />
<ClInclude Include="..\..\..\src\common\Tokens.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_argchk.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cfg.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cipher.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_custom.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_hash.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_mac.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_macros.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_math.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_misc.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pk.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pkcs.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_prng.h" />
<ClInclude Include="..\..\..\src\common\unicode_util.h" />
<ClInclude Include="..\..\..\src\common\UtilSvc.h" />
<ClInclude Include="..\..\..\src\common\utils_proto.h" />

View File

@ -13,6 +13,9 @@
<Filter Include="headers">
<UniqueIdentifier>{03f83331-723e-4ba5-9ebb-348f0554a088}</UniqueIdentifier>
</Filter>
<Filter Include="tomcrypt">
<UniqueIdentifier>{dd0bb92e-0a1e-4406-96ff-5265e8d28258}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\common\xdr.cpp">
@ -219,6 +222,24 @@
<ClCompile Include="..\..\..\src\common\DecFloat.cpp">
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\crypt_argchk.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\md5.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha1.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha256.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha512.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
<Filter>classes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
@ -536,5 +557,44 @@
<ClInclude Include="..\..\..\src\common\DecFloat.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_argchk.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cfg.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cipher.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_custom.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_hash.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_mac.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_macros.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_math.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_misc.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pk.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pkcs.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_prng.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -45,6 +45,7 @@
<ClCompile Include="..\..\..\src\common\classes\SyncObject.cpp" />
<ClCompile Include="..\..\..\src\common\classes\TempFile.cpp" />
<ClCompile Include="..\..\..\src\common\classes\timestamp.cpp" />
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp" />
<ClCompile Include="..\..\..\src\common\classes\UserBlob.cpp" />
<ClCompile Include="..\..\..\src\common\config\config.cpp" />
<ClCompile Include="..\..\..\src\common\config\ConfigCache.cpp" />
@ -58,6 +59,7 @@
</ClCompile>
<ClCompile Include="..\..\..\src\common\cvt.cpp" />
<ClCompile Include="..\..\..\src\common\db_alias.cpp" />
<ClCompile Include="..\..\..\src\common\DecFloat.cpp" />
<ClCompile Include="..\..\..\src\common\dllinst.cpp" />
<ClCompile Include="..\..\..\src\common\dsc.cpp" />
<ClCompile Include="..\..\..\src\common\DynamicStrings.cpp" />
@ -87,6 +89,11 @@
<ClCompile Include="..\..\..\src\common\ThreadData.cpp" />
<ClCompile Include="..\..\..\src\common\ThreadStart.cpp" />
<ClCompile Include="..\..\..\src\common\Tokens.cpp" />
<ClCompile Include="..\..\..\src\common\tomcrypt\crypt_argchk.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\md5.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha1.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha256.c" />
<ClCompile Include="..\..\..\src\common\tomcrypt\sha512.c" />
<ClCompile Include="..\..\..\src\common\unicode_util.cpp" />
<ClCompile Include="..\..\..\src\common\utils.cpp" />
<ClCompile Include="..\..\..\src\common\UtilSvc.cpp" />
@ -154,6 +161,7 @@
<ClInclude Include="..\..\..\src\common\CsConvert.h" />
<ClInclude Include="..\..\..\src\common\cvt.h" />
<ClInclude Include="..\..\..\src\common\db_alias.h" />
<ClInclude Include="..\..\..\src\common\DecFloat.h" />
<ClInclude Include="..\..\..\src\common\dllinst.h" />
<ClInclude Include="..\..\..\src\common\dsc.h" />
<ClInclude Include="..\..\..\src\common\dsc_proto.h" />
@ -192,6 +200,19 @@
<ClInclude Include="..\..\..\src\common\ThreadData.h" />
<ClInclude Include="..\..\..\src\common\ThreadStart.h" />
<ClInclude Include="..\..\..\src\common\Tokens.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_argchk.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cfg.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cipher.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_custom.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_hash.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_mac.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_macros.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_math.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_misc.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pk.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pkcs.h" />
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_prng.h" />
<ClInclude Include="..\..\..\src\common\unicode_util.h" />
<ClInclude Include="..\..\..\src\common\UtilSvc.h" />
<ClInclude Include="..\..\..\src\common\utils_proto.h" />
@ -283,7 +304,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Release\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -299,7 +320,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Debug\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -318,7 +339,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Release\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -336,7 +357,7 @@
<Culture>0x041d</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\Debug\tommath.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;../../../extern/libtommath/lib/$(PlatformName)\$(Configuration)\tommath.lib;../../../extern/decNumber/lib/$(PlatformName)\$(Configuration)\decnumber.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -13,6 +13,9 @@
<Filter Include="headers">
<UniqueIdentifier>{03f83331-723e-4ba5-9ebb-348f0554a088}</UniqueIdentifier>
</Filter>
<Filter Include="tomcrypt">
<UniqueIdentifier>{dd0bb92e-0a1e-4406-96ff-5265e8d28258}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\common\xdr.cpp">
@ -216,6 +219,27 @@
<ClCompile Include="..\..\..\src\common\CRC32C.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\DecFloat.cpp">
<Filter>classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\crypt_argchk.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\md5.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha1.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha256.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\tomcrypt\sha512.c">
<Filter>tomcrypt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
<Filter>classes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
@ -530,5 +554,47 @@
<ClInclude Include="..\..\..\src\common\Tokens.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\DecFloat.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_argchk.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cfg.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_cipher.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_custom.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_hash.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_mac.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_macros.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_math.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_misc.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pk.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_pkcs.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\common\tomcrypt\tomcrypt_prng.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1264,7 +1264,6 @@ case "$PLATFORM" in
INSTALL_SRC_DIR=builds/install/arch-specific/linux
AC_CONFIG_FILES([
gen/install/makeInstallImage.sh:builds/install/arch-specific/linux/makeInstallImage.sh.in
gen/install/misc/firebird.xinetd:builds/install/arch-specific/linux/firebird.xinetd.in
gen/install/misc/firebird.init.d.generic:builds/install/arch-specific/linux/firebird.init.d.generic.in
gen/install/misc/firebird.init.d.mandrake:builds/install/arch-specific/linux/firebird.init.d.mandrake.in
gen/install/misc/firebird.init.d.suse:builds/install/arch-specific/linux/firebird.init.d.suse.in
@ -1273,9 +1272,7 @@ case "$PLATFORM" in
gen/install/misc/firebird.init.d.slackware:builds/install/arch-specific/linux/firebird.init.d.slackware.in
gen/install/misc/rc.config.firebird:builds/install/arch-specific/linux/rc.config.firebird.in
gen/Release/firebird/bin/linuxLibrary.sh:builds/install/arch-specific/linux/linuxLibrary.sh.in
gen/install/misc/firebird-classic@.service:builds/install/arch-specific/linux/firebird-classic.service.in
gen/install/misc/firebird-classic.socket:builds/install/arch-specific/linux/firebird-classic.socket.in
gen/install/misc/firebird-superserver.service:builds/install/arch-specific/linux/firebird-superserver.service.in
gen/install/misc/firebird.service:builds/install/arch-specific/linux/firebird.service.in
],
[chmod a+x gen/install/*sh 2>/dev/null])
;;

View File

@ -473,13 +473,21 @@ HASH
----
Function:
Returns a HASH of a string.
Returns a HASH of a string using a specified algorithm.
Format:
HASH( <string> )
HASH( <string> [ USING <algorithm> ] )
algorithm ::= { MD5 | SHA1 | SHA256 | SHA512 }
Important:
- The syntax without USING is very discouraged and maintained for backward compatibility.
It returns a 64 bit integer and produces very bad hashes that easily result in collisions.
- The syntax with USING is introduced in FB 4.0 and returns VARCHAR strings with OCTETS charset.
Example:
select hash(x) from y;
select hash(x using sha256) from y;
----

View File

@ -7,7 +7,7 @@ Author:
Description:
Support for PSQL subroutines (functions and procedures) inside functions, procedures, triggers
and EXECUTE BLOCK. Subroutines are declared in the main routine and may be used from there.
and EXECUTE BLOCK. Subroutines are declared in the main routine and may be used from there or others subroutines.
Syntax:
<declaration item> ::=
@ -15,7 +15,21 @@ Syntax:
|
DECLARE [VARIABLE] CURSOR <cursor name> FOR (<query>);
|
DECLARE FUNCTION <function name> RETURNS <data type>
<subroutine declaration>
|
<subroutine implementation>
<subroutine declaration> ::=
DECLARE FUNCTION <function name> [ (<input parameters>) ]
RETURNS <data type>
[ [ NOT ] DETERMINISTIC ] ;
|
DECLARE PROCEDURE <procedure name> [ (<input parameters>) ] [ RETURNS (<output parameters>) ] ;
<subroutine implementation> ::=
DECLARE FUNCTION <function name> [ (<input parameters>) ]
RETURNS <data type>
[ [ NOT ] DETERMINISTIC ]
AS
...
BEGIN
@ -32,8 +46,11 @@ Syntax:
Limitations:
1) Subroutines may not be nested in another subroutine. They are only supported in the main
routine.
2) Currently, a subroutine may not directly access or use variables, cursors or another
subroutines of the main statements. This may be allowed in the future.
2) Currently, a subroutine may not directly access or use variables or cursors of the
main statements. This may be allowed in the future.
Notes:
1) Starting in FB 4, subroutines may be recursive or call others subroutines.
Examples:
set term !;
@ -89,3 +106,57 @@ Examples:
end!
select func1(5, 6) from rdb$database!
-- 3) Recursive sub-function in EXECUTE BLOCK.
execute block returns (i integer, o integer)
as
-- Recursive function without forward declaration.
declare function fibonacci(n integer) returns integer
as
begin
if (n = 0 or n = 1) then
return n;
else
return fibonacci(n - 1) + fibonacci(n - 2);
end
begin
i = 0;
while (i < 10)
do
begin
o = fibonacci(i);
suspend;
i = i + 1;
end
end!
-- 4) Example with forward declaration and parameter with default values.
execute block returns (o integer)
as
-- Forward declaration of P1.
declare procedure p1(i integer = 1) returns (o integer);
-- Forward declaration of P2.
declare procedure p2(i integer) returns (o integer);
-- Implementation of P1 should not re-declare parameter default value.
declare procedure p1(i integer) returns (o integer)
as
begin
execute procedure p2(i) returning_values o;
end
declare procedure p2(i integer) returns (o integer)
as
begin
o = i;
end
begin
execute procedure p1 returning_values o;
suspend;
end!

View File

@ -279,6 +279,73 @@ With `ROWS`, order expressions is not limited by number or types. In this case,
The frame syntax with `<window frame start>` specifies the start frame, with the end frame being `CURRENT ROW`.
When `ORDER BY` window clause is used but frame clause is omitted, it defaults to `RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`. This fact makes the query below to produce "weird" behaviour for the "sum_salary" column. It sums from the partition start to the current key, instead of sum the whole partition.
```sql
select
id,
salary,
sum(salary) over (order by salary) sum_salary
from employee
order by salary;
```
| id | salary | sum_salary |
|---:|-------:|-----------:|
| 3 | 8.00 | 8.00 |
| 4 | 9.00 | 17.00 |
| 1 | 10.00 | 37.00 |
| 5 | 10.00 | 37.00 |
| 2 | 12.00 | 49.00 |
You can explicitely set a frame to sum the whole partition as following query:
```sql
select
id,
salary,
sum(salary) over (
order by salary
rows between unbounded preceding and unbounded following
) sum_salary
from employee
order by salary;
```
| id | salary | sum_salary |
|---:|-------:|-----------:|
| 3 | 8.00 | 49.00 |
| 4 | 9.00 | 49.00 |
| 1 | 10.00 | 49.00 |
| 5 | 10.00 | 49.00 |
| 2 | 12.00 | 49.00 |
While this query "fixes" the weird nature of the default frame clause, it produces a result similar to a simple `OVER ()` clause without `ORDER BY`.
We can use a range frame to compute the count of employees with salaries between his salary - 1 and his salary + 1 with this query:
```sql
select
id,
salary,
count(*) over (
order by salary
range between 1 preceding and 1 following
) range_count
from employee
order by salary;
```
| id | salary | range_count |
|---:|-------:|------------:|
| 3 | 8.00 | 2 |
| 4 | 9.00 | 4 |
| 1 | 10.00 | 3 |
| 5 | 10.00 | 3 |
| 2 | 12.00 | 1 |
Some window functions discard frames. `ROW_NUMBER`, `LAG` and `LEAD` always work as `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`. And `DENSE_RANK`, `RANK`, `PERCENT_RANK` and `CUME_DIST` always work as `RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`.
`FIRST_VALUE`, `LAST_VALUE` and `NTH_VALUE` respect frames, but the `RANGE` unit works identically as `ROWS`.

View File

@ -1698,6 +1698,24 @@ C --
PARAMETER (GDS__decfloat_overflow = 335545142)
INTEGER*4 GDS__decfloat_underflow
PARAMETER (GDS__decfloat_underflow = 335545143)
INTEGER*4 GDS__subfunc_notdef
PARAMETER (GDS__subfunc_notdef = 335545144)
INTEGER*4 GDS__subproc_notdef
PARAMETER (GDS__subproc_notdef = 335545145)
INTEGER*4 GDS__subfunc_signat
PARAMETER (GDS__subfunc_signat = 335545146)
INTEGER*4 GDS__subproc_signat
PARAMETER (GDS__subproc_signat = 335545147)
INTEGER*4 GDS__subfunc_defvaldecl
PARAMETER (GDS__subfunc_defvaldecl = 335545148)
INTEGER*4 GDS__subproc_defvaldecl
PARAMETER (GDS__subproc_defvaldecl = 335545149)
INTEGER*4 GDS__subfunc_not_impl
PARAMETER (GDS__subfunc_not_impl = 335545150)
INTEGER*4 GDS__subproc_not_impl
PARAMETER (GDS__subproc_not_impl = 335545151)
INTEGER*4 GDS__sysf_invalid_hash_algorithm
PARAMETER (GDS__sysf_invalid_hash_algorithm = 335545152)
INTEGER*4 GDS__gfix_db_name
PARAMETER (GDS__gfix_db_name = 335740929)
INTEGER*4 GDS__gfix_invalid_sw

View File

@ -1693,6 +1693,24 @@ const
gds_decfloat_overflow = 335545142;
isc_decfloat_underflow = 335545143;
gds_decfloat_underflow = 335545143;
isc_subfunc_notdef = 335545144;
gds_subfunc_notdef = 335545144;
isc_subproc_notdef = 335545145;
gds_subproc_notdef = 335545145;
isc_subfunc_signat = 335545146;
gds_subfunc_signat = 335545146;
isc_subproc_signat = 335545147;
gds_subproc_signat = 335545147;
isc_subfunc_defvaldecl = 335545148;
gds_subfunc_defvaldecl = 335545148;
isc_subproc_defvaldecl = 335545149;
gds_subproc_defvaldecl = 335545149;
isc_subfunc_not_impl = 335545150;
gds_subfunc_not_impl = 335545150;
isc_subproc_not_impl = 335545151;
gds_subproc_not_impl = 335545151;
isc_sysf_invalid_hash_algorithm = 335545152;
gds_sysf_invalid_hash_algorithm = 335545152;
isc_gfix_db_name = 335740929;
gds_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930;

View File

@ -2936,6 +2936,7 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation)
ULONG records = 0;
rec_type record;
bool resync = false;
while (true)
{
@ -3027,11 +3028,13 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation)
// ASF: Preferable we should call isc_start_and_send only when records == 1, but this leaks
// memory when there are blobs and arrays fields - CORE-3802.
if (records % 1000 == 1)
if (resync || records % 1000 == 1)
s = isc_start_and_send(status_vector, &request, &gds_trans, 0, (USHORT) length, buffer, 0);
else
s = isc_send(status_vector, &request, 0, (USHORT) length, buffer, 0);
resync = (s != 0);
if (s)
{
if (status_vector[1] == isc_not_valid)
@ -3071,7 +3074,10 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation)
BURP_error_redirect (status_vector, 48);
// msg 48 isc_send failed
}
records--;
}
if (record != rec_data)
break;
} // while (true)

View File

@ -266,6 +266,11 @@ void ClumpletWriter::insertString(UCHAR tag, const char* str, FB_SIZE_T length)
insertBytesLengthCheck(tag, str, length);
}
void ClumpletWriter::insertData(UCHAR tag, const UCharBuffer& data)
{
insertBytesLengthCheck(tag, data.begin(), data.getCount());
}
void ClumpletWriter::insertPath(UCHAR tag, const PathName& str)
{
insertString(tag, str.c_str(), str.length());

View File

@ -77,6 +77,7 @@ public:
void insertPath(UCHAR tag, const PathName& str);
void insertString(UCHAR tag, const char* str);
void insertString(UCHAR tag, const char* str, FB_SIZE_T length);
void insertData(UCHAR tag, const UCharBuffer& data);
void insertByte(UCHAR tag, const UCHAR byte);
void insertTag(UCHAR tag);
void insertDouble(UCHAR tag, const double value);

View File

@ -232,4 +232,15 @@ inline bool isinf(F x)
#endif // isinf
#endif // WIN_NT
namespace Firebird {
inline bool isNegativeInf(double x)
{
#ifdef WIN_NT
return _fpclass(x) == _FPCLASS_NINF;
#else
return x == -INFINITY;
#endif
}
}
#endif //CLASSES_FPE_CONTROL_H

View File

@ -108,3 +108,26 @@ unsigned int InternalHash::hash(unsigned int length, const UCHAR* value)
{
return internalHash(length, value);
}
void WeakHashContext::update(const void* data, FB_SIZE_T length)
{
const UCHAR* p = static_cast<const UCHAR*>(data);
for (const UCHAR* end = p + length; p != end; ++p)
{
hashNumber = (hashNumber << 4) + *p;
const SINT64 n = hashNumber & FB_CONST64(0xF000000000000000);
if (n)
hashNumber ^= n >> 56;
hashNumber &= ~n;
}
}
void WeakHashContext::finish(Buffer& result)
{
UCHAR* resultBuffer = result.getBuffer(sizeof(hashNumber));
memcpy(resultBuffer, &hashNumber, sizeof(hashNumber));
}

View File

@ -28,7 +28,7 @@
#ifndef CLASSES_HASH_H
#define CLASSES_HASH_H
#include "../common/classes/vector.h"
#include "../common/classes/array.h"
namespace Firebird
{
@ -341,7 +341,78 @@ namespace Firebird
}
};
class HashContext
{
public:
typedef HalfStaticArray<UCHAR, 256> Buffer;
public:
virtual ~HashContext()
{
}
public:
virtual void update(const void* data, FB_SIZE_T length) = 0;
virtual void finish(Buffer& result) = 0;
};
class WeakHashContext FB_FINAL : public HashContext
{
public:
virtual void update(const void* data, FB_SIZE_T length);
virtual void finish(Buffer& result);
private:
SINT64 hashNumber = 0;
};
class LibTomCryptHashContext : public HashContext
{
public:
struct Descriptor;
private:
struct State;
protected:
LibTomCryptHashContext(MemoryPool& pool, const Descriptor* descriptor);
public:
virtual ~LibTomCryptHashContext();
public:
virtual void update(const void* data, FB_SIZE_T length);
virtual void finish(Buffer& result);
private:
const Descriptor* descriptor;
State* statePtr;
};
class Md5HashContext FB_FINAL : public LibTomCryptHashContext
{
public:
Md5HashContext(MemoryPool& pool);
};
class Sha1HashContext FB_FINAL : public LibTomCryptHashContext
{
public:
Sha1HashContext(MemoryPool& pool);
};
class Sha256HashContext FB_FINAL : public LibTomCryptHashContext
{
public:
Sha256HashContext(MemoryPool& pool);
};
class Sha512HashContext FB_FINAL : public LibTomCryptHashContext
{
public:
Sha512HashContext(MemoryPool& pool);
};
} // namespace Firebird
#endif // CLASSES_HASH_H

View File

@ -0,0 +1,96 @@
/*
* Hashing using libtomcrypt library.
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2017 Adriano dos Santos Fernandes <adrianosf@gmail.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../common/classes/Hash.h"
#include "../common/tomcrypt/tomcrypt.h"
using namespace Firebird;
struct LibTomCryptHashContext::Descriptor
{
const ltc_hash_descriptor* tcDesc;
};
struct LibTomCryptHashContext::State
{
hash_state tcState;
};
LibTomCryptHashContext::LibTomCryptHashContext(MemoryPool& pool, const Descriptor* aDescriptor)
: descriptor(aDescriptor)
{
statePtr = FB_NEW_POOL(pool) State();
descriptor->tcDesc->init(&statePtr->tcState);
}
LibTomCryptHashContext::~LibTomCryptHashContext()
{
delete statePtr;
}
void LibTomCryptHashContext::update(const void* data, FB_SIZE_T length)
{
descriptor->tcDesc->process(&statePtr->tcState, static_cast<const UCHAR*>(data), length);
}
void LibTomCryptHashContext::finish(Buffer& result)
{
unsigned char* hashResult = result.getBuffer(descriptor->tcDesc->hashsize);
descriptor->tcDesc->done(&statePtr->tcState, hashResult);
}
static LibTomCryptHashContext::Descriptor md5Descriptor{&md5_desc};
Md5HashContext::Md5HashContext(MemoryPool& pool)
: LibTomCryptHashContext(pool, &md5Descriptor)
{
}
static LibTomCryptHashContext::Descriptor sha1Descriptor{&sha1_desc};
Sha1HashContext::Sha1HashContext(MemoryPool& pool)
: LibTomCryptHashContext(pool, &sha1Descriptor)
{
}
static LibTomCryptHashContext::Descriptor sha256Descriptor{&sha256_desc};
Sha256HashContext::Sha256HashContext(MemoryPool& pool)
: LibTomCryptHashContext(pool, &sha256Descriptor)
{
}
static LibTomCryptHashContext::Descriptor sha512Descriptor{&sha512_desc};
Sha512HashContext::Sha512HashContext(MemoryPool& pool)
: LibTomCryptHashContext(pool, &sha512Descriptor)
{
}

View File

@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
#include <signal.h>
/**
@file crypt_argchk.c
Perform argument checking, Tom St Denis
*/
#if (ARGTYPE == 0)
void crypt_argchk(char *v, char *s, int d)
{
fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
v, d, s);
(void)raise(SIGABRT);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

368
src/common/tomcrypt/md5.c Normal file
View File

@ -0,0 +1,368 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
/**
@file md5.c
LTC_MD5 hash function by Tom St Denis
*/
#ifdef LTC_MD5
const struct ltc_hash_descriptor md5_desc =
{
"md5",
3,
16,
64,
/* OID */
{ 1, 2, 840, 113549, 2, 5, },
6,
&md5_init,
&md5_process,
&md5_done,
&md5_test,
NULL
};
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define G(x,y,z) (y ^ (z & (y ^ x)))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|(~z)))
#ifdef LTC_SMALL_CODE
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
static const unsigned char Worder[64] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
static const unsigned char Rorder[64] = {
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
static const ulong32 Korder[64] = {
0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
};
#else
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
#endif
#ifdef LTC_CLEAN_STACK
static int _md5_compress(hash_state *md, unsigned char *buf)
#else
static int md5_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 i, W[16], a, b, c, d;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32L(W[i], buf + (4*i));
}
/* copy state */
a = md->md5.state[0];
b = md->md5.state[1];
c = md->md5.state[2];
d = md->md5.state[3];
#ifdef LTC_SMALL_CODE
for (i = 0; i < 16; ++i) {
FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 32; ++i) {
GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 48; ++i) {
HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 64; ++i) {
II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
#else
FF(a,b,c,d,W[0],7,0xd76aa478UL)
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
FF(c,d,a,b,W[2],17,0x242070dbUL)
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
FF(d,a,b,c,W[5],12,0x4787c62aUL)
FF(c,d,a,b,W[6],17,0xa8304613UL)
FF(b,c,d,a,W[7],22,0xfd469501UL)
FF(a,b,c,d,W[8],7,0x698098d8UL)
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
FF(b,c,d,a,W[11],22,0x895cd7beUL)
FF(a,b,c,d,W[12],7,0x6b901122UL)
FF(d,a,b,c,W[13],12,0xfd987193UL)
FF(c,d,a,b,W[14],17,0xa679438eUL)
FF(b,c,d,a,W[15],22,0x49b40821UL)
GG(a,b,c,d,W[1],5,0xf61e2562UL)
GG(d,a,b,c,W[6],9,0xc040b340UL)
GG(c,d,a,b,W[11],14,0x265e5a51UL)
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
GG(a,b,c,d,W[5],5,0xd62f105dUL)
GG(d,a,b,c,W[10],9,0x02441453UL)
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
GG(d,a,b,c,W[14],9,0xc33707d6UL)
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
GG(b,c,d,a,W[8],20,0x455a14edUL)
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
GG(c,d,a,b,W[7],14,0x676f02d9UL)
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
HH(a,b,c,d,W[5],4,0xfffa3942UL)
HH(d,a,b,c,W[8],11,0x8771f681UL)
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
HH(b,c,d,a,W[14],23,0xfde5380cUL)
HH(a,b,c,d,W[1],4,0xa4beea44UL)
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
HH(d,a,b,c,W[0],11,0xeaa127faUL)
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
HH(b,c,d,a,W[6],23,0x04881d05UL)
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
II(a,b,c,d,W[0],6,0xf4292244UL)
II(d,a,b,c,W[7],10,0x432aff97UL)
II(c,d,a,b,W[14],15,0xab9423a7UL)
II(b,c,d,a,W[5],21,0xfc93a039UL)
II(a,b,c,d,W[12],6,0x655b59c3UL)
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
II(c,d,a,b,W[10],15,0xffeff47dUL)
II(b,c,d,a,W[1],21,0x85845dd1UL)
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
II(c,d,a,b,W[6],15,0xa3014314UL)
II(b,c,d,a,W[13],21,0x4e0811a1UL)
II(a,b,c,d,W[4],6,0xf7537e82UL)
II(d,a,b,c,W[11],10,0xbd3af235UL)
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
II(b,c,d,a,W[9],21,0xeb86d391UL)
#endif
md->md5.state[0] = md->md5.state[0] + a;
md->md5.state[1] = md->md5.state[1] + b;
md->md5.state[2] = md->md5.state[2] + c;
md->md5.state[3] = md->md5.state[3] + d;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int md5_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _md5_compress(md, buf);
burn_stack(sizeof(ulong32) * 21);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md5_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->md5.state[0] = 0x67452301UL;
md->md5.state[1] = 0xefcdab89UL;
md->md5.state[2] = 0x98badcfeUL;
md->md5.state[3] = 0x10325476UL;
md->md5.curlen = 0;
md->md5.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(md5_process, md5_compress, md5, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md5_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md5.curlen >= sizeof(md->md5.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->md5.length += md->md5.curlen * 8;
/* append the '1' bit */
md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->md5.curlen > 56) {
while (md->md5.curlen < 64) {
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
}
md5_compress(md, md->md5.buf);
md->md5.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->md5.curlen < 56) {
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->md5.length, md->md5.buf+56);
md5_compress(md, md->md5.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->md5.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
{ "a",
{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
{ "abc",
{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
{ "message digest",
{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
md5_init(&md);
md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
md5_done(&md, tmp);
if (XMEMCMP(tmp, tests[i].hash, 16) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

288
src/common/tomcrypt/sha1.c Normal file
View File

@ -0,0 +1,288 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
/**
@file sha1.c
LTC_SHA1 code by Tom St Denis
*/
#ifdef LTC_SHA1
const struct ltc_hash_descriptor sha1_desc =
{
"sha1",
2,
20,
64,
/* OID */
{ 1, 3, 14, 3, 2, 26, },
6,
&sha1_init,
&sha1_process,
&sha1_done,
&sha1_test,
NULL
};
#define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z)
#ifdef LTC_CLEAN_STACK
static int _sha1_compress(hash_state *md, unsigned char *buf)
#else
static int sha1_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 a,b,c,d,e,W[80],i;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* copy state */
a = md->sha1.state[0];
b = md->sha1.state[1];
c = md->sha1.state[2];
d = md->sha1.state[3];
e = md->sha1.state[4];
/* expand it */
for (i = 16; i < 80; i++) {
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
}
/* compress */
/* round one */
#define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
#define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
#define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
#define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
#ifdef LTC_SMALL_CODE
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 40; ) {
FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 60; ) {
FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 80; ) {
FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
#else
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++);
FF0(e,a,b,c,d,i++);
FF0(d,e,a,b,c,i++);
FF0(c,d,e,a,b,i++);
FF0(b,c,d,e,a,i++);
}
/* round two */
for (; i < 40; ) {
FF1(a,b,c,d,e,i++);
FF1(e,a,b,c,d,i++);
FF1(d,e,a,b,c,i++);
FF1(c,d,e,a,b,i++);
FF1(b,c,d,e,a,i++);
}
/* round three */
for (; i < 60; ) {
FF2(a,b,c,d,e,i++);
FF2(e,a,b,c,d,i++);
FF2(d,e,a,b,c,i++);
FF2(c,d,e,a,b,i++);
FF2(b,c,d,e,a,i++);
}
/* round four */
for (; i < 80; ) {
FF3(a,b,c,d,e,i++);
FF3(e,a,b,c,d,i++);
FF3(d,e,a,b,c,i++);
FF3(c,d,e,a,b,i++);
FF3(b,c,d,e,a,i++);
}
#endif
#undef FF0
#undef FF1
#undef FF2
#undef FF3
/* store */
md->sha1.state[0] = md->sha1.state[0] + a;
md->sha1.state[1] = md->sha1.state[1] + b;
md->sha1.state[2] = md->sha1.state[2] + c;
md->sha1.state[3] = md->sha1.state[3] + d;
md->sha1.state[4] = md->sha1.state[4] + e;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int sha1_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _sha1_compress(md, buf);
burn_stack(sizeof(ulong32) * 87);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha1_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha1.state[0] = 0x67452301UL;
md->sha1.state[1] = 0xefcdab89UL;
md->sha1.state[2] = 0x98badcfeUL;
md->sha1.state[3] = 0x10325476UL;
md->sha1.state[4] = 0xc3d2e1f0UL;
md->sha1.curlen = 0;
md->sha1.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int sha1_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha1.length += md->sha1.curlen * 8;
/* append the '1' bit */
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha1.curlen > 56) {
while (md->sha1.curlen < 64) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
sha1_compress(md, md->sha1.buf);
md->sha1.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha1.curlen < 56) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha1.length, md->sha1.buf+56);
sha1_compress(md, md->sha1.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32H(md->sha1.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha1_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[20];
} tests[] = {
{ "abc",
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
0x9c, 0xd0, 0xd8, 0x9d }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha1_init(&md);
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha1_done(&md, tmp);
if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,340 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
/**
@file sha256.c
LTC_SHA256 by Tom St Denis
*/
#ifdef LTC_SHA256
const struct ltc_hash_descriptor sha256_desc =
{
"sha256",
0,
32,
64,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 1, },
9,
&sha256_init,
&sha256_process,
&sha256_done,
&sha256_test,
NULL
};
#ifdef LTC_SMALL_CODE
/* the K array */
static const ulong32 K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
#endif
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) RORc((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
/* compress 512-bits */
#ifdef LTC_CLEAN_STACK
static int _sha256_compress(hash_state * md, unsigned char *buf)
#else
static int sha256_compress(hash_state * md, unsigned char *buf)
#endif
{
ulong32 S[8], W[64], t0, t1;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->sha256.state[i];
}
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* fill W[16..63] */
for (i = 16; i < 64; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#ifdef LTC_SMALL_CODE
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 64; ++i) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
}
#else
#define RND(a,b,c,d,e,f,g,h,i,ki) \
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
#undef RND
#endif
/* feedback */
for (i = 0; i < 8; i++) {
md->sha256.state[i] = md->sha256.state[i] + S[i];
}
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int sha256_compress(hash_state * md, unsigned char *buf)
{
int err;
err = _sha256_compress(md, buf);
burn_stack(sizeof(ulong32) * 74);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha256_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha256.curlen = 0;
md->sha256.length = 0;
md->sha256.state[0] = 0x6A09E667UL;
md->sha256.state[1] = 0xBB67AE85UL;
md->sha256.state[2] = 0x3C6EF372UL;
md->sha256.state[3] = 0xA54FF53AUL;
md->sha256.state[4] = 0x510E527FUL;
md->sha256.state[5] = 0x9B05688CUL;
md->sha256.state[6] = 0x1F83D9ABUL;
md->sha256.state[7] = 0x5BE0CD19UL;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (32 bytes)
@return CRYPT_OK if successful
*/
int sha256_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha256.length += md->sha256.curlen * 8;
/* append the '1' bit */
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha256.curlen > 56) {
while (md->sha256.curlen < 64) {
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
}
sha256_compress(md, md->sha256.buf);
md->sha256.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha256.curlen < 56) {
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha256.length, md->sha256.buf+56);
sha256_compress(md, md->sha256.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE32H(md->sha256.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[32];
} tests[] = {
{ "abc",
{ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
},
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha256_init(&md);
sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha256_done(&md, tmp);
if (XMEMCMP(tmp, tests[i].hash, 32) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#ifdef LTC_SHA224
#include "sha224.c"
#endif
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,319 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
/**
@param sha512.c
LTC_SHA512 by Tom St Denis
*/
#ifdef LTC_SHA512
const struct ltc_hash_descriptor sha512_desc =
{
"sha512",
5,
64,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 3, },
9,
&sha512_init,
&sha512_process,
&sha512_done,
&sha512_test,
NULL
};
/* the K array */
static const ulong64 K[80] = {
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
};
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64c(x, n)
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
/* compress 1024-bits */
#ifdef LTC_CLEAN_STACK
static int _sha512_compress(hash_state * md, unsigned char *buf)
#else
static int sha512_compress(hash_state * md, unsigned char *buf)
#endif
{
ulong64 S[8], W[80], t0, t1;
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->sha512.state[i];
}
/* copy the state into 1024-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD64H(W[i], buf + (8*i));
}
/* fill W[16..79] */
for (i = 16; i < 80; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#ifdef LTC_SMALL_CODE
for (i = 0; i < 80; i++) {
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
S[7] = S[6];
S[6] = S[5];
S[5] = S[4];
S[4] = S[3] + t0;
S[3] = S[2];
S[2] = S[1];
S[1] = S[0];
S[0] = t0 + t1;
}
#else
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 80; i += 8) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
}
#endif
/* feedback */
for (i = 0; i < 8; i++) {
md->sha512.state[i] = md->sha512.state[i] + S[i];
}
return CRYPT_OK;
}
/* compress 1024-bits */
#ifdef LTC_CLEAN_STACK
static int sha512_compress(hash_state * md, unsigned char *buf)
{
int err;
err = _sha512_compress(md, buf);
burn_stack(sizeof(ulong64) * 90 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha512_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
md->sha512.state[4] = CONST64(0x510e527fade682d1);
md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (64 bytes)
@return CRYPT_OK if successful
*/
int sha512_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha512.length += md->sha512.curlen * CONST64(8);
/* append the '1' bit */
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
/* if the length is currently above 112 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha512.curlen > 112) {
while (md->sha512.curlen < 128) {
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
}
sha512_compress(md, md->sha512.buf);
md->sha512.curlen = 0;
}
/* pad upto 120 bytes of zeroes
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
* > 2^64 bits of data... :-)
*/
while (md->sha512.curlen < 120) {
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha512.length, md->sha512.buf+120);
sha512_compress(md, md->sha512.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE64H(md->sha512.state[i], out+(8*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[64];
} tests[] = {
{ "abc",
{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
},
};
int i;
unsigned char tmp[64];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha512_init(&md);
sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha512_done(&md, tmp);
if (XMEMCMP(tmp, tests[i].hash, 64) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#ifdef LTC_SHA384
#include "sha384.c"
#endif
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,87 @@
#ifndef TOMCRYPT_H_
#define TOMCRYPT_H_
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <limits.h>
/* use configuration data */
#include "tomcrypt_custom.h"
#ifdef __cplusplus
extern "C" {
#endif
/* version */
#define CRYPT 0x0117
#define SCRYPT "1.17"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128
/* descriptor table size */
#define TAB_SIZE 32
/* error codes [will be expanded in future releases] */
enum {
CRYPT_OK=0, /* Result OK */
CRYPT_ERROR, /* Generic Error */
CRYPT_NOP, /* Not a failure but no operation was performed */
CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
CRYPT_INVALID_PACKET, /* Invalid input packet given */
CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
CRYPT_INVALID_HASH, /* Invalid hash specified */
CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
CRYPT_MEM, /* Out of memory */
CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
CRYPT_INVALID_ARG, /* Generic invalid argument */
CRYPT_FILE_NOTFOUND, /* File Not Found */
CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
CRYPT_PK_DUP, /* Duplicate key already in key ring */
CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
CRYPT_PK_INVALID_PADDING /* Invalid padding on input */
};
#include "tomcrypt_cfg.h"
#include "tomcrypt_macros.h"
#include "tomcrypt_cipher.h"
#include "tomcrypt_hash.h"
#include "tomcrypt_mac.h"
#include "tomcrypt_prng.h"
#include "tomcrypt_pk.h"
#include "tomcrypt_math.h"
#include "tomcrypt_misc.h"
#include "tomcrypt_argchk.h"
#include "tomcrypt_pkcs.h"
#ifdef __cplusplus
}
#endif
#endif /* TOMCRYPT_H_ */
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,38 @@
/* Defines the LTC_ARGCHK macro used within the library */
/* ARGTYPE is defined in mycrypt_cfg.h */
#if ARGTYPE == 0
#include <signal.h>
/* this is the default LibTomCrypt macro */
void crypt_argchk(char *v, char *s, int d);
#define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 1
/* fatal type of error */
#define LTC_ARGCHK(x) assert((x))
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 2
#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); }
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 3
#define LTC_ARGCHK(x)
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 4
#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG;
#define LTC_ARGCHKVD(x) if (!(x)) return;
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,136 @@
/* This is the build config file.
*
* With this you can setup what to inlcude/exclude automatically during any build. Just comment
* out the line that #define's the word for the thing you want to remove. phew!
*/
#ifndef TOMCRYPT_CFG_H
#define TOMCRYPT_CFG_H
#if defined(_WIN32) || defined(_MSC_VER)
#define LTC_CALL __cdecl
#else
#ifndef LTC_CALL
#define LTC_CALL
#endif
#endif
#ifndef LTC_EXPORT
#define LTC_EXPORT
#endif
/* certain platforms use macros for these, making the prototypes broken */
#ifndef LTC_NO_PROTOTYPES
/* you can change how memory allocation works ... */
LTC_EXPORT void * LTC_CALL XMALLOC(size_t n);
LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n);
LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s);
LTC_EXPORT void LTC_CALL XFREE(void *p);
LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
/* change the clock function too */
LTC_EXPORT clock_t LTC_CALL XCLOCK(void);
/* various other functions */
LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
#endif
/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
#ifndef ARGTYPE
#define ARGTYPE 0
#endif
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code
*
* Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes.
* The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST**
* use the portable [slower] macros.
*/
/* detect x86-32 machines somewhat */
#if !defined(__STRICT_ANSI__) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))))
#define ENDIAN_LITTLE
#define ENDIAN_32BITWORD
#define LTC_FAST
#define LTC_FAST_TYPE unsigned long
#endif
/* detects MIPS R5900 processors (PS2) */
#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
#define ENDIAN_LITTLE
#define ENDIAN_64BITWORD
#endif
/* detect amd64 */
#if !defined(__STRICT_ANSI__) && defined(__x86_64__)
#define ENDIAN_LITTLE
#define ENDIAN_64BITWORD
#define LTC_FAST
#define LTC_FAST_TYPE unsigned long
#endif
/* detect PPC32 */
#if !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
#define ENDIAN_BIG
#define ENDIAN_32BITWORD
#define LTC_FAST
#define LTC_FAST_TYPE unsigned long
#endif
/* detect sparc and sparc64 */
#if defined(__sparc__)
#define ENDIAN_BIG
#if defined(__arch64__)
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#endif
#ifdef LTC_NO_FAST
#ifdef LTC_FAST
#undef LTC_FAST
#endif
#endif
/* No asm is a quick way to disable anything "not portable" */
#ifdef LTC_NO_ASM
#undef ENDIAN_LITTLE
#undef ENDIAN_BIG
#undef ENDIAN_32BITWORD
#undef ENDIAN_64BITWORD
#undef LTC_FAST
#undef LTC_FAST_TYPE
#define LTC_NO_ROLC
#define LTC_NO_BSWAP
#endif
/* #define ENDIAN_LITTLE */
/* #define ENDIAN_BIG */
/* #define ENDIAN_32BITWORD */
/* #define ENDIAN_64BITWORD */
#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
#error You must specify a word size as well as endianess in tomcrypt_cfg.h
#endif
#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
#define ENDIAN_NEUTRAL
#endif
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,891 @@
/* ---- SYMMETRIC KEY STUFF -----
*
* We put each of the ciphers scheduled keys in their own structs then we put all of
* the key formats in one union. This makes the function prototypes easier to use.
*/
#ifdef LTC_BLOWFISH
struct blowfish_key {
ulong32 S[4][256];
ulong32 K[18];
};
#endif
#ifdef LTC_RC5
struct rc5_key {
int rounds;
ulong32 K[50];
};
#endif
#ifdef LTC_RC6
struct rc6_key {
ulong32 K[44];
};
#endif
#ifdef LTC_SAFERP
struct saferp_key {
unsigned char K[33][16];
long rounds;
};
#endif
#ifdef LTC_RIJNDAEL
struct rijndael_key {
ulong32 eK[60], dK[60];
int Nr;
};
#endif
#ifdef LTC_KSEED
struct kseed_key {
ulong32 K[32], dK[32];
};
#endif
#ifdef LTC_KASUMI
struct kasumi_key {
ulong32 KLi1[8], KLi2[8],
KOi1[8], KOi2[8], KOi3[8],
KIi1[8], KIi2[8], KIi3[8];
};
#endif
#ifdef LTC_XTEA
struct xtea_key {
unsigned long A[32], B[32];
};
#endif
#ifdef LTC_TWOFISH
#ifndef LTC_TWOFISH_SMALL
struct twofish_key {
ulong32 S[4][256], K[40];
};
#else
struct twofish_key {
ulong32 K[40];
unsigned char S[32], start;
};
#endif
#endif
#ifdef LTC_SAFER
#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6
#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10
#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8
#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10
#define LTC_SAFER_MAX_NOF_ROUNDS 13
#define LTC_SAFER_BLOCK_LEN 8
#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS))
typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN];
typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN];
struct safer_key { safer_key_t key; };
#endif
#ifdef LTC_RC2
struct rc2_key { unsigned xkey[64]; };
#endif
#ifdef LTC_DES
struct des_key {
ulong32 ek[32], dk[32];
};
struct des3_key {
ulong32 ek[3][32], dk[3][32];
};
#endif
#ifdef LTC_CAST5
struct cast5_key {
ulong32 K[32], keylen;
};
#endif
#ifdef LTC_NOEKEON
struct noekeon_key {
ulong32 K[4], dK[4];
};
#endif
#ifdef LTC_SKIPJACK
struct skipjack_key {
unsigned char key[10];
};
#endif
#ifdef LTC_KHAZAD
struct khazad_key {
ulong64 roundKeyEnc[8 + 1];
ulong64 roundKeyDec[8 + 1];
};
#endif
#ifdef LTC_ANUBIS
struct anubis_key {
int keyBits;
int R;
ulong32 roundKeyEnc[18 + 1][4];
ulong32 roundKeyDec[18 + 1][4];
};
#endif
#ifdef LTC_MULTI2
struct multi2_key {
int N;
ulong32 uk[8];
};
#endif
typedef union Symmetric_key {
#ifdef LTC_DES
struct des_key des;
struct des3_key des3;
#endif
#ifdef LTC_RC2
struct rc2_key rc2;
#endif
#ifdef LTC_SAFER
struct safer_key safer;
#endif
#ifdef LTC_TWOFISH
struct twofish_key twofish;
#endif
#ifdef LTC_BLOWFISH
struct blowfish_key blowfish;
#endif
#ifdef LTC_RC5
struct rc5_key rc5;
#endif
#ifdef LTC_RC6
struct rc6_key rc6;
#endif
#ifdef LTC_SAFERP
struct saferp_key saferp;
#endif
#ifdef LTC_RIJNDAEL
struct rijndael_key rijndael;
#endif
#ifdef LTC_XTEA
struct xtea_key xtea;
#endif
#ifdef LTC_CAST5
struct cast5_key cast5;
#endif
#ifdef LTC_NOEKEON
struct noekeon_key noekeon;
#endif
#ifdef LTC_SKIPJACK
struct skipjack_key skipjack;
#endif
#ifdef LTC_KHAZAD
struct khazad_key khazad;
#endif
#ifdef LTC_ANUBIS
struct anubis_key anubis;
#endif
#ifdef LTC_KSEED
struct kseed_key kseed;
#endif
#ifdef LTC_KASUMI
struct kasumi_key kasumi;
#endif
#ifdef LTC_MULTI2
struct multi2_key multi2;
#endif
void *data;
} symmetric_key;
#ifdef LTC_ECB_MODE
/** A block cipher ECB structure */
typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen;
/** The scheduled key */
symmetric_key key;
} symmetric_ECB;
#endif
#ifdef LTC_CFB_MODE
/** A block cipher CFB structure */
typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE],
/** The pad used to encrypt/decrypt */
pad[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
} symmetric_CFB;
#endif
#ifdef LTC_OFB_MODE
/** A block cipher OFB structure */
typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
} symmetric_OFB;
#endif
#ifdef LTC_CBC_MODE
/** A block cipher CBC structure */
typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
} symmetric_CBC;
#endif
#ifdef LTC_CTR_MODE
/** A block cipher CTR structure */
typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen,
/** The mode (endianess) of the CTR, 0==little, 1==big */
mode,
/** counter width */
ctrlen;
/** The counter */
unsigned char ctr[MAXBLOCKSIZE],
/** The pad used to encrypt/decrypt */
pad[MAXBLOCKSIZE];
/** The scheduled key */
symmetric_key key;
} symmetric_CTR;
#endif
#ifdef LTC_LRW_MODE
/** A LRW structure */
typedef struct {
/** The index of the cipher chosen (must be a 128-bit block cipher) */
int cipher;
/** The current IV */
unsigned char IV[16],
/** the tweak key */
tweak[16],
/** The current pad, it's the product of the first 15 bytes against the tweak key */
pad[16];
/** The scheduled symmetric key */
symmetric_key key;
#ifdef LRW_TABLES
/** The pre-computed multiplication table */
unsigned char PC[16][256][16];
#endif
} symmetric_LRW;
#endif
#ifdef LTC_F8_MODE
/** A block cipher F8 structure */
typedef struct {
/** The index of the cipher chosen */
int cipher,
/** The block size of the given cipher */
blocklen,
/** The padding offset */
padlen;
/** The current IV */
unsigned char IV[MAXBLOCKSIZE],
MIV[MAXBLOCKSIZE];
/** Current block count */
ulong32 blockcnt;
/** The scheduled key */
symmetric_key key;
} symmetric_F8;
#endif
/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */
extern struct ltc_cipher_descriptor {
/** name of cipher */
char *name;
/** internal ID */
unsigned char ID;
/** min keysize (octets) */
int min_key_length,
/** max keysize (octets) */
max_key_length,
/** block size (octets) */
block_length,
/** default number of rounds */
default_rounds;
/** Setup the cipher
@param key The input symmetric key
@param keylen The length of the input key (octets)
@param num_rounds The requested number of rounds (0==default)
@param skey [out] The destination of the scheduled key
@return CRYPT_OK if successful
*/
int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
/** Encrypt a block
@param pt The plaintext
@param ct [out] The ciphertext
@param skey The scheduled key
@return CRYPT_OK if successful
*/
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
/** Decrypt a block
@param ct The ciphertext
@param pt [out] The plaintext
@param skey The scheduled key
@return CRYPT_OK if successful
*/
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
/** Test the block cipher
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
int (*test)(void);
/** Terminate the context
@param skey The scheduled key
*/
void (*done)(symmetric_key *skey);
/** Determine a key size
@param keysize [in/out] The size of the key desired and the suggested size
@return CRYPT_OK if successful
*/
int (*keysize)(int *keysize);
/** Accelerators **/
/** Accelerated ECB encryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
/** Accelerated ECB decryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
/** Accelerated CBC encryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
/** Accelerated CBC decryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
/** Accelerated CTR encryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param mode little or big endian counter (mode=0 or mode=1)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
/** Accelerated LRW
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param tweak The LRW tweak
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
/** Accelerated LRW
@param ct Ciphertext
@param pt Plaintext
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param tweak The LRW tweak
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey);
/** Accelerated CCM packet (one-shot)
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param uskey A previously scheduled key [optional can be NULL]
@param nonce The session nonce [use once]
@param noncelen The length of the nonce
@param header The header for the session
@param headerlen The length of the header (octets)
@param pt [out] The plaintext
@param ptlen The length of the plaintext (octets)
@param ct [out] The ciphertext
@param tag [out] The destination tag
@param taglen [in/out] The max size and resulting size of the authentication tag
@param direction Encrypt or Decrypt direction (0 or 1)
@return CRYPT_OK if successful
*/
int (*accel_ccm_memory)(
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
/** Accelerated GCM packet (one shot)
@param key The secret key
@param keylen The length of the secret key
@param IV The initial vector
@param IVlen The length of the initial vector
@param adata The additional authentication data (header)
@param adatalen The length of the adata
@param pt The plaintext
@param ptlen The length of the plaintext (ciphertext length is the same)
@param ct The ciphertext
@param tag [out] The MAC tag
@param taglen [in/out] The MAC tag length
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
@return CRYPT_OK on success
*/
int (*accel_gcm_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
/** Accelerated one shot LTC_OMAC
@param key The secret key
@param keylen The key length (octets)
@param in The message
@param inlen Length of message (octets)
@param out [out] Destination for tag
@param outlen [in/out] Initial and final size of out
@return CRYPT_OK on success
*/
int (*omac_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
/** Accelerated one shot XCBC
@param key The secret key
@param keylen The key length (octets)
@param in The message
@param inlen Length of message (octets)
@param out [out] Destination for tag
@param outlen [in/out] Initial and final size of out
@return CRYPT_OK on success
*/
int (*xcbc_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
/** Accelerated one shot F9
@param key The secret key
@param keylen The key length (octets)
@param in The message
@param inlen Length of message (octets)
@param out [out] Destination for tag
@param outlen [in/out] Initial and final size of out
@return CRYPT_OK on success
@remark Requires manual padding
*/
int (*f9_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
} cipher_descriptor[];
#ifdef LTC_BLOWFISH
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int blowfish_test(void);
void blowfish_done(symmetric_key *skey);
int blowfish_keysize(int *keysize);
extern const struct ltc_cipher_descriptor blowfish_desc;
#endif
#ifdef LTC_RC5
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc5_test(void);
void rc5_done(symmetric_key *skey);
int rc5_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rc5_desc;
#endif
#ifdef LTC_RC6
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc6_test(void);
void rc6_done(symmetric_key *skey);
int rc6_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rc6_desc;
#endif
#ifdef LTC_RC2
int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc2_test(void);
void rc2_done(symmetric_key *skey);
int rc2_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rc2_desc;
#endif
#ifdef LTC_SAFERP
int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int saferp_test(void);
void saferp_done(symmetric_key *skey);
int saferp_keysize(int *keysize);
extern const struct ltc_cipher_descriptor saferp_desc;
#endif
#ifdef LTC_SAFER
int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
int safer_k64_test(void);
int safer_sk64_test(void);
int safer_sk128_test(void);
void safer_done(symmetric_key *skey);
int safer_64_keysize(int *keysize);
int safer_128_keysize(int *keysize);
extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc;
#endif
#ifdef LTC_RIJNDAEL
/* make aes an alias */
#define aes_setup rijndael_setup
#define aes_ecb_encrypt rijndael_ecb_encrypt
#define aes_ecb_decrypt rijndael_ecb_decrypt
#define aes_test rijndael_test
#define aes_done rijndael_done
#define aes_keysize rijndael_keysize
#define aes_enc_setup rijndael_enc_setup
#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
#define aes_enc_keysize rijndael_enc_keysize
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rijndael_test(void);
void rijndael_done(symmetric_key *skey);
int rijndael_keysize(int *keysize);
int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void rijndael_enc_done(symmetric_key *skey);
int rijndael_enc_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
#endif
#ifdef LTC_XTEA
int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int xtea_test(void);
void xtea_done(symmetric_key *skey);
int xtea_keysize(int *keysize);
extern const struct ltc_cipher_descriptor xtea_desc;
#endif
#ifdef LTC_TWOFISH
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int twofish_test(void);
void twofish_done(symmetric_key *skey);
int twofish_keysize(int *keysize);
extern const struct ltc_cipher_descriptor twofish_desc;
#endif
#ifdef LTC_DES
int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int des_test(void);
void des_done(symmetric_key *skey);
int des_keysize(int *keysize);
int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int des3_test(void);
void des3_done(symmetric_key *skey);
int des3_keysize(int *keysize);
extern const struct ltc_cipher_descriptor des_desc, des3_desc;
#endif
#ifdef LTC_CAST5
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int cast5_test(void);
void cast5_done(symmetric_key *skey);
int cast5_keysize(int *keysize);
extern const struct ltc_cipher_descriptor cast5_desc;
#endif
#ifdef LTC_NOEKEON
int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int noekeon_test(void);
void noekeon_done(symmetric_key *skey);
int noekeon_keysize(int *keysize);
extern const struct ltc_cipher_descriptor noekeon_desc;
#endif
#ifdef LTC_SKIPJACK
int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int skipjack_test(void);
void skipjack_done(symmetric_key *skey);
int skipjack_keysize(int *keysize);
extern const struct ltc_cipher_descriptor skipjack_desc;
#endif
#ifdef LTC_KHAZAD
int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int khazad_test(void);
void khazad_done(symmetric_key *skey);
int khazad_keysize(int *keysize);
extern const struct ltc_cipher_descriptor khazad_desc;
#endif
#ifdef LTC_ANUBIS
int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int anubis_test(void);
void anubis_done(symmetric_key *skey);
int anubis_keysize(int *keysize);
extern const struct ltc_cipher_descriptor anubis_desc;
#endif
#ifdef LTC_KSEED
int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int kseed_test(void);
void kseed_done(symmetric_key *skey);
int kseed_keysize(int *keysize);
extern const struct ltc_cipher_descriptor kseed_desc;
#endif
#ifdef LTC_KASUMI
int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int kasumi_test(void);
void kasumi_done(symmetric_key *skey);
int kasumi_keysize(int *keysize);
extern const struct ltc_cipher_descriptor kasumi_desc;
#endif
#ifdef LTC_MULTI2
int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int multi2_test(void);
void multi2_done(symmetric_key *skey);
int multi2_keysize(int *keysize);
extern const struct ltc_cipher_descriptor multi2_desc;
#endif
#ifdef LTC_ECB_MODE
int ecb_start(int cipher, const unsigned char *key,
int keylen, int num_rounds, symmetric_ECB *ecb);
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb);
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb);
int ecb_done(symmetric_ECB *ecb);
#endif
#ifdef LTC_CFB_MODE
int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CFB *cfb);
int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
int cfb_done(symmetric_CFB *cfb);
#endif
#ifdef LTC_OFB_MODE
int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_OFB *ofb);
int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
int ofb_done(symmetric_OFB *ofb);
#endif
#ifdef LTC_CBC_MODE
int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CBC *cbc);
int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc);
int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc);
int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
int cbc_done(symmetric_CBC *cbc);
#endif
#ifdef LTC_CTR_MODE
#define CTR_COUNTER_LITTLE_ENDIAN 0x0000
#define CTR_COUNTER_BIG_ENDIAN 0x1000
#define LTC_CTR_RFC3686 0x2000
int ctr_start( int cipher,
const unsigned char *IV,
const unsigned char *key, int keylen,
int num_rounds, int ctr_mode,
symmetric_CTR *ctr);
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
int ctr_done(symmetric_CTR *ctr);
int ctr_test(void);
#endif
#ifdef LTC_LRW_MODE
#define LRW_ENCRYPT 0
#define LRW_DECRYPT 1
int lrw_start( int cipher,
const unsigned char *IV,
const unsigned char *key, int keylen,
const unsigned char *tweak,
int num_rounds,
symmetric_LRW *lrw);
int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw);
int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw);
int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw);
int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw);
int lrw_done(symmetric_LRW *lrw);
int lrw_test(void);
/* don't call */
int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw);
#endif
#ifdef LTC_F8_MODE
int f8_start( int cipher, const unsigned char *IV,
const unsigned char *key, int keylen,
const unsigned char *salt_key, int skeylen,
int num_rounds, symmetric_F8 *f8);
int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8);
int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8);
int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8);
int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8);
int f8_done(symmetric_F8 *f8);
int f8_test_mode(void);
#endif
#ifdef LTC_XTS_MODE
typedef struct {
symmetric_key key1, key2;
int cipher;
} symmetric_xts;
int xts_start( int cipher,
const unsigned char *key1,
const unsigned char *key2,
unsigned long keylen,
int num_rounds,
symmetric_xts *xts);
int xts_encrypt(
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
const unsigned char *tweak,
symmetric_xts *xts);
int xts_decrypt(
const unsigned char *ct, unsigned long ptlen,
unsigned char *pt,
const unsigned char *tweak,
symmetric_xts *xts);
void xts_done(symmetric_xts *xts);
int xts_test(void);
void xts_mult_x(unsigned char *I);
#endif
int find_cipher(const char *name);
int find_cipher_any(const char *name, int blocklen, int keylen);
int find_cipher_id(unsigned char ID);
int register_cipher(const struct ltc_cipher_descriptor *cipher);
int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
int cipher_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_cipher_mutex)
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,431 @@
#ifndef TOMCRYPT_CUSTOM_H_
#define TOMCRYPT_CUSTOM_H_
/*** Firebird customizations - begin ***/
#define LTC_NO_ASM // ASF: Defined to not use assembly
#define LTC_NO_CIPHERS
#define LTC_NO_HASHES
#define LTC_NO_MODES
#define LTC_NO_MACS
#define LTC_NO_PRNGS
#define LTC_NO_MATH
#define LTC_NO_PK
#define LTC_NO_PKCS
#define LTC_NO_CURVES
#define LTC_MD5
#define LTC_SHA1
#define LTC_SHA256
#define LTC_SHA512
#if defined(_MSC_VER)
#define LTC_NO_PROTOTYPES
#endif
/*** Firebird customizations - end ***/
/* macros for various libc functions you can change for embedded targets */
#ifndef XMALLOC
#ifdef malloc
#define LTC_NO_PROTOTYPES
#endif
#define XMALLOC malloc
#endif
#ifndef XREALLOC
#ifdef realloc
#define LTC_NO_PROTOTYPES
#endif
#define XREALLOC realloc
#endif
#ifndef XCALLOC
#ifdef calloc
#define LTC_NO_PROTOTYPES
#endif
#define XCALLOC calloc
#endif
#ifndef XFREE
#ifdef free
#define LTC_NO_PROTOTYPES
#endif
#define XFREE free
#endif
#ifndef XMEMSET
#ifdef memset
#define LTC_NO_PROTOTYPES
#endif
#define XMEMSET memset
#endif
#ifndef XMEMCPY
#ifdef memcpy
#define LTC_NO_PROTOTYPES
#endif
#define XMEMCPY memcpy
#endif
#ifndef XMEMCMP
#ifdef memcmp
#define LTC_NO_PROTOTYPES
#endif
#define XMEMCMP memcmp
#endif
#ifndef XSTRCMP
#ifdef strcmp
#define LTC_NO_PROTOTYPES
#endif
#define XSTRCMP strcmp
#endif
#ifndef XCLOCK
#define XCLOCK clock
#endif
#ifndef XCLOCKS_PER_SEC
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC
#endif
#ifndef XQSORT
#ifdef qsort
#define LTC_NO_PROTOTYPES
#endif
#define XQSORT qsort
#endif
/* Easy button? */
#ifdef LTC_EASY
#define LTC_NO_CIPHERS
#define LTC_RIJNDAEL
#define LTC_BLOWFISH
#define LTC_DES
#define LTC_CAST5
#define LTC_NO_MODES
#define LTC_ECB_MODE
#define LTC_CBC_MODE
#define LTC_CTR_MODE
#define LTC_NO_HASHES
#define LTC_SHA1
#define LTC_SHA512
#define LTC_SHA384
#define LTC_SHA256
#define LTC_SHA224
#define LTC_NO_MACS
#define LTC_HMAC
#define LTC_OMAC
#define LTC_CCM_MODE
#define LTC_NO_PRNGS
#define LTC_SPRNG
#define LTC_YARROW
#define LTC_DEVRANDOM
#define TRY_URANDOM_FIRST
#define LTC_NO_PK
#define LTC_MRSA
#define LTC_MECC
#endif
/* Use small code where possible */
/* #define LTC_SMALL_CODE */
/* Enable self-test test vector checking */
#ifndef LTC_NO_TEST
#define LTC_TEST
#endif
/* clean the stack of functions which put private information on stack */
/* #define LTC_CLEAN_STACK */
/* disable all file related functions */
/* #define LTC_NO_FILE */
/* disable all forms of ASM */
/* #define LTC_NO_ASM */
/* disable FAST mode */
/* #define LTC_NO_FAST */
/* disable BSWAP on x86 */
/* #define LTC_NO_BSWAP */
/* ---> Symmetric Block Ciphers <--- */
#ifndef LTC_NO_CIPHERS
#define LTC_BLOWFISH
#define LTC_RC2
#define LTC_RC5
#define LTC_RC6
#define LTC_SAFERP
#define LTC_RIJNDAEL
#define LTC_XTEA
/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
* (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
#define LTC_TWOFISH
#ifndef LTC_NO_TABLES
#define LTC_TWOFISH_TABLES
/* #define LTC_TWOFISH_ALL_TABLES */
#else
#define LTC_TWOFISH_SMALL
#endif
/* #define LTC_TWOFISH_SMALL */
/* LTC_DES includes EDE triple-LTC_DES */
#define LTC_DES
#define LTC_CAST5
#define LTC_NOEKEON
#define LTC_SKIPJACK
#define LTC_SAFER
#define LTC_KHAZAD
#define LTC_ANUBIS
#define LTC_ANUBIS_TWEAK
#define LTC_KSEED
#define LTC_KASUMI
#endif /* LTC_NO_CIPHERS */
/* ---> Block Cipher Modes of Operation <--- */
#ifndef LTC_NO_MODES
#define LTC_CFB_MODE
#define LTC_OFB_MODE
#define LTC_ECB_MODE
#define LTC_CBC_MODE
#define LTC_CTR_MODE
/* F8 chaining mode */
#define LTC_F8_MODE
/* LRW mode */
#define LTC_LRW_MODE
#ifndef LTC_NO_TABLES
/* like GCM mode this will enable 16 8x128 tables [64KB] that make
* seeking very fast.
*/
#define LRW_TABLES
#endif
/* XTS mode */
#define LTC_XTS_MODE
#endif /* LTC_NO_MODES */
/* ---> One-Way Hash Functions <--- */
#ifndef LTC_NO_HASHES
#define LTC_CHC_HASH
#define LTC_WHIRLPOOL
#define LTC_SHA512
#define LTC_SHA384
#define LTC_SHA256
#define LTC_SHA224
#define LTC_TIGER
#define LTC_SHA1
#define LTC_MD5
#define LTC_MD4
#define LTC_MD2
#define LTC_RIPEMD128
#define LTC_RIPEMD160
#define LTC_RIPEMD256
#define LTC_RIPEMD320
#endif /* LTC_NO_HASHES */
/* ---> MAC functions <--- */
#ifndef LTC_NO_MACS
#define LTC_HMAC
#define LTC_OMAC
#define LTC_PMAC
#define LTC_XCBC
#define LTC_F9_MODE
#define LTC_PELICAN
#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL)
#error Pelican-MAC requires LTC_RIJNDAEL
#endif
/* ---> Encrypt + Authenticate Modes <--- */
#define LTC_EAX_MODE
#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC))
#error LTC_EAX_MODE requires CTR and LTC_OMAC mode
#endif
#define LTC_OCB_MODE
#define LTC_CCM_MODE
#define LTC_GCM_MODE
/* Use 64KiB tables */
#ifndef LTC_NO_TABLES
#define LTC_GCM_TABLES
#endif
/* USE SSE2? requires GCC works on x86_32 and x86_64*/
#ifdef LTC_GCM_TABLES
/* #define LTC_GCM_TABLES_SSE2 */
#endif
#endif /* LTC_NO_MACS */
/* Various tidbits of modern neatoness */
#define LTC_BASE64
/* --> Pseudo Random Number Generators <--- */
#ifndef LTC_NO_PRNGS
/* Yarrow */
#define LTC_YARROW
/* which descriptor of AES to use? */
/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */
#define LTC_YARROW_AES 0
#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE)
#error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined!
#endif
/* a PRNG that simply reads from an available system source */
#define LTC_SPRNG
/* The LTC_RC4 stream cipher */
#define LTC_RC4
/* Fortuna PRNG */
#define LTC_FORTUNA
/* reseed every N calls to the read function */
#define LTC_FORTUNA_WD 10
/* number of pools (4..32) can save a bit of ram by lowering the count */
#define LTC_FORTUNA_POOLS 32
/* Greg's LTC_SOBER128 PRNG ;-0 */
#define LTC_SOBER128
/* the *nix style /dev/random device */
#define LTC_DEVRANDOM
/* try /dev/urandom before trying /dev/random */
#define TRY_URANDOM_FIRST
#endif /* LTC_NO_PRNGS */
/* ---> math provider? <--- */
#ifndef LTC_NO_MATH
/* LibTomMath */
/* #define LTM_LTC_DESC */
/* TomsFastMath */
/* #define TFM_LTC_DESC */
#endif /* LTC_NO_MATH */
/* ---> Public Key Crypto <--- */
#ifndef LTC_NO_PK
/* Include RSA support */
#define LTC_MRSA
/* Include Katja (a Rabin variant like RSA) */
/* #define MKAT */
/* Digital Signature Algorithm */
#define LTC_MDSA
/* ECC */
#define LTC_MECC
/* use Shamir's trick for point mul (speeds up signature verification) */
#define LTC_ECC_SHAMIR
#if defined(TFM_LTC_DESC) && defined(LTC_MECC)
#define LTC_MECC_ACCEL
#endif
/* do we want fixed point ECC */
/* #define LTC_MECC_FP */
/* Timing Resistant? */
/* #define LTC_ECC_TIMING_RESISTANT */
#endif /* LTC_NO_PK */
/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */
#ifndef LTC_NO_PKCS
#define LTC_PKCS_1
#define LTC_PKCS_5
/* Include ASN.1 DER (required by DSA/RSA) */
#define LTC_DER
#endif /* LTC_NO_PKCS */
/* cleanup */
#ifdef LTC_MECC
/* Supported ECC Key Sizes */
#ifndef LTC_NO_CURVES
#define ECC112
#define ECC128
#define ECC160
#define ECC192
#define ECC224
#define ECC256
#define ECC384
#define ECC521
#endif
#endif
#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA)
/* Include the MPI functionality? (required by the PK algorithms) */
#define MPI
#endif
#ifdef LTC_MRSA
#define LTC_PKCS_1
#endif
#if defined(LTC_DER) && !defined(MPI)
#error ASN.1 DER requires MPI functionality
#endif
#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER)
#error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled
#endif
/* THREAD management */
#ifdef LTC_PTHREAD
#include <pthread.h>
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
#define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL);
#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
#else
/* default no functions */
#define LTC_MUTEX_GLOBAL(x)
#define LTC_MUTEX_PROTO(x)
#define LTC_MUTEX_TYPE(x)
#define LTC_MUTEX_INIT(x)
#define LTC_MUTEX_LOCK(x)
#define LTC_MUTEX_UNLOCK(x)
#endif
/* Debuggers */
/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */
/* #define LTC_VALGRIND */
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,379 @@
/* ---- HASH FUNCTIONS ---- */
#ifdef LTC_SHA512
struct sha512_state {
ulong64 length, state[8];
unsigned long curlen;
unsigned char buf[128];
};
#endif
#ifdef LTC_SHA256
struct sha256_state {
ulong64 length;
ulong32 state[8], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_SHA1
struct sha1_state {
ulong64 length;
ulong32 state[5], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_MD5
struct md5_state {
ulong64 length;
ulong32 state[4], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_MD4
struct md4_state {
ulong64 length;
ulong32 state[4], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_TIGER
struct tiger_state {
ulong64 state[3], length;
unsigned long curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_MD2
struct md2_state {
unsigned char chksum[16], X[48], buf[16];
unsigned long curlen;
};
#endif
#ifdef LTC_RIPEMD128
struct rmd128_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[4];
};
#endif
#ifdef LTC_RIPEMD160
struct rmd160_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[5];
};
#endif
#ifdef LTC_RIPEMD256
struct rmd256_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[8];
};
#endif
#ifdef LTC_RIPEMD320
struct rmd320_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[10];
};
#endif
#ifdef LTC_WHIRLPOOL
struct whirlpool_state {
ulong64 length, state[8];
unsigned char buf[64];
ulong32 curlen;
};
#endif
#ifdef LTC_CHC_HASH
struct chc_state {
ulong64 length;
unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE];
ulong32 curlen;
};
#endif
typedef union Hash_state {
char dummy[1];
#ifdef LTC_CHC_HASH
struct chc_state chc;
#endif
#ifdef LTC_WHIRLPOOL
struct whirlpool_state whirlpool;
#endif
#ifdef LTC_SHA512
struct sha512_state sha512;
#endif
#ifdef LTC_SHA256
struct sha256_state sha256;
#endif
#ifdef LTC_SHA1
struct sha1_state sha1;
#endif
#ifdef LTC_MD5
struct md5_state md5;
#endif
#ifdef LTC_MD4
struct md4_state md4;
#endif
#ifdef LTC_MD2
struct md2_state md2;
#endif
#ifdef LTC_TIGER
struct tiger_state tiger;
#endif
#ifdef LTC_RIPEMD128
struct rmd128_state rmd128;
#endif
#ifdef LTC_RIPEMD160
struct rmd160_state rmd160;
#endif
#ifdef LTC_RIPEMD256
struct rmd256_state rmd256;
#endif
#ifdef LTC_RIPEMD320
struct rmd320_state rmd320;
#endif
void *data;
} hash_state;
/** hash descriptor */
extern struct ltc_hash_descriptor {
/** name of hash */
char *name;
/** internal ID */
unsigned char ID;
/** Size of digest in octets */
unsigned long hashsize;
/** Input block size in octets */
unsigned long blocksize;
/** ASN.1 OID */
unsigned long OID[16];
/** Length of DER encoding */
unsigned long OIDlen;
/** Init a hash state
@param hash The hash to initialize
@return CRYPT_OK if successful
*/
int (*init)(hash_state *hash);
/** Process a block of data
@param hash The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen);
/** Produce the digest and store it
@param hash The hash state
@param out [out] The destination of the digest
@return CRYPT_OK if successful
*/
int (*done)(hash_state *hash, unsigned char *out);
/** Self-test
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int (*test)(void);
/* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */
int (*hmac_block)(const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
} hash_descriptor[];
#ifdef LTC_CHC_HASH
int chc_register(int cipher);
int chc_init(hash_state * md);
int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int chc_done(hash_state * md, unsigned char *hash);
int chc_test(void);
extern const struct ltc_hash_descriptor chc_desc;
#endif
#ifdef LTC_WHIRLPOOL
int whirlpool_init(hash_state * md);
int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int whirlpool_done(hash_state * md, unsigned char *hash);
int whirlpool_test(void);
extern const struct ltc_hash_descriptor whirlpool_desc;
#endif
#ifdef LTC_SHA512
int sha512_init(hash_state * md);
int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha512_done(hash_state * md, unsigned char *hash);
int sha512_test(void);
extern const struct ltc_hash_descriptor sha512_desc;
#endif
#ifdef LTC_SHA384
#ifndef LTC_SHA512
#error LTC_SHA512 is required for LTC_SHA384
#endif
int sha384_init(hash_state * md);
#define sha384_process sha512_process
int sha384_done(hash_state * md, unsigned char *hash);
int sha384_test(void);
extern const struct ltc_hash_descriptor sha384_desc;
#endif
#ifdef LTC_SHA256
int sha256_init(hash_state * md);
int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha256_done(hash_state * md, unsigned char *hash);
int sha256_test(void);
extern const struct ltc_hash_descriptor sha256_desc;
#ifdef LTC_SHA224
#ifndef LTC_SHA256
#error LTC_SHA256 is required for LTC_SHA224
#endif
int sha224_init(hash_state * md);
#define sha224_process sha256_process
int sha224_done(hash_state * md, unsigned char *hash);
int sha224_test(void);
extern const struct ltc_hash_descriptor sha224_desc;
#endif
#endif
#ifdef LTC_SHA1
int sha1_init(hash_state * md);
int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha1_done(hash_state * md, unsigned char *hash);
int sha1_test(void);
extern const struct ltc_hash_descriptor sha1_desc;
#endif
#ifdef LTC_MD5
int md5_init(hash_state * md);
int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int md5_done(hash_state * md, unsigned char *hash);
int md5_test(void);
extern const struct ltc_hash_descriptor md5_desc;
#endif
#ifdef LTC_MD4
int md4_init(hash_state * md);
int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int md4_done(hash_state * md, unsigned char *hash);
int md4_test(void);
extern const struct ltc_hash_descriptor md4_desc;
#endif
#ifdef LTC_MD2
int md2_init(hash_state * md);
int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int md2_done(hash_state * md, unsigned char *hash);
int md2_test(void);
extern const struct ltc_hash_descriptor md2_desc;
#endif
#ifdef LTC_TIGER
int tiger_init(hash_state * md);
int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int tiger_done(hash_state * md, unsigned char *hash);
int tiger_test(void);
extern const struct ltc_hash_descriptor tiger_desc;
#endif
#ifdef LTC_RIPEMD128
int rmd128_init(hash_state * md);
int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd128_done(hash_state * md, unsigned char *hash);
int rmd128_test(void);
extern const struct ltc_hash_descriptor rmd128_desc;
#endif
#ifdef LTC_RIPEMD160
int rmd160_init(hash_state * md);
int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd160_done(hash_state * md, unsigned char *hash);
int rmd160_test(void);
extern const struct ltc_hash_descriptor rmd160_desc;
#endif
#ifdef LTC_RIPEMD256
int rmd256_init(hash_state * md);
int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd256_done(hash_state * md, unsigned char *hash);
int rmd256_test(void);
extern const struct ltc_hash_descriptor rmd256_desc;
#endif
#ifdef LTC_RIPEMD320
int rmd320_init(hash_state * md);
int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd320_done(hash_state * md, unsigned char *hash);
int rmd320_test(void);
extern const struct ltc_hash_descriptor rmd320_desc;
#endif
int find_hash(const char *name);
int find_hash_id(unsigned char ID);
int find_hash_oid(const unsigned long *ID, unsigned long IDlen);
int find_hash_any(const char *name, int digestlen);
int register_hash(const struct ltc_hash_descriptor *hash);
int unregister_hash(const struct ltc_hash_descriptor *hash);
int hash_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_hash_mutex)
int hash_memory(int hash,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen);
/* a simple macro for making hash "process" functions */
#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \
{ \
unsigned long n; \
int err; \
LTC_ARGCHK(md != NULL); \
LTC_ARGCHK(in != NULL); \
if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
return CRYPT_INVALID_ARG; \
} \
while (inlen > 0) { \
if (md-> state_var .curlen == 0 && inlen >= block_size) { \
if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \
return err; \
} \
md-> state_var .length += block_size * 8; \
in += block_size; \
inlen -= block_size; \
} else { \
n = MIN(inlen, (block_size - md-> state_var .curlen)); \
memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \
md-> state_var .curlen += n; \
in += n; \
inlen -= n; \
if (md-> state_var .curlen == block_size) { \
if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \
return err; \
} \
md-> state_var .length += 8*block_size; \
md-> state_var .curlen = 0; \
} \
} \
} \
return CRYPT_OK; \
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,384 @@
#ifdef LTC_HMAC
typedef struct Hmac_state {
hash_state md;
int hash;
hash_state hashstate;
unsigned char *key;
} hmac_state;
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen);
int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen);
int hmac_test(void);
int hmac_memory(int hash,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int hmac_memory_multi(int hash,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen,
unsigned char *dst, unsigned long *dstlen);
#endif
#ifdef LTC_OMAC
typedef struct {
int cipher_idx,
buflen,
blklen;
unsigned char block[MAXBLOCKSIZE],
prev[MAXBLOCKSIZE],
Lu[2][MAXBLOCKSIZE];
symmetric_key key;
} omac_state;
int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen);
int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen);
int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen);
int omac_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int omac_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int omac_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int omac_test(void);
#endif /* LTC_OMAC */
#ifdef LTC_PMAC
typedef struct {
unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
Lr[MAXBLOCKSIZE], /* L * x^-1 */
block[MAXBLOCKSIZE], /* currently accumulated block */
checksum[MAXBLOCKSIZE]; /* current checksum */
symmetric_key key; /* scheduled key for cipher */
unsigned long block_index; /* index # for current block */
int cipher_idx, /* cipher idx */
block_len, /* length of block */
buflen; /* number of bytes in the buffer */
} pmac_state;
int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);
int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen);
int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen);
int pmac_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *msg, unsigned long msglen,
unsigned char *out, unsigned long *outlen);
int pmac_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int pmac_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int pmac_test(void);
/* internal functions */
int pmac_ntz(unsigned long x);
void pmac_shift_xor(pmac_state *pmac);
#endif /* PMAC */
#ifdef LTC_EAX_MODE
#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
#error LTC_EAX_MODE requires LTC_OMAC and CTR
#endif
typedef struct {
unsigned char N[MAXBLOCKSIZE];
symmetric_CTR ctr;
omac_state headeromac, ctomac;
} eax_state;
int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen);
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
int eax_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int eax_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
unsigned char *tag, unsigned long taglen,
int *stat);
int eax_test(void);
#endif /* EAX MODE */
#ifdef LTC_OCB_MODE
typedef struct {
unsigned char L[MAXBLOCKSIZE], /* L value */
Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
Lr[MAXBLOCKSIZE], /* L * x^-1 */
R[MAXBLOCKSIZE], /* R value */
checksum[MAXBLOCKSIZE]; /* current checksum */
symmetric_key key; /* scheduled key for cipher */
unsigned long block_index; /* index # for current block */
int cipher, /* cipher idx */
block_len; /* length of block */
} ocb_state;
int ocb_init(ocb_state *ocb, int cipher,
const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
int ocb_done_encrypt(ocb_state *ocb,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int ocb_done_decrypt(ocb_state *ocb,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen, int *stat);
int ocb_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int ocb_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen,
int *stat);
int ocb_test(void);
/* internal functions */
void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
int ocb_ntz(unsigned long x);
int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
#endif /* LTC_OCB_MODE */
#ifdef LTC_CCM_MODE
#define CCM_ENCRYPT 0
#define CCM_DECRYPT 1
int ccm_memory(int cipher,
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
int ccm_test(void);
#endif /* LTC_CCM_MODE */
#if defined(LRW_MODE) || defined(LTC_GCM_MODE)
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
#endif
/* table shared between GCM and LRW */
#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
extern const unsigned char gcm_shift_table[];
#endif
#ifdef LTC_GCM_MODE
#define GCM_ENCRYPT 0
#define GCM_DECRYPT 1
#define LTC_GCM_MODE_IV 0
#define LTC_GCM_MODE_AAD 1
#define LTC_GCM_MODE_TEXT 2
typedef struct {
symmetric_key K;
unsigned char H[16], /* multiplier */
X[16], /* accumulator */
Y[16], /* counter */
Y_0[16], /* initial counter */
buf[16]; /* buffer for stuff */
int cipher, /* which cipher */
ivmode, /* Which mode is the IV in? */
mode, /* mode the GCM code is in */
buflen; /* length of data in buf */
ulong64 totlen, /* 64-bit counter used for IV and AAD */
pttotlen; /* 64-bit counter for the PT */
#ifdef LTC_GCM_TABLES
unsigned char PC[16][256][16] /* 16 tables of 8x128 */
#ifdef LTC_GCM_TABLES_SSE2
__attribute__ ((aligned (16)))
#endif
;
#endif
} gcm_state;
void gcm_mult_h(gcm_state *gcm, unsigned char *I);
int gcm_init(gcm_state *gcm, int cipher,
const unsigned char *key, int keylen);
int gcm_reset(gcm_state *gcm);
int gcm_add_iv(gcm_state *gcm,
const unsigned char *IV, unsigned long IVlen);
int gcm_add_aad(gcm_state *gcm,
const unsigned char *adata, unsigned long adatalen);
int gcm_process(gcm_state *gcm,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
int direction);
int gcm_done(gcm_state *gcm,
unsigned char *tag, unsigned long *taglen);
int gcm_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
int gcm_test(void);
#endif /* LTC_GCM_MODE */
#ifdef LTC_PELICAN
typedef struct pelican_state
{
symmetric_key K;
unsigned char state[16];
int buflen;
} pelican_state;
int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
int pelican_done(pelican_state *pelmac, unsigned char *out);
int pelican_test(void);
int pelican_memory(const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out);
#endif
#ifdef LTC_XCBC
/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
#define LTC_XCBC_PURE 0x8000UL
typedef struct {
unsigned char K[3][MAXBLOCKSIZE],
IV[MAXBLOCKSIZE];
symmetric_key key;
int cipher,
buflen,
blocksize;
} xcbc_state;
int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
int xcbc_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int xcbc_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int xcbc_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int xcbc_test(void);
#endif
#ifdef LTC_F9_MODE
typedef struct {
unsigned char akey[MAXBLOCKSIZE],
ACC[MAXBLOCKSIZE],
IV[MAXBLOCKSIZE];
symmetric_key key;
int cipher,
buflen,
keylen,
blocksize;
} f9_state;
int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
int f9_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int f9_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int f9_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int f9_test(void);
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,424 @@
/* fix for MSVC ...evil! */
#ifdef _MSC_VER
#define CONST64(n) n ## ui64
typedef unsigned __int64 ulong64;
#else
#define CONST64(n) n ## ULL
typedef unsigned long long ulong64;
#endif
/* this is the "32-bit at least" data type
* Re-define it to suit your platform but it must be at least 32-bits
*/
#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__))
typedef unsigned ulong32;
#else
typedef unsigned long ulong32;
#endif
/* ---- HELPER MACROS ---- */
#ifdef ENDIAN_NEUTRAL
#define STORE32L(x, y) \
{ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
#define LOAD32L(x, y) \
{ x = ((unsigned long)((y)[3] & 255)<<24) | \
((unsigned long)((y)[2] & 255)<<16) | \
((unsigned long)((y)[1] & 255)<<8) | \
((unsigned long)((y)[0] & 255)); }
#define STORE64L(x, y) \
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
#define LOAD64L(x, y) \
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
#define STORE32H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
#define LOAD32H(x, y) \
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
((unsigned long)((y)[1] & 255)<<16) | \
((unsigned long)((y)[2] & 255)<<8) | \
((unsigned long)((y)[3] & 255)); }
#define STORE64H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
#define LOAD64H(x, y) \
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
#endif /* ENDIAN_NEUTRAL */
#ifdef ENDIAN_LITTLE
#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
#define STORE32H(x, y) \
asm __volatile__ ( \
"bswapl %0 \n\t" \
"movl %0,(%1)\n\t" \
"bswapl %0 \n\t" \
::"r"(x), "r"(y));
#define LOAD32H(x, y) \
asm __volatile__ ( \
"movl (%1),%0\n\t" \
"bswapl %0\n\t" \
:"=r"(x): "r"(y));
#else
#define STORE32H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
#define LOAD32H(x, y) \
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
((unsigned long)((y)[1] & 255)<<16) | \
((unsigned long)((y)[2] & 255)<<8) | \
((unsigned long)((y)[3] & 255)); }
#endif
/* x86_64 processor */
#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
#define STORE64H(x, y) \
asm __volatile__ ( \
"bswapq %0 \n\t" \
"movq %0,(%1)\n\t" \
"bswapq %0 \n\t" \
::"r"(x), "r"(y));
#define LOAD64H(x, y) \
asm __volatile__ ( \
"movq (%1),%0\n\t" \
"bswapq %0\n\t" \
:"=r"(x): "r"(y));
#else
#define STORE64H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
#define LOAD64H(x, y) \
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
#endif
#ifdef ENDIAN_32BITWORD
#define STORE32L(x, y) \
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
#define LOAD32L(x, y) \
XMEMCPY(&(x), y, 4);
#define STORE64L(x, y) \
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
#define LOAD64L(x, y) \
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
#else /* 64-bit words then */
#define STORE32L(x, y) \
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
#define LOAD32L(x, y) \
{ XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
#define STORE64L(x, y) \
{ ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
#define LOAD64L(x, y) \
{ XMEMCPY(&(x), y, 8); }
#endif /* ENDIAN_64BITWORD */
#endif /* ENDIAN_LITTLE */
#ifdef ENDIAN_BIG
#define STORE32L(x, y) \
{ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
#define LOAD32L(x, y) \
{ x = ((unsigned long)((y)[3] & 255)<<24) | \
((unsigned long)((y)[2] & 255)<<16) | \
((unsigned long)((y)[1] & 255)<<8) | \
((unsigned long)((y)[0] & 255)); }
#define STORE64L(x, y) \
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
#define LOAD64L(x, y) \
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
#ifdef ENDIAN_32BITWORD
#define STORE32H(x, y) \
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
#define LOAD32H(x, y) \
XMEMCPY(&(x), y, 4);
#define STORE64H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
#define LOAD64H(x, y) \
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
(((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
#else /* 64-bit words then */
#define STORE32H(x, y) \
{ ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
#define LOAD32H(x, y) \
{ XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
#define STORE64H(x, y) \
{ ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
#define LOAD64H(x, y) \
{ XMEMCPY(&(x), y, 8); }
#endif /* ENDIAN_64BITWORD */
#endif /* ENDIAN_BIG */
#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
/* 32-bit Rotates */
#if defined(_MSC_VER)
/* instrinsic rotate */
#include <stdlib.h>
#pragma intrinsic(_lrotr,_lrotl)
#define ROR(x,n) _lrotr(x,n)
#define ROL(x,n) _lrotl(x,n)
#define RORc(x,n) _lrotr(x,n)
#define ROLc(x,n) _lrotl(x,n)
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
static inline unsigned ROL(unsigned word, int i)
{
asm ("roll %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
static inline unsigned ROR(unsigned word, int i)
{
asm ("rorl %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
#ifndef LTC_NO_ROLC
static inline unsigned ROLc(unsigned word, const int i)
{
asm ("roll %2,%0"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
static inline unsigned RORc(unsigned word, const int i)
{
asm ("rorl %2,%0"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
#else
#define ROLc ROL
#define RORc ROR
#endif
#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
static inline unsigned ROL(unsigned word, int i)
{
asm ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (i));
return word;
}
static inline unsigned ROR(unsigned word, int i)
{
asm ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (32-i));
return word;
}
#ifndef LTC_NO_ROLC
static inline unsigned ROLc(unsigned word, const int i)
{
asm ("rotlwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
static inline unsigned RORc(unsigned word, const int i)
{
asm ("rotrwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
#else
#define ROLc ROL
#define RORc ROR
#endif
#else
/* rotates the hard way */
#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
#endif
/* 64-bit Rotates */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
static inline unsigned long ROL64(unsigned long word, int i)
{
asm("rolq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
static inline unsigned long ROR64(unsigned long word, int i)
{
asm("rorq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
#ifndef LTC_NO_ROLC
static inline unsigned long ROL64c(unsigned long word, const int i)
{
asm("rolq %2,%0"
:"=r" (word)
:"0" (word),"J" (i));
return word;
}
static inline unsigned long ROR64c(unsigned long word, const int i)
{
asm("rorq %2,%0"
:"=r" (word)
:"0" (word),"J" (i));
return word;
}
#else /* LTC_NO_ROLC */
#define ROL64c ROL64
#define ROR64c ROR64
#endif
#else /* Not x86_64 */
#define ROL64(x, y) \
( (((x)<<((ulong64)(y)&63)) | \
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
#define ROR64(x, y) \
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
#define ROL64c(x, y) \
( (((x)<<((ulong64)(y)&63)) | \
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
#define ROR64c(x, y) \
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
#endif
#ifndef MAX
#define MAX(x, y) ( ((x)>(y))?(x):(y) )
#endif
#ifndef MIN
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
#endif
/* extract a byte portably */
#ifdef _MSC_VER
#define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
#else
#define byte(x, n) (((x) >> (8 * (n))) & 255)
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,500 @@
/** math functions **/
#define LTC_MP_LT -1
#define LTC_MP_EQ 0
#define LTC_MP_GT 1
#define LTC_MP_NO 0
#define LTC_MP_YES 1
#ifndef LTC_MECC
typedef void ecc_point;
#endif
#ifndef LTC_MRSA
typedef void rsa_key;
#endif
/** math descriptor */
typedef struct {
/** Name of the math provider */
char *name;
/** Bits per digit, amount of bits must fit in an unsigned long */
int bits_per_digit;
/* ---- init/deinit functions ---- */
/** initialize a bignum
@param a The number to initialize
@return CRYPT_OK on success
*/
int (*init)(void **a);
/** init copy
@param dst The number to initialize and write to
@param src The number to copy from
@return CRYPT_OK on success
*/
int (*init_copy)(void **dst, void *src);
/** deinit
@param a The number to free
@return CRYPT_OK on success
*/
void (*deinit)(void *a);
/* ---- data movement ---- */
/** negate
@param src The number to negate
@param dst The destination
@return CRYPT_OK on success
*/
int (*neg)(void *src, void *dst);
/** copy
@param src The number to copy from
@param dst The number to write to
@return CRYPT_OK on success
*/
int (*copy)(void *src, void *dst);
/* ---- trivial low level functions ---- */
/** set small constant
@param a Number to write to
@param n Source upto bits_per_digit (actually meant for very small constants)
@return CRYPT_OK on succcess
*/
int (*set_int)(void *a, unsigned long n);
/** get small constant
@param a Number to read, only fetches upto bits_per_digit from the number
@return The lower bits_per_digit of the integer (unsigned)
*/
unsigned long (*get_int)(void *a);
/** get digit n
@param a The number to read from
@param n The number of the digit to fetch
@return The bits_per_digit sized n'th digit of a
*/
unsigned long (*get_digit)(void *a, int n);
/** Get the number of digits that represent the number
@param a The number to count
@return The number of digits used to represent the number
*/
int (*get_digit_count)(void *a);
/** compare two integers
@param a The left side integer
@param b The right side integer
@return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
*/
int (*compare)(void *a, void *b);
/** compare against int
@param a The left side integer
@param b The right side integer (upto bits_per_digit)
@return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison)
*/
int (*compare_d)(void *a, unsigned long n);
/** Count the number of bits used to represent the integer
@param a The integer to count
@return The number of bits required to represent the integer
*/
int (*count_bits)(void * a);
/** Count the number of LSB bits which are zero
@param a The integer to count
@return The number of contiguous zero LSB bits
*/
int (*count_lsb_bits)(void *a);
/** Compute a power of two
@param a The integer to store the power in
@param n The power of two you want to store (a = 2^n)
@return CRYPT_OK on success
*/
int (*twoexpt)(void *a , int n);
/* ---- radix conversions ---- */
/** read ascii string
@param a The integer to store into
@param str The string to read
@param radix The radix the integer has been represented in (2-64)
@return CRYPT_OK on success
*/
int (*read_radix)(void *a, const char *str, int radix);
/** write number to string
@param a The integer to store
@param str The destination for the string
@param radix The radix the integer is to be represented in (2-64)
@return CRYPT_OK on success
*/
int (*write_radix)(void *a, char *str, int radix);
/** get size as unsigned char string
@param a The integer to get the size (when stored in array of octets)
@return The length of the integer
*/
unsigned long (*unsigned_size)(void *a);
/** store an integer as an array of octets
@param src The integer to store
@param dst The buffer to store the integer in
@return CRYPT_OK on success
*/
int (*unsigned_write)(void *src, unsigned char *dst);
/** read an array of octets and store as integer
@param dst The integer to load
@param src The array of octets
@param len The number of octets
@return CRYPT_OK on success
*/
int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len);
/* ---- basic math ---- */
/** add two integers
@param a The first source integer
@param b The second source integer
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*add)(void *a, void *b, void *c);
/** add two integers
@param a The first source integer
@param b The second source integer (single digit of upto bits_per_digit in length)
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*addi)(void *a, unsigned long b, void *c);
/** subtract two integers
@param a The first source integer
@param b The second source integer
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*sub)(void *a, void *b, void *c);
/** subtract two integers
@param a The first source integer
@param b The second source integer (single digit of upto bits_per_digit in length)
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*subi)(void *a, unsigned long b, void *c);
/** multiply two integers
@param a The first source integer
@param b The second source integer (single digit of upto bits_per_digit in length)
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*mul)(void *a, void *b, void *c);
/** multiply two integers
@param a The first source integer
@param b The second source integer (single digit of upto bits_per_digit in length)
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*muli)(void *a, unsigned long b, void *c);
/** Square an integer
@param a The integer to square
@param b The destination
@return CRYPT_OK on success
*/
int (*sqr)(void *a, void *b);
/** Divide an integer
@param a The dividend
@param b The divisor
@param c The quotient (can be NULL to signify don't care)
@param d The remainder (can be NULL to signify don't care)
@return CRYPT_OK on success
*/
int (*mpdiv)(void *a, void *b, void *c, void *d);
/** divide by two
@param a The integer to divide (shift right)
@param b The destination
@return CRYPT_OK on success
*/
int (*div_2)(void *a, void *b);
/** Get remainder (small value)
@param a The integer to reduce
@param b The modulus (upto bits_per_digit in length)
@param c The destination for the residue
@return CRYPT_OK on success
*/
int (*modi)(void *a, unsigned long b, unsigned long *c);
/** gcd
@param a The first integer
@param b The second integer
@param c The destination for (a, b)
@return CRYPT_OK on success
*/
int (*gcd)(void *a, void *b, void *c);
/** lcm
@param a The first integer
@param b The second integer
@param c The destination for [a, b]
@return CRYPT_OK on success
*/
int (*lcm)(void *a, void *b, void *c);
/** Modular multiplication
@param a The first source
@param b The second source
@param c The modulus
@param d The destination (a*b mod c)
@return CRYPT_OK on success
*/
int (*mulmod)(void *a, void *b, void *c, void *d);
/** Modular squaring
@param a The first source
@param b The modulus
@param c The destination (a*a mod b)
@return CRYPT_OK on success
*/
int (*sqrmod)(void *a, void *b, void *c);
/** Modular inversion
@param a The value to invert
@param b The modulus
@param c The destination (1/a mod b)
@return CRYPT_OK on success
*/
int (*invmod)(void *, void *, void *);
/* ---- reduction ---- */
/** setup montgomery
@param a The modulus
@param b The destination for the reduction digit
@return CRYPT_OK on success
*/
int (*montgomery_setup)(void *a, void **b);
/** get normalization value
@param a The destination for the normalization value
@param b The modulus
@return CRYPT_OK on success
*/
int (*montgomery_normalization)(void *a, void *b);
/** reduce a number
@param a The number [and dest] to reduce
@param b The modulus
@param c The value "b" from montgomery_setup()
@return CRYPT_OK on success
*/
int (*montgomery_reduce)(void *a, void *b, void *c);
/** clean up (frees memory)
@param a The value "b" from montgomery_setup()
@return CRYPT_OK on success
*/
void (*montgomery_deinit)(void *a);
/* ---- exponentiation ---- */
/** Modular exponentiation
@param a The base integer
@param b The power (can be negative) integer
@param c The modulus integer
@param d The destination
@return CRYPT_OK on success
*/
int (*exptmod)(void *a, void *b, void *c, void *d);
/** Primality testing
@param a The integer to test
@param b The destination of the result (FP_YES if prime)
@return CRYPT_OK on success
*/
int (*isprime)(void *a, int *b);
/* ---- (optional) ecc point math ---- */
/** ECC GF(p) point multiplication (from the NIST curves)
@param k The integer to multiply the point by
@param G The point to multiply
@param R The destination for kG
@param modulus The modulus for the field
@param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
@return CRYPT_OK on success
*/
int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
/** ECC GF(p) point addition
@param P The first point
@param Q The second point
@param R The destination of P + Q
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
/** ECC GF(p) point double
@param P The first point
@param R The destination of 2P
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
/** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
@param P The point to map
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
@remark The mapping can be different but keep in mind a ecc_point only has three
integers (x,y,z) so if you use a different mapping you have to make it fit.
*/
int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
/** Computes kA*A + kB*B = C using Shamir's Trick
@param A First point to multiply
@param kA What to multiple A by
@param B Second point to multiply
@param kB What to multiple B by
@param C [out] Destination point (can overlap with A or B
@param modulus Modulus for curve
@return CRYPT_OK on success
*/
int (*ecc_mul2add)(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C,
void *modulus);
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
/** RSA Key Generation
@param prng An active PRNG state
@param wprng The index of the PRNG desired
@param size The size of the modulus (key size) desired (octets)
@param e The "e" value (public key). e==65537 is a good choice
@param key [out] Destination of a newly created private key pair
@return CRYPT_OK if successful, upon error all allocated ram is freed
*/
int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
/** RSA exponentiation
@param in The octet array representing the base
@param inlen The length of the input
@param out The destination (to be stored in an octet array format)
@param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus)
@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
@param key The RSA key to use
@return CRYPT_OK on success
*/
int (*rsa_me)(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
rsa_key *key);
} ltc_math_descriptor;
extern ltc_math_descriptor ltc_mp;
int ltc_init_multi(void **a, ...);
void ltc_deinit_multi(void *a, ...);
#ifdef LTM_DESC
extern const ltc_math_descriptor ltm_desc;
#endif
#ifdef TFM_DESC
extern const ltc_math_descriptor tfm_desc;
#endif
#ifdef GMP_DESC
extern const ltc_math_descriptor gmp_desc;
#endif
#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)
#define MP_DIGIT_BIT ltc_mp.bits_per_digit
/* some handy macros */
#define mp_init(a) ltc_mp.init(a)
#define mp_init_multi ltc_init_multi
#define mp_clear(a) ltc_mp.deinit(a)
#define mp_clear_multi ltc_deinit_multi
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
#define mp_neg(a, b) ltc_mp.neg(a, b)
#define mp_copy(a, b) ltc_mp.copy(a, b)
#define mp_set(a, b) ltc_mp.set_int(a, b)
#define mp_set_int(a, b) ltc_mp.set_int(a, b)
#define mp_get_int(a) ltc_mp.get_int(a)
#define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
#define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
#define mp_cmp(a, b) ltc_mp.compare(a, b)
#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
#define mp_count_bits(a) ltc_mp.count_bits(a)
#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
#define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
#define mp_add(a, b, c) ltc_mp.add(a, b, c)
#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
#define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
#define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
#define mp_sqr(a, b) ltc_mp.sqr(a, b)
#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
#define mp_div_2(a, b) ltc_mp.div_2(a, b)
#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c)
#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0);
#define mp_tohex(a, b) mp_toradix(a, b, 16)
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,23 @@
/* ---- LTC_BASE64 Routines ---- */
#ifdef LTC_BASE64
int base64_encode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
int base64_decode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
#endif
/* ---- MEM routines ---- */
void zeromem(void *dst, size_t len);
void burn_stack(unsigned long len);
const char *error_to_string(int err);
extern const char *crypt_build_settings;
/* ---- HMM ---- */
int crypt_fsa(void *mp, ...);
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,552 @@
/* ---- NUMBER THEORY ---- */
enum {
PK_PUBLIC=0,
PK_PRIVATE=1
};
int rand_prime(void *N, long len, prng_state *prng, int wprng);
/* ---- RSA ---- */
#ifdef LTC_MRSA
/* Min and Max RSA key sizes (in bits) */
#define MIN_RSA_SIZE 1024
#define MAX_RSA_SIZE 4096
/** RSA LTC_PKCS style key */
typedef struct Rsa_key {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** The public exponent */
void *e;
/** The private exponent */
void *d;
/** The modulus */
void *N;
/** The p factor of N */
void *p;
/** The q factor of N */
void *q;
/** The 1/q mod p CRT param */
void *qP;
/** The d mod (p - 1) CRT param */
void *dP;
/** The d mod (q - 1) CRT param */
void *dQ;
} rsa_key;
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
rsa_key *key);
void rsa_free(rsa_key *key);
/* These use LTC_PKCS #1 v2.0 padding */
#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \
rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key)
#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \
rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key)
#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \
rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key)
#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \
rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key)
/* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */
int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key);
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int padding,
int *stat, rsa_key *key);
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int padding,
prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
rsa_key *key);
int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int padding,
int hash_idx, unsigned long saltlen,
int *stat, rsa_key *key);
/* LTC_PKCS #1 import/export */
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
#endif
/* ---- Katja ---- */
#ifdef MKAT
/* Min and Max KAT key sizes (in bits) */
#define MIN_KAT_SIZE 1024
#define MAX_KAT_SIZE 4096
/** Katja LTC_PKCS style key */
typedef struct KAT_key {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** The private exponent */
void *d;
/** The modulus */
void *N;
/** The p factor of N */
void *p;
/** The q factor of N */
void *q;
/** The 1/q mod p CRT param */
void *qP;
/** The d mod (p - 1) CRT param */
void *dP;
/** The d mod (q - 1) CRT param */
void *dQ;
/** The pq param */
void *pq;
} katja_key;
int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
int katja_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
katja_key *key);
void katja_free(katja_key *key);
/* These use LTC_PKCS #1 v2.0 padding */
int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int *stat,
katja_key *key);
/* LTC_PKCS #1 import/export */
int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
#endif
/* ---- ECC Routines ---- */
#ifdef LTC_MECC
/* size of our temp buffers for exported keys */
#define ECC_BUF_SIZE 256
/* max private key size */
#define ECC_MAXSIZE 66
/** Structure defines a NIST GF(p) curve */
typedef struct {
/** The size of the curve in octets */
int size;
/** name of curve */
char *name;
/** The prime that defines the field the curve is in (encoded in hex) */
char *prime;
/** The fields B param (hex) */
char *B;
/** The order of the curve (hex) */
char *order;
/** The x co-ordinate of the base point on the curve (hex) */
char *Gx;
/** The y co-ordinate of the base point on the curve (hex) */
char *Gy;
} ltc_ecc_set_type;
/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
typedef struct {
/** The x co-ordinate */
void *x;
/** The y co-ordinate */
void *y;
/** The z co-ordinate */
void *z;
} ecc_point;
/** An ECC key */
typedef struct {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */
int idx;
/** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
const ltc_ecc_set_type *dp;
/** The public key */
ecc_point pubkey;
/** The private key */
void *k;
} ecc_key;
/** the ECC params provided */
extern const ltc_ecc_set_type ltc_ecc_sets[];
int ecc_test(void);
void ecc_sizes(int *low, int *high);
int ecc_get_size(ecc_key *key);
int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
void ecc_free(ecc_key *key);
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen);
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
ecc_key *key);
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ecc_key *key);
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, ecc_key *key);
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, ecc_key *key);
/* low level functions */
ecc_point *ltc_ecc_new_point(void);
void ltc_ecc_del_point(ecc_point *p);
int ltc_ecc_is_valid_idx(int n);
/* point ops (mp == montgomery digit) */
#if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC)
/* R = 2P */
int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
/* R = P + Q */
int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
#endif
#if defined(LTC_MECC_FP)
/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
/* functions for saving/loading/freeing/adding to fixed point cache */
int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
void ltc_ecc_fp_free(void);
int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
/* lock/unlock all points currently in fixed point cache */
void ltc_ecc_fp_tablelock(int lock);
#endif
/* R = kG */
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
#ifdef LTC_ECC_SHAMIR
/* kA*A + kB*B = C */
int ltc_ecc_mul2add(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C,
void *modulus);
#ifdef LTC_MECC_FP
/* Shamir's trick with optimized point multiplication using fixed point cache */
int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C, void *modulus);
#endif
#endif
/* map P to affine from projective */
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
#endif
#ifdef LTC_MDSA
/* Max diff between group and modulus size in bytes */
#define LTC_MDSA_DELTA 512
/* Max DSA group size in bytes (default allows 4k-bit groups) */
#define LTC_MDSA_MAX_GROUP 512
/** DSA key structure */
typedef struct {
/** The key type, PK_PRIVATE or PK_PUBLIC */
int type;
/** The order of the sub-group used in octets */
int qord;
/** The generator */
void *g;
/** The prime used to generate the sub-group */
void *q;
/** The large prime that generats the field the contains the sub-group */
void *p;
/** The private key */
void *x;
/** The public key */
void *y;
} dsa_key;
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
void dsa_free(dsa_key *key);
int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
void *r, void *s,
prng_state *prng, int wprng, dsa_key *key);
int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, dsa_key *key);
int dsa_verify_hash_raw( void *r, void *s,
const unsigned char *hash, unsigned long hashlen,
int *stat, dsa_key *key);
int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, dsa_key *key);
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
dsa_key *key);
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
dsa_key *key);
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
int dsa_verify_key(dsa_key *key, int *stat);
int dsa_shared_secret(void *private_key, void *base,
dsa_key *public_key,
unsigned char *out, unsigned long *outlen);
#endif
#ifdef LTC_DER
/* DER handling */
enum {
LTC_ASN1_EOL,
LTC_ASN1_BOOLEAN,
LTC_ASN1_INTEGER,
LTC_ASN1_SHORT_INTEGER,
LTC_ASN1_BIT_STRING,
LTC_ASN1_OCTET_STRING,
LTC_ASN1_NULL,
LTC_ASN1_OBJECT_IDENTIFIER,
LTC_ASN1_IA5_STRING,
LTC_ASN1_PRINTABLE_STRING,
LTC_ASN1_UTF8_STRING,
LTC_ASN1_UTCTIME,
LTC_ASN1_CHOICE,
LTC_ASN1_SEQUENCE,
LTC_ASN1_SET,
LTC_ASN1_SETOF
};
/** A LTC ASN.1 list type */
typedef struct ltc_asn1_list_ {
/** The LTC ASN.1 enumerated type identifier */
int type;
/** The data to encode or place for decoding */
void *data;
/** The size of the input or resulting output */
unsigned long size;
/** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
int used;
/** prev/next entry in the list */
struct ltc_asn1_list_ *prev, *next, *child, *parent;
} ltc_asn1_list;
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
do { \
int LTC_MACRO_temp = (index); \
ltc_asn1_list *LTC_MACRO_list = (list); \
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
} while (0);
/* SEQUENCE */
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int type_of);
#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
ltc_asn1_list *list, unsigned long outlen, int ordered);
#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen);
/* SET */
#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
#define der_length_set der_length_sequence
int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
/* VA list handy helpers with triplets of <type, size, data> */
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
/* FLEXI DECODER handle unknown list decoder */
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
void der_free_sequence_flexi(ltc_asn1_list *list);
void der_sequence_free(ltc_asn1_list *in);
/* BOOLEAN */
int der_length_boolean(unsigned long *outlen);
int der_encode_boolean(int in,
unsigned char *out, unsigned long *outlen);
int der_decode_boolean(const unsigned char *in, unsigned long inlen,
int *out);
/* INTEGER */
int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
int der_length_integer(void *num, unsigned long *len);
/* INTEGER -- handy for 0..2^32-1 values */
int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num);
int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen);
int der_length_short_integer(unsigned long num, unsigned long *outlen);
/* BIT STRING */
int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
/* OCTET STRING */
int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
/* OBJECT IDENTIFIER */
int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
unsigned char *out, unsigned long *outlen);
int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
unsigned long *words, unsigned long *outlen);
int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen);
unsigned long der_object_identifier_bits(unsigned long x);
/* IA5 STRING */
int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
int der_ia5_char_encode(int c);
int der_ia5_value_decode(int v);
/* Printable STRING */
int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
int der_printable_char_encode(int c);
int der_printable_value_decode(int v);
/* UTF-8 */
#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
#include <wchar.h>
#else
typedef ulong32 wchar_t;
#endif
int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
wchar_t *out, unsigned long *outlen);
unsigned long der_utf8_charsize(const wchar_t c);
int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen);
/* CHOICE */
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list *list, unsigned long outlen);
/* UTCTime */
typedef struct {
unsigned YY, /* year */
MM, /* month */
DD, /* day */
hh, /* hour */
mm, /* minute */
ss, /* second */
off_dir, /* timezone offset direction 0 == +, 1 == - */
off_hh, /* timezone offset hours */
off_mm; /* timezone offset minutes */
} ltc_utctime;
int der_encode_utctime(ltc_utctime *utctime,
unsigned char *out, unsigned long *outlen);
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
ltc_utctime *out);
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,89 @@
/* LTC_PKCS Header Info */
/* ===> LTC_PKCS #1 -- RSA Cryptography <=== */
#ifdef LTC_PKCS_1
enum ltc_pkcs_1_v1_5_blocks
{
LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */
LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */
};
enum ltc_pkcs_1_paddings
{
LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */
LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */
LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */
};
int pkcs_1_mgf1( int hash_idx,
const unsigned char *seed, unsigned long seedlen,
unsigned char *mask, unsigned long masklen);
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);
/* *** v1.5 padding */
int pkcs_1_v1_5_encode(const unsigned char *msg,
unsigned long msglen,
int block_type,
unsigned long modulus_bitlen,
prng_state *prng,
int prng_idx,
unsigned char *out,
unsigned long *outlen);
int pkcs_1_v1_5_decode(const unsigned char *msg,
unsigned long msglen,
int block_type,
unsigned long modulus_bitlen,
unsigned char *out,
unsigned long *outlen,
int *is_valid);
/* *** v2.1 padding */
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen);
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen,
int *res);
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen);
int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
const unsigned char *sig, unsigned long siglen,
unsigned long saltlen, int hash_idx,
unsigned long modulus_bitlen, int *res);
#endif /* LTC_PKCS_1 */
/* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */
#ifdef LTC_PKCS_5
/* Algorithm #1 (old) */
int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
/* Algorithm #2 (new) */
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
#endif /* LTC_PKCS_5 */
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,199 @@
/* ---- PRNG Stuff ---- */
#ifdef LTC_YARROW
struct yarrow_prng {
int cipher, hash;
unsigned char pool[MAXBLOCKSIZE];
symmetric_CTR ctr;
LTC_MUTEX_TYPE(prng_lock)
};
#endif
#ifdef LTC_RC4
struct rc4_prng {
int x, y;
unsigned char buf[256];
};
#endif
#ifdef LTC_FORTUNA
struct fortuna_prng {
hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */
symmetric_key skey;
unsigned char K[32], /* the current key */
IV[16]; /* IV for CTR mode */
unsigned long pool_idx, /* current pool we will add to */
pool0_len, /* length of 0'th pool */
wd;
ulong64 reset_cnt; /* number of times we have reset */
LTC_MUTEX_TYPE(prng_lock)
};
#endif
#ifdef LTC_SOBER128
struct sober128_prng {
ulong32 R[17], /* Working storage for the shift register */
initR[17], /* saved register contents */
konst, /* key dependent constant */
sbuf; /* partial word encryption buffer */
int nbuf, /* number of part-word stream bits buffered */
flag, /* first add_entropy call or not? */
set; /* did we call add_entropy to set key? */
};
#endif
typedef union Prng_state {
char dummy[1];
#ifdef LTC_YARROW
struct yarrow_prng yarrow;
#endif
#ifdef LTC_RC4
struct rc4_prng rc4;
#endif
#ifdef LTC_FORTUNA
struct fortuna_prng fortuna;
#endif
#ifdef LTC_SOBER128
struct sober128_prng sober128;
#endif
} prng_state;
/** PRNG descriptor */
extern struct ltc_prng_descriptor {
/** Name of the PRNG */
char *name;
/** size in bytes of exported state */
int export_size;
/** Start a PRNG state
@param prng [out] The state to initialize
@return CRYPT_OK if successful
*/
int (*start)(prng_state *prng);
/** Add entropy to the PRNG
@param in The entropy
@param inlen Length of the entropy (octets)\
@param prng The PRNG state
@return CRYPT_OK if successful
*/
int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng);
/** Ready a PRNG state to read from
@param prng The PRNG state to ready
@return CRYPT_OK if successful
*/
int (*ready)(prng_state *prng);
/** Read from the PRNG
@param out [out] Where to store the data
@param outlen Length of data desired (octets)
@param prng The PRNG state to read from
@return Number of octets read
*/
unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng);
/** Terminate a PRNG state
@param prng The PRNG state to terminate
@return CRYPT_OK if successful
*/
int (*done)(prng_state *prng);
/** Export a PRNG state
@param out [out] The destination for the state
@param outlen [in/out] The max size and resulting size of the PRNG state
@param prng The PRNG to export
@return CRYPT_OK if successful
*/
int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng);
/** Import a PRNG state
@param in The data to import
@param inlen The length of the data to import (octets)
@param prng The PRNG to initialize/import
@return CRYPT_OK if successful
*/
int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng);
/** Self-test the PRNG
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
int (*test)(void);
} prng_descriptor[];
#ifdef LTC_YARROW
int yarrow_start(prng_state *prng);
int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int yarrow_ready(prng_state *prng);
unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int yarrow_done(prng_state *prng);
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int yarrow_test(void);
extern const struct ltc_prng_descriptor yarrow_desc;
#endif
#ifdef LTC_FORTUNA
int fortuna_start(prng_state *prng);
int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int fortuna_ready(prng_state *prng);
unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int fortuna_done(prng_state *prng);
int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int fortuna_test(void);
extern const struct ltc_prng_descriptor fortuna_desc;
#endif
#ifdef LTC_RC4
int rc4_start(prng_state *prng);
int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int rc4_ready(prng_state *prng);
unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int rc4_done(prng_state *prng);
int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int rc4_test(void);
extern const struct ltc_prng_descriptor rc4_desc;
#endif
#ifdef LTC_SPRNG
int sprng_start(prng_state *prng);
int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sprng_ready(prng_state *prng);
unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int sprng_done(prng_state *prng);
int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sprng_test(void);
extern const struct ltc_prng_descriptor sprng_desc;
#endif
#ifdef LTC_SOBER128
int sober128_start(prng_state *prng);
int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sober128_ready(prng_state *prng);
unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int sober128_done(prng_state *prng);
int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sober128_test(void);
extern const struct ltc_prng_descriptor sober128_desc;
#endif
int find_prng(const char *name);
int register_prng(const struct ltc_prng_descriptor *prng);
int unregister_prng(const struct ltc_prng_descriptor *prng);
int prng_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_prng_mutex)
/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
* might not work on all platforms as planned
*/
unsigned long rng_get_bytes(unsigned char *out,
unsigned long outlen,
void (*callback)(void));
int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -320,6 +320,37 @@ void DsqlCompilerScratch::putLocalVariables(CompoundStmtNode* parameters, USHORT
else
fb_assert(false);
}
if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE))
{
// Check not implemented sub-functions.
GenericMap<Left<MetaName, DeclareSubFuncNode*> >::ConstAccessor funcAccessor(&subFunctions);
for (bool found = funcAccessor.getFirst(); found; found = funcAccessor.getNext())
{
if (!funcAccessor.current()->second->dsqlBlock)
{
status_exception::raise(
Arg::Gds(isc_subfunc_not_impl) <<
funcAccessor.current()->first.c_str());
}
}
// Check not implemented sub-procedures.
GenericMap<Left<MetaName, DeclareSubProcNode*> >::ConstAccessor procAccessor(&subProcedures);
for (bool found = procAccessor.getFirst(); found; found = procAccessor.getNext())
{
if (!procAccessor.current()->second->dsqlBlock)
{
status_exception::raise(
Arg::Gds(isc_subproc_not_impl) <<
procAccessor.current()->first.c_str());
}
}
}
}
// Write out local variable field data type.
@ -586,6 +617,50 @@ void DsqlCompilerScratch::checkUnusedCTEs() const
}
}
DeclareSubFuncNode* DsqlCompilerScratch::getSubFunction(const Firebird::MetaName& name)
{
DeclareSubFuncNode* subFunc = NULL;
subFunctions.get(name, subFunc);
if (!subFunc && mainScratch)
subFunc = mainScratch->getSubFunction(name);
return subFunc;
}
void DsqlCompilerScratch::putSubFunction(DeclareSubFuncNode* subFunc, bool replace)
{
if (!replace && subFunctions.exist(subFunc->name))
{
status_exception::raise(
Arg::Gds(isc_dsql_duplicate_spec) << subFunc->name);
}
subFunctions.put(subFunc->name, subFunc);
}
DeclareSubProcNode* DsqlCompilerScratch::getSubProcedure(const Firebird::MetaName& name)
{
DeclareSubProcNode* subProc = NULL;
subProcedures.get(name, subProc);
if (!subProc && mainScratch)
subProc = mainScratch->getSubProcedure(name);
return subProc;
}
void DsqlCompilerScratch::putSubProcedure(DeclareSubProcNode* subProc, bool replace)
{
if (!replace && subProcedures.exist(subProc->name))
{
status_exception::raise(
Arg::Gds(isc_dsql_duplicate_spec) << subProc->name);
}
subProcedures.put(subProc->name, subProc);
}
// Process derived table which can be recursive CTE.
// If it is non-recursive return input node unchanged.
// If it is recursive return new derived table which is an union of union of anchor (non-recursive)

View File

@ -70,7 +70,7 @@ public:
public:
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
DsqlCompiledStatement* aStatement)
DsqlCompiledStatement* aStatement, DsqlCompilerScratch* aMainScratch = NULL)
: BlrDebugWriter(p),
dbb(aDbb),
transaction(aTransaction),
@ -79,7 +79,6 @@ public:
nestingLevel(0),
ports(p),
relation(NULL),
procedure(NULL),
mainContext(p),
context(&mainContext),
unionContext(p),
@ -115,6 +114,7 @@ public:
ctes(p),
cteAliases(p),
psql(false),
mainScratch(aMainScratch),
subFunctions(p),
subProcedures(p)
{
@ -247,43 +247,11 @@ public:
bool isPsql() const { return psql; }
void setPsql(bool value) { psql = value; }
dsql_udf* getSubFunction(const Firebird::MetaName& name)
{
dsql_udf* subFunc = NULL;
subFunctions.get(name, subFunc);
return subFunc;
}
DeclareSubFuncNode* getSubFunction(const Firebird::MetaName& name);
void putSubFunction(DeclareSubFuncNode* subFunc, bool replace = false);
void putSubFunction(dsql_udf* subFunc)
{
if (subFunctions.exist(subFunc->udf_name.identifier))
{
using namespace Firebird;
status_exception::raise(
Arg::Gds(isc_dsql_duplicate_spec) << subFunc->udf_name.identifier);
}
subFunctions.put(subFunc->udf_name.identifier, subFunc);
}
dsql_prc* getSubProcedure(const Firebird::MetaName& name)
{
dsql_prc* subProc = NULL;
subProcedures.get(name, subProc);
return subProc;
}
void putSubProcedure(dsql_prc* subProc)
{
if (subProcedures.exist(subProc->prc_name.identifier))
{
using namespace Firebird;
status_exception::raise(
Arg::Gds(isc_dsql_duplicate_spec) << subProc->prc_name.identifier);
}
subProcedures.put(subProc->prc_name.identifier, subProc);
}
DeclareSubProcNode* getSubProcedure(const Firebird::MetaName& name);
void putSubProcedure(DeclareSubProcNode* subProc, bool replace = false);
private:
SelectExprNode* pass1RecursiveCte(SelectExprNode* input);
@ -300,7 +268,6 @@ public:
unsigned nestingLevel; // begin...end nesting level
Firebird::Array<dsql_msg*> ports; // Port messages
dsql_rel* relation; // relation created by this request (for DDL)
dsql_prc* procedure; // procedure created by this request (for DDL)
DsqlContextStack mainContext;
DsqlContextStack* context;
DsqlContextStack unionContext; // Save contexts for views of unions
@ -340,8 +307,9 @@ private:
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions
Firebird::HalfStaticArray<const Firebird::string*, 4> cteAliases; // CTE aliases in recursive members
bool psql;
Firebird::GenericMap<Firebird::Left<Firebird::MetaName, dsql_udf*> > subFunctions;
Firebird::GenericMap<Firebird::Left<Firebird::MetaName, dsql_prc*> > subProcedures;
DsqlCompilerScratch* mainScratch;
Firebird::GenericMap<Firebird::Left<Firebird::MetaName, DeclareSubFuncNode*> > subFunctions;
Firebird::GenericMap<Firebird::Left<Firebird::MetaName, DeclareSubProcNode*> > subProcedures;
};
class PsqlChanger

View File

@ -11589,8 +11589,12 @@ DmlNode* UdfCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch*
if (blrOp == blr_subfunc)
{
DeclareSubFuncNode* declareNode;
if (csb->subFunctions.get(name.identifier, declareNode))
node->function = declareNode->routine;
for (auto curCsb = csb; curCsb && !node->function; curCsb = curCsb->mainCsb)
{
if (curCsb->subFunctions.get(name.identifier, declareNode))
node->function = declareNode->routine;
}
}
Function* function = node->function;
@ -12023,7 +12027,10 @@ ValueExprNode* UdfCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
doDsqlPass(dsqlScratch, args));
if (name.package.isEmpty())
node->dsqlFunction = dsqlScratch->getSubFunction(name.identifier);
{
DeclareSubFuncNode* subFunction = dsqlScratch->getSubFunction(name.identifier);
node->dsqlFunction = subFunction ? subFunction->dsqlFunction : NULL;
}
if (!node->dsqlFunction)
node->dsqlFunction = METD_get_function(dsqlScratch->getTransaction(), dsqlScratch, name);

View File

@ -51,164 +51,6 @@ DATABASE DB = STATIC "ODS.RDB";
namespace
{
struct ParameterInfo
{
explicit ParameterInfo(MemoryPool& p)
: type(0),
number(0),
name(p),
fieldSource(p),
fieldName(p),
relationName(p),
mechanism(0)
{
defaultSource.clear();
defaultValue.clear();
}
ParameterInfo(MemoryPool& p, const ParameterInfo& o)
: type(o.type),
number(o.number),
name(p, o.name),
fieldSource(p, o.fieldSource),
fieldName(p, o.fieldName),
relationName(p, o.relationName),
collationId(o.collationId),
nullFlag(o.nullFlag),
mechanism(o.mechanism),
fieldLength(o.fieldLength),
fieldScale(o.fieldScale),
fieldType(o.fieldType),
fieldSubType(o.fieldSubType),
fieldSegmentLength(o.fieldSegmentLength),
fieldNullFlag(o.fieldNullFlag),
fieldCharLength(o.fieldCharLength),
fieldCollationId(o.fieldCollationId),
fieldCharSetId(o.fieldCharSetId),
fieldPrecision(o.fieldPrecision),
defaultSource(o.defaultSource),
defaultValue(o.defaultValue)
{
}
SSHORT type;
SSHORT number;
MetaName name;
MetaName fieldSource;
MetaName fieldName;
MetaName relationName;
Nullable<SSHORT> collationId;
Nullable<SSHORT> nullFlag;
SSHORT mechanism;
Nullable<SSHORT> fieldLength;
Nullable<SSHORT> fieldScale;
Nullable<SSHORT> fieldType;
Nullable<SSHORT> fieldSubType;
Nullable<SSHORT> fieldSegmentLength;
Nullable<SSHORT> fieldNullFlag;
Nullable<SSHORT> fieldCharLength;
Nullable<SSHORT> fieldCollationId;
Nullable<SSHORT> fieldCharSetId;
Nullable<SSHORT> fieldPrecision;
// Not compared
bid defaultSource;
bid defaultValue;
bool operator >(const ParameterInfo& o) const
{
return type > o.type || (type == o.type && number > o.number);
}
bool operator ==(const ParameterInfo& o) const
{
return type == o.type && number == o.number && name == o.name &&
(fieldSource == o.fieldSource ||
(fb_utils::implicit_domain(fieldSource.c_str()) &&
fb_utils::implicit_domain(o.fieldSource.c_str()))) &&
fieldName == o.fieldName && relationName == o.relationName &&
collationId == o.collationId && nullFlag == o.nullFlag &&
mechanism == o.mechanism && fieldLength == o.fieldLength &&
fieldScale == o.fieldScale && fieldType == o.fieldType &&
fieldSubType == o.fieldSubType && fieldSegmentLength == o.fieldSegmentLength &&
fieldNullFlag == o.fieldNullFlag && fieldCharLength == o.fieldCharLength &&
fieldCollationId == o.fieldCollationId && fieldCharSetId == o.fieldCharSetId &&
fieldPrecision == o.fieldPrecision;
}
bool operator !=(const ParameterInfo& o) const
{
return !(*this == o);
}
};
struct Signature
{
Signature(MemoryPool& p, const MetaName& aName)
: name(p, aName),
parameters(p),
defined(false)
{
}
explicit Signature(const MetaName& aName)
: name(aName),
parameters(*getDefaultMemoryPool()),
defined(false)
{
}
explicit Signature(MemoryPool& p)
: name(p),
parameters(p),
defined(false)
{
}
Signature(MemoryPool& p, const Signature& o)
: name(p, o.name),
parameters(p),
defined(o.defined)
{
for (SortedObjectsArray<ParameterInfo>::const_iterator i = o.parameters.begin();
i != o.parameters.end(); ++i)
{
parameters.add(*i);
}
}
bool operator >(const Signature& o) const
{
return name > o.name;
}
bool operator ==(const Signature& o) const
{
if (name != o.name || parameters.getCount() != o.parameters.getCount())
return false;
for (SortedObjectsArray<ParameterInfo>::const_iterator i = parameters.begin(),
j = o.parameters.begin();
i != parameters.end(); ++i, ++j)
{
if (*i != *j)
return false;
}
return true;
}
bool operator !=(const Signature& o) const
{
return !(*this == o);
}
MetaName name;
SortedObjectsArray<ParameterInfo> parameters;
bool defined;
};
// Return function and procedure names (in the user charset) and optionally its details for a
// given package.
void collectPackagedItems(thread_db* tdbb, jrd_tra* transaction, const MetaName& metaName,
@ -225,6 +67,9 @@ namespace
Signature function(FUN.RDB$FUNCTION_NAME);
function.defined = !FUN.RDB$FUNCTION_BLR.NULL || !FUN.RDB$ENTRYPOINT.NULL;
if (!FUN.RDB$DETERMINISTIC_FLAG.NULL && FUN.RDB$DETERMINISTIC_FLAG != 0)
function.flags |= Signature::FLAG_DETERMINISTIC;
if (details)
{
FOR (REQUEST_HANDLE requestHandle2 TRANSACTION_HANDLE transaction)
@ -234,7 +79,7 @@ namespace
ARG.RDB$FUNCTION_NAME EQ FUN.RDB$FUNCTION_NAME AND
FLD.RDB$FIELD_NAME EQ ARG.RDB$FIELD_SOURCE
{
ParameterInfo parameter(*getDefaultMemoryPool());
SignatureParameter parameter(*getDefaultMemoryPool());
parameter.number = ARG.RDB$ARGUMENT_POSITION;
parameter.name = ARG.RDB$ARGUMENT_NAME;
@ -271,11 +116,6 @@ namespace
if (!FLD.RDB$FIELD_PRECISION.NULL)
parameter.fieldPrecision = FLD.RDB$FIELD_PRECISION;
if (!ARG.RDB$DEFAULT_SOURCE.NULL)
parameter.defaultSource = ARG.RDB$DEFAULT_SOURCE;
if (!ARG.RDB$DEFAULT_VALUE.NULL)
parameter.defaultValue = ARG.RDB$DEFAULT_VALUE;
function.parameters.add(parameter);
}
END_FOR
@ -304,7 +144,7 @@ namespace
PRM.RDB$PROCEDURE_NAME EQ PRC.RDB$PROCEDURE_NAME AND
FLD.RDB$FIELD_NAME EQ PRM.RDB$FIELD_SOURCE
{
ParameterInfo parameter(*getDefaultMemoryPool());
SignatureParameter parameter(*getDefaultMemoryPool());
parameter.type = PRM.RDB$PARAMETER_TYPE;
parameter.number = PRM.RDB$PARAMETER_NUMBER;
parameter.name = PRM.RDB$PARAMETER_NAME;
@ -341,11 +181,6 @@ namespace
if (!FLD.RDB$FIELD_PRECISION.NULL)
parameter.fieldPrecision = FLD.RDB$FIELD_PRECISION;
if (!PRM.RDB$DEFAULT_SOURCE.NULL)
parameter.defaultSource = PRM.RDB$DEFAULT_SOURCE;
if (!PRM.RDB$DEFAULT_VALUE.NULL)
parameter.defaultValue = PRM.RDB$DEFAULT_VALUE;
procedure.parameters.add(parameter);
}
END_FOR

View File

@ -1402,7 +1402,8 @@ DmlNode* DeclareSubFuncNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerSc
{ // scope
CompilerScratch* const subCsb = node->subCsb =
FB_NEW_POOL(csb->csb_pool) CompilerScratch(csb->csb_pool);
FB_NEW_POOL(csb->csb_pool) CompilerScratch(csb->csb_pool, csb);
subCsb->csb_g_flags |= csb_subroutine | (csb->csb_g_flags & csb_get_dependencies);
subCsb->csb_blr_reader = csb->csb_blr_reader;
@ -1520,6 +1521,97 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE)
ERR_post(Arg::Gds(isc_wish_list) << Arg::Gds(isc_random) << "nested sub function");
DeclareSubFuncNode* prevDecl = dsqlScratch->getSubFunction(name);
bool implemetingForward = prevDecl && !prevDecl->dsqlBlock && dsqlBlock;
dsqlFunction = implemetingForward ? prevDecl->dsqlFunction : FB_NEW_POOL(pool) dsql_udf(pool);
dsqlFunction->udf_flags = UDF_subfunc;
dsqlFunction->udf_name.identifier = name;
fb_assert(dsqlReturns.getCount() == 1);
const TypeClause* returnType = dsqlReturns[0]->type;
dsqlFunction->udf_dtype = returnType->dtype;
dsqlFunction->udf_scale = returnType->scale;
dsqlFunction->udf_sub_type = returnType->subType;
dsqlFunction->udf_length = returnType->length;
dsqlFunction->udf_character_set_id = returnType->charSetId;
if (dsqlDeterministic)
dsqlSignature.flags |= Signature::FLAG_DETERMINISTIC;
SignatureParameter sigRet(pool);
sigRet.type = 1;
sigRet.number = -1;
sigRet.fromType(returnType);
dsqlSignature.parameters.add(sigRet);
Array<NestConst<ParameterClause> >& paramArray = dsqlParameters;
bool defaultFound = false;
for (NestConst<ParameterClause>* i = paramArray.begin(); i != paramArray.end(); ++i)
{
ParameterClause* param = *i;
const unsigned paramIndex = i - paramArray.begin();
SignatureParameter sigParam(pool);
sigParam.type = 0;
sigParam.number = (SSHORT) dsqlSignature.parameters.getCount();
sigParam.name = param->name;
sigParam.fromType(param->type);
dsqlSignature.parameters.add(sigParam);
if (!implemetingForward)
{
// ASF: dsqlFunction->udf_arguments is only checked for its count for now.
dsqlFunction->udf_arguments.add(dsc());
}
if (param->defaultClause)
{
if (prevDecl)
{
status_exception::raise(
Arg::Gds(isc_subfunc_defvaldecl) <<
name.c_str());
}
defaultFound = true;
if (!implemetingForward && dsqlFunction->udf_def_count == 0)
dsqlFunction->udf_def_count = paramArray.end() - i;
}
else
{
if (defaultFound)
{
// Parameter without default value after parameters with default.
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_bad_default_value) <<
Arg::Gds(isc_invalid_clause) << Arg::Str("defaults must be last"));
}
if (prevDecl && paramIndex < prevDecl->dsqlParameters.getCount())
param->defaultClause = prevDecl->dsqlParameters[paramIndex]->defaultClause;
}
}
if (!implemetingForward)
dsqlScratch->putSubFunction(this);
else if (dsqlSignature != prevDecl->dsqlSignature)
{
status_exception::raise(
Arg::Gds(isc_subfunc_signat) <<
name.c_str());
}
if (!dsqlBlock) // forward decl
return this;
if (prevDecl)
dsqlScratch->putSubFunction(this, true);
DsqlCompiledStatement* statement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool);
if (dsqlScratch->clientDialect > SQL_DIALECT_V5)
@ -1535,58 +1627,23 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
statement->setType(DsqlCompiledStatement::TYPE_SELECT);
blockScratch = FB_NEW_POOL(pool) DsqlCompilerScratch(pool,
dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), statement);
dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), statement, dsqlScratch);
blockScratch->clientDialect = dsqlScratch->clientDialect;
blockScratch->flags |= DsqlCompilerScratch::FLAG_FUNCTION | DsqlCompilerScratch::FLAG_SUB_ROUTINE;
blockScratch->flags |= dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL;
blockScratch->flags |=
DsqlCompilerScratch::FLAG_FUNCTION |
DsqlCompilerScratch::FLAG_SUB_ROUTINE |
(dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL);
dsqlBlock = dsqlBlock->dsqlPass(blockScratch);
dsqlFunction = FB_NEW_POOL(pool) dsql_udf(pool);
dsqlFunction->udf_flags = UDF_subfunc;
dsqlFunction->udf_name.identifier = name;
fb_assert(dsqlBlock->returns.getCount() == 1);
const TypeClause* returnType = dsqlBlock->returns[0]->type;
dsqlFunction->udf_dtype = returnType->dtype;
dsqlFunction->udf_scale = returnType->scale;
dsqlFunction->udf_sub_type = returnType->subType;
dsqlFunction->udf_length = returnType->length;
dsqlFunction->udf_character_set_id = returnType->charSetId;
const Array<NestConst<ParameterClause> >& paramArray = dsqlBlock->parameters;
bool defaultFound = false;
for (const NestConst<ParameterClause>* i = paramArray.begin(); i != paramArray.end(); ++i)
{
// ASF: dsqlFunction->udf_arguments is only checked for its count for now.
dsqlFunction->udf_arguments.add(dsc());
const ParameterClause* param = *i;
if (param->defaultClause)
{
defaultFound = true;
if (dsqlFunction->udf_def_count == 0)
dsqlFunction->udf_def_count = paramArray.end() - i;
}
else if (defaultFound)
{
// Parameter without default value after parameters with default.
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_bad_default_value) <<
Arg::Gds(isc_invalid_clause) << Arg::Str("defaults must be last"));
}
}
dsqlScratch->putSubFunction(dsqlFunction);
return this;
}
void DeclareSubFuncNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
if (!dsqlBlock) // forward decl
return;
GEN_request(blockScratch, dsqlBlock);
dsqlScratch->appendUChar(blr_subfunc_decl);
@ -1677,7 +1734,8 @@ DmlNode* DeclareSubProcNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerSc
{ // scope
CompilerScratch* const subCsb = node->subCsb =
FB_NEW_POOL(csb->csb_pool) CompilerScratch(csb->csb_pool);
FB_NEW_POOL(csb->csb_pool) CompilerScratch(csb->csb_pool, csb);
subCsb->csb_g_flags |= csb_subroutine | (csb->csb_g_flags & csb_get_dependencies);
subCsb->csb_blr_reader = csb->csb_blr_reader;
@ -1803,6 +1861,100 @@ DeclareSubProcNode* DeclareSubProcNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE)
ERR_post(Arg::Gds(isc_wish_list) << Arg::Gds(isc_random) << "nested sub procedure");
DeclareSubProcNode* prevDecl = dsqlScratch->getSubProcedure(name);
bool implemetingForward = prevDecl && !prevDecl->dsqlBlock && dsqlBlock;
dsqlProcedure = implemetingForward ? prevDecl->dsqlProcedure : FB_NEW_POOL(pool) dsql_prc(pool);
dsqlProcedure->prc_flags = PRC_subproc;
dsqlProcedure->prc_name.identifier = name;
dsqlProcedure->prc_in_count = USHORT(dsqlParameters.getCount());
dsqlProcedure->prc_out_count = USHORT(dsqlReturns.getCount());
if (dsqlParameters.hasData())
{
Array<NestConst<ParameterClause> >& paramArray = dsqlParameters;
bool defaultFound = false;
dsqlProcedure->prc_inputs = paramArray.front()->type;
for (NestConst<ParameterClause>* i = paramArray.begin(); i != paramArray.end(); ++i)
{
ParameterClause* param = *i;
const unsigned paramIndex = i - paramArray.begin();
SignatureParameter sigParam(pool);
sigParam.type = 0; // input
sigParam.number = (SSHORT) dsqlSignature.parameters.getCount();
sigParam.name = param->name;
sigParam.fromType(param->type);
dsqlSignature.parameters.add(sigParam);
if (param->defaultClause)
{
if (prevDecl)
{
status_exception::raise(
Arg::Gds(isc_subproc_defvaldecl) <<
name.c_str());
}
defaultFound = true;
if (!implemetingForward && dsqlProcedure->prc_def_count == 0)
dsqlProcedure->prc_def_count = paramArray.end() - i;
}
else
{
if (defaultFound)
{
// Parameter without default value after parameters with default.
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_bad_default_value) <<
Arg::Gds(isc_invalid_clause) << Arg::Str("defaults must be last"));
}
if (prevDecl && paramIndex < prevDecl->dsqlParameters.getCount())
param->defaultClause = prevDecl->dsqlParameters[paramIndex]->defaultClause;
}
}
}
if (dsqlReturns.hasData())
{
Array<NestConst<ParameterClause> >& paramArray = dsqlReturns;
dsqlProcedure->prc_outputs = paramArray.front()->type;
for (NestConst<ParameterClause>* i = paramArray.begin(); i != paramArray.end(); ++i)
{
ParameterClause* param = *i;
const unsigned paramIndex = i - paramArray.begin();
SignatureParameter sigParam(pool);
sigParam.type = 1; // output
sigParam.number = (SSHORT) dsqlSignature.parameters.getCount();
sigParam.name = param->name;
sigParam.fromType(param->type);
dsqlSignature.parameters.add(sigParam);
}
}
if (!implemetingForward)
dsqlScratch->putSubProcedure(this);
else if (dsqlSignature != prevDecl->dsqlSignature)
{
status_exception::raise(
Arg::Gds(isc_subproc_signat) <<
name.c_str());
}
if (!dsqlBlock) // forward decl
return this;
if (prevDecl)
dsqlScratch->putSubProcedure(this, true);
DsqlCompiledStatement* statement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool);
if (dsqlScratch->clientDialect > SQL_DIALECT_V5)
@ -1818,54 +1970,21 @@ DeclareSubProcNode* DeclareSubProcNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
statement->setType(DsqlCompiledStatement::TYPE_SELECT);
blockScratch = FB_NEW_POOL(pool) DsqlCompilerScratch(pool,
dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), statement);
dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), statement, dsqlScratch);
blockScratch->clientDialect = dsqlScratch->clientDialect;
blockScratch->flags |= DsqlCompilerScratch::FLAG_PROCEDURE | DsqlCompilerScratch::FLAG_SUB_ROUTINE;
blockScratch->flags |= dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL;
dsqlBlock = dsqlBlock->dsqlPass(blockScratch);
dsqlProcedure = FB_NEW_POOL(pool) dsql_prc(pool);
dsqlProcedure->prc_flags = PRC_subproc;
dsqlProcedure->prc_name.identifier = name;
dsqlProcedure->prc_in_count = USHORT(dsqlBlock->parameters.getCount());
dsqlProcedure->prc_out_count = USHORT(dsqlBlock->returns.getCount());
if (dsqlBlock->parameters.hasData())
{
Array<NestConst<ParameterClause> >& paramArray = dsqlBlock->parameters;
dsqlProcedure->prc_inputs = paramArray.front()->type;
for (const NestConst<ParameterClause>* i = paramArray.begin(); i != paramArray.end(); ++i)
{
const ParameterClause* param = *i;
if (param->defaultClause)
{
if (dsqlProcedure->prc_def_count == 0)
dsqlProcedure->prc_def_count = paramArray.end() - i;
}
else if (dsqlProcedure->prc_def_count != 0)
{
// Parameter without default value after parameters with default.
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_bad_default_value) <<
Arg::Gds(isc_invalid_clause) << Arg::Str("defaults must be last"));
}
}
}
if (dsqlBlock->returns.hasData())
dsqlProcedure->prc_outputs = dsqlBlock->returns.front()->type;
dsqlScratch->putSubProcedure(dsqlProcedure);
return this;
}
void DeclareSubProcNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
if (!dsqlBlock) // forward decl
return;
GEN_request(blockScratch, dsqlBlock);
dsqlScratch->appendUChar(blr_subproc_decl);
@ -2636,8 +2755,12 @@ DmlNode* ExecProcedureNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr
if (blrOp == blr_exec_subproc)
{
DeclareSubProcNode* declareNode;
if (csb->subProcedures.get(name.identifier, declareNode))
procedure = declareNode->routine;
for (auto curCsb = csb; curCsb && !procedure; curCsb = curCsb->mainCsb)
{
if (curCsb->subProcedures.get(name.identifier, declareNode))
procedure = declareNode->routine;
}
}
else
procedure = MET_lookup_procedure(tdbb, name, false);
@ -2669,7 +2792,10 @@ ExecProcedureNode* ExecProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
dsql_prc* procedure = NULL;
if (dsqlName.package.isEmpty())
procedure = dsqlScratch->getSubProcedure(dsqlName.identifier);
{
DeclareSubProcNode* subProcedure = dsqlScratch->getSubProcedure(dsqlName.identifier);
procedure = subProcedure ? subProcedure->dsqlProcedure : NULL;
}
if (!procedure)
procedure = METD_get_procedure(dsqlScratch->getTransaction(), dsqlScratch, dsqlName);
@ -2683,10 +2809,7 @@ ExecProcedureNode* ExecProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
}
if (!dsqlScratch->isPsql())
{
dsqlScratch->procedure = procedure;
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_EXEC_PROCEDURE);
}
ExecProcedureNode* node = FB_NEW_POOL(getPool()) ExecProcedureNode(getPool(), dsqlName);
node->dsqlProcedure = procedure;
@ -2740,7 +2863,7 @@ ExecProcedureNode* ExecProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
Arg::Gds(isc_random) << Arg::Str("RETURNING_VALUES"));
}
node->outputSources = explodeOutputs(dsqlScratch, dsqlScratch->procedure);
node->outputSources = explodeOutputs(dsqlScratch, procedure);
}
if (node->outputSources)

View File

@ -420,6 +420,9 @@ public:
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_SUBFUNC>(pool),
name(pool, aName),
dsqlDeterministic(false),
dsqlParameters(pool),
dsqlReturns(pool),
dsqlSignature(pool, aName),
dsqlBlock(NULL),
blockScratch(NULL),
dsqlFunction(NULL),
@ -451,6 +454,9 @@ private:
public:
Firebird::MetaName name;
bool dsqlDeterministic;
Firebird::Array<NestConst<ParameterClause> > dsqlParameters;
Firebird::Array<NestConst<ParameterClause> > dsqlReturns;
Signature dsqlSignature;
NestConst<ExecBlockNode> dsqlBlock;
DsqlCompilerScratch* blockScratch;
dsql_udf* dsqlFunction;
@ -467,6 +473,9 @@ public:
explicit DeclareSubProcNode(MemoryPool& pool, const Firebird::MetaName& aName)
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_SUBPROC>(pool),
name(pool, aName),
dsqlParameters(pool),
dsqlReturns(pool),
dsqlSignature(pool, aName),
dsqlBlock(NULL),
blockScratch(NULL),
dsqlProcedure(NULL),
@ -497,6 +506,9 @@ private:
public:
Firebird::MetaName name;
Firebird::Array<NestConst<ParameterClause> > dsqlParameters;
Firebird::Array<NestConst<ParameterClause> > dsqlReturns;
Signature dsqlSignature;
NestConst<ExecBlockNode> dsqlBlock;
DsqlCompilerScratch* blockScratch;
dsql_prc* dsqlProcedure;

View File

@ -1000,6 +1000,196 @@ private:
int scale;
};
struct SignatureParameter
{
explicit SignatureParameter(MemoryPool& p)
: type(0),
number(0),
name(p),
fieldSource(p),
fieldName(p),
relationName(p),
charSetName(p),
collationName(p),
subTypeName(p),
mechanism(0)
{
}
SignatureParameter(MemoryPool& p, const SignatureParameter& o)
: type(o.type),
number(o.number),
name(p, o.name),
fieldSource(p, o.fieldSource),
fieldName(p, o.fieldName),
relationName(p, o.relationName),
charSetName(p, o.charSetName),
collationName(p, o.collationName),
subTypeName(p, o.subTypeName),
collationId(o.collationId),
nullFlag(o.nullFlag),
mechanism(o.mechanism),
fieldLength(o.fieldLength),
fieldScale(o.fieldScale),
fieldType(o.fieldType),
fieldSubType(o.fieldSubType),
fieldSegmentLength(o.fieldSegmentLength),
fieldNullFlag(o.fieldNullFlag),
fieldCharLength(o.fieldCharLength),
fieldCollationId(o.fieldCollationId),
fieldCharSetId(o.fieldCharSetId),
fieldPrecision(o.fieldPrecision)
{
}
void fromType(const TypeClause* type)
{
fieldType = type->dtype;
fieldScale = type->scale;
subTypeName = type->subTypeName;
fieldSubType = type->subType;
fieldLength = type->length;
fieldCharLength = type->charLength;
charSetName = type->charSet;
fieldCharSetId = type->charSetId;
collationName = type->collate;
fieldCollationId = type->collationId;
fieldSource = type->fieldSource;
fieldName = type->typeOfName;
relationName = type->typeOfTable;
fieldSegmentLength = type->segLength;
fieldPrecision = type->precision;
nullFlag = (SSHORT) type->notNull;
mechanism = (SSHORT) type->fullDomain;
}
SSHORT type;
SSHORT number;
Firebird::MetaName name;
Firebird::MetaName fieldSource;
Firebird::MetaName fieldName;
Firebird::MetaName relationName;
Firebird::MetaName charSetName;
Firebird::MetaName collationName;
Firebird::MetaName subTypeName;
Nullable<SSHORT> collationId;
Nullable<SSHORT> nullFlag;
SSHORT mechanism;
Nullable<SSHORT> fieldLength;
Nullable<SSHORT> fieldScale;
Nullable<SSHORT> fieldType;
Nullable<SSHORT> fieldSubType;
Nullable<SSHORT> fieldSegmentLength;
Nullable<SSHORT> fieldNullFlag;
Nullable<SSHORT> fieldCharLength;
Nullable<SSHORT> fieldCollationId;
Nullable<SSHORT> fieldCharSetId;
Nullable<SSHORT> fieldPrecision;
bool operator >(const SignatureParameter& o) const
{
return type > o.type || (type == o.type && number > o.number);
}
bool operator ==(const SignatureParameter& o) const
{
return type == o.type && number == o.number && name == o.name &&
(fieldSource == o.fieldSource ||
(fb_utils::implicit_domain(fieldSource.c_str()) &&
fb_utils::implicit_domain(o.fieldSource.c_str()))) &&
fieldName == o.fieldName && relationName == o.relationName &&
collationId == o.collationId && nullFlag == o.nullFlag &&
mechanism == o.mechanism && fieldLength == o.fieldLength &&
fieldScale == o.fieldScale && fieldType == o.fieldType &&
fieldSubType == o.fieldSubType && fieldSegmentLength == o.fieldSegmentLength &&
fieldNullFlag == o.fieldNullFlag && fieldCharLength == o.fieldCharLength &&
charSetName == o.charSetName && collationName == o.collationName && subTypeName == o.subTypeName &&
fieldCollationId == o.fieldCollationId && fieldCharSetId == o.fieldCharSetId &&
fieldPrecision == o.fieldPrecision;
}
bool operator !=(const SignatureParameter& o) const
{
return !(*this == o);
}
};
struct Signature
{
const static unsigned FLAG_DETERMINISTIC = 0x01;
Signature(MemoryPool& p, const Firebird::MetaName& aName)
: name(p, aName),
parameters(p),
flags(0),
defined(false)
{
}
explicit Signature(const Firebird::MetaName& aName)
: name(aName),
parameters(*getDefaultMemoryPool()),
flags(0),
defined(false)
{
}
explicit Signature(MemoryPool& p)
: name(p),
parameters(p),
flags(0),
defined(false)
{
}
Signature(MemoryPool& p, const Signature& o)
: name(p, o.name),
parameters(p),
flags(o.flags),
defined(o.defined)
{
for (Firebird::SortedObjectsArray<SignatureParameter>::const_iterator i = o.parameters.begin();
i != o.parameters.end();
++i)
{
parameters.add(*i);
}
}
bool operator >(const Signature& o) const
{
return name > o.name;
}
bool operator ==(const Signature& o) const
{
if (name != o.name || flags != o.flags || parameters.getCount() != o.parameters.getCount())
return false;
for (Firebird::SortedObjectsArray<SignatureParameter>::const_iterator i = parameters.begin(),
j = o.parameters.begin();
i != parameters.end();
++i, ++j)
{
if (*i != *j)
return false;
}
return true;
}
bool operator !=(const Signature& o) const
{
return !(*this == o);
}
Firebird::MetaName name;
Firebird::SortedObjectsArray<SignatureParameter> parameters;
unsigned flags;
bool defined;
};
} // namespace
/*! \var unsigned DSQL_debug

View File

@ -1 +1 @@
46 shift/reduce conflicts, 17 reduce/reduce conflicts.
54 shift/reduce conflicts, 17 reduce/reduce conflicts.

View File

@ -2539,7 +2539,7 @@ procedure_clause
%type <createAlterProcedureNode> psql_procedure_clause
psql_procedure_clause
: procedure_clause_start sql_security_clause AS local_declaration_list full_proc_block
: procedure_clause_start sql_security_clause AS local_declarations_opt full_proc_block
{
$$ = $1;
$$->ssDefiner = $2;
@ -2670,7 +2670,7 @@ function_clause
%type <createAlterFunctionNode> psql_function_clause
psql_function_clause
: function_clause_start sql_security_clause AS local_declaration_list full_proc_block
: function_clause_start sql_security_clause AS local_declarations_opt full_proc_block
{
$$ = $1;
$$->ssDefiner = $2;
@ -2869,73 +2869,131 @@ package_body_item
;
%type <compoundStmtNode> local_declaration_list
local_declaration_list
: /* nothing */ { $$ = NULL; }
| local_declarations
%type <compoundStmtNode> local_declarations_opt
local_declarations_opt
: local_forward_declarations_opt local_nonforward_declarations_opt
{
CompoundStmtNode* forward = $1;
CompoundStmtNode* nonForward = $2;
if (!forward)
$$ = nonForward;
else
{
if (nonForward)
forward->statements.add(nonForward->statements.begin(), nonForward->statements.getCount());
$$ = forward;
}
}
;
%type <compoundStmtNode> local_declarations
local_declarations
: local_declaration
%type <compoundStmtNode> local_forward_declarations_opt
local_forward_declarations_opt
: /* nothing */ { $$ = NULL; }
| local_forward_declarations
;
%type <compoundStmtNode> local_forward_declarations
local_forward_declarations
: local_forward_declaration
{
$$ = newNode<CompoundStmtNode>();
$$->statements.add($1);
}
| local_declarations local_declaration
| local_forward_declarations local_forward_declaration
{
$1->statements.add($2);
$$ = $1;
}
;
%type <stmtNode> local_declaration
local_declaration
%type <stmtNode> local_forward_declaration
local_forward_declaration
: local_declaration_subproc_start ';' { $$ = $1; }
| local_declaration_subfunc_start ';' { $$ = $1; }
;
%type <compoundStmtNode> local_nonforward_declarations_opt
local_nonforward_declarations_opt
: /* nothing */ { $$ = NULL; }
| local_nonforward_declarations
;
%type <compoundStmtNode> local_nonforward_declarations
local_nonforward_declarations
: local_nonforward_declaration
{
$$ = newNode<CompoundStmtNode>();
$$->statements.add($1);
}
| local_nonforward_declarations local_nonforward_declaration
{
$1->statements.add($2);
$$ = $1;
}
;
%type <stmtNode> local_nonforward_declaration
local_nonforward_declaration
: DECLARE var_decl_opt local_declaration_item ';'
{
$$ = $3;
$$->line = YYPOSNARG(1).firstLine;
$$->column = YYPOSNARG(1).firstColumn;
}
| DECLARE PROCEDURE symbol_procedure_name
{ $<execBlockNode>$ = newNode<ExecBlockNode>(); }
input_parameters(NOTRIAL(&$<execBlockNode>4->parameters))
output_parameters(NOTRIAL(&$<execBlockNode>4->returns)) AS
local_declaration_list
full_proc_block
| local_declaration_subproc_start AS local_declarations_opt full_proc_block
{
DeclareSubProcNode* node = newNode<DeclareSubProcNode>(*$3);
node->dsqlBlock = $<execBlockNode>4;
node->dsqlBlock->localDeclList = $8;
node->dsqlBlock->body = $9;
DeclareSubProcNode* node = $1;
node->dsqlBlock = newNode<ExecBlockNode>();
node->dsqlBlock->parameters = node->dsqlParameters;
node->dsqlBlock->returns = node->dsqlReturns;
node->dsqlBlock->localDeclList = $3;
node->dsqlBlock->body = $4;
for (FB_SIZE_T i = 0; i < node->dsqlBlock->parameters.getCount(); ++i)
node->dsqlBlock->parameters[i]->parameterExpr = make_parameter();
$$ = node;
}
| DECLARE FUNCTION symbol_UDF_name
{ $<execBlockNode>$ = newNode<ExecBlockNode>(); }
input_parameters(NOTRIAL(&$<execBlockNode>4->parameters))
RETURNS domain_or_non_array_type collate_clause deterministic_opt AS
local_declaration_list
full_proc_block
| local_declaration_subfunc_start AS local_declarations_opt full_proc_block
{
DeclareSubFuncNode* node = newNode<DeclareSubFuncNode>(*$3);
node->dsqlDeterministic = $9;
node->dsqlBlock = $<execBlockNode>4;
node->dsqlBlock->localDeclList = $11;
node->dsqlBlock->body = $12;
DeclareSubFuncNode* node = $1;
node->dsqlBlock = newNode<ExecBlockNode>();
node->dsqlBlock->parameters = node->dsqlParameters;
node->dsqlBlock->returns = node->dsqlReturns;
node->dsqlBlock->localDeclList = $3;
node->dsqlBlock->body = $4;
for (FB_SIZE_T i = 0; i < node->dsqlBlock->parameters.getCount(); ++i)
node->dsqlBlock->parameters[i]->parameterExpr = make_parameter();
node->dsqlBlock->returns.add(newNode<ParameterClause>($<legacyField>7, optName($8)));
$$ = node;
}
;
%type <declareSubProcNode> local_declaration_subproc_start
local_declaration_subproc_start
: DECLARE PROCEDURE symbol_procedure_name
{ $$ = newNode<DeclareSubProcNode>(NOTRIAL(*$3)); }
input_parameters(NOTRIAL(&$4->dsqlParameters))
output_parameters(NOTRIAL(&$4->dsqlReturns))
{ $$ = $4; }
;
%type <declareSubFuncNode> local_declaration_subfunc_start
local_declaration_subfunc_start
: DECLARE FUNCTION symbol_UDF_name
{ $$ = newNode<DeclareSubFuncNode>(NOTRIAL(*$3)); }
input_parameters(NOTRIAL(&$4->dsqlParameters))
RETURNS domain_or_non_array_type collate_clause deterministic_opt
{
$$ = $4;
$$->dsqlReturns.add(newNode<ParameterClause>($<legacyField>7, optName($8)));
$$->dsqlDeterministic = $9;
}
;
%type <stmtNode> local_declaration_item
local_declaration_item
: var_declaration_item
@ -3526,7 +3584,7 @@ exec_block
{ $<execBlockNode>$ = newNode<ExecBlockNode>(); }
block_input_params(NOTRIAL(&$3->parameters))
output_parameters(NOTRIAL(&$3->returns)) AS
local_declaration_list
local_declarations_opt
full_proc_block
{
ExecBlockNode* node = $3;
@ -3597,7 +3655,7 @@ check_opt
%type <createAlterTriggerNode> trigger_clause
trigger_clause
: create_trigger_start trg_sql_security_clause AS local_declaration_list full_proc_block
: create_trigger_start trg_sql_security_clause AS local_declarations_opt full_proc_block
{
$$ = $1;
$$->ssDefiner = $2;
@ -4244,7 +4302,7 @@ crypt_key_clause($alterDatabaseNode)
%type <createAlterTriggerNode> alter_trigger_clause
alter_trigger_clause
: symbol_trigger_name trigger_active trigger_type_opt trigger_position trg_sql_security_clause
AS local_declaration_list full_proc_block
AS local_declarations_opt full_proc_block
{
$$ = newNode<CreateAlterTriggerNode>(*$1);
$$->alter = true;
@ -7651,7 +7709,6 @@ system_function_std_syntax
| EXP
| FLOOR
| GEN_UUID
| HASH
| LEFT
| LN
| LOG
@ -7711,6 +7768,14 @@ system_function_special_syntax
newNode<ValueListNode>(MAKE_const_slong($3))->add($5)->add($7));
$$->dsqlSpecialSyntax = true;
}
| HASH '(' value ')'
{ $$ = newNode<SysFuncCallNode>(*$1, newNode<ValueListNode>($3)); }
| HASH '(' value USING valid_symbol_name ')'
{
$$ = newNode<SysFuncCallNode>(*$1,
newNode<ValueListNode>($3)->add(MAKE_str_constant(newIntlString($5->c_str()), CS_ASCII)));
$$->dsqlSpecialSyntax = true;
}
| OVERLAY '(' value PLACING value FROM value FOR value ')'
{
$$ = newNode<SysFuncCallNode>(*$1,

View File

@ -367,7 +367,10 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
else if (procNode && (procNode->dsqlName.package.hasData() || procNode->sourceList))
{
if (procNode->dsqlName.package.isEmpty())
procedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier);
{
DeclareSubProcNode* subProcedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier);
procedure = subProcedure ? subProcedure->dsqlProcedure : NULL;
}
if (!procedure)
{
@ -390,7 +393,10 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
else
{
if (procNode && procNode->dsqlName.package.isEmpty())
procedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier);
{
DeclareSubProcNode* subProcedure = dsqlScratch->getSubProcedure(procNode->dsqlName.identifier);
procedure = subProcedure ? subProcedure->dsqlProcedure : NULL;
}
if (!procedure)
relation = METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, relation_name);

View File

@ -148,6 +148,7 @@
<address-element> ::=
isc_dpb_addr_protocol <byte-clumplet-length> <protocol-string> |
isc_dpb_addr_endpoint <byte-clumplet-length> <remote-endpoint-string>
isc_dpb_addr_flags <byte-clumplet-length> <flags-int>
<protocol-string> ::=
"TCPv4" |
@ -161,12 +162,20 @@
<IPv6-address> | // such as "2001:0:13FF:09FF::1"
<xnet-process-id> | // such as "17864"
...
<flags-int> ::=
bitmask of possible flags
*/
#define isc_dpb_address 1
#define isc_dpb_addr_protocol 1
#define isc_dpb_addr_endpoint 2
#define isc_dpb_addr_flags 3
/* possible addr flags */
#define isc_dpb_addr_flag_conn_compressed 0x01
#define isc_dpb_addr_flag_conn_encrypted 0x02
/*********************************/
/* isc_dpb_verify specific flags */

View File

@ -1080,6 +1080,9 @@ interface TraceParams : Versioned
{
uint getCount();
const dsc* getParam(uint idx);
version:
const string getTextUTF8(Status status, uint idx);
}
interface TraceStatement : Versioned

View File

@ -4259,6 +4259,7 @@ namespace Firebird
{
unsigned (CLOOP_CARG *getCount)(ITraceParams* self) throw();
const dsc* (CLOOP_CARG *getParam)(ITraceParams* self, unsigned idx) throw();
const char* (CLOOP_CARG *getTextUTF8)(ITraceParams* self, IStatus* status, unsigned idx) throw();
};
protected:
@ -4272,7 +4273,7 @@ namespace Firebird
}
public:
static const unsigned VERSION = 2;
static const unsigned VERSION = 3;
unsigned getCount()
{
@ -4285,6 +4286,20 @@ namespace Firebird
const dsc* ret = static_cast<VTable*>(this->cloopVTable)->getParam(this, idx);
return ret;
}
template <typename StatusType> const char* getTextUTF8(StatusType* status, unsigned idx)
{
if (cloopVTable->version < 3)
{
StatusType::setVersionError(status, "ITraceParams", cloopVTable->version, 3);
StatusType::checkException(status);
return 0;
}
StatusType::clearException(status);
const char* ret = static_cast<VTable*>(this->cloopVTable)->getTextUTF8(this, status, idx);
StatusType::checkException(status);
return ret;
}
};
class ITraceStatement : public IVersioned
@ -14254,6 +14269,7 @@ namespace Firebird
this->version = Base::VERSION;
this->getCount = &Name::cloopgetCountDispatcher;
this->getParam = &Name::cloopgetParamDispatcher;
this->getTextUTF8 = &Name::cloopgetTextUTF8Dispatcher;
}
} vTable;
@ -14285,6 +14301,21 @@ namespace Firebird
return static_cast<const dsc*>(0);
}
}
static const char* CLOOP_CARG cloopgetTextUTF8Dispatcher(ITraceParams* self, IStatus* status, unsigned idx) throw()
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::getTextUTF8(&status2, idx);
}
catch (...)
{
StatusType::catchException(&status2);
return static_cast<const char*>(0);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<ITraceParams> > >
@ -14302,6 +14333,7 @@ namespace Firebird
virtual unsigned getCount() = 0;
virtual const dsc* getParam(unsigned idx) = 0;
virtual const char* getTextUTF8(StatusType* status, unsigned idx) = 0;
};
template <typename Name, typename StatusType, typename Base>

View File

@ -330,13 +330,13 @@ public:
{
CheckStatusWrapper statusWrapper(status);
if (!run(&statusWrapper, plugin, &IUdrPlugin::registerFunction, regFunctions))
if (!run<IUdrFunctionFactory>(&statusWrapper, plugin, &IUdrPlugin::registerFunction, regFunctions))
return;
if (!run(&statusWrapper, plugin, &IUdrPlugin::registerProcedure, regProcedures))
if (!run<IUdrProcedureFactory>(&statusWrapper, plugin, &IUdrPlugin::registerProcedure, regProcedures))
return;
if (!run(&statusWrapper, plugin, &IUdrPlugin::registerTrigger, regTriggers))
if (!run<IUdrTriggerFactory>(&statusWrapper, plugin, &IUdrPlugin::registerTrigger, regTriggers))
return;
}

View File

@ -845,6 +845,15 @@ static const struct {
{"decfloat_invalid_operation", 335545141},
{"decfloat_overflow", 335545142},
{"decfloat_underflow", 335545143},
{"subfunc_notdef", 335545144},
{"subproc_notdef", 335545145},
{"subfunc_signat", 335545146},
{"subproc_signat", 335545147},
{"subfunc_defvaldecl", 335545148},
{"subproc_defvaldecl", 335545149},
{"subfunc_not_impl", 335545150},
{"subproc_not_impl", 335545151},
{"sysf_invalid_hash_algorithm", 335545152},
{"gfix_db_name", 335740929},
{"gfix_invalid_sw", 335740930},
{"gfix_incmp_sw", 335740932},

View File

@ -879,6 +879,15 @@ const ISC_STATUS isc_decfloat_inexact_result = 335545140L;
const ISC_STATUS isc_decfloat_invalid_operation = 335545141L;
const ISC_STATUS isc_decfloat_overflow = 335545142L;
const ISC_STATUS isc_decfloat_underflow = 335545143L;
const ISC_STATUS isc_subfunc_notdef = 335545144L;
const ISC_STATUS isc_subproc_notdef = 335545145L;
const ISC_STATUS isc_subfunc_signat = 335545146L;
const ISC_STATUS isc_subproc_signat = 335545147L;
const ISC_STATUS isc_subfunc_defvaldecl = 335545148L;
const ISC_STATUS isc_subproc_defvaldecl = 335545149L;
const ISC_STATUS isc_subfunc_not_impl = 335545150L;
const ISC_STATUS isc_subproc_not_impl = 335545151L;
const ISC_STATUS isc_sysf_invalid_hash_algorithm = 335545152L;
const ISC_STATUS isc_gfix_db_name = 335740929L;
const ISC_STATUS isc_gfix_invalid_sw = 335740930L;
const ISC_STATUS isc_gfix_incmp_sw = 335740932L;
@ -1353,7 +1362,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
const ISC_STATUS isc_err_max = 1297;
const ISC_STATUS isc_err_max = 1306;
#else /* c definitions */
@ -2202,6 +2211,15 @@ const ISC_STATUS isc_err_max = 1297;
#define isc_decfloat_invalid_operation 335545141L
#define isc_decfloat_overflow 335545142L
#define isc_decfloat_underflow 335545143L
#define isc_subfunc_notdef 335545144L
#define isc_subproc_notdef 335545145L
#define isc_subfunc_signat 335545146L
#define isc_subproc_signat 335545147L
#define isc_subfunc_defvaldecl 335545148L
#define isc_subproc_defvaldecl 335545149L
#define isc_subfunc_not_impl 335545150L
#define isc_subproc_not_impl 335545151L
#define isc_sysf_invalid_hash_algorithm 335545152L
#define isc_gfix_db_name 335740929L
#define isc_gfix_invalid_sw 335740930L
#define isc_gfix_incmp_sw 335740932L
@ -2676,7 +2694,7 @@ const ISC_STATUS isc_err_max = 1297;
#define isc_trace_switch_param_miss 337182758L
#define isc_trace_param_act_notcompat 337182759L
#define isc_trace_mandatory_switch_miss 337182760L
#define isc_err_max 1297
#define isc_err_max 1306
#endif

View File

@ -521,6 +521,8 @@
const USHORT f_mon_att_idle_timeout = 20;
const USHORT f_mon_att_idle_timer = 21;
const USHORT f_mon_att_stmt_timeout = 22;
const USHORT f_mon_att_conn_compressed = 23;
const USHORT f_mon_att_conn_encrypted = 24;
// Relation 35 (MON$TRANSACTIONS)

View File

@ -848,6 +848,15 @@ Data source : @4"}, /* eds_statement */
{335545141, "Decimal float invalid operation. An indeterminant error occurred during an operation."}, /* decfloat_invalid_operation */
{335545142, "Decimal float overflow. The exponent of a result is greater than the magnitude allowed."}, /* decfloat_overflow */
{335545143, "Decimal float underflow. The exponent of a result is less than the magnitude allowed."}, /* decfloat_underflow */
{335545144, "Sub-function @1 has not been defined"}, /* subfunc_notdef */
{335545145, "Sub-procedure @1 has not been defined"}, /* subproc_notdef */
{335545146, "Sub-function @1 has a signature mismatch with its forward declaration"}, /* subfunc_signat */
{335545147, "Sub-procedure @1 has a signature mismatch with its forward declaration"}, /* subproc_signat */
{335545148, "Default values for parameters are not allowed in definition of the previously declared sub-function @1"}, /* subfunc_defvaldecl */
{335545149, "Default values for parameters are not allowed in definition of the previously declared sub-procedure @1"}, /* subproc_defvaldecl */
{335545150, "Sub-function @1 was declared but not implemented"}, /* subfunc_not_impl */
{335545151, "Sub-procedure @1 was declared but not implemented"}, /* subproc_not_impl */
{335545152, "Invalid HASH algorithm @1"}, /* sysf_invalid_hash_algorithm */
{335740929, "data base file name (@1) already given"}, /* gfix_db_name */
{335740930, "invalid switch @1"}, /* gfix_invalid_sw */
{335740932, "incompatible switch combination"}, /* gfix_incmp_sw */
@ -976,7 +985,7 @@ Data source : @4"}, /* eds_statement */
{336068872, "Procedure @1 has not been defined on the package body @2"}, /* dyn_procnotdef_package */
{336068873, "Function @1 has a signature mismatch on package body @2"}, /* dyn_funcsignat_package */
{336068874, "Procedure @1 has a signature mismatch on package body @2"}, /* dyn_procsignat_package */
{336068875, "Default values for parameters are allowed only in declaration of packaged procedure @1.@2"}, /* dyn_defvaldecl_package_proc */
{336068875, "Default values for parameters are not allowed in the definition of a previously declared packaged procedure @1.@2"}, /* dyn_defvaldecl_package_proc */
{336068877, "Package body @1 already exists"}, /* dyn_package_body_exists */
{336068878, "Invalid DDL statement for function @1"}, /* dyn_invalid_ddl_func */
{336068879, "Cannot alter new style function @1 with ALTER EXTERNAL FUNCTION. Use ALTER FUNCTION instead."}, /* dyn_newfc_oldsyntax */
@ -990,7 +999,7 @@ Data source : @4"}, /* eds_statement */
{336068895, "System @1 @2 cannot be modified"}, /* dyn_cant_modify_sysobj */
{336068896, "INCREMENT BY 0 is an illegal option for sequence @1"}, /* dyn_cant_use_zero_increment */
{336068897, "Can't use @1 in FOREIGN KEY constraint"}, /* dyn_cant_use_in_foreignkey */
{336068898, "Default values for parameters are allowed only in declaration of packaged function @1.@2"}, /* dyn_defvaldecl_package_func */
{336068898, "Default values for parameters are not allowed in the definition of a previously declared packaged function @1.@2"}, /* dyn_defvaldecl_package_func */
{336068904, "INCREMENT BY 0 is an illegal option for identity column @1 of table @2"}, /* dyn_cant_use_zero_inc_ident */
{336330753, "found unknown switch"}, /* gbak_unknown_switch */
{336330754, "page size parameter missing"}, /* gbak_page_size_missing */

View File

@ -844,6 +844,15 @@ static const struct {
{335545141, -901}, /* 821 decfloat_invalid_operation */
{335545142, -901}, /* 822 decfloat_overflow */
{335545143, -901}, /* 823 decfloat_underflow */
{335545144, -901}, /* 824 subfunc_notdef */
{335545145, -901}, /* 825 subproc_notdef */
{335545146, -901}, /* 826 subfunc_signat */
{335545147, -901}, /* 827 subproc_signat */
{335545148, -901}, /* 828 subfunc_defvaldecl */
{335545149, -901}, /* 829 subproc_defvaldecl */
{335545150, -901}, /* 830 subfunc_not_impl */
{335545151, -901}, /* 831 subproc_not_impl */
{335545152, -901}, /* 832 sysf_invalid_hash_algorithm */
{335740929, -901}, /* 1 gfix_db_name */
{335740930, -901}, /* 2 gfix_invalid_sw */
{335740932, -901}, /* 4 gfix_incmp_sw */

View File

@ -844,6 +844,15 @@ static const struct {
{335545141, "22000"}, // 821 decfloat_invalid_operation
{335545142, "22003"}, // 822 decfloat_overflow
{335545143, "22003"}, // 823 decfloat_underflow
{335545144, "42000"}, // 824 subfunc_notdef
{335545145, "42000"}, // 825 subproc_notdef
{335545146, "42000"}, // 826 subfunc_signat
{335545147, "42000"}, // 827 subproc_signat
{335545148, "42000"}, // 828 subfunc_defvaldecl
{335545149, "42000"}, // 829 subproc_defvaldecl
{335545150, "42000"}, // 830 subfunc_not_impl
{335545151, "42000"}, // 831 subproc_not_impl
{335545152, "42000"}, // 832 sysf_invalid_hash_algorithm
{335740929, "00000"}, // 1 gfix_db_name
{335740930, "00000"}, // 2 gfix_invalid_sw
{335740932, "00000"}, // 4 gfix_incmp_sw

View File

@ -395,8 +395,7 @@ static processing_state print_performance(const SINT64* perf_before);
static void print_message(Firebird::IMessageMetadata* msg, const char* dir);
static void process_header(Firebird::IMessageMetadata*, const unsigned pad[], TEXT header[], TEXT header2[]);
static void process_plan();
static SINT64 process_record_count(const int statement_type);
static int process_request_type();
static SINT64 process_record_count(const unsigned statement_type);
static unsigned process_message_display(Firebird::IMessageMetadata* msg, unsigned pad[]);
static processing_state process_statement(const TEXT*);
#ifdef WIN_NT
@ -2703,7 +2702,7 @@ static processing_state bulk_insert_hack(const char* command)
ISQL_warning(fbStatus);
// Find out what kind of statement this is
const int statement_type = process_request_type();
const unsigned statement_type = global_Stmt->getType(fbStatus);
if (!statement_type)
return ps_ERR;
@ -6982,7 +6981,7 @@ static bool checkSpecial(TEXT* const p, const int length, const double value)
if (isnan(value))
t = "NaN";
else if (isinf(value))
t = "Infinity";
t = Firebird::isNegativeInf(value) ? "-Infinity" : "Infinity";
else
return false;
@ -7705,7 +7704,7 @@ static processing_state print_performance(const SINT64* perf_before)
{
TEXT report_1[MSG_LENGTH];
IUTILS_msg_get(REPORT_NEW1, report_1);
// Current memory = !\nDelta memory = !\nMax memory = !\nElapsed time= ~ sec\n
// Current memory = !\nDelta memory = !\nMax memory = !\nElapsed time = ~ sec\n
diag->assign(report_1);
#ifndef WIN_NT
@ -7933,7 +7932,7 @@ static void process_plan()
// Get number of records affected for updates, deletions and insertions.
// Return -1 if the statement is not one of those or if there's an error
// retrieving the information from the server.
static SINT64 process_record_count(const int statement_type)
static SINT64 process_record_count(const unsigned statement_type)
{
if (!global_Stmt)
return -1;
@ -7988,34 +7987,6 @@ static SINT64 process_record_count(const int statement_type)
}
// ***************************************
// p r o c e s s _ r e q u e s t _ t y p e
// ***************************************
// Retrieve the statement type according to the DSQL layer.
// A failure is indicated by returning zero.
static int process_request_type()
{
if (!global_Stmt)
return 0;
const UCHAR sqlda_info[] = { isc_info_sql_stmt_type };
UCHAR info_buffer[16];
global_Stmt->getInfo(fbStatus, sizeof(sqlda_info), sqlda_info, sizeof(info_buffer), info_buffer);
if (!ISQL_errmsg(fbStatus))
{
if (info_buffer[0] == isc_info_sql_stmt_type)
{
const UCHAR* b = info_buffer;
const SSHORT len = gds__vax_integer(b + 1, 2);
return gds__vax_integer(b + 3, len);
}
//IUTILS_msg_get(UNKNOWN_STATEMENT_TYPE, errmsg);
STDERROUT("Cannot determine statement type");
}
return 0;
}
// *********************************************
// p r o c e s s _ m e s s a g e _ d i s p l a y
// *********************************************
@ -8261,7 +8232,7 @@ static processing_state process_statement(const TEXT* str2)
setValues.StmtTimeout = 0;
// Find out what kind of statement this is
const int statement_type = process_request_type();
const unsigned statement_type = global_Stmt->getType(fbStatus);
if (!statement_type)
return ps_ERR;

View File

@ -140,7 +140,7 @@ const int HLP_QUIT = 40; // QUIT -- Exit program and rollback changes\n\n
const int HLP_ALL = 41; // All commands may be abbreviated to letters in CAPs\n
const int HLP_SETSCHEMA = 42; // \tSET SCHema/DB <db name> -- changes current database\n
const int YES_ANS = 43; // Yes
const int REPORT1 = 44; // Current memory = !c\nDelta memory = !d\nMax memory = !x\nElapsed time= !e sec\n
const int REPORT1 = 44; // Current memory = !c\nDelta memory = !d\nMax memory = !x\nElapsed time = !e sec\n
#if (defined WIN_NT)
const int REPORT2 = 93; // Buffers = !b\nReads = !r\nWrites = !w\nFetches = !f\n
#else
@ -255,7 +255,7 @@ const int NO_GRANT_ON_CS = 177; // There is no privilege granted on character
const int NO_GRANT_ON_COLL = 178; // There is no privilege granted on collation @1 in this database
const int NO_GRANT_ON_PKG = 179; // There is no privilege granted on package @1 in this database
const int NO_GRANT_ON_FUN = 180; // There is no privilege granted on function @1 in this database
const int REPORT_NEW1 = 181; // Current memory = !\nDelta memory = !\nMax memory = !\nElapsed time= ~ sec\n
const int REPORT_NEW1 = 181; // Current memory = !\nDelta memory = !\nMax memory = !\nElapsed time = ~ sec\n
const int REPORT_NEW2 = 182; // Cpu = ~ sec\n (skipped on windows)
const int REPORT_NEW3 = 183; // Buffers = !\nReads = !\nWrites = !\nFetches = !\n
const int NO_MAP = 184; // There is no mapping from @1 in this database

View File

@ -316,6 +316,7 @@ public:
Firebird::string att_network_protocol; // Network protocol used by client for connection
Firebird::string att_remote_address; // Protocol-specific address of remote client
SLONG att_remote_pid; // Process id of remote client
ULONG att_remote_flags; // Flags specific for server/client link
Firebird::PathName att_remote_process; // Process name of remote client
Firebird::string att_client_version; // Version of the client library
Firebird::string att_remote_protocol; // Details about the remote protocol

View File

@ -395,6 +395,18 @@ namespace Jrd {
checkDigitalSignature(tdbb, hdr);
}
void CryptoManager::setDbInfo(IDbCryptPlugin* cp)
{
FbLocalStatus status;
cp->setInfo(&status, dbInfo);
if (status->getState() & IStatus::STATE_ERRORS)
{
const ISC_STATUS* v = status->getErrors();
if (v[0] == isc_arg_gds && v[1] != isc_arg_end && v[1] != isc_interface_version_too_old)
status_exception::raise(&status);
}
}
void CryptoManager::loadPlugin(thread_db* tdbb, const char* pluginName)
{
if (cryptPlugin)
@ -416,15 +428,7 @@ namespace Jrd {
// do not assign cryptPlugin directly before key init complete
IDbCryptPlugin* p = cryptControl->plugin();
FbLocalStatus status;
p->setInfo(&status, dbInfo);
if (status->getState() & IStatus::STATE_ERRORS)
{
const ISC_STATUS* v = status->getErrors();
if (v[0] == isc_arg_gds && v[1] != isc_arg_end && v[1] != isc_interface_version_too_old)
status_exception::raise(&status);
}
setDbInfo(p);
keyHolderPlugins.init(p, keyName);
cryptPlugin = p;
@ -1321,6 +1325,7 @@ namespace Jrd {
FbLocalStatus st;
AutoPtr<IDbCryptPlugin, ReleasePlugin> crypt(mgr->checkFactory->makeInstance());
mgr->setDbInfo(crypt);
crypt->setKey(&st, keyHolder ? 1 : 0, &keyHolder, keyName.c_str());
if (st.isSuccess())

View File

@ -298,6 +298,7 @@ public:
void cryptThread();
bool checkValidation(Firebird::IDbCryptPlugin* crypt);
void setDbInfo(Firebird::IDbCryptPlugin* cp);
ULONG getCurrentPage() const;
UCHAR getCurrentState() const;

View File

@ -898,6 +898,14 @@ void Monitoring::putAttachment(SnapshotData::DumpRecord& record, const Jrd::Atta
record.storeInteger(f_mon_att_remote_pid, attachment->att_remote_pid);
// remote process name
record.storeString(f_mon_att_remote_process, attachment->att_remote_process);
// remote connection flags
if (attachment->att_remote_address.hasData())
{
record.storeBoolean(f_mon_att_conn_compressed,
attachment->att_remote_flags & isc_dpb_addr_flag_conn_compressed);
record.storeBoolean(f_mon_att_conn_encrypted,
attachment->att_remote_flags & isc_dpb_addr_flag_conn_encrypted);
}
// charset
record.storeInteger(f_mon_att_charset_id, attachment->att_charset);
// timestamp

View File

@ -910,9 +910,13 @@ ProcedureSourceNode* ProcedureSourceNode::parse(thread_db* tdbb, CompilerScratch
if (blrOp == blr_subproc)
{
DeclareSubProcNode* node;
if (csb->subProcedures.get(name.identifier, node))
procedure = node->routine;
DeclareSubProcNode* declareNode;
for (auto curCsb = csb; curCsb && !procedure; curCsb = curCsb->mainCsb)
{
if (curCsb->subProcedures.get(name.identifier, declareNode))
procedure = declareNode->routine;
}
}
else
procedure = MET_lookup_procedure(tdbb, name, false);

View File

@ -30,6 +30,7 @@
#include "firebird.h"
#include "../common/classes/VaryStr.h"
#include "../common/classes/Hash.h"
#include "../jrd/SysFunction.h"
#include "../jrd/DataTypeUtil.h"
#include "../include/fb_blk.h"
@ -100,6 +101,58 @@ enum TrigonFunction
};
struct HashAlgorithmDescriptor
{
const char* name;
USHORT length;
HashContext* (*create)(MemoryPool&);
static const HashAlgorithmDescriptor* find(const char* name);
};
template <typename T>
struct HashAlgorithmDescriptorFactory
{
static HashAlgorithmDescriptor* getInstance(const char* name, USHORT length)
{
desc.name = name;
desc.length = length;
desc.create = createContext;
return &desc;
}
static HashContext* createContext(MemoryPool& pool)
{
return FB_NEW_POOL(pool) T(pool);
}
static HashAlgorithmDescriptor desc;
};
template <typename T> HashAlgorithmDescriptor HashAlgorithmDescriptorFactory<T>::desc;
static const HashAlgorithmDescriptor* hashAlgorithmDescriptors[] = {
HashAlgorithmDescriptorFactory<Md5HashContext>::getInstance("MD5", 16),
HashAlgorithmDescriptorFactory<Sha1HashContext>::getInstance("SHA1", 20),
HashAlgorithmDescriptorFactory<Sha256HashContext>::getInstance("SHA256", 32),
HashAlgorithmDescriptorFactory<Sha512HashContext>::getInstance("SHA512", 64)
};
const HashAlgorithmDescriptor* HashAlgorithmDescriptor::find(const char* name)
{
unsigned count = FB_NELEM(hashAlgorithmDescriptors);
for (unsigned i = 0; i < count; ++i)
{
if (strcmp(name, hashAlgorithmDescriptors[i]->name) == 0)
return hashAlgorithmDescriptors[i];
}
status_exception::raise(Arg::Gds(isc_sysf_invalid_hash_algorithm) << name);
return nullptr;
}
// constants
const int oneDay = 86400;
@ -144,6 +197,7 @@ void makeBinShift(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, d
void makeCeilFloor(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
void makeDateAdd(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
void makeGetSetContext(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
void makeHash(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
void makeLeftRight(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
void makeMod(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
void makeOverlay(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
@ -900,6 +954,27 @@ void makeGetSetContext(DataTypeUtilBase* /*dataTypeUtil*/, const SysFunction* fu
}
void makeHash(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result,
int argsCount, const dsc** args)
{
fb_assert(argsCount >= function->minArgCount);
if (argsCount == 1)
makeInt64Result(dataTypeUtil, function, result, argsCount, args);
else if (argsCount >= 2)
{
if (!args[1]->dsc_address || !args[1]->isText()) // not a constant
status_exception::raise(Arg::Gds(isc_sysf_invalid_hash_algorithm) << "<not a string constant>");
MetaName algorithmName;
MOV_get_metaname(JRD_get_thread_data(), args[1], algorithmName);
result->makeVarying(HashAlgorithmDescriptor::find(algorithmName.c_str())->length, ttype_binary);
result->setNullable(args[0]->isNullable());
}
}
void makeLeftRight(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result,
int argsCount, const dsc** args)
{
@ -2639,7 +2714,7 @@ dsc* evlSetContext(thread_db* tdbb, const SysFunction*, const NestValueArray& ar
dsc* evlHash(thread_db* tdbb, const SysFunction*, const NestValueArray& args,
impure_value* impure)
{
fb_assert(args.getCount() == 1);
fb_assert(args.getCount() >= 1);
jrd_req* request = tdbb->getRequest();
@ -2647,9 +2722,27 @@ dsc* evlHash(thread_db* tdbb, const SysFunction*, const NestValueArray& args,
if (request->req_flags & req_null) // return NULL if value is NULL
return NULL;
impure->vlu_misc.vlu_int64 = 0;
AutoPtr<HashContext> hashContext;
MemoryPool& pool = *request->req_pool;
UCHAR* address;
if (args.getCount() >= 2)
{
const dsc* algorithmDesc = EVL_expr(tdbb, request, args[1]);
if (request->req_flags & req_null) // return NULL if algorithm is NULL
return NULL;
if (!algorithmDesc->isText())
status_exception::raise(Arg::Gds(isc_sysf_invalid_hash_algorithm) << "<not a string constant>");
MetaName algorithmName;
MOV_get_metaname(tdbb, algorithmDesc, algorithmName);
hashContext.reset(HashAlgorithmDescriptor::find(algorithmName.c_str())->create(pool));
}
else
{
hashContext.reset(FB_NEW_POOL(pool) WeakHashContext());
impure->vlu_misc.vlu_int64 = 0;
}
if (value->isBlob())
{
@ -2659,40 +2752,37 @@ dsc* evlHash(thread_db* tdbb, const SysFunction*, const NestValueArray& args,
while (!(blob->blb_flags & BLB_eof))
{
address = buffer;
const ULONG length = blob->BLB_get_data(tdbb, address, sizeof(buffer), false);
for (const UCHAR* end = address + length; address < end; ++address)
{
impure->vlu_misc.vlu_int64 = (impure->vlu_misc.vlu_int64 << 4) + *address;
const SINT64 n = impure->vlu_misc.vlu_int64 & FB_CONST64(0xF000000000000000);
if (n)
impure->vlu_misc.vlu_int64 ^= n >> 56;
impure->vlu_misc.vlu_int64 &= ~n;
}
const ULONG length = blob->BLB_get_data(tdbb, buffer, sizeof(buffer), false);
hashContext->update(buffer, length);
}
blob->BLB_close(tdbb);
}
else
{
UCHAR* address;
MoveBuffer buffer;
const ULONG length = MOV_make_string2(tdbb, value, value->getTextType(), &address, buffer, false);
for (const UCHAR* end = address + length; address < end; ++address)
{
impure->vlu_misc.vlu_int64 = (impure->vlu_misc.vlu_int64 << 4) + *address;
const SINT64 n = impure->vlu_misc.vlu_int64 & FB_CONST64(0xF000000000000000);
if (n)
impure->vlu_misc.vlu_int64 ^= n >> 56;
impure->vlu_misc.vlu_int64 &= ~n;
}
hashContext->update(address, length);
}
// make descriptor for return value
impure->vlu_desc.makeInt64(0, &impure->vlu_misc.vlu_int64);
HashContext::Buffer resultBuffer;
hashContext->finish(resultBuffer);
if (args.getCount() >= 2)
{
dsc result;
result.makeText(resultBuffer.getCount(), ttype_binary, resultBuffer.begin());
EVL_make_value(tdbb, &result, impure);
}
else
{
fb_assert(resultBuffer.getCount() == sizeof(SINT64));
memcpy(&impure->vlu_misc.vlu_int64, resultBuffer.begin(), sizeof(SINT64));
// make descriptor for return value
impure->vlu_desc.makeInt64(0, &impure->vlu_misc.vlu_int64);
}
return &impure->vlu_desc;
}
@ -4274,7 +4364,7 @@ const SysFunction SysFunction::functions[] =
{"EXP", 1, 1, setParamsDblDec, makeDblDecResult, evlExp, NULL},
{"FLOOR", 1, 1, setParamsDblDec, makeCeilFloor, evlFloor, NULL},
{"GEN_UUID", 0, 0, NULL, makeUuid, evlGenUuid, NULL},
{"HASH", 1, 1, NULL, makeInt64Result, evlHash, NULL},
{"HASH", 1, 2, NULL, makeHash, evlHash, NULL},
{"LEFT", 2, 2, setParamsSecondInteger, makeLeftRight, evlLeft, NULL},
{"LN", 1, 1, setParamsDblDec, makeDblDecResult, evlLnLog10, (void*) funLnat},
{"LOG", 2, 2, setParamsDblDec, makeDblDecResult, evlLog, NULL},

View File

@ -3,16 +3,16 @@
*** DO NOT EDIT ***
TO CHANGE ANY INFORMATION IN HERE PLEASE
EDIT src/misc/writeBuildNum.sh
FORMAL BUILD NUMBER:685
FORMAL BUILD NUMBER:722
*/
#define PRODUCT_VER_STRING "4.0.0.685"
#define FILE_VER_STRING "WI-T4.0.0.685"
#define LICENSE_VER_STRING "WI-T4.0.0.685"
#define FILE_VER_NUMBER 4, 0, 0, 685
#define PRODUCT_VER_STRING "4.0.0.722"
#define FILE_VER_STRING "WI-T4.0.0.722"
#define LICENSE_VER_STRING "WI-T4.0.0.722"
#define FILE_VER_NUMBER 4, 0, 0, 722
#define FB_MAJOR_VER "4"
#define FB_MINOR_VER "0"
#define FB_REV_NO "0"
#define FB_BUILD_NO "685"
#define FB_BUILD_NO "722"
#define FB_BUILD_TYPE "T"
#define FB_BUILD_SUFFIX "Firebird 4.0 Alpha 1"

View File

@ -427,7 +427,7 @@ public:
SLONG subNumber;
};
explicit CompilerScratch(MemoryPool& p)
explicit CompilerScratch(MemoryPool& p, CompilerScratch* aMainCsb = NULL)
: /*csb_node(0),
csb_variables(0),
csb_dependencies(0),
@ -439,6 +439,7 @@ public:
#ifdef CMP_DEBUG
csb_dump(p),
#endif
mainCsb(aMainCsb),
csb_external(p),
csb_access(p),
csb_resources(p),
@ -486,6 +487,7 @@ public:
Firebird::string csb_dump;
#endif
CompilerScratch* mainCsb;
Firebird::BlrReader csb_blr_reader;
DmlNode* csb_node;
ExternalAccessList csb_external; // Access to outside procedures/triggers to be checked

View File

@ -769,6 +769,10 @@ void INF_database_info(thread_db* tdbb,
dbb->dbb_crypto_manager->getCurrentState() : 0, buffer);
break;
case fb_info_conn_flags:
length = INF_convert(tdbb->getAttachment()->att_remote_flags, buffer);
break;
case fb_info_statement_timeout_db:
length = INF_convert(dbb->dbb_config->getStatementTimeout(), buffer);
break;

View File

@ -142,12 +142,14 @@ enum db_info_types
fb_info_crypt_state = 126,
fb_info_statement_timeout_db,
fb_info_statement_timeout_att,
fb_info_statement_timeout_db = 127,
fb_info_statement_timeout_att = 128,
fb_info_ses_idle_timeout_db,
fb_info_ses_idle_timeout_att,
fb_info_ses_idle_timeout_run,
fb_info_ses_idle_timeout_db = 129,
fb_info_ses_idle_timeout_att = 130,
fb_info_ses_idle_timeout_run = 131,
fb_info_conn_flags = 132,
isc_info_db_last_value /* Leave this LAST! */
};

View File

@ -949,6 +949,7 @@ public:
bool dpb_nolinger;
bool dpb_reset_icu;
bool dpb_map_attach;
ULONG dpb_remote_flags;
// here begin compound objects
// for constructor to work properly dpb_user_name
@ -6108,6 +6109,9 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
case isc_dpb_addr_endpoint:
address.getString(dpb_remote_address);
break;
case isc_dpb_addr_flags:
dpb_remote_flags = address.getInt();
break;
default:
break;
}
@ -6388,6 +6392,7 @@ static JAttachment* create_attachment(const PathName& alias_name,
attachment->att_network_protocol = options.dpb_network_protocol;
attachment->att_remote_address = options.dpb_remote_address;
attachment->att_remote_pid = options.dpb_remote_pid;
attachment->att_remote_flags = options.dpb_remote_flags;
attachment->att_remote_process = options.dpb_remote_process;
attachment->att_remote_host = options.dpb_remote_host;
attachment->att_remote_os_user = options.dpb_remote_os_user;

View File

@ -176,7 +176,7 @@ void MOV_get_metaname(Jrd::thread_db* tdbb, const dsc* desc, MetaName& name)
fb_assert(length && ptr);
fb_assert(length <= MAX_SQL_IDENTIFIER_LEN);
fb_assert(ttype == ttype_metadata);
fb_assert(ttype == ttype_ascii || ttype == ttype_metadata);
name.assign(reinterpret_cast<char*>(ptr), length);
}

View File

@ -413,3 +413,6 @@ NAME("MON$IDLE_TIMEOUT", nam_idle_timeout)
NAME("MON$IDLE_TIMER", nam_idle_timer)
NAME("MON$STATEMENT_TIMEOUT", nam_stmt_timeout)
NAME("MON$STATEMENT_TIMER", nam_stmt_timer)
NAME("MON$CONNECTION_COMPRESSED", nam_conn_compressed)
NAME("MON$CONNECTION_ENCRYPTED", nam_conn_encrypted)

View File

@ -520,6 +520,8 @@ RELATION(nam_mon_attachments, rel_mon_attachments, ODS_11_1, rel_virtual)
FIELD(f_mon_att_idle_timeout, nam_idle_timeout, fld_idle_timeout, 0, ODS_13_0)
FIELD(f_mon_att_idle_timer, nam_idle_timer, fld_idle_timer, 0, ODS_13_0)
FIELD(f_mon_att_stmt_timeout, nam_stmt_timeout, fld_stmt_timeout, 0, ODS_13_0)
FIELD(f_mon_att_conn_compressed, nam_conn_compressed, fld_bool, 0, ODS_13_0)
FIELD(f_mon_att_conn_encrypted, nam_conn_encrypted, fld_bool, 0, ODS_13_0)
END_RELATION
// Relation 35 (MON$TRANSACTIONS)

View File

@ -257,7 +257,7 @@ void Service::getOptions(ClumpletReader& spb)
break;
case isc_spb_address_path:
spb.getString(svc_address_path);
spb.getData(svc_address_path);
{
ClumpletReader address_stack(ClumpletReader::UnTagged,
spb.getBytes(), spb.getClumpLength());
@ -570,7 +570,7 @@ void Service::fillDpb(ClumpletWriter& dpb)
dpb.insertString(isc_dpb_config, EMBEDDED_PROVIDERS, fb_strlen(EMBEDDED_PROVIDERS));
if (svc_address_path.hasData())
{
dpb.insertString(isc_dpb_address_path, svc_address_path);
dpb.insertData(isc_dpb_address_path, svc_address_path);
}
if (svc_utf8)
{

View File

@ -307,7 +307,7 @@ private:
bool svc_utf8;
Firebird::string svc_switches; // Full set of switches
Firebird::string svc_perm_sw; // Switches, taken from services table and/or passed using spb_command_line
Firebird::string svc_address_path;
Firebird::UCharBuffer svc_address_path;
Firebird::string svc_command_line;
Firebird::string svc_network_protocol;

View File

@ -75,6 +75,7 @@
#include "../jrd/Collation.h"
#include "../jrd/Mapping.h"
#include "../jrd/DbCreators.h"
#include "../common/os/fbsyslog.h"
const int DYN_MSG_FAC = 8;
@ -98,7 +99,6 @@ static tx_inv_page* fetch_inventory_page(thread_db*, WIN* window, ULONG sequence
static const char* get_lockname_v3(const UCHAR lock);
static ULONG inventory_page(thread_db*, ULONG);
static int limbo_transaction(thread_db*, TraNumber id);
static void link_transaction(thread_db*, jrd_tra*);
static void restart_requests(thread_db*, jrd_tra*);
static void start_sweeper(thread_db*);
static THREAD_ENTRY_DECLARE sweep_database(THREAD_ENTRY_PARAM);
@ -1151,7 +1151,7 @@ jrd_tra* TRA_reconnect(thread_db* tdbb, const UCHAR* id, USHORT length)
trans->tra_number = number;
trans->tra_flags |= TRA_prepared | TRA_reconnected | TRA_write;
link_transaction(tdbb, trans);
trans->linkToAttachment(attachment);
return trans;
}
@ -1275,14 +1275,7 @@ void TRA_release_transaction(thread_db* tdbb, jrd_tra* transaction, Jrd::TraceTr
// Unlink the transaction from the attachment block
for (jrd_tra** ptr = &attachment->att_transactions; *ptr; ptr = &(*ptr)->tra_next)
{
if (*ptr == transaction)
{
*ptr = transaction->tra_next;
break;
}
}
transaction->unlinkFromAttachment();
// Release transaction's under-modification-rpb list
@ -2318,7 +2311,22 @@ static int limbo_transaction(thread_db* tdbb, TraNumber id)
}
static void link_transaction(thread_db* tdbb, jrd_tra* transaction)
void jrd_tra::unlinkFromAttachment()
{
for (jrd_tra** ptr = &tra_attachment->att_transactions; *ptr; ptr = &(*ptr)->tra_next)
{
if (*ptr == this)
{
*ptr = tra_next;
return;
}
}
tra_abort("transaction to unlink is missing in the attachment");
}
void jrd_tra::linkToAttachment(Attachment* attachment)
{
/**************************************
*
@ -2330,11 +2338,20 @@ static void link_transaction(thread_db* tdbb, jrd_tra* transaction)
* Link transaction block into database attachment.
*
**************************************/
SET_TDBB(tdbb);
tra_next = attachment->att_transactions;
attachment->att_transactions = this;
}
Jrd::Attachment* attachment = tdbb->getAttachment();
transaction->tra_next = attachment->att_transactions;
attachment->att_transactions = transaction;
void jrd_tra::tra_abort(const char* reason)
{
string buff;
buff.printf("Failure working with transactions list: %s", reason);
Syslog::Record(Syslog::Error, buff.c_str());
gds__log(buff.c_str());
#ifdef DEV_BUILD
abort();
#endif
}
@ -3166,230 +3183,238 @@ static void transaction_start(thread_db* tdbb, jrd_tra* trans)
// Link the transaction to the attachment block before releasing
// header page for handling signals.
link_transaction(tdbb, trans);
trans->linkToAttachment(attachment);
try
{
#ifndef SUPERSERVER_V2
if (!dbb->readOnly())
CCH_RELEASE(tdbb, &window);
if (!dbb->readOnly())
CCH_RELEASE(tdbb, &window);
#endif
if (dbb->readOnly())
{
// Set transaction flags to TRA_precommitted, TRA_readonly
trans->tra_flags |= (TRA_readonly | TRA_precommitted);
}
if (dbb->readOnly())
{
// Set transaction flags to TRA_precommitted, TRA_readonly
trans->tra_flags |= (TRA_readonly | TRA_precommitted);
}
// Next, take a snapshot of all transactions between the oldest interesting
// transaction and the current. Don't bother to get a snapshot for
// read-committed transactions; they use the snapshot off the dbb block
// since they need to know what is currently committed.
// Next, take a snapshot of all transactions between the oldest interesting
// transaction and the current. Don't bother to get a snapshot for
// read-committed transactions; they use the snapshot off the dbb block
// since they need to know what is currently committed.
if (trans->tra_flags & TRA_read_committed)
TPC_initialize_tpc(tdbb, top);
else if (top > base)
TRA_get_inventory(tdbb, trans->tra_transactions.begin(), base, top);
// Next task is to find the oldest active transaction on the system. This
// is needed for garbage collection. Things are made ever so slightly
// more complicated by the fact that existing transaction may have oldest
// actives older than they are.
Lock temp_lock(tdbb, sizeof(TraNumber), LCK_tra, trans);
trans->tra_oldest_active = number;
base = oldest & ~TRA_MASK;
oldest_active = number;
bool cleanup = !(number % TRA_ACTIVE_CLEANUP);
int oldest_state;
for (; active < top; active++)
{
if (trans->tra_flags & TRA_read_committed)
{
const ULONG mask = (1 << tra_active);
active = TPC_find_states(tdbb, active, top, mask, oldest_state);
if (!active)
{
active = number;
break;
}
fb_assert(oldest_state == tra_active);
}
else
{
const ULONG byte = TRANS_OFFSET(active - base);
const USHORT shift = TRANS_SHIFT(active);
oldest_state = (trans->tra_transactions[byte] >> shift) & TRA_MASK;
}
TPC_initialize_tpc(tdbb, top);
else if (top > base)
TRA_get_inventory(tdbb, trans->tra_transactions.begin(), base, top);
if (oldest_state == tra_active)
// Next task is to find the oldest active transaction on the system. This
// is needed for garbage collection. Things are made ever so slightly
// more complicated by the fact that existing transaction may have oldest
// actives older than they are.
Lock temp_lock(tdbb, sizeof(TraNumber), LCK_tra, trans);
trans->tra_oldest_active = number;
base = oldest & ~TRA_MASK;
oldest_active = number;
bool cleanup = !(number % TRA_ACTIVE_CLEANUP);
int oldest_state;
for (; active < top; active++)
{
temp_lock.setKey(active);
TraNumber data = LCK_read_data(tdbb, &temp_lock);
if (!data)
if (trans->tra_flags & TRA_read_committed)
{
if (cleanup)
const ULONG mask = (1 << tra_active);
active = TPC_find_states(tdbb, active, top, mask, oldest_state);
if (!active)
{
if (TRA_wait(tdbb, trans, active, jrd_tra::tra_no_wait) == tra_committed)
cleanup = false;
continue;
active = number;
break;
}
fb_assert(oldest_state == tra_active);
}
else
{
const ULONG byte = TRANS_OFFSET(active - base);
const USHORT shift = TRANS_SHIFT(active);
oldest_state = (trans->tra_transactions[byte] >> shift) & TRA_MASK;
}
if (oldest_state == tra_active)
{
temp_lock.setKey(active);
TraNumber data = LCK_read_data(tdbb, &temp_lock);
if (!data)
{
if (cleanup)
{
if (TRA_wait(tdbb, trans, active, jrd_tra::tra_no_wait) == tra_committed)
cleanup = false;
continue;
}
data = active;
}
data = active;
}
oldest_active = MIN(oldest_active, active);
oldest_active = MIN(oldest_active, active);
// Find the oldest record version that cannot be garbage collected yet
// by taking the minimum of all all versions needed by all active transactions.
// Find the oldest record version that cannot be garbage collected yet
// by taking the minimum of all all versions needed by all active transactions.
if (data < trans->tra_oldest_active)
trans->tra_oldest_active = data;
if (data < trans->tra_oldest_active)
trans->tra_oldest_active = data;
// If the lock data for any active transaction matches a previously
// computed value then there is no need to continue. There can't be
// an older lock data in the remaining active transactions.
// If the lock data for any active transaction matches a previously
// computed value then there is no need to continue. There can't be
// an older lock data in the remaining active transactions.
if (trans->tra_oldest_active == oldest_snapshot)
break;
if (trans->tra_oldest_active == oldest_snapshot)
// Query the minimum lock data for all active transaction locks.
// This will be the oldest active snapshot used for regulating garbage collection.
data = LCK_query_data(tdbb, LCK_tra, LCK_MIN);
if (data && data < trans->tra_oldest_active)
trans->tra_oldest_active = data;
break;
// Query the minimum lock data for all active transaction locks.
// This will be the oldest active snapshot used for regulating garbage collection.
data = LCK_query_data(tdbb, LCK_tra, LCK_MIN);
if (data && data < trans->tra_oldest_active)
trans->tra_oldest_active = data;
break;
}
}
}
// Calculate attachment-local oldest active and oldest snapshot numbers
// looking at current attachment's transactions only. Calculated values
// are used to determine garbage collection threshold for attachment-local
// data such as temporary tables (GTT's).
// Calculate attachment-local oldest active and oldest snapshot numbers
// looking at current attachment's transactions only. Calculated values
// are used to determine garbage collection threshold for attachment-local
// data such as temporary tables (GTT's).
trans->tra_att_oldest_active = number;
TraNumber att_oldest_active = number;
TraNumber att_oldest_snapshot = number;
trans->tra_att_oldest_active = number;
TraNumber att_oldest_active = number;
TraNumber att_oldest_snapshot = number;
for (jrd_tra* tx_att = attachment->att_transactions; tx_att; tx_att = tx_att->tra_next)
{
att_oldest_active = MIN(att_oldest_active, tx_att->tra_number);
att_oldest_snapshot = MIN(att_oldest_snapshot, tx_att->tra_att_oldest_active);
}
trans->tra_att_oldest_active = (trans->tra_flags & TRA_read_committed) ? number : att_oldest_active;
if (attachment->att_oldest_snapshot < att_oldest_snapshot)
attachment->att_oldest_snapshot = att_oldest_snapshot;
// Put the TID of the oldest active transaction (just calculated)
// in the new transaction's lock.
// hvlad: for read-committed transaction put tra_number to prevent
// unnecessary blocking of garbage collection by read-committed
// transactions
const TraNumber lck_data = (trans->tra_flags & TRA_read_committed) ? number : oldest_active;
//fb_assert(sizeof(lock->lck_data) == sizeof(lck_data));
if (lock->lck_data != (SLONG) lck_data)
LCK_write_data(tdbb, lock, lck_data);
// Finally, scan transactions looking for the oldest interesting transaction -- the oldest
// non-commited transaction. This will not be updated immediately, but saved until the
// next update access to the header page
oldest_state = tra_committed;
for (oldest = trans->tra_oldest; oldest < top; oldest++)
{
if (trans->tra_flags & TRA_read_committed)
for (jrd_tra* tx_att = attachment->att_transactions; tx_att; tx_att = tx_att->tra_next)
{
const ULONG mask = ~((1 << tra_committed) | (1 << tra_precommitted));
oldest = TPC_find_states(tdbb, trans->tra_oldest, top, mask, oldest_state);
if (!oldest)
att_oldest_active = MIN(att_oldest_active, tx_att->tra_number);
att_oldest_snapshot = MIN(att_oldest_snapshot, tx_att->tra_att_oldest_active);
}
trans->tra_att_oldest_active = (trans->tra_flags & TRA_read_committed) ? number : att_oldest_active;
if (attachment->att_oldest_snapshot < att_oldest_snapshot)
attachment->att_oldest_snapshot = att_oldest_snapshot;
// Put the TID of the oldest active transaction (just calculated)
// in the new transaction's lock.
// hvlad: for read-committed transaction put tra_number to prevent
// unnecessary blocking of garbage collection by read-committed
// transactions
const TraNumber lck_data = (trans->tra_flags & TRA_read_committed) ? number : oldest_active;
//fb_assert(sizeof(lock->lck_data) == sizeof(lck_data));
if (lock->lck_data != (SLONG) lck_data)
LCK_write_data(tdbb, lock, lck_data);
// Finally, scan transactions looking for the oldest interesting transaction -- the oldest
// non-commited transaction. This will not be updated immediately, but saved until the
// next update access to the header page
oldest_state = tra_committed;
for (oldest = trans->tra_oldest; oldest < top; oldest++)
{
if (trans->tra_flags & TRA_read_committed)
{
oldest = top;
break;
const ULONG mask = ~((1 << tra_committed) | (1 << tra_precommitted));
oldest = TPC_find_states(tdbb, trans->tra_oldest, top, mask, oldest_state);
if (!oldest)
{
oldest = top;
break;
}
fb_assert(oldest_state != tra_committed && oldest_state != tra_precommitted);
}
fb_assert(oldest_state != tra_committed && oldest_state != tra_precommitted);
else
{
const ULONG byte = TRANS_OFFSET(oldest - base);
const USHORT shift = TRANS_SHIFT(oldest);
oldest_state = (trans->tra_transactions[byte] >> shift) & TRA_MASK;
}
if (oldest_state != tra_committed && oldest_state != tra_precommitted)
break;
}
else
if (oldest >= top && dbb->dbb_flags & DBB_read_only)
oldest = number;
if (--oldest > dbb->dbb_oldest_transaction)
dbb->dbb_oldest_transaction = oldest;
if (oldest_active > dbb->dbb_oldest_active)
dbb->dbb_oldest_active = oldest_active;
if (trans->tra_oldest_active > dbb->dbb_oldest_snapshot)
{
const ULONG byte = TRANS_OFFSET(oldest - base);
const USHORT shift = TRANS_SHIFT(oldest);
oldest_state = (trans->tra_transactions[byte] >> shift) & TRA_MASK;
dbb->dbb_oldest_snapshot = trans->tra_oldest_active;
if (!(dbb->dbb_flags & DBB_gc_active) && (dbb->dbb_flags & DBB_gc_background))
{
dbb->dbb_flags |= DBB_gc_pending;
dbb->dbb_gc_sem.release();
}
}
if (oldest_state != tra_committed && oldest_state != tra_precommitted)
break;
}
// If the transaction block is getting out of hand, force a sweep
if (oldest >= top && dbb->dbb_flags & DBB_read_only)
oldest = number;
if (--oldest > dbb->dbb_oldest_transaction)
dbb->dbb_oldest_transaction = oldest;
if (oldest_active > dbb->dbb_oldest_active)
dbb->dbb_oldest_active = oldest_active;
if (trans->tra_oldest_active > dbb->dbb_oldest_snapshot)
{
dbb->dbb_oldest_snapshot = trans->tra_oldest_active;
if (!(dbb->dbb_flags & DBB_gc_active) && (dbb->dbb_flags & DBB_gc_background))
if (dbb->dbb_sweep_interval &&
(trans->tra_oldest_active > oldest) &&
(trans->tra_oldest_active - oldest > dbb->dbb_sweep_interval) &&
oldest_state != tra_limbo)
{
dbb->dbb_flags |= DBB_gc_pending;
dbb->dbb_gc_sem.release();
start_sweeper(tdbb);
}
// Start a 'transaction-level' savepoint, unless this is the
// system transaction, or unless the transactions doesn't want
// a savepoint to be started. This savepoint will be used to
// undo the transaction if it rolls back.
if (!(trans->tra_flags & TRA_system) && !(trans->tra_flags & TRA_no_auto_undo))
trans->startSavepoint(true);
// if the user asked us to restart all requests in this attachment,
// do so now using the new transaction
if (trans->tra_flags & TRA_restart_requests)
restart_requests(tdbb, trans);
// If the transaction is read-only and read committed, it can be
// precommitted because it can't modify any records and doesn't
// need a snapshot preserved. This transaction type can run
// forever without impacting garbage collection or causing
// transaction bitmap growth.
if ((trans->tra_flags & TRA_readonly) && (trans->tra_flags & TRA_read_committed))
{
TRA_set_state(tdbb, trans, trans->tra_number, tra_committed);
LCK_release(tdbb, lock);
lock->lck_type = LCK_tra_pc; // note, LCK_tra_pc belongs to the same owner as LCK_tra
lock->lck_data = 0;
if (!LCK_lock(tdbb, lock, LCK_write, LCK_WAIT))
ERR_post(Arg::Gds(isc_lock_conflict));
trans->tra_flags |= TRA_precommitted;
}
if (trans->tra_flags & TRA_precommitted)
TRA_precommited(tdbb, 0, trans->tra_number);
}
// If the transaction block is getting out of hand, force a sweep
if (dbb->dbb_sweep_interval &&
(trans->tra_oldest_active > oldest) &&
(trans->tra_oldest_active - oldest > dbb->dbb_sweep_interval) &&
oldest_state != tra_limbo)
catch (const Firebird::Exception&)
{
start_sweeper(tdbb);
}
// Start a 'transaction-level' savepoint, unless this is the
// system transaction, or unless the transactions doesn't want
// a savepoint to be started. This savepoint will be used to
// undo the transaction if it rolls back.
if (!(trans->tra_flags & TRA_system) && !(trans->tra_flags & TRA_no_auto_undo))
trans->startSavepoint(true);
// if the user asked us to restart all requests in this attachment,
// do so now using the new transaction
if (trans->tra_flags & TRA_restart_requests)
restart_requests(tdbb, trans);
// If the transaction is read-only and read committed, it can be
// precommitted because it can't modify any records and doesn't
// need a snapshot preserved. This transaction type can run
// forever without impacting garbage collection or causing
// transaction bitmap growth.
if ((trans->tra_flags & TRA_readonly) && (trans->tra_flags & TRA_read_committed))
{
TRA_set_state(tdbb, trans, trans->tra_number, tra_committed);
LCK_release(tdbb, lock);
lock->lck_type = LCK_tra_pc; // note, LCK_tra_pc belongs to the same owner as LCK_tra
lock->lck_data = 0;
if (!LCK_lock(tdbb, lock, LCK_write, LCK_WAIT))
ERR_post(Arg::Gds(isc_lock_conflict));
trans->tra_flags |= TRA_precommitted;
}
if (trans->tra_flags & TRA_precommitted)
TRA_precommited(tdbb, 0, trans->tra_number);
trans->unlinkFromAttachment();
throw;
}
}

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