On Fri, May 20, 2016 at 10:03:27 -0400, John Ferlan wrote:
On 05/20/2016 08:56 AM, Peter Krempa wrote:
> On Thu, May 19, 2016 at 16:29:01 -0400, John Ferlan wrote:
>> Introduce virCryptoHaveCipher and virCryptoEncryptData to handle
>> performing encryption.
>>
>> virCryptoHaveCipher:
>> Boolean function to determine whether the requested cipher algorithm
>> is available. It's expected this API will be called prior to
>> virCryptoEncryptdata. It will return true/false.
>>
>> virCryptoEncryptData:
>> Based on the requested cipher type, call the specific encryption
>> API to encrypt the data.
>>
>> Currently the only algorithm support is the AES 256 CBC encryption.
>>
>> Adjust tests for the API's
>>
>> Signed-off-by: John Ferlan <jferlan(a)redhat.com>
>> ---
>> configure.ac | 1 +
>> src/libvirt_private.syms | 2 +
>> src/util/vircrypto.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++-
>> src/util/vircrypto.h | 20 ++++-
>> tests/vircryptotest.c | 100 +++++++++++++++++++++++-
>> 5 files changed, 312 insertions(+), 3 deletions(-)
[...]
>> + /* Fill in the padding of the buffer with the size of
the padding
>> + * which is required for decryption. */
>> + for (i = datalen; i < ciphertextlen; i++)
>> + ciphertext[i] = ciphertextlen - datalen;
>> +
>> + /* Initialize the gnutls cipher */
>> + enc_key.size = enckeylen;
>> + enc_key.data = enckey;
>> + if (iv) {
>> + iv_buf.size = ivlen;
>> + iv_buf.data = iv;
>> + }
>> + if ((rc = gnutls_cipher_init(&handle, gnutls_enc_alg,
>> + &enc_key, &iv_buf)) < 0) {
>> + virReportError(VIR_ERR_INTERNAL_ERROR,
>> + _("failed to initialize cipher:
'%s'"),
>> + gnutls_strerror(rc));
>> + goto error;
>> + }
>> +
>> + /* Encrypt the data and free the memory for cipher operations */
>> + rc = gnutls_cipher_encrypt(handle, ciphertext, ciphertextlen);
>> + gnutls_cipher_deinit(handle);
memset(&enc_key, 0, sizeof(gnutls_datum_t));
memset(&iv_key, 0, sizeof(gnutls_datum_t));
Note that this doesn't catch the cleanup path if gnutls_cipher_init
fails.
>> + if (rc < 0) {
>> + virReportError(VIR_ERR_INTERNAL_ERROR,
>> + _("failed to encrypt the data:
'%s'"),
>> + gnutls_strerror(rc));
>> + goto error;
>> + }
>> +
>> + *ciphertextret = ciphertext;
>> + *ciphertextlenret = ciphertextlen;
>> + return 0;
>> +
>> + error:
>> + VIR_DISPOSE_N(ciphertext, ciphertextlen);
>> + return -1;
>
> In both cases you should clear the stack'd copy of the encryption key.
>
>> +}
>> +#endif
>> +