diff --git a/src/crypto/gcm.c b/src/crypto/gcm.c index 3948e0a07..f569be0ad 100644 --- a/src/crypto/gcm.c +++ b/src/crypto/gcm.c @@ -37,6 +37,7 @@ FILE_SECBOOT ( PERMITTED ); #include #include +#include #include #include #include @@ -473,7 +474,7 @@ int gcm_setiv ( struct cipher_algorithm *cipher, void *ctx, /* Initialisation vector is exactly 96 bits, use it as-is */ memcpy ( context->gcm.ctr.ctr.iv, iv, ivlen ); - } else { + } else if ( ivlen ) { /* Calculate hash over initialisation vector */ context->gcm.flags = GCM_FL_IV; @@ -486,6 +487,11 @@ int gcm_setiv ( struct cipher_algorithm *cipher, void *ctx, build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) ); build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) ); build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) ); + + } else { + + /* Zero-length IVs are not permitted */ + return -ENOTSUP; } DBGC2 ( context, "GCM %p Y[0]:\n", context ); diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 0e908d957..31175d33c 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -457,6 +457,7 @@ FILE_SECBOOT ( PERMITTED ); #define ERRFILE_cbc ( ERRFILE_OTHER | 0x006c0000 ) #define ERRFILE_channel ( ERRFILE_OTHER | 0x006d0000 ) #define ERRFILE_tlskey ( ERRFILE_OTHER | 0x006e0000 ) +#define ERRFILE_gcm ( ERRFILE_OTHER | 0x006f0000 ) /** @} */ diff --git a/src/tests/gcm_test.c b/src/tests/gcm_test.c index 04a42b5c9..2246a28f5 100644 --- a/src/tests/gcm_test.c +++ b/src/tests/gcm_test.c @@ -357,6 +357,10 @@ CIPHER_TEST ( gcm_test_18, &aes_gcm_algorithm, GCM_KEY_256, AUTH ( 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a ) ); +/** Zero-length IV */ +CIPHER_TEST ( gcm_empty_iv, &aes_gcm_algorithm, GCM_KEY_256, IV(), + ADDITIONAL(), PLAINTEXT(), CIPHERTEXT(), AUTH() ); + /** * Perform Galois/Counter Mode self-test * @@ -384,6 +388,7 @@ static void gcm_test_exec ( void ) { cipher_ok ( &gcm_test_16 ); cipher_ok ( &gcm_test_17 ); cipher_ok ( &gcm_test_18 ); + cipher_iv_fail_ok ( &gcm_empty_iv ); /* Speed tests */ for ( keylen = 128 ; keylen <= 256 ; keylen += 64 ) {