Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Source/DEC60.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ uses
DECZIPHelper in 'DECZIPHelper.pas',
DECCipherPaddings in 'DECCipherPaddings.pas',
DECCipherModesCCM in 'DECCipherModesCCM.pas',
DECAuthenticatedCipherModesBase in 'DECAuthenticatedCipherModesBase.pas';
DECAuthenticatedCipherModesBase in 'DECAuthenticatedCipherModesBase.pas',
DECCipherModesPoly1305 in 'DECCipherModesPoly1305.pas',
DECCPUSupport in 'DECCPUSupport.pas';

begin
try
Expand Down
96 changes: 94 additions & 2 deletions Source/DECAuthenticatedCipherModesBase.pas
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ EDECAuthLengthException = class(EDECException);
/// Base class for authenticated cipher modes
/// </summary>
TAuthenticatedCipherModesBase = class(TObject)
private
/// <summary>
/// Flag that indicates if the method has been initialized
/// </summary>
fAuthMethodInit : boolean;

/// <summary>
/// Length of the processed buffer
/// </summary>
fEncDecLen : Int64;
strict protected
/// <summary>
/// The data which shall be authenticated in parallel to the encryption
Expand Down Expand Up @@ -99,6 +109,32 @@ TAuthenticatedCipherModesBase = class(TObject)
/// Length of the calculated authentication value in bit
/// </returns>
function GetAuthenticationTagBitLength: UInt32; virtual;


/// <summary>
/// Initialize the authentication procedure. This is a good place to initialize
/// the data structures and initialize with the (unencrypted) authenticated buffer
/// </summary>
procedure InitAuth; virtual; abstract;

/// <summary>
/// Updates the mac. Can be called multiple times!
/// </summary>
procedure UpdateWithEncDecBuf(buf : PUInt8Array; Size : Integer); virtual; abstract;

/// <summary>
/// finalize the MAC - typically the processed buffer lengths are incorporated here.
/// </summary>
procedure FinalizeMAC( authLen, encDecBufSize : Int64 ); virtual; abstract;

/// <summary>
/// Encoding/Decoding routine that is called in the Encode/Decode routine.
/// This version simply calls the EncryptionMethod givin in the init call
/// </summary>
procedure LocEncodeDecode(Source, Dest: Pointer; Size: Integer); virtual;

procedure Burn; virtual; abstract;

public
/// <summary>
/// Should be called when starting encryption/decryption in order to
Expand Down Expand Up @@ -127,7 +163,7 @@ TAuthenticatedCipherModesBase = class(TObject)
/// </param>
procedure Encode(Source,
Dest : PUInt8Array;
Size : Integer); virtual; abstract;
Size : Integer); virtual;
/// <summary>
/// Decodes a block of data using the supplied cipher
/// </summary>
Expand All @@ -142,7 +178,13 @@ TAuthenticatedCipherModesBase = class(TObject)
/// </param>
procedure Decode(Source,
Dest : PUInt8Array;
Size : Integer); virtual; abstract;
Size : Integer); virtual;

/// <summary>
/// Call this function to calculate the final MAC - typically one updates the
/// remaining buffer with buffer lengths.
/// </summary>
procedure FinalizeAEAD;

/// <summary>
/// Returns a list of authentication tag lengths explicitely specified by
Expand Down Expand Up @@ -192,6 +234,48 @@ implementation

{ TAuthenticatedCipherModesBase }

procedure TAuthenticatedCipherModesBase.Decode(Source, Dest: PUInt8Array;
Size: Integer);
begin
if not fAuthMethodInit then
begin
InitAuth;
fAuthMethodInit := True;
end;

UpdateWithEncDecBuf(Source, size);
LocEncodeDecode(Source, Dest, Size);
inc(fEncDecLen, Size);
end;

procedure TAuthenticatedCipherModesBase.Encode(Source, Dest: PUInt8Array;
Size: Integer);
begin
if not fAuthMethodInit then
begin
InitAuth;
fAuthMethodInit := True;
end;

LocEncodeDecode(Source, Dest, Size);
UpdateWithEncDecBuf(Dest, size);
inc(fEncDecLen, Size);
end;

procedure TAuthenticatedCipherModesBase.FinalizeAEAD;
begin
if not fAuthMethodInit then
begin
InitAuth;
fAuthMethodInit := True;
end;

SetLength(FCalcAuthenticationTag, FCalcAuthenticationTagLength);
FinalizeMAC(Length(FDataToAuthenticate), fEncDecLen);

Burn;
end;

function TAuthenticatedCipherModesBase.GetAuthenticationTagBitLength: UInt32;
begin
Result := FCalcAuthenticationTagLength shl 3;
Expand All @@ -210,6 +294,7 @@ procedure TAuthenticatedCipherModesBase.Init(EncryptionMethod : TEncodeDecodeMet
Assert(Assigned(EncryptionMethod), 'No encryption method specified');

// Clear calculated authentication value
fAuthMethodInit := False;
CalcAuthLength := Length(FCalcAuthenticationTag);
if (CalcAuthLength > 0) then
begin
Expand All @@ -218,9 +303,16 @@ procedure TAuthenticatedCipherModesBase.Init(EncryptionMethod : TEncodeDecodeMet
FillChar(FCalcAuthenticationTag[0], CalcAuthLength, #0);
end;

fEncDecLen := 0;
FEncryptionMethod := EncryptionMethod;
end;

procedure TAuthenticatedCipherModesBase.LocEncodeDecode(Source, Dest: Pointer;
Size: Integer);
begin
FEncryptionMethod(Source, Dest, Size);
end;

procedure TAuthenticatedCipherModesBase.SetAuthenticationTagLength(const Value: UInt32);
begin
FCalcAuthenticationTagLength := Value shr 3;
Expand Down
117 changes: 117 additions & 0 deletions Source/DECCPUSupport.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory
of this project in the file LICENCE.txt or alternatively at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}

/// <summary>
/// x86 and x64 CPU instruction support functions.
/// this class only works for intel cpus - arm will result.
/// The functions defined here return true if the feature is availabe
/// for the cpu
/// </summary>

unit DECCPUSupport;

interface

type
TDEC_CPUSupport = class(TObject)
public
// flags are set in initialization
class var AES : boolean;
class var AVX : boolean;
class var AVX2 : boolean;

class var SSE : boolean;
class var SSE2 : boolean;
class var SSE3 : boolean;
class var SSE41 : boolean;
class var SSE42 : boolean;

class var RDRand : boolean;
class var RDSeed : boolean;
end;

implementation

{$IFDEF CPUX64}
{$DEFINE x64}
{$ENDIF}
{$IFDEF cpux86_64}
{$DEFINE x64}
{$ENDIF}

{$IFDEF CPU86}
{$DEFINE x86}
{$ENDIF}
{$IFDEF CPUX86}
{$DEFINE x86}
{$ENDIF}

{$IFDEF CPU386}
{$DEFINE x86}
{$ENDIF}


{$IF Defined(x64) or Defined(x86)}
{$WARN SYMBOL_PLATFORM OFF}
procedure InitFlags;
var reg : TCPUIDRec;
nids : LongWord;
begin
reg := GetCPUID(0, 0);
nids := reg.EAX;


if nids >= 1 then
begin
reg := GetCPUID(1, 0);
TDEC_CPUSupport.SSE := (reg.EDX and (1 shl 25)) <> 0;
TDEC_CPUSupport.SSE2 := (reg.EDX and (1 shl 26)) <> 0;
TDEC_CPUSupport.SSE3 := (reg.ECX and (1 shl 9)) <> 0;
TDEC_CPUSupport.SSE41 := (reg.ECX and (1 shl 19)) <> 0;
TDEC_CPUSupport.SSE42 := (reg.ECX and (1 shl 20)) <> 0;
TDEC_CPUSupport.AES := (reg.ECX and (1 shl 25)) <> 0;

TDEC_CPUSupport.AVX := (reg.ECX and (1 shl 28)) <> 0;
TDEC_CPUSupport.RDRAND := (reg.ECX and (1 shl 30)) <> 0;
end;

if nids >= 7 then
begin
reg := GetCPUID($7);
TDEC_CPUSupport.AVX2 := (reg.EBX and (1 shl 5)) <> 0;
TDEC_CPUSupport.RDSEED := (reg.EBX and (1 shl 18)) <> 0;
end;
end;
{$ENDIF}

initialization
TDEC_CPUSupport.AES := False;
TDEC_CPUSupport.AVX := False;
TDEC_CPUSupport.AVX2 := False;

TDEC_CPUSupport.SSE := False;
TDEC_CPUSupport.SSE2 := False;
TDEC_CPUSupport.SSE3 := False;
TDEC_CPUSupport.SSE41 := False;
TDEC_CPUSupport.SSE42 := False;

TDEC_CPUSupport.RDRand := False;
TDEC_CPUSupport.RDSeed := False;
{$IF Defined(x64) or Defined(x86)}
InitFlags;
{$IFEND}
end.
5 changes: 3 additions & 2 deletions Source/DECCipherBase.pas
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ interface
cmCFSx, // CFS on Blocksize bytes
cmECBx, // Electronic Code Book
cmGCM, // Galois Counter Mode
cmCCM // Counter with CBC-MAC Mode
cmCCM, // Counter with CBC-MAC Mode
cmPoly1305 // Poly1305 for ChaCha
{$IFDEF DEC3_CMCTS}
,cmCTS3 // double CBC, with less secure padding of truncated final block
// for DEC 3.0 compatibility only (see DECOptions.inc)
Expand Down Expand Up @@ -1012,7 +1013,7 @@ procedure TDECCipher.Init(const Key; Size: Integer; const IVector;
if (Size > Context.KeySize) and (not (ctNull in Context.CipherType)) then
raise EDECCipherException.CreateRes(@sKeyMaterialTooLarge);

if (FInitVectorSize > FBufferSize) and (not (FMode = cmGCM)) then
if (FInitVectorSize > FBufferSize) and (not (FMode in [cmGCM, cmPoly1305])) then
raise EDECCipherException.CreateRes(@sIVMaterialTooLarge);

DoInit(Key, Size);
Expand Down
21 changes: 9 additions & 12 deletions Source/DECCipherFormats.pas
Original file line number Diff line number Diff line change
Expand Up @@ -730,10 +730,10 @@ function TDECFormattedCipher.EncodeBytes(const Source: TBytes): TBytes;
begin
SetLength(Result, Length(Source));
if Length(Result) > 0 then
Encode(Source[0], Result[0], Length(Source))
else
if (FMode = cmGCM) then
EncodeGCM(nil, nil, 0);
Encode(Source[0], Result[0], Length(Source));
//else
// if (FMode = cmGCM) then
// EncodeWithAuthObj(nil, nil, 0);
end;

begin
Expand All @@ -745,18 +745,15 @@ function TDECFormattedCipher.EncodeBytes(const Source: TBytes): TBytes;

function TDECFormattedCipher.DecodeBytes(const Source: TBytes): TBytes;
begin
Result := Source;
SetLength(Result, Length(Source));

if Length(Result) > 0 then
begin
if (FMode = cmGCM) then
SetLength(Result, Length(Source));

Decode(Source[0], Result[0], Length(Source));
end
else
if (FMode = cmGCM) then
DecodeGCM(nil, nil, 0);
end;
//else
//if (FMode = cmGCM) then
// DecodeGCM(nil, nil, 0);

if not (FPaddingClass = nil) then
Result := FPaddingClass.RemovePadding(Result, Context.BlockSize);
Expand Down
Loading