IESCipherTests.pas 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. { *********************************************************************************** }
  2. { * CryptoLib Library * }
  3. { * Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe * }
  4. { * Github Repository <https://github.com/Xor-el> * }
  5. { * Distributed under the MIT software license, see the accompanying file LICENSE * }
  6. { * or visit http://www.opensource.org/licenses/mit-license.php. * }
  7. { * Acknowledgements: * }
  8. { * * }
  9. { * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
  10. { * development of this library * }
  11. { * ******************************************************************************* * }
  12. (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
  13. unit IESCipherTests;
  14. interface
  15. {$IFDEF FPC}
  16. {$MODE DELPHI}
  17. {$ENDIF FPC}
  18. uses
  19. SysUtils,
  20. {$IFDEF FPC}
  21. fpcunit,
  22. testregistry,
  23. {$ELSE}
  24. TestFramework,
  25. {$ENDIF FPC}
  26. ClpIMac,
  27. ClpAesEngine,
  28. ClpIAesEngine,
  29. ClpIAsymmetricCipherKeyPairGenerator,
  30. ClpGeneratorUtilities,
  31. ClpIESParameterSpec,
  32. ClpIIESParameterSpec,
  33. ClpIAlgorithmParameterSpec,
  34. // ClpKeyParameter,
  35. // ClpIKeyParameter,
  36. // ClpParametersWithIV,
  37. // ClpIParametersWithIV,
  38. ClpIBufferedBlockCipher,
  39. // ClpParameterUtilities,
  40. // ClpCipherUtilities,
  41. ClpBlockCipherModes,
  42. ClpIBlockCipherModes,
  43. ClpPaddedBufferedBlockCipher,
  44. ClpECDHBasicAgreement,
  45. ClpIECDHBasicAgreement,
  46. ClpIESEngine,
  47. ClpIIESEngine,
  48. ClpPaddingModes,
  49. ClpIPaddingModes,
  50. ClpKdf2BytesGenerator,
  51. ClpIKdf2BytesGenerator,
  52. ClpIX9ECParameters,
  53. ClpSecNamedCurves,
  54. ClpIECDomainParameters,
  55. ClpECDomainParameters,
  56. ClpECKeyGenerationParameters,
  57. ClpSecureRandom,
  58. ClpISecureRandom,
  59. ClpIAsymmetricCipherKeyPair,
  60. ClpIECPublicKeyParameters,
  61. ClpIECPrivateKeyParameters,
  62. ClpIIESCipher,
  63. ClpIESCipher,
  64. ClpEncoders,
  65. ClpDigestUtilities,
  66. ClpMacUtilities,
  67. ClpConverters,
  68. ClpArrayUtils;
  69. type
  70. TCryptoLibTestCase = class abstract(TTestCase)
  71. end;
  72. type
  73. TTestIESCipher = class(TCryptoLibTestCase)
  74. private
  75. function GetECIESAES256CBCEngine: IIESEngine;
  76. function GetECKeyPair: IAsymmetricCipherKeyPair;
  77. function GetIESParameterSpec: IAlgorithmParameterSpec;
  78. procedure DoIESCipher_Encryption_Decryption_TestWithIV
  79. (const KeyPair: IAsymmetricCipherKeyPair;
  80. const param: IAlgorithmParameterSpec; const Random: ISecureRandom;
  81. const PlainText: String);
  82. protected
  83. procedure SetUp; override;
  84. procedure TearDown; override;
  85. published
  86. procedure TestIESCipher_Random_Values_Encryption_Decryption_AES256_CBC_PKCS7PADDING;
  87. end;
  88. implementation
  89. { TTestIESCipher }
  90. procedure TTestIESCipher.DoIESCipher_Encryption_Decryption_TestWithIV
  91. (const KeyPair: IAsymmetricCipherKeyPair;
  92. const param: IAlgorithmParameterSpec; const Random: ISecureRandom;
  93. const PlainText: String);
  94. var
  95. PlainTextBytes, CipherTextBytes, DecryptionResultBytes: TBytes;
  96. CipherEncrypt, CipherDecrypt: IIESCipher;
  97. begin
  98. PlainTextBytes := TConverters.ConvertStringToBytes(PlainText, TEncoding.UTF8);
  99. // Encryption
  100. CipherEncrypt := TIESCipher.Create(GetECIESAES256CBCEngine);
  101. CipherEncrypt.Init(True, KeyPair.Public as IECPublicKeyParameters,
  102. param, Random);
  103. CipherTextBytes := CipherEncrypt.DoFinal(PlainTextBytes);
  104. // Decryption
  105. CipherDecrypt := TIESCipher.Create(GetECIESAES256CBCEngine);
  106. CipherDecrypt.Init(False, KeyPair.Private as IECPrivateKeyParameters,
  107. param, Random);
  108. DecryptionResultBytes := CipherDecrypt.DoFinal(CipherTextBytes);
  109. if (not TArrayUtils.AreEqual(PlainTextBytes, DecryptionResultBytes)) then
  110. begin
  111. Fail(Format('Decryption Failed - Expected %s but got %s',
  112. [THex.Encode(PlainTextBytes), THex.Encode(DecryptionResultBytes)]));
  113. end;
  114. end;
  115. function TTestIESCipher.GetECIESAES256CBCEngine: IIESEngine;
  116. var
  117. Cipher: IBufferedBlockCipher;
  118. AesEngine: IAesEngine;
  119. blockCipher: ICbcBlockCipher;
  120. ECDHBasicAgreementInstance: IECDHBasicAgreement;
  121. KDFInstance: IKdf2BytesGenerator;
  122. DigestMACInstance: IMac;
  123. begin
  124. // // Set up IES Cipher Engine
  125. ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
  126. KDFInstance := TKdf2BytesGenerator.Create
  127. (TDigestUtilities.GetDigest('SHA-256'));
  128. DigestMACInstance := TMacUtilities.GetMac('HMAC-SHA-256');
  129. // Method 1: Set Up Block Cipher
  130. // Cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING') as IBufferedBlockCipher;
  131. // Method 2: Set Up Block Cipher
  132. AesEngine := TAesEngine.Create(); // AES Engine
  133. blockCipher := TCbcBlockCipher.Create(AesEngine); // CBC
  134. Cipher := TPaddedBufferedBlockCipher.Create(blockCipher,
  135. TPkcs7Padding.Create() as IPkcs7Padding); // Pkcs7Padding
  136. // Cipher := TPaddedBufferedBlockCipher.Create(blockCipher,
  137. // TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
  138. result := TIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
  139. DigestMACInstance, Cipher);
  140. end;
  141. function TTestIESCipher.GetECKeyPair: IAsymmetricCipherKeyPair;
  142. var
  143. CurveName: string;
  144. KeyPairGeneratorInstance: IAsymmetricCipherKeyPairGenerator;
  145. RandomInstance: ISecureRandom;
  146. Lcurve: IX9ECParameters;
  147. ecSpec: IECDomainParameters;
  148. begin
  149. // Set Up EC Key Pair
  150. CurveName := 'secp256k1';
  151. Lcurve := TSecNamedCurves.GetByName(CurveName);
  152. KeyPairGeneratorInstance := TGeneratorUtilities.GetKeyPairGenerator('ECDSA');
  153. ecSpec := TECDomainParameters.Create(Lcurve.Curve, Lcurve.G, Lcurve.N,
  154. Lcurve.H, Lcurve.GetSeed);
  155. RandomInstance := TSecureRandom.Create();
  156. KeyPairGeneratorInstance.Init(TECKeyGenerationParameters.Create(ecSpec,
  157. RandomInstance));
  158. result := KeyPairGeneratorInstance.GenerateKeyPair();
  159. end;
  160. function TTestIESCipher.GetIESParameterSpec: IAlgorithmParameterSpec;
  161. var
  162. Derivation, Encoding, IVBytes: TBytes;
  163. MacKeySizeInBits, CipherKeySizeInBits: Int32;
  164. UsePointCompression: Boolean;
  165. begin
  166. // Setup IES With Cipher Parameters
  167. // The derivation and encoding vectors are used when initialising the KDF and MAC.
  168. // They're optional but if used then they need to be known by the other user so that
  169. // they can decrypt the ciphertext and verify the MAC correctly. The security is based
  170. // on the shared secret coming from the (static-ephemeral) ECDH key agreement.
  171. Derivation := Nil;
  172. Encoding := Nil;
  173. System.SetLength(IVBytes, 16); // using Zero Initialized IV for ease
  174. MacKeySizeInBits := 32 * 8; // Since we are using SHA2_256 for MAC
  175. CipherKeySizeInBits := 32 * 8; // Since we are using AES256 for Cipher
  176. // whether to use point compression when deriving the octets string
  177. // from a point or not in the EphemeralKeyPairGenerator
  178. UsePointCompression := False;
  179. result := TIESParameterSpec.Create(Derivation, Encoding, MacKeySizeInBits,
  180. CipherKeySizeInBits, IVBytes, UsePointCompression);
  181. end;
  182. procedure TTestIESCipher.SetUp;
  183. begin
  184. inherited;
  185. end;
  186. procedure TTestIESCipher.TearDown;
  187. begin
  188. inherited;
  189. end;
  190. procedure TTestIESCipher.
  191. TestIESCipher_Random_Values_Encryption_Decryption_AES256_CBC_PKCS7PADDING;
  192. var
  193. RandomInstance: ISecureRandom;
  194. PlainText: string;
  195. I: Int32;
  196. RandomBytes: TBytes;
  197. begin
  198. RandomInstance := TSecureRandom.Create();
  199. I := 0;
  200. while I <= 10 do
  201. begin
  202. System.SetLength(RandomBytes, Byte(RandomInstance.NextInt32));
  203. RandomInstance.NextBytes(RandomBytes);
  204. PlainText := THex.Encode(RandomBytes);
  205. // Call IESCipher Encryption and Decryption Method
  206. DoIESCipher_Encryption_Decryption_TestWithIV(GetECKeyPair,
  207. GetIESParameterSpec, RandomInstance, PlainText);
  208. System.Inc(I);
  209. end;
  210. end;
  211. initialization
  212. // Register any test cases with the test runner
  213. {$IFDEF FPC}
  214. RegisterTest(TTestIESCipher);
  215. {$ELSE}
  216. RegisterTest(TTestIESCipher.Suite);
  217. {$ENDIF FPC}
  218. end.