Bug 2095251

Summary: Input size for AES-GCM is not limited
Product: Red Hat Enterprise Linux 9 Reporter: Ondrej Moriš <omoris>
Component: gnutlsAssignee: Daiki Ueno <dueno>
Status: CLOSED CURRENTRELEASE QA Contact: Ondrej Moriš <omoris>
Severity: unspecified Docs Contact:
Priority: high    
Version: 9.0CC: asosedki, ssorce
Target Milestone: rcKeywords: Triaged, ZStream
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: gnutls-3.7.6-3.el9 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 2108635 (view as bug list) Environment:
Last Closed: 2023-05-25 14:30:29 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2108635    

Description Ondrej Moriš 2022-06-09 11:16:28 UTC
Description of problem:

GnuTLS seems not to restrict the size of input for AES-GCM encryption even though NIST SP 800-38D recommends to limit it to 2^39 - 256 bits, ie. 64 GiB (recommendation for GCM mode, 5.2.1.1 Input Data).

I don't see any limits hardcoded in the code of AES-GCM and hence I tried to test is via gnutls_aead_cipher_encryptv2() as follows:

...
uint8_t data[1024];
...
iov[0].iov_len = sizeof(data);
...
gnutls_aead_cipher_init(&ch, algo, &key);
gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 1, iov,
1, tag, &tag_size);
...
gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 1, iov,
1, tag, &tag_size);
gnutls_aead_cipher_deinit(ch);

Encryption still works after the limit of 64 GiB of encrypted data is reached. Daiki confirmed that there is a limit only on TLS level but it is higher:

 * https://datatracker.ietf.org/doc/html/rfc8446#section-5.5

Even though FIPS indicators can be used to indicate when the input data size limit is reached I think the limit recommendation actually makes sense regardless of FIPS mode (this is how it work in both OpenSSL and NSS).

Version-Release number of selected component (if applicable):

gnutls-3.7.3-9.el9

Additional info:

I can supply a simple reproducer once the logic of using gnutls_aead_cipher_encryptv2() mentioned above is confirmed.

Comment 1 Daiki Ueno 2022-06-09 12:27:31 UTC
(In reply to Ondrej Moriš from comment #0)

> gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 1, iov,
> 1, tag, &tag_size);
> ...
> gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 1, iov,
> 1, tag, &tag_size);

If I understand correctly, the limit specified in SP800-38D is per message, so I don't think it applies to repeated calls like this,
where applications are supposed to supply unique IV to each gnutls_aead_cipher_encryptv2 call.

Therefore I think the only thing we could do is to add a limit check (i.e., the length of iov is lower than the limit, per message) in gnutls_aead_cipher_encryptv2.

> Even though FIPS indicators can be used to indicate when the input data size
> limit is reached I think the limit recommendation actually makes sense
> regardless of FIPS mode (this is how it work in both OpenSSL and NSS).

I agree.

Comment 2 Ondrej Moriš 2022-06-09 12:54:33 UTC
(In reply to Daiki Ueno from comment #1)
> (In reply to Ondrej Moriš from comment #0)
> 
> > gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 1, iov,
> > 1, tag, &tag_size);
> > ...
> > gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 1, iov,
> > 1, tag, &tag_size);
> 
> If I understand correctly, the limit specified in SP800-38D is per message,
> so I don't think it applies to repeated calls like this,
> where applications are supposed to supply unique IV to each
> gnutls_aead_cipher_encryptv2 call.
> 
> Therefore I think the only thing we could do is to add a limit check (i.e.,
> the length of iov is lower than the limit, per message) in
> gnutls_aead_cipher_encryptv2.

Right, I was also not sure about this approach, hence your proposal makes sense to me.