aws / aws/aws-lc

Add public CRYPTO_cts128_encrypt/_decrypt and <openssl/modes.h> for krb5 integration

Open
#3,309 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Assembly
Stars
830
Forks
212
Avg merge
2d 22h
Merged PRs (30d)
61

Description

## Summary

AWS-LC currently has no public AES Ciphertext Stealing (CTS) API. There is an internal declaration of `CRYPTO_cts128_encrypt_block` in `crypto/fipsmodule/modes/internal.h:411`, but no implementation exists, and `` is not shipped at all.

This blocks integration with MIT krb5 (and likely other consumers) which uses CTS for the standard Kerberos enctypes.

## Background

MIT krb5's `lib/crypto/openssl/enc_provider/aes.c` and `camellia.c` implement AES-CTS / Camellia-CTS for the `aes128-cts-hmac-*` and `camellia*-cts-cmac` enctypes. On the OpenSSL <3.0 path it calls:

```c
#include
size = CRYPTO_cts128_encrypt(dbuf, oblock, dlen, &enck, iv_cts,
(cbc128_f)AES_cbc_encrypt);
size = CRYPTO_cts128_decrypt(dbuf, oblock, dlen, &deck, iv_cts,
(cbc128_f)AES_cbc_encrypt);
```

On the OpenSSL ≥3.0 path it uses `EVP_CIPHER_fetch("AES-128-CBC-CTS")` plus `OSSL_PARAM`s — provider/property infrastructure that AWS-LC does not implement and is not on a roadmap.

Since AWS-LC reports `OPENSSL_VERSION_NUMBER < 0x30000000L` for compatibility, krb5 takes the legacy path and tries to `#include `. AWS-LC doesn't ship that header, so the include falls through to system OpenSSL 3.x's `/usr/include/openssl/modes.h`, which transitively pulls OpenSSL 3.x's `` and produces typedef collisions on `EVP_MD`, `EVP_MD_CTX`, `ASN1_NULL`, `EVP_ENCODE_CTX`, etc. Even if the include were resolved (e.g. by shipping a stub `modes.h`), `CRYPTO_cts128_encrypt` and `CRYPTO_cts128_decrypt` are still undefined at link time.

This was discovered while adding a krb5 integration test in #3308.

## Asks

1. **Implement `CRYPTO_cts128_encrypt` and `CRYPTO_cts128_decrypt`** (CS1 / RFC 2040 RC5-CTS variant — this is what OpenSSL's legacy API does and what krb5 calls). These wrap a caller-provided `cbc128_f` and process arbitrary-length input ≥ one block.

2. **Ship a public ``** exporting:
- `cbc128_f` (typedef)
- `CRYPTO_cts128_encrypt`
- `CRYPTO_cts128_decrypt`
- And, for symmetry, the existing `CRYPTO_cbc128_encrypt`/`_decrypt` and `CRYPTO_cfb128_*` already declared internally — these are commonly imported by OpenSSL consumers.

3. **Add comprehensive tests** with NIST / RFC 2040 vectors covering:
- All input lengths from 17 bytes through several full-block multiples (boundary conditions: residue == 1, residue == blocksize, residue in between)
- Encrypt/decrypt roundtrip
- Decrypt of a known-good ciphertext (asymmetric verification)
- IV update behavior matches OpenSSL's

The CS3 ("always swap") variant used by krb5's OpenSSL-3.x path is *not* requested here; CS1 alone is what unblocks the krb5 integration on the legacy path AWS-LC is compatible with.

## Acceptance criteria

- `` is installed as a public header and `CRYPTO_cts128_*` symbols are exported from `libcrypto`.
- The MIT krb5 integration test (#3308) builds and passes against AWS-LC.
- New unit tests cover all input-length boundary cases and verify against fixed reference vectors.

Contributor guide

Open the contributing guide

Research direction

Start with the internal declaration of CRYPTO_cts128_encrypt_block in crypto/fipsmodule/modes/internal.h:411, then read MIT krb5's lib/crypto/openssl/enc_provider/aes.c and camellia.c to understand the legacy calls. Check the integration test from #3308 and verify that openssl/modes.h is installed, the CTS symbols are exported, and the new vectors cover the stated lengths, round trips, IV behavior, and fixed ciphertexts.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
cryptography
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.