xtool/contrib/DelphiEncryptionCompendium/Unit Tests/Tests/TestDECHashMAC.pas

241 lines
12 KiB
ObjectPascal
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{*****************************************************************************
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.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECHashMAC;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
{$INCLUDE ..\..\Source\DECOptions.inc}
uses
System.Classes, System.SysUtils, Generics.Collections,
{$IFDEF DUnitX}
DUnitX.TestFramework, DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
TestDECTestDataContainer, DECBaseClass, DECHash, DECHashBase;
type
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
/// <summary>
/// All test cases for the HMAC class methods.
/// </summary>
TestTHash_HMAC = class(TTestCase)
published
procedure TestBytes;
procedure TestRawByteString;
procedure TestAAx80StringBytes;
procedure TestAAx80StringString;
end;
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
/// <summary>
/// All test cases for the HMAC class methods.
/// </summary>
TestTHash_PBKDF2 = class(TTestCase)
published
procedure TestBytes;
procedure TestRawByteString;
end;
implementation
uses
DECFormatBase, DECFormat;
{ TestTHash_HMAC }
procedure TestTHash_HMAC.TestAAx80StringBytes;
var
AAx80String : TBytes;
Result : TBytes;
begin
SetLength(AAx80String, 80);
FillChar(AAx80String[0], 80, $AA);
Result := THash_MD5.HMAC(AAx80String,
BytesOf('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('6F630FAD67CDA0EE1FB1F562DB3AA53E', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_MD5.HMAC(AAx80String, BytesOf('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('6B1AB7FE4BD7BF8F0B62E6CE61B9D0CD', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'MD5 Test Using Larger Than Block-Size Key - Hash Key First');
Result := THash_SHA1.HMAC(AAx80String,
BytesOf('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('E8E99D0F45237D786D6BBAA7965C7808BBFF1A91', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_SHA1.HMAC(AAx80String,
BytesOf('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('AA4AE5E15272D00E95705637CE8A3B55ED402112', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key - Hash Key First');
end;
procedure TestTHash_HMAC.TestAAx80StringString;
var
AAx80String : TBytes;
Result : TBytes;
begin
SetLength(AAx80String, 80);
FillChar(AAx80String[0], 80, $AA);
Result := THash_MD5.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('6F630FAD67CDA0EE1FB1F562DB3AA53E', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_MD5.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('6B1AB7FE4BD7BF8F0B62E6CE61B9D0CD', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'MD5 Test Using Larger Than Block-Size Key - Hash Key First');
Result := THash_SHA1.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('E8E99D0F45237D786D6BBAA7965C7808BBFF1A91', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_SHA1.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('AA4AE5E15272D00E95705637CE8A3B55ED402112', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key - Hash Key First');
end;
procedure TestTHash_HMAC.TestBytes;
var
Res: TBytes;
begin
// test vectors from https://en.wikipedia.org/wiki/HMAC
Res := THash_MD5.HMAC(BytesOf('key'), BytesOf('The quick brown fox jumps over the lazy dog'));
CheckEquals('80070713463E7749B90C2DC24911E275', StringOf(ValidFormat(TFormat_HEX).Encode(Res)),
'MD5 failure in The quick...');
Res := THash_SHA1.HMAC(BytesOf('key'), BytesOf('The quick brown fox jumps over the lazy dog'));
CheckEquals('DE7C9B85B8B78AA6BC8A7A36F70A90701C9DB4D9', StringOf(ValidFormat(TFormat_HEX).Encode(Res)),
'SHA1 failure in The quick...');
Res := THash_SHA256.HMAC(BytesOf('key'), BytesOf('The quick brown fox jumps over the lazy dog'));
CheckEquals('F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8',
StringOf(ValidFormat(TFormat_HEX).Encode(Res)),
'SHA256 failure in The quick...');
end;
procedure TestTHash_HMAC.TestRawByteString;
var
Result: TBytes;
begin
// test vectors from https://en.wikipedia.org/wiki/HMAC
Result := THash_MD5.HMAC(RawByteString('key'), RawByteString('The quick brown fox jumps over the lazy dog'));
CheckEquals('80070713463E7749B90C2DC24911E275', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'MD5 failure in The quick...');
Result := THash_SHA1.HMAC(RawByteString('key'), RawByteString('The quick brown fox jumps over the lazy dog'));
CheckEquals('DE7C9B85B8B78AA6BC8A7A36F70A90701C9DB4D9', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 failure in The quick...');
Result := THash_SHA256.HMAC(RawByteString('key'), RawByteString('The quick brown fox jumps over the lazy dog'));
CheckEquals('F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8',
StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA256 failure in The quick...');
end;
{ TestTHash_PBKDF2 }
procedure TestTHash_PBKDF2.TestBytes;
var
Result : string;
begin
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA1.PBKDF2(BytesOf('password'), BytesOf('salt'), 1, 20)));
CheckEquals('0C60C80F961F0E71F3A9B524AF6012062FE037A6', result, 'SHA1 password salt 1 20');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 1, 32)));
CheckEquals('120FB6CFFCF8B32C43E7225256C4F837A86548C92CCC35480805987CB70BE17B', result, 'SHA256 password salt 1 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 2, 32)));
CheckEquals('AE4D0C95AF6B46D32D0ADFF928F06DD02A303F8EF3C251DFD6E2D85A95474C43', result, 'SHA256 password salt 2 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 4096, 32)));
CheckEquals('C5E478D59288C841AA530DB6845C4C8D962893A001CE4E11A4963873AA98134A', result, 'SHA256 password salt 4096 32');
// PBKDF2-HMAC-SHA512 test vectors from https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2(BytesOf('password'), BytesOf('salt'), 1, 64)));
CheckEquals('867F70CF1ADE02CFF3752599A3A53DC4AF34C7A669815AE5D513554E1C8CF252C02D470A285A0501BAD999BFE943C08F050235D7D68B1DA55E63F73B60A57FCE',
result, 'SHA512 password salt 1 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2(BytesOf('password'), BytesOf('salt'), 2, 64)));
CheckEquals('E1D9C16AA681708A45F5C7C4E215CEB66E011A2E9F0040713F18AEFDB866D53CF76CAB2868A39B9F7840EDCE4FEF5A82BE67335C77A6068E04112754F27CCF4E',
result, 'SHA512 password salt 2 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2(BytesOf('password'), BytesOf('salt'), 4096, 64)));
CheckEquals('D197B1B33DB0143E018B12F3D1D1479E6CDEBDCC97C5C0F87F6902E072F457B5143F30602641B3D55CD335988CB36B84376060ECD532E039B742A239434AF2D5',
result, 'SHA512 password salt 4096 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 1000000, 32)));
CheckEquals('505112A590BE61AC9D3A235BF0A8EECEA40E54652EC0E3C257C227C9AA5E664C',
result, 'SHA256 password salt 1000000 32');
end;
procedure TestTHash_PBKDF2.TestRawByteString;
var
Result : string;
begin
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA1.PBKDF2('password', 'salt', 1, 20)));
CheckEquals('0C60C80F961F0E71F3A9B524AF6012062FE037A6', result, 'SHA1 password salt 1 20');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 1, 32)));
CheckEquals('120FB6CFFCF8B32C43E7225256C4F837A86548C92CCC35480805987CB70BE17B', result, 'SHA256 password salt 1 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 2, 32)));
CheckEquals('AE4D0C95AF6B46D32D0ADFF928F06DD02A303F8EF3C251DFD6E2D85A95474C43', result, 'SHA256 password salt 2 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 4096, 32)));
CheckEquals('C5E478D59288C841AA530DB6845C4C8D962893A001CE4E11A4963873AA98134A', result, 'SHA256 password salt 4096 32');
// PBKDF2-HMAC-SHA512 test vectors from https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2('password', 'salt', 1, 64)));
CheckEquals('867F70CF1ADE02CFF3752599A3A53DC4AF34C7A669815AE5D513554E1C8CF252C02D470A285A0501BAD999BFE943C08F050235D7D68B1DA55E63F73B60A57FCE',
result, 'SHA512 password salt 1 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2('password', 'salt', 2, 64)));
CheckEquals('E1D9C16AA681708A45F5C7C4E215CEB66E011A2E9F0040713F18AEFDB866D53CF76CAB2868A39B9F7840EDCE4FEF5A82BE67335C77A6068E04112754F27CCF4E',
result, 'SHA512 password salt 2 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2('password', 'salt', 4096, 64)));
CheckEquals('D197B1B33DB0143E018B12F3D1D1479E6CDEBDCC97C5C0F87F6902E072F457B5143F30602641B3D55CD335988CB36B84376060ECD532E039B742A239434AF2D5',
result, 'SHA512 password salt 4096 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 1000000, 32)));
CheckEquals('505112A590BE61AC9D3A235BF0A8EECEA40E54652EC0E3C257C227C9AA5E664C',
result, 'SHA256 password salt 1000000 32');
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTHash_HMAC);
TDUnitX.RegisterTestFixture(TestTHash_PBKDF2);
{$ELSE}
RegisterTests('DECHashHMAC', [TestTHash_HMAC.Suite]);
RegisterTests('DECHashHMAC', [TestTHash_PBKDF2.Suite]);
{$ENDIF}
end.