@ -30,73 +30,119 @@
# include "../test/test_util.h"
# include "../test/wycheproof_util.h"
// kLimitedImplementation indicates that tests that assume a generic AEAD
// interface should not be performed. For example, the key-wrap AEADs only
// handle inputs that are a multiple of eight bytes in length and the TLS CBC
// AEADs have the concept of “direction”.
constexpr uint32_t kLimitedImplementation = 1 < < 0 ;
// kCanTruncateTags indicates that the AEAD supports truncatating tags to
// arbitrary lengths.
constexpr uint32_t kCanTruncateTags = 1 < < 1 ;
// kVariableNonce indicates that the AEAD supports a variable-length nonce.
constexpr uint32_t kVariableNonce = 1 < < 2 ;
// RequiresADLength encodes an AD length requirement into flags.
constexpr uint32_t RequiresADLength ( size_t length ) {
// If we had a more recent C++ version we could assert that the length is
// sufficiently small with:
//
// if (length >= 16) {
// __builtin_unreachable();
// }
return ( length & 0xf ) < < 3 ;
}
// RequiredADLength returns the AD length requirement encoded in |flags|, or
// zero if there isn't one.
constexpr size_t RequiredADLength ( uint32_t flags ) {
return ( flags > > 3 ) & 0xf ;
}
struct KnownAEAD {
const char name [ 40 ] ;
const EVP_AEAD * ( * func ) ( void ) ;
const char * test_vectors ;
// limited_implementation indicates that tests that assume a generic AEAD
// interface should not be performed. For example, the key-wrap AEADs only
// handle inputs that are a multiple of eight bytes in length and the TLS CBC
// AEADs have the concept of “direction”.
bool limited_implementation ;
// truncated_tags is true if the AEAD supports truncating tags to arbitrary
// lengths.
bool truncated_tags ;
// variable_nonce is true if the AEAD supports a variable nonce length.
bool variable_nonce ;
// ad_len, if non-zero, is the required length of the AD.
size_t ad_len ;
uint32_t flags ;
} ;
static const struct KnownAEAD kAEADs [ ] = {
{ " AES_128_GCM " , EVP_aead_aes_128_gcm , " aes_128_gcm_tests.txt " , false , true ,
true , 0 } ,
{ " AES_128_GCM " , EVP_aead_aes_128_gcm , " aes_128_gcm_tests.txt " ,
kCanTruncateTags | kVariableNonce } ,
{ " AES_128_GCM_NIST " , EVP_aead_aes_128_gcm , " nist_cavp/aes_128_gcm.txt " ,
false , true , true , 0 } ,
{ " AES_192_GCM " , EVP_aead_aes_192_gcm , " aes_192_gcm_tests.txt " , false , true ,
true , 0 } ,
{ " AES_256_GCM " , EVP_aead_aes_256_gcm , " aes_256_gcm_tests.txt " , false , true ,
true , 0 } ,
kCanTruncateTags | kVariableNonce } ,
{ " AES_192_GCM " , EVP_aead_aes_192_gcm , " aes_192_gcm_tests.txt " ,
kCanTruncateTags | kVariableNonce } ,
{ " AES_256_GCM " , EVP_aead_aes_256_gcm , " aes_256_gcm_tests.txt " ,
kCanTruncateTags | kVariableNonce } ,
{ " AES_256_GCM_NIST " , EVP_aead_aes_256_gcm , " nist_cavp/aes_256_gcm.txt " ,
false , true , true , 0 } ,
kCanTruncateTags | kVariableNonce } ,
{ " AES_128_GCM_SIV " , EVP_aead_aes_128_gcm_siv , " aes_128_gcm_siv_tests.txt " ,
false , false , false , 0 } ,
0 } ,
{ " AES_256_GCM_SIV " , EVP_aead_aes_256_gcm_siv , " aes_256_gcm_siv_tests.txt " ,
false , false , false , 0 } ,
0 } ,
{ " ChaCha20Poly1305 " , EVP_aead_chacha20_poly1305 ,
" chacha20_poly1305_tests.txt " , false , true , false , 0 } ,
" chacha20_poly1305_tests.txt " , kCanTruncateTags } ,
{ " XChaCha20Poly1305 " , EVP_aead_xchacha20_poly1305 ,
" xchacha20_poly1305_tests.txt " , false , true , false , 0 } ,
" xchacha20_poly1305_tests.txt " , kCanTruncateTags } ,
{ " AES_128_CBC_SHA1_TLS " , EVP_aead_aes_128_cbc_sha1_tls ,
" aes_128_cbc_sha1_tls_tests.txt " , true , false , false , 11 } ,
" aes_128_cbc_sha1_tls_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_128_CBC_SHA1_TLSImplicitIV " ,
EVP_aead_aes_128_cbc_sha1_tls_implicit_iv ,
" aes_128_cbc_sha1_tls_implicit_iv_tests.txt " , true , false , false , 11 } ,
" aes_128_cbc_sha1_tls_implicit_iv_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_128_CBC_SHA256_TLS " , EVP_aead_aes_128_cbc_sha256_tls ,
" aes_128_cbc_sha256_tls_tests.txt " , true , false , false , 11 } ,
" aes_128_cbc_sha256_tls_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_256_CBC_SHA1_TLS " , EVP_aead_aes_256_cbc_sha1_tls ,
" aes_256_cbc_sha1_tls_tests.txt " , true , false , false , 11 } ,
" aes_256_cbc_sha1_tls_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_256_CBC_SHA1_TLSImplicitIV " ,
EVP_aead_aes_256_cbc_sha1_tls_implicit_iv ,
" aes_256_cbc_sha1_tls_implicit_iv_tests.txt " , true , false , false , 11 } ,
" aes_256_cbc_sha1_tls_implicit_iv_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_256_CBC_SHA256_TLS " , EVP_aead_aes_256_cbc_sha256_tls ,
" aes_256_cbc_sha256_tls_tests.txt " , true , false , false , 11 } ,
" aes_256_cbc_sha256_tls_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_256_CBC_SHA384_TLS " , EVP_aead_aes_256_cbc_sha384_tls ,
" aes_256_cbc_sha384_tls_tests.txt " , true , false , false , 11 } ,
" aes_256_cbc_sha384_tls_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " DES_EDE3_CBC_SHA1_TLS " , EVP_aead_des_ede3_cbc_sha1_tls ,
" des_ede3_cbc_sha1_tls_tests.txt " , true , false , false , 11 } ,
" des_ede3_cbc_sha1_tls_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " DES_EDE3_CBC_SHA1_TLSImplicitIV " ,
EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv ,
" des_ede3_cbc_sha1_tls_implicit_iv_tests.txt " , true , false , false , 11 } ,
" des_ede3_cbc_sha1_tls_implicit_iv_tests.txt " ,
kLimitedImplementation | RequiresADLength ( 11 ) } ,
{ " AES_128_CTR_HMAC_SHA256 " , EVP_aead_aes_128_ctr_hmac_sha256 ,
" aes_128_ctr_hmac_sha256.txt " , false , true , false , 0 } ,
" aes_128_ctr_hmac_sha256.txt " , kCanTruncateTags } ,
{ " AES_256_CTR_HMAC_SHA256 " , EVP_aead_aes_256_ctr_hmac_sha256 ,
" aes_256_ctr_hmac_sha256.txt " , false , true , false , 0 } ,
" aes_256_ctr_hmac_sha256.txt " , kCanTruncateTags } ,
{ " AES_128_CCM_BLUETOOTH " , EVP_aead_aes_128_ccm_bluetooth ,
" aes_128_ccm_bluetooth_tests.txt " , false , false , false , 0 } ,
" aes_128_ccm_bluetooth_tests.txt " , 0 } ,
{ " AES_128_CCM_BLUETOOTH_8 " , EVP_aead_aes_128_ccm_bluetooth_8 ,
" aes_128_ccm_bluetooth_8_tests.txt " , false , false , false , 0 } ,
" aes_128_ccm_bluetooth_8_tests.txt " , 0 } ,
} ;
class PerAEADTest : public testing : : TestWithParam < KnownAEAD > {
@ -409,7 +455,7 @@ TEST_P(PerAEADTest, CleanupAfterInitFailure) {
}
TEST_P ( PerAEADTest , TruncatedTags ) {
if ( ! GetParam ( ) . truncated_tags ) {
if ( ! ( GetParam ( ) . flags & kCanTruncateTags ) ) {
return ;
}
@ -469,7 +515,7 @@ TEST_P(PerAEADTest, TruncatedTags) {
}
TEST_P ( PerAEADTest , AliasedBuffers ) {
if ( GetParam ( ) . limited_i mplementation) {
if ( GetParam ( ) . flags & kLimitedI mplementation) {
return ;
}
@ -555,8 +601,9 @@ TEST_P(PerAEADTest, UnalignedInput) {
ASSERT_GE ( sizeof ( key ) - 1 , key_len ) ;
const size_t nonce_len = EVP_AEAD_nonce_length ( aead ( ) ) ;
ASSERT_GE ( sizeof ( nonce ) - 1 , nonce_len ) ;
const size_t ad_len =
GetParam ( ) . ad_len ! = 0 ? GetParam ( ) . ad_len : sizeof ( ad ) - 1 ;
const size_t ad_len = RequiredADLength ( GetParam ( ) . flags ) ! = 0
? RequiredADLength ( GetParam ( ) . flags )
: sizeof ( ad ) - 1 ;
ASSERT_GE ( sizeof ( ad ) - 1 , ad_len ) ;
// Encrypt some input.
@ -619,7 +666,7 @@ TEST_P(PerAEADTest, InvalidNonceLength) {
// variable-length nonces, it does not allow the empty nonce.
nonce_lens . push_back ( 0 ) ;
}
if ( ! GetParam ( ) . variable_nonce ) {
if ( ! ( GetParam ( ) . flags & kVariableNonce ) ) {
nonce_lens . push_back ( valid_nonce_len + 1 ) ;
if ( valid_nonce_len ! = 0 ) {
nonce_lens . push_back ( valid_nonce_len - 1 ) ;
@ -627,7 +674,9 @@ TEST_P(PerAEADTest, InvalidNonceLength) {
}
static const uint8_t kZeros [ EVP_AEAD_MAX_KEY_LENGTH ] = { 0 } ;
const size_t ad_len = GetParam ( ) . ad_len ! = 0 ? GetParam ( ) . ad_len : 16 ;
const size_t ad_len = RequiredADLength ( GetParam ( ) . flags ) ! = 0
? RequiredADLength ( GetParam ( ) . flags )
: 16 ;
ASSERT_LE ( ad_len , sizeof ( kZeros ) ) ;
for ( size_t nonce_len : nonce_lens ) {
@ -723,9 +772,10 @@ TEST_P(PerAEADTest, ABI) {
alignas ( 2 ) uint8_t ad_buf [ 512 ] ;
OPENSSL_memset ( ad_buf , ' A ' , sizeof ( ad_buf ) ) ;
const uint8_t * const ad = ad_buf + 1 ;
ASSERT_LE ( GetParam ( ) . ad_len , sizeof ( ad_buf ) - 1 ) ;
const size_t ad_len =
GetParam ( ) . ad_len ! = 0 ? GetParam ( ) . ad_len : sizeof ( ad_buf ) - 1 ;
ASSERT_LE ( RequiredADLength ( GetParam ( ) . flags ) , sizeof ( ad_buf ) - 1 ) ;
const size_t ad_len = RequiredADLength ( GetParam ( ) . flags ) ! = 0
? RequiredADLength ( GetParam ( ) . flags )
: sizeof ( ad_buf ) - 1 ;
uint8_t nonce [ EVP_AEAD_MAX_NONCE_LENGTH ] ;
const size_t nonce_len = EVP_AEAD_nonce_length ( aead ( ) ) ;