AES-GCM and (ECB, OFB, CFB) Encryption in ABAP


Symptom

You need AES-GCM (Galois/Counter Mode) or one of the other modes (ECB, OFB, CFB) Encryption/Decryption in ABAP.

Problems

SAP offers neither solution nor support for this. See 2972991 and 3074516.

For GCM you cannot use OpenSSL either.

Standard ABAP. Monalisa Biswal has written a blog about AES Encryption.
But the standard cl_sec_sxml_writer methods { decrypt / encrypt } support only Cipher Block Chaining CBC. In encrypt you cannot even supply the IV. It is randomly generated for you. cl_sec_sxml_writer has another method crypt_aes_ctr, which provides counter mode CTR.

Possible solutions

There is a pure ABAP implementation: https://github.com/Sumu-Ning/AES.
It has support for modes ECB, OFB, CFB, CTR, CBC and PCBC.
GCM is still missing.

For GCM decryption if the IV is exactly 12 bytes and you don’t care about the TAG you may have  a look here.

Solution

Here you can find complete AES-GCM implementation in ABAP: https://github.com/rstenet/abap-aes.

Additional to GCM it is offering ECB, OFB and CFB modes. The methods are basically wrappers around the methods decrypt, encrypt and encrypt_iv of class cl_sec_sxml_writer.

Using the Kernel to do the AES encrypt/decrypt results in hundreds of times better performance for ECB, OFB and CFB compared to the pure ABAP implementation above.

GCM consists of 2 functions: encryption AES-CTR and authentication. As the authentication (ghash/gf_multiply) is implemented in ABAP performance will be slow.

It is not perfect though. You have to care about padding and the nonce when needed . For GCM only 128 bit TAG is implemented. Other lengths can be easily implemented, as this will require just stripping the extra length.

Example

DATA: key TYPE xstring, iv TYPE xstring, plain TYPE xstring, cipher TYPE xstring, aad TYPE xstring, tag TYPE xstring, l_plain TYPE xstring, l_cipher TYPE xstring, l_tag TYPE xstring. " test case 16
key = 'FEFFE9928665731C6D6A8F9467308308FEFFE9928665731C6D6A8F9467308308'.
iv = 'CAFEBABEFACEDBADDECAF888'.
plain = 'D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39'.
cipher = '522DC1F099567D07F47F37A32A84427D643A8CDCBFE5C0C97598A2BD2555D1AA8CB08E48590DBB3DA7B08B1056828838C5F61E6393BA7A0ABCC9F662'.
aad = 'FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2'.
tag = '76FC6ECE0F4E1768CDDF8853BB2D551B'. zcl_aes=>encrypt_aes_gcm( EXPORTING plain = plain key = key iv = iv aad = aad IMPORTING cipher = l_cipher tag = l_tag
). zcl_aes=>decrypt_aes_gcm( EXPORTING cipher = l_cipher key = key iv = iv aad = aad tag = l_tag IMPORTING plain = l_plain
).

More examples and test cases are here. The tests for GCM are taken from the AES-GCM Specs.

To summarize

AES Encryption in ABAP is possible for all modes using the Kernel. This way we don’t have to take countermeasures against side channel attacks or the like. CommonCryptoLib is doing this for us. The authentication TAG in GCM is still calculated in ABAP, but it doesn’t involve the key.
I hope someone will find it (especially GCM) useful.

Thank you for reading. Please feel free to send me a message or write a comment here.