1313import org .bouncycastle .tls .crypto .TlsCryptoUtils ;
1414import org .bouncycastle .tls .crypto .TlsDecodeResult ;
1515import org .bouncycastle .tls .crypto .TlsEncodeResult ;
16+ import org .bouncycastle .tls .crypto .TlsNonceGenerator ;
1617import org .bouncycastle .tls .crypto .TlsSecret ;
1718import org .bouncycastle .util .Arrays ;
1819
20+ import static org .bouncycastle .jsse .provider .GcmTls12NonceGeneratorUtil .createGcmFipsNonceGenerator ;
21+ import static org .bouncycastle .jsse .provider .GcmTls12NonceGeneratorUtil .isGcmFipsNonceGeneratorFactorySet ;
22+
1923/**
2024 * A generic TLS 1.2 AEAD cipher.
2125 */
@@ -30,6 +34,8 @@ public final class TlsAEADCipher
3034 private static final int NONCE_RFC7905 = 2 ;
3135 private static final long SEQUENCE_NUMBER_PLACEHOLDER = -1L ;
3236
37+ private static final byte [] EPOCH_1 = {0x00 , 0x01 };
38+
3339 private final TlsCryptoParameters cryptoParams ;
3440 private final int keySize ;
3541 private final int macSize ;
@@ -43,6 +49,7 @@ public final class TlsAEADCipher
4349
4450 private final boolean isTLSv13 ;
4551 private final int nonceMode ;
52+ private final TlsNonceGenerator gcmFipsNonceGenerator ;
4653
4754 public TlsAEADCipher (TlsCryptoParameters cryptoParams , TlsAEADCipherImpl encryptCipher , TlsAEADCipherImpl decryptCipher ,
4855 int keySize , int macSize , int aeadType ) throws IOException
@@ -91,6 +98,7 @@ public TlsAEADCipher(TlsCryptoParameters cryptoParams, TlsAEADCipherImpl encrypt
9198 final boolean isServer = cryptoParams .isServer ();
9299 if (isTLSv13 )
93100 {
101+ gcmFipsNonceGenerator = null ;
94102 rekeyCipher (securityParameters , decryptCipher , decryptNonce , !isServer );
95103 rekeyCipher (securityParameters , encryptCipher , encryptNonce , isServer );
96104 return ;
@@ -121,6 +129,28 @@ public TlsAEADCipher(TlsCryptoParameters cryptoParams, TlsAEADCipherImpl encrypt
121129 {
122130 throw new TlsFatalAlert (AlertDescription .internal_error );
123131 }
132+
133+ if (AEAD_GCM == aeadType && isGcmFipsNonceGeneratorFactorySet ())
134+ {
135+ final int nonceLength = fixed_iv_length + record_iv_length ;
136+ final byte [] baseNonce = Arrays .copyOf (encryptNonce , nonceLength );
137+ final int counterSizeInBits ;
138+ if (negotiatedVersion .isDTLS ())
139+ {
140+ counterSizeInBits = (record_iv_length - 2 ) * 8 ; // 48
141+ baseNonce [baseNonce .length - 8 ] ^= EPOCH_1 [0 ];
142+ baseNonce [baseNonce .length - 7 ] ^= EPOCH_1 [1 ];
143+ }
144+ else
145+ {
146+ counterSizeInBits = record_iv_length * 8 ; // 64
147+ }
148+ gcmFipsNonceGenerator = createGcmFipsNonceGenerator (baseNonce , counterSizeInBits );
149+ }
150+ else
151+ {
152+ gcmFipsNonceGenerator = null ;
153+ }
124154 }
125155
126156 public int getCiphertextDecodeLimit (int plaintextLimit )
@@ -154,24 +184,33 @@ public int getPlaintextEncodeLimit(int ciphertextLimit)
154184 public TlsEncodeResult encodePlaintext (long seqNo , short contentType , ProtocolVersion recordVersion ,
155185 int headerAllocation , byte [] plaintext , int plaintextOffset , int plaintextLength ) throws IOException
156186 {
157- byte [] nonce = new byte [encryptNonce .length + record_iv_length ];
187+ final int nonceSize = encryptNonce .length + record_iv_length ;
188+ final byte [] nonce ;
158189
159- switch ( nonceMode )
190+ if ( null != gcmFipsNonceGenerator )
160191 {
161- case NONCE_RFC5288 :
162- System .arraycopy (encryptNonce , 0 , nonce , 0 , encryptNonce .length );
163- // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
164- TlsUtils .writeUint64 (seqNo , nonce , encryptNonce .length );
165- break ;
166- case NONCE_RFC7905 :
167- TlsUtils .writeUint64 (seqNo , nonce , nonce .length - 8 );
168- for (int i = 0 ; i < encryptNonce .length ; ++i )
192+ nonce = gcmFipsNonceGenerator .generateNonce (nonceSize );
193+ }
194+ else
195+ {
196+ nonce = new byte [nonceSize ];
197+ switch (nonceMode )
169198 {
170- nonce [i ] ^= encryptNonce [i ];
199+ case NONCE_RFC5288 :
200+ System .arraycopy (encryptNonce , 0 , nonce , 0 , encryptNonce .length );
201+ // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number.
202+ TlsUtils .writeUint64 (seqNo , nonce , encryptNonce .length );
203+ break ;
204+ case NONCE_RFC7905 :
205+ TlsUtils .writeUint64 (seqNo , nonce , nonce .length - 8 );
206+ for (int i = 0 ; i < encryptNonce .length ; ++i )
207+ {
208+ nonce [i ] ^= encryptNonce [i ];
209+ }
210+ break ;
211+ default :
212+ throw new TlsFatalAlert (AlertDescription .internal_error );
171213 }
172- break ;
173- default :
174- throw new TlsFatalAlert (AlertDescription .internal_error );
175214 }
176215
177216 // TODO[tls13, cid] If we support adding padding to (D)TLSInnerPlaintext, this will need review
0 commit comments