Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

AEAD AES 128-bit GCM

See more Encryption Examples

Demonstrates AES encryption using the Galois/Counter Mode (GCM). GCM is an authenticated encryption mode with "additional data" (often referred to as AEAD). GCM is a cipher mode that can be applied to any symmetric encryption algorithm with a 16-byte block size, such as AES and Twofish. In GCM mode, the block encryption algorithm is transformed into a stream encryption algorithm, and therefore no padding occurs (and the PaddingScheme property does not apply). The "additional data" (known as the AAD) does not get encrypted but plays a role in the computation of the resulting "authenticated tag".

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Crypt2;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  crypt: TCrypt2;
  K: string;
  IV: string;
  AAD: string;
  PT: string;
  CT: string;
  T: string;
  ctResult: string;
  tResult: string;
  ptResult: string;
  tInvalid: string;

begin
  success := False;

  //  This example assumes the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  crypt := TCrypt2.Create;

  //  Set the encryption algorithm to "AES"	
  crypt.CryptAlgorithm := 'aes';

  //  Indicate that the Galois/Counter Mode (GCM) should be used:
  crypt.CipherMode := 'gcm';

  //  KeyLength may be 128, 192, 256
  crypt.KeyLength := 128;

  //  This is the 128-bit AES secret key (in hex format)
  K := 'feffe9928665731c6d6a8f9467308308';

  //  This is the 16-byte initialization vector:
  IV := 'cafebabefacedbaddecaf888';

  //  This is the additional data to be used as input to the GCM AEAD algorithm,
  //  but is not included in the output.  It plays a role in the computation of the
  //  resulting authenticated tag.
  AAD := 'feedfacedeadbeeffeedfacedeadbeefabaddad2';

  //  The plain-text bytes (in hex format) to be encrypted.
  PT := 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39';

  //  The expected cipher text (in hex format)
  CT := '42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091';

  //  The expected authenticated tag given the above inputs.
  T := '5bc94fbc3221a5db94fae95ae7121a47';

  //  Note: The above data are the values for test vector #4 from 
  //  the PDF document at: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf

  //  EncodingMode specifies the encoding of the output for
  //  encryption, and the input for decryption.
  //  It may be "hex", "url", "base64", or "quoted-printable".
  crypt.EncodingMode := 'hex';

  //  Set the secret key and IV
  crypt.SetEncodedIV(IV,'hex');
  crypt.SetEncodedKey(K,'hex');

  //  Set the additional authenticated data (AAD)
  success := crypt.SetEncodedAad(AAD,'hex');

  //  For the purpose of duplicating the test vectors, we are using the EncryptEncoded method.
  //  This method decodes the input string according to the encoding specified by the EncodingMode
  //  property, which in this case is "hex".  The decoded bytes are encrypted using the mode specified
  //  by the CipherMode property.  The resulting
  //  encrypted bytes are encoded (again using the encoding mode specified by EncodingMode),
  //  and the result is returned.
  //  <b>Note:</b> The CipherMode property sets the block mode of operation (gcm, cfb, cbc, ofb, ecb, etc.) 
  //  for any of the Chilkat encryption/decryption methods (such as EncryptBytes, EncryptString, 
  //  CkEncryptFile, etc.)   Just because GCM mode is demonstrated with EncryptEncoded/DecryptEncoded,
  //  does not imply that GCM mode is specific to only these methods.
  ctResult := crypt.EncryptEncoded(PT);
  if (crypt.LastMethodSuccess <> True) then
    begin
      WriteLn(crypt.LastErrorText);
      Exit;
    end;

  //  Examine the result.  It should be the same (case insensitive) as our expected result:
  WriteLn('computed result: ' + ctResult);
  WriteLn('expected result: ' + CT);

  //  Examine the authenticated tag. It should be the same (case insensitive) as our expected authenticated tag:
  tResult := crypt.GetEncodedAuthTag('hex');
  WriteLn('computed authTag: ' + tResult);
  WriteLn('expected authTag: ' + T);

  //  -------------------------------------------------------------------------------------
  //  Now let's GCM decrypt...
  //  -------------------------------------------------------------------------------------

  //  Before GCM decrypting, we must set the authenticated tag to the value that is expected.
  //  The decryption will fail if the resulting authenticated tag is not equal (case insensitive) to 
  //  the expected result.
  //  Note: The return value of SetEncodedAuthTag indicates whether the string passed was a valid
  //  representation of the encoding specified in the 2nd arg.
  success := crypt.SetEncodedAuthTag(T,'hex');

  //  All of our properties (IV, secret key, cipher mode, and AAD) are already set from the code above...

  //  So let's decrypt CT to and check to see if we get PT.
  ptResult := crypt.DecryptEncoded(CT);
  if (crypt.LastMethodSuccess <> True) then
    begin
      //  Failed.  The resultant authenticated tag did not equal the expected authentication tag.
      WriteLn(crypt.LastErrorText);
      Exit;
    end;

  //  Examine the decrypted result.  It should be the same as our expected plaintext (case insensitive)
  WriteLn('plaintext decrypted: ' + ptResult);
  WriteLn('plaintext expected:  ' + PT);

  //  Let's intentionally set the expected authenticated tag to an incorrect value. 
  //  The decrypt operation should fail:
  tInvalid := 'ffaabbbc3221a5db94fae95ae7121a47';

  success := crypt.SetEncodedAuthTag(tInvalid,'hex');

  ptResult := crypt.DecryptEncoded(CT);
  if (crypt.LastMethodSuccess <> True) then
    begin
      //  Failed.  The resultant authenticated tag did not equal the expected authentication tag.
      WriteLn(crypt.LastErrorText);
    end;


  crypt.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.