Why is this an issue?
Encryption algorithms should use secure modes and padding schemes where appropriate to guarantee data confidentiality and integrity.
- For block cipher encryption algorithms (like AES):
- The ECB (Electronic Codebook) cipher mode doesn’t provide serious message confidentiality: under a given key any given plaintext block
always gets encrypted to the same ciphertext block. This mode should never be used.
- The CBC (Cipher Block Chaining) mode by itself provides only data confidentiality. This cipher mode is also vulnerable to padding oracle attacks when used with padding. Using CBC along with Message
Authentication Code can provide data integrity and should prevent such attacks. In practice the implementation has many pitfalls and it’s
recommended to avoid CBC with padding completely.
- The GCM (Galois Counter Mode) mode which works
internally with zero/no padding scheme, is recommended, as it is designed to provide both data authenticity (integrity) and confidentiality.
Other similar modes are CCM, CWC, EAX, IAPM and OCB.
- For RSA encryption algorithm, the recommended padding scheme is OAEP.
Noncompliant code example
botan
#include <botan/cipher_mode.h>
#include <botan/pubkey.h>
#include <botan/rsa.h>
// Example for a symmetric cipher: AES
Botan::Cipher_Mode::create("AES-256/ECB", Botan::ENCRYPTION); // Noncompliant
Botan::Cipher_Mode::create("AES-256/CBC/PKCS7", Botan::ENCRYPTION); // Noncompliant
// Example for a asymmetric cipher: RSA
std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);
Botan::RSA_PrivateKey rsaKey(*rng.get(), 2048);
Botan::PK_Encryptor_EME(rsaKey, *rng.get(), "PKCS1v15"); // Noncompliant
crypto++
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/rsa.h>
// Example for a symmetric cipher: AES
CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption(); // Noncompliant
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption(); // Noncompliant
// Example for a asymmetric cipher: RSA
CryptoPP::RSAES<CryptoPP::PKCS1v15>::Encryptor(); // Noncompliant
OpenSSL
#include <openssl/evp.h>
#include <openssl/rsa.h>
// Example for a symmetric cipher: AES
EVP_aes_128_ecb(); // Noncompliant
EVP_aes_128_cbc(); // Noncompliant
// Example for a asymmetric cipher: RSA
RSA_public_decrypt(flen, from, to, key, RSA_PKCS1_PADDING); // Noncompliant
RSA_public_decrypt(flen, from, to, key, RSA_SSLV23_PADDING); // Noncompliant
RSA_public_decrypt(flen, from, to, key, RSA_NO_PADDING); // Noncompliant
Compliant solution
botan
#include <botan/cipher_mode.h>
#include <botan/pubkey.h>
#include <botan/rsa.h>
// AES symmetric cipher is recommended to be used with GCM mode
Botan::Cipher_Mode::create("AES-256/GCM", Botan::ENCRYPTION); // Compliant
// RSA asymmetric cipher is recommended to be used with OAEP padding
std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);
Botan::RSA_PrivateKey rsaKey(*rng.get(), 2048);
Botan::PK_Encryptor_EME(rsaKey, *rng.get(), "OAEP"); // Compliant
crypto++
#include <cryptopp/gcm.h>
// AES symmetric cipher is recommended to be used with GCM mode
CryptoPP::GCM<CryptoPP::AES>::Encryption(); // Compliant
// RSA asymmetric cipher is recommended to be used with OAEP padding
CryptoPP::RSAES<CryptoPP::OAEP<CryptoPP::SHA1>>::Encryptor(); // Compliant
OpenSSL
#include <openssl/evp.h>
// AES symmetric cipher is recommended to be used with GCM mode
EVP_aes_128_gcm() // Compliant
// RSA asymmetric cipher is recommended be used with OAEP padding
RSA_public_decrypt(flen, from, to, key, RSA_PKCS1_OAEP_PADDING); // Compliant
Resources