diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2016-08-24 16:28:15 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2016-09-12 12:00:06 +0100 |
commit | a5d2f44d0d3e7523670e103a8c37faed29ff2b76 (patch) | |
tree | 605c0414b74ebd8bdea7a31fde1da0205a056be0 /tests/test-crypto-cipher.c | |
parent | c2a57aae9a1c3dd7de77daf5478df10379aeeebf (diff) |
crypto: ensure XTS is only used with ciphers with 16 byte blocks
The XTS cipher mode needs to be used with a cipher which has
a block size of 16 bytes. If a mis-matching block size is used,
the code will either corrupt memory beyond the IV array, or
not fully encrypt/decrypt the IV.
This fixes a memory corruption crash when attempting to use
cast5-128 with xts, since the former has an 8 byte block size.
A test case is added to ensure the cipher creation fails with
such an invalid combination.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'tests/test-crypto-cipher.c')
-rw-r--r-- | tests/test-crypto-cipher.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c index 1b5130d5f6..b89dfa2b65 100644 --- a/tests/test-crypto-cipher.c +++ b/tests/test-crypto-cipher.c @@ -370,6 +370,17 @@ static QCryptoCipherTestData test_data[] = { "eb4a427d1923ce3ff262735779a418f2" "0a282df920147beabe421ee5319d0568", }, + { + /* Bad config - cast5-128 has 8 byte block size + * which is incompatible with XTS + */ + .path = "/crypto/cipher/cast5-xts-128", + .alg = QCRYPTO_CIPHER_ALG_CAST5_128, + .mode = QCRYPTO_CIPHER_MODE_XTS, + .key = + "27182818284590452353602874713526" + "31415926535897932384626433832795", + } }; @@ -432,15 +443,23 @@ static void test_cipher(const void *opaque) const QCryptoCipherTestData *data = opaque; QCryptoCipher *cipher; - uint8_t *key, *iv, *ciphertext, *plaintext, *outtext; - size_t nkey, niv, nciphertext, nplaintext; - char *outtexthex; + uint8_t *key, *iv = NULL, *ciphertext = NULL, + *plaintext = NULL, *outtext = NULL; + size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0; + char *outtexthex = NULL; size_t ivsize, keysize, blocksize; + Error *err = NULL; nkey = unhex_string(data->key, &key); - niv = unhex_string(data->iv, &iv); - nciphertext = unhex_string(data->ciphertext, &ciphertext); - nplaintext = unhex_string(data->plaintext, &plaintext); + if (data->iv) { + niv = unhex_string(data->iv, &iv); + } + if (data->ciphertext) { + nciphertext = unhex_string(data->ciphertext, &ciphertext); + } + if (data->plaintext) { + nplaintext = unhex_string(data->plaintext, &plaintext); + } g_assert(nciphertext == nplaintext); @@ -449,8 +468,15 @@ static void test_cipher(const void *opaque) cipher = qcrypto_cipher_new( data->alg, data->mode, key, nkey, - &error_abort); - g_assert(cipher != NULL); + &err); + if (data->plaintext) { + g_assert(err == NULL); + g_assert(cipher != NULL); + } else { + error_free_or_abort(&err); + g_assert(cipher == NULL); + goto cleanup; + } keysize = qcrypto_cipher_get_key_len(data->alg); blocksize = qcrypto_cipher_get_block_len(data->alg); @@ -498,6 +524,7 @@ static void test_cipher(const void *opaque) g_assert_cmpstr(outtexthex, ==, data->plaintext); + cleanup: g_free(outtext); g_free(outtexthex); g_free(key); |