@@ -198,7 +198,7 @@ TFormMain = class(TForm)
198
198
// / Get the clipboard instance to be able to put something in it
199
199
// / </summary>
200
200
// / <param name="Clipboard">
201
- // / If successfull the aquired clipboard object
201
+ // / The aquired clipboard object, if successfull
202
202
// / </param>
203
203
// / <returns>
204
204
// / true if the clipboard instance could be aquired
@@ -250,7 +250,8 @@ function TFormMain.TryGetClipboardService(out Clipboard: IFMXClipboardService):
250
250
begin
251
251
Result := TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService);
252
252
if Result then
253
- Clipboard := IFMXClipboardService(TPlatformServices.Current.GetPlatformService(IFMXClipboardService));
253
+ Clipboard := IFMXClipboardService(
254
+ TPlatformServices.Current.GetPlatformService(IFMXClipboardService));
254
255
end ;
255
256
256
257
procedure TFormMain.StringToClipboard (const s: string);
@@ -267,13 +268,20 @@ procedure TFormMain.ButtonCreateKeyClick(Sender: TObject);
267
268
Context : TCipherContext;
268
269
RandBytes: TBytes;
269
270
begin
270
- Assert(ComboBoxCipherAlgorithm.ItemIndex >= 0 , ' No algo selected' );
271
- KeyFormat := TDECFormat.ClassByName(ComboBoxKeyIVFormat.Items[ComboBoxKeyIVFormat.ItemIndex]);
271
+ Assert(ComboBoxCipherAlgorithm.ItemIndex >= 0 , ' No cipher algorithm selected' );
272
+ // creates a randomized encryption/decryption key in the key format selected
272
273
274
+ // Determinhe the selected key format
275
+ KeyFormat := TDECFormat.ClassByName(
276
+ ComboBoxKeyIVFormat.Items[ComboBoxKeyIVFormat.ItemIndex]);
277
+ // This failed. It should not happen though, because all formats should be registered
273
278
Assert(Assigned(KeyFormat), ' Missing format' );
279
+
280
+ // Get metadata for the selected encryption algorithm. We need the key length
274
281
Context := TDECCipher.ClassByName(
275
282
ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex]).Context;
276
-
283
+ // Create a random key using DEC's pseudo random number generator and write the
284
+ // formatted output into the edit
277
285
RandBytes := RandomBytes(Context.KeySize);
278
286
EditKey.Text := StringOf(KeyFormat.Encode(RandBytes));
279
287
end ;
@@ -285,12 +293,27 @@ procedure TFormMain.ButtonCreateIVClick(Sender: TObject);
285
293
RandBytes: TBytes;
286
294
begin
287
295
Assert(ComboBoxCipherAlgorithm.ItemIndex >= 0 , ' No algo selected' );
296
+ // Creates a randomized initialization vector. That is one possible way to
297
+ // generate an initialization vector IV. The IV should be a new and unique
298
+ // value for each use of the encryption algorithm. It may be stored along
299
+ // with the encrypted data as it is needed by the receiver to decrypt the
300
+ // data. Not using a unique value for this is a security problem as it makes
301
+ // cracking the encryption easier. When decrypting data the very same IV which
302
+ // was used for encrypting the data needs to be set as IV, so this button is
303
+ // useless in decryption scenarios! The filler byte one can specify is used to
304
+ // fill up any IV which is shorter than the length of the encryption key.
305
+
306
+ // Determine the selected IV format
288
307
IVFormat := TDECFormat.ClassByName(ComboBoxKeyIVFormat.Items[ComboBoxKeyIVFormat.ItemIndex]);
289
308
290
309
Assert(Assigned(IVFormat), ' Missing format' );
310
+ // get meta data for the encryption/decryption algorithm used. The lenght of
311
+ // the IV usually matches the length of the encryption key
291
312
Context := TDECCipher.ClassByName(
292
313
ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex]).Context;
293
314
315
+ // Create a random IV using DEC's pseudo random number generator and write the
316
+ // formatted output into the edit
294
317
RandBytes := RandomBytes(Context.BlockSize);
295
318
EditInitVector.Text := StringOf(IVFormat.Encode(RandBytes));
296
319
end ;
@@ -299,13 +322,16 @@ procedure TFormMain.ButtonCopyClick(Sender: TObject);
299
322
var
300
323
s : string;
301
324
begin
325
+ // Copy entered data into the clipboard
302
326
s := ' //start' + sLineBreak +
303
327
' Cipher: ' +
304
328
ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex] +
305
329
sLineBreak +
306
330
' Mode: ' +
307
331
ComboBoxChainingMethod.Items[ComboBoxChainingMethod.ItemIndex] +
308
332
sLineBreak +
333
+ ' Padding mode: ' + ComboBoxPaddingMode.Items[ComboBoxPaddingMode.ItemIndex] +
334
+ sLineBreak +
309
335
' Key: ' + EditKey.Text + sLineBreak +
310
336
' Init vector: ' + EditInitVector.Text + sLineBreak +
311
337
' Filler: ' + EditFiller.Text + sLineBreak +
@@ -337,10 +363,14 @@ procedure TFormMain.ButtonDecryptClick(Sender: TObject);
337
363
AuthenticationOK : Boolean; // for authenticated ciphers: is the calculated
338
364
// authentication result value correct?
339
365
begin
366
+ // Decrypts the entered encrypted data using the settings made
367
+
368
+ // Determine desired output format
340
369
if not GetFormatSettings(PlainTextFormatting, CipherTextFormatting) then
341
370
exit;
342
371
343
372
try
373
+ // Create an instance for the cypher used to decrypt and initialize its properties
344
374
Cipher := GetInitializedCipherInstance;
345
375
346
376
try
@@ -353,16 +383,18 @@ procedure TFormMain.ButtonDecryptClick(Sender: TObject);
353
383
AuthenticationOK := false;
354
384
355
385
try
386
+ // the real decryption
356
387
CipherTextBuffer := CipherTextFormatting.Decode(CipherTextBuffer);
357
388
LabelLenChiffreText.Text := Format(' Buffer: %d bytes, Formatted: %d chars' ,
358
389
[length(CipherTextBuffer), length(EditCipherText.Text)]);
359
390
360
391
PlainTextBuffer := (Cipher as TDECFormattedCipher).DecodeBytes(CipherTextBuffer);
392
+
361
393
// in case of an authenticated cipher mode like cmGCM the Done method
362
394
// will raise an exception when the calculated authentication value does
363
395
// not match the given expected one set in SetAuthenticationParams().
364
-
365
396
(Cipher as TDECFormattedCipher).Done;
397
+
366
398
// If we managed to get to here, the calculated authentication value is
367
399
// ok if we're in an authenticated mode and have entered an expected value.
368
400
if (length(EditExpectedAuthenthicationResult.Text) > 0 ) and
@@ -383,6 +415,7 @@ procedure TFormMain.ButtonDecryptClick(Sender: TObject);
383
415
384
416
if Cipher.IsAuthenticated then
385
417
begin
418
+ // Display calculated authentication value
386
419
EditCalculatedAuthenticationValue.Text :=
387
420
StringOf(TFormat_HEXL.Encode(Cipher.CalculatedAuthenticationResult));
388
421
@@ -391,6 +424,8 @@ procedure TFormMain.ButtonDecryptClick(Sender: TObject);
391
424
TMsgDlgType.mtInformation);
392
425
end ;
393
426
427
+ // Transform decrypted data into the requested display/output format
428
+ // and display it
394
429
EditPlainText.Text := DECUtil.BytesToString(PlainTextFormatting.Encode(PlainTextBuffer));
395
430
LabelLenPlainText.Text := Format(' Buffer: %d bytes, Formatted: %d chars' ,
396
431
[length(PlainTextBuffer), length(EditPlainText.Text)]);
@@ -401,13 +436,18 @@ procedure TFormMain.ButtonDecryptClick(Sender: TObject);
401
436
TextFailed.Visible := false;
402
437
end
403
438
else
439
+ // We have remembered the last enetered plain text and can compare
440
+ // with that. This can be used to demo that this plain text I just
441
+ // encrypted wa sproperly decrypted in my immediate decryption demo
404
442
if FLastEncryptedPlainText = EditPlainText.Text then
405
443
begin
406
444
TextPassed.Visible := true;
407
445
TextFailed.Visible := false;
408
446
end
409
447
else
410
448
begin
449
+ // The demo failed, most likely because the decryption was done on
450
+ // something else than the encryption of that last used plain text
411
451
TextPassed.Visible := false;
412
452
TextFailed.Visible := true;
413
453
end ;
@@ -438,6 +478,7 @@ procedure TFormMain.ButtonEncryptClick(Sender: TObject);
438
478
exit;
439
479
440
480
try
481
+ // Create an instance for the cypher used to encrypt and initialize its properties
441
482
Cipher := GetInitializedCipherInstance;
442
483
443
484
try
@@ -446,16 +487,19 @@ procedure TFormMain.ButtonEncryptClick(Sender: TObject);
446
487
else
447
488
InputBuffer := DECUtil.RawStringToBytes(RawByteString(EditPlainText.Text));
448
489
490
+ // Check if the data to be encrypted matches the selected format
449
491
if InputFormatting.IsValid(InputBuffer) then
450
492
begin
451
493
// Set all authentication related properties
452
494
SetAuthenticationParams(Cipher);
453
495
454
496
try
497
+ // transform the text to be encrypted from the format given into a byte buffer
455
498
InputBuffer := InputFormatting.Decode(InputBuffer);
456
499
LabelLenPlainText.Text := Format(' Buffer: %d bytes, Formatted: %d chars' ,
457
500
[length(InputBuffer), length(EditPlainText.Text)]);
458
501
502
+ // Perform the actual encryption
459
503
OutputBuffer := (Cipher as TDECFormattedCipher).EncodeBytes(InputBuffer);
460
504
(Cipher as TDECFormattedCipher).Done;
461
505
FLastEncryptedPlainText := EditPlainText.Text;
@@ -465,10 +509,14 @@ procedure TFormMain.ButtonEncryptClick(Sender: TObject);
465
509
TMsgDlgType.mtError);
466
510
end ;
467
511
468
- EditCipherText.Text := string(DECUtil.BytesToRawString(OutputFormatting.Encode(OutputBuffer)));
512
+ // display the encrypted text in the selected output format
513
+ EditCipherText.Text := string(DECUtil.BytesToRawString(
514
+ OutputFormatting.Encode(OutputBuffer)));
469
515
LabelLenChiffreText.Text := Format(' Buffer: %d bytes, Formatted: %d chars' ,
470
516
[length(OutputBuffer), length(EditCipherText.Text)]);
471
517
518
+ // If the algorithm is an authenticated cipher display the calculated
519
+ // authentication value
472
520
if Cipher.IsAuthenticated then
473
521
EditCalculatedAuthenticationValue.Text :=
474
522
StringOf(TFormat_HEXL.Encode(Cipher.CalculatedAuthenticationResult));
@@ -498,6 +546,7 @@ procedure TFormMain.ComboBoxKeyIVFormatChange(Sender: TObject);
498
546
NewFormat: TDECFormatClass;
499
547
Raw : RawByteString;
500
548
begin
549
+ // determine the desired input format for the initialization vector IV
501
550
NewFormat := TDECFormat.ClassByName(
502
551
ComboBoxKeyIVFormat.Items[ComboBoxKeyIVFormat.ItemIndex]);
503
552
@@ -534,6 +583,7 @@ procedure TFormMain.ComboBoxKeyIVFormatChange(Sender: TObject);
534
583
535
584
procedure TFormMain.EditPlainCipherTextChangeTracking (Sender: TObject);
536
585
begin
586
+ // when plain text changed hide some labels related to authentication result
537
587
TextPassed.Visible := false;
538
588
TextFailed.Visible := false;
539
589
end ;
@@ -542,6 +592,7 @@ procedure TFormMain.ComboBoxCipherAlgorithmChange(Sender: TObject);
542
592
var
543
593
Context : TCipherContext;
544
594
begin
595
+ // if a different cipher algorithm is selected update the displayed meta data
545
596
Context := TDECCipher.ClassByName(
546
597
ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex]).Context;
547
598
@@ -582,6 +633,8 @@ procedure TFormMain.FormCreate(Sender: TObject);
582
633
var
583
634
AppService : IFMXApplicationService;
584
635
begin
636
+ // Display program version fetched from the binary. The platform service
637
+ // only supports a shorter format.
585
638
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationService,
586
639
IInterface(AppService)) then
587
640
LabelVersion.Text := format(LabelVersion.Text, [AppService.AppVersion])
@@ -620,6 +673,7 @@ procedure TFormMain.InitPaddingModesCombo;
620
673
var
621
674
PaddingMode: TPaddingMode;
622
675
begin
676
+ // add all available padding modes to the combo box
623
677
ComboBoxPaddingMode.Clear;
624
678
625
679
for PaddingMode := low(TPaddingMode) to high(TPaddingMode) do
@@ -674,6 +728,9 @@ function TFormMain.GetInitializedCipherInstance: TDECCipherModes;
674
728
KeyIVFormat: TDECFormatClass;
675
729
FillerByte : UInt8;
676
730
begin
731
+ // Get data from the user input or where it is missing define some
732
+
733
+ // Initialization vector IV fill up byte for too short vectors entered
677
734
if not EditFiller.Text.IsEmpty then
678
735
begin
679
736
while length(EditFiller.Text) < 2 do
@@ -685,13 +742,17 @@ function TFormMain.GetInitializedCipherInstance: TDECCipherModes;
685
742
// we need to assume something to be able to call that init overload
686
743
FillerByte := 0 ;
687
744
745
+ // get selected input format for IV
688
746
KeyIVFormat := TDECFormat.ClassByName(
689
747
ComboBoxKeyIVFormat.Items[ComboBoxKeyIVFormat.ItemIndex]);
690
748
Assert(Assigned(KeyIVFormat), ' Missing format' );
691
749
750
+ // Check entered IV for format/syntax validity
692
751
if KeyIVFormat.IsValid(RawByteString(EditInitVector.Text)) and
693
752
KeyIVFormat.IsValid(RawByteString(EditKey.Text)) then
694
753
begin
754
+ // Create instance of the cipher algorithm and initialize it using key, IV
755
+ // and padding mode given by the user
695
756
Result := GetCipherInstance;
696
757
Result.Init(RawStringToBytes(KeyIVFormat.Decode(RawByteString(EditKey.Text))),
697
758
RawStringToBytes(KeyIVFormat.Decode(RawByteString(EditInitVector.Text))),
@@ -705,21 +766,23 @@ function TFormMain.GetSelectedCipherMode: TCipherMode;
705
766
var
706
767
ModeStr : string;
707
768
begin
769
+ // Display value of the selected block concatenation mode
708
770
ModeStr := ComboBoxChainingMethod.Items[ComboBoxChainingMethod.ItemIndex];
709
771
772
+ // remove things only present for display purposes
710
773
if ModeStr.Contains(' (' ) then
711
774
ModeStr := ModeStr.Remove(ModeStr.IndexOf(' (' )-1 );
712
775
713
776
// Determine selected block chaining method via RTTI (runtime type information)
714
777
Result := TCipherMode(System.TypInfo.GetEnumValue(
715
- TypeInfo(TCipherMode),
716
- ModeStr));
778
+ TypeInfo(TCipherMode), ModeStr));
717
779
end ;
718
780
719
781
function TFormMain.GetSelectedPaddingMode : TPaddingMode;
720
782
var
721
783
ModeStr : string;
722
784
begin
785
+ // Display value of the selected padding mode (filling up a last incomplete block)
723
786
ModeStr := ComboBoxPaddingMode.Items[ComboBoxPaddingMode.ItemIndex];
724
787
// Determine selected block chaining method via RTTI (runtime type information)
725
788
Result := TPaddingMode(System.TypInfo.GetEnumValue(TypeInfo(TPaddingMode),
@@ -731,6 +794,7 @@ procedure TFormMain.InitCipherCombo;
731
794
MyClass : TPair<Int64, TDECClass>;
732
795
Ciphers : TStringList;
733
796
begin
797
+ // List all registered ciphers in the combobox
734
798
Ciphers := TStringList.Create;
735
799
736
800
try
@@ -757,6 +821,7 @@ procedure TFormMain.InitCipherModes;
757
821
CipherMode : TCipherMode;
758
822
Name : string;
759
823
begin
824
+ // List all available block chaining modes in the combobox
760
825
ComboBoxChainingMethod.Clear;
761
826
for CipherMode := low(TCipherMode) to high(TCipherMode) do
762
827
begin
0 commit comments