Skip to content

Commit

Permalink
crypto: add additional query accessors for cipher instances
Browse files Browse the repository at this point in the history
Adds new methods to allow querying the length of the cipher
key, block size and initialization vectors.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
  • Loading branch information
berrange committed Dec 23, 2015
1 parent 5dc42c1 commit dd2bf9e
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
48 changes: 48 additions & 0 deletions crypto/cipher.c
Expand Up @@ -28,6 +28,54 @@ static size_t alg_key_len[QCRYPTO_CIPHER_ALG_LAST] = {
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
};

static size_t alg_block_len[QCRYPTO_CIPHER_ALG_LAST] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 16,
[QCRYPTO_CIPHER_ALG_AES_256] = 16,
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
};

static bool mode_need_iv[QCRYPTO_CIPHER_MODE_LAST] = {
[QCRYPTO_CIPHER_MODE_ECB] = false,
[QCRYPTO_CIPHER_MODE_CBC] = true,
};


size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg)
{
if (alg >= G_N_ELEMENTS(alg_key_len)) {
return 0;
}
return alg_block_len[alg];
}


size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg)
{
if (alg >= G_N_ELEMENTS(alg_key_len)) {
return 0;
}
return alg_key_len[alg];
}


size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
if (alg >= G_N_ELEMENTS(alg_block_len)) {
return 0;
}
if (mode >= G_N_ELEMENTS(mode_need_iv)) {
return 0;
}

if (mode_need_iv[mode]) {
return alg_block_len[alg];
}
return 0;
}


static bool
qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
size_t nkey,
Expand Down
37 changes: 37 additions & 0 deletions include/crypto/cipher.h
Expand Up @@ -107,6 +107,43 @@ struct QCryptoCipher {
*/
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg);

/**
* qcrypto_cipher_get_block_len:
* @alg: the cipher algorithm
*
* Get the required data block size in bytes. When
* encrypting data, it must be a multiple of the
* block size.
*
* Returns: the block size in bytes
*/
size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg);


/**
* qcrypto_cipher_get_key_len:
* @alg: the cipher algorithm
*
* Get the required key size in bytes.
*
* Returns: the key size in bytes
*/
size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg);


/**
* qcrypto_cipher_get_iv_len:
* @alg: the cipher algorithm
* @mode: the cipher mode
*
* Get the required initialization vector size
* in bytes, if one is required.
*
* Returns: the IV size in bytes, or 0 if no IV is permitted
*/
size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode);


/**
* qcrypto_cipher_new:
Expand Down
10 changes: 10 additions & 0 deletions tests/test-crypto-cipher.c
Expand Up @@ -229,6 +229,7 @@ static void test_cipher(const void *opaque)
uint8_t *key, *iv, *ciphertext, *plaintext, *outtext;
size_t nkey, niv, nciphertext, nplaintext;
char *outtexthex;
size_t ivsize, keysize, blocksize;

nkey = unhex_string(data->key, &key);
niv = unhex_string(data->iv, &iv);
Expand All @@ -245,6 +246,15 @@ static void test_cipher(const void *opaque)
&error_abort);
g_assert(cipher != NULL);

keysize = qcrypto_cipher_get_key_len(data->alg);
blocksize = qcrypto_cipher_get_block_len(data->alg);
ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);

g_assert_cmpint(keysize, ==, nkey);
g_assert_cmpint(ivsize, ==, niv);
if (niv) {
g_assert_cmpint(blocksize, ==, niv);
}

if (iv) {
g_assert(qcrypto_cipher_setiv(cipher,
Expand Down

0 comments on commit dd2bf9e

Please sign in to comment.