Weak Encryption Mode of Operation

ID

swift.weak_encryption_mode_of_operation

Severity

critical

Resource

Cryptography

Language

Swift

Tags

CWE:327, MASWE:0020, NIST.SP.800-53, OWASP:2021:A2, PCI-DSS:6.5.3, crypto

Description

The use of weak encryption modes of operation, such as ECB, can compromise the confidentiality and integrity of data by allowing patterns to be detected in encrypted data. This is particularly pertinent in applications where secure encryption practices are crucial for protecting sensitive information.

Rationale

Certain encryption modes like Electronic Codebook (ECB) are considered weak because they encrypt identical plaintext blocks into identical ciphertext blocks.

This lack of semantic security may lead to pattern detection, data leakage, or could aid attackers in deciphering the content. Using stronger modes such as Cipher Block Chaining (CBC) or Galois/Counter Mode (GCM) enhances security by introducing an initialization vector (IV) or nonce, ensuring that ciphertext appears random even when plaintexts are identical.

In Swift, using ECB mode is a critical vulnerability:

Vulnerable: Using ECB mode with CryptoSwift
import CryptoSwift

func encryptWithECB(_ plaintext: String, key: [UInt8]) throws -> [UInt8] {
    // FLAW: ECB mode reveals patterns in plaintext
    let blockMode = ECB()  // FLAW
    let aes = try AES(key: key, blockMode: blockMode, padding: .pkcs7)
    return try aes.encrypt(Array(plaintext.utf8))
}

Another vulnerable example with Blowfish:

Vulnerable: Blowfish with ECB mode
import CryptoSwift

func encryptBlowfishECB(_ data: Data, key: [UInt8]) throws -> [UInt8] {
    // FLAW: ECB mode with Blowfish
    let blockMode = ECB()  // FLAW
    let blowfish = try Blowfish(key: key, blockMode: blockMode, padding: .pkcs7)
    return try blowfish.encrypt([UInt8](data))
}

Remediation

To remediate the use of weak encryption modes, it is advisable to use secure modes such as CBC or GCM, which require an IV or nonce, thus preventing pattern detection and data leakage. Below is an example using AES-128-CBC with a random IV:

For Swift, use secure modes with proper IV / nonce generation:

Fixed: Using CBC mode with random IV
import CryptoSwift

struct EncryptedData {
    let ciphertext: [UInt8]
    let iv: [UInt8]
}

func encryptWithCBC(_ plaintext: String, key: [UInt8]) throws -> EncryptedData {
    // FIXED: CBC mode with random IV
    let iv = (0..<AES.blockSize).map { _ in UInt8.random(in: 0...UInt8.max) }
    let blockMode = CBC(iv: iv)  // FIXED

    let aes = try AES(key: key, blockMode: blockMode, padding: .pkcs7)
    let ciphertext = try aes.encrypt(Array(plaintext.utf8))

    return EncryptedData(ciphertext: ciphertext, iv: iv)
}

Better yet, use CryptoKit with AES-GCM (AEAD):

Fixed: Using CryptoKit AES-GCM (AEAD)
import CryptoKit
import Foundation

func encryptWithAESGCM(_ plaintext: Data, key: SymmetricKey) throws -> Data {
    // FIXED: AES-GCM provides authenticated encryption
    let sealedBox = try AES.GCM.seal(plaintext, using: key)

    // Combined data includes nonce, ciphertext, and authentication tag
    return sealedBox.combined!
}

func decryptWithAESGCM(_ combined: Data, key: SymmetricKey) throws -> Data {
    let sealedBox = try AES.GCM.SealedBox(combined: combined)
    return try AES.GCM.open(sealedBox, using: key)
}

Using ChaCha20-Poly1305 for authenticated encryption:

Fixed: ChaCha20-Poly1305 (AEAD)
import CryptoKit
import Foundation

func encryptWithChaCha20Poly1305(_ plaintext: Data, key: SymmetricKey) throws -> Data {
    // FIXED: ChaCha20-Poly1305 provides authenticated encryption
    let nonce = try ChaChaPoly.Nonce(data: Data(count: 12))
    let sealedBox = try ChaChaPoly.seal(plaintext, using: key, nonce: nonce)

    return sealedBox.combined
}

func decryptWithChaCha20Poly1305(_ combined: Data, key: SymmetricKey) throws -> Data {
    let sealedBox = try ChaChaPoly.SealedBox(combined: combined)
    return try ChaChaPoly.open(sealedBox, using: key)
}

Configuration

The detector has the following configurable parameters:

  • forbiddenModes, that indicates the modes that are considered weak and that should not be used.

Example configuration:

properties:
  forbiddenModes:
    - ECB  # Electronic Codebook - never secure
    - CTR  # Counter mode - dangerous without proper nonce management

References