[libvirt] [PATCH v3 05/10] encryption: Add <cipher> and <ivgen> to encryption
John Ferlan
jferlan at redhat.com
Sat Jun 25 11:13:54 UTC 2016
On 06/25/2016 01:46 AM, Ján Tomko wrote:
> On Fri, Jun 24, 2016 at 04:53:34PM -0400, John Ferlan wrote:
>> For a luks device, allow the configuration of a specific cipher to be
>> used for encrypting the volume.
>>
>> Signed-off-by: John Ferlan <jferlan at redhat.com>
>> ---
>> docs/formatstorageencryption.html.in | 83 ++++++++++++-
>> docs/schemas/storagecommon.rng | 44 ++++++-
>> src/conf/domain_conf.c | 11 ++
>> src/util/virstorageencryption.c | 138
>> +++++++++++++++++++++
>> src/util/virstorageencryption.h | 14 +++
>> .../qemuxml2argv-luks-disk-cipher.xml | 45 +++++++
>> .../qemuxml2xmlout-luks-disk-cipher.xml | 1 +
>> tests/qemuxml2xmltest.c | 1 +
>> tests/storagevolxml2xmlin/vol-luks-cipher.xml | 23 ++++
>> tests/storagevolxml2xmlout/vol-luks-cipher.xml | 23 ++++
>> tests/storagevolxml2xmltest.c | 1 +
>> 11 files changed, 378 insertions(+), 6 deletions(-)
>> create mode 100644
>> tests/qemuxml2argvdata/qemuxml2argv-luks-disk-cipher.xml
>> create mode 120000
>> tests/qemuxml2xmloutdata/qemuxml2xmlout-luks-disk-cipher.xml
>> create mode 100644 tests/storagevolxml2xmlin/vol-luks-cipher.xml
>> create mode 100644 tests/storagevolxml2xmlout/vol-luks-cipher.xml
>>
>
>> +static int
>> +virStorageEncryptionInfoParseCipher(xmlNodePtr info_node,
>> + virStorageEncryptionInfoDefPtr info)
>> +{
>> + int ret = -1;
>> + char *size_str = NULL;
>> +
>> + if (!(info->cipher_name = virXMLPropString(info_node, "name"))) {
>> + virReportError(VIR_ERR_XML_ERROR, "%s",
>> + _("missing cipher info name string"));
>
> Either 'missing cipher name' or use "cipher info missing '%s'
> attribute"...
>
OK
>> + goto cleanup;
>> + }
>> +
>> + if ((size_str = virXMLPropString(info_node, "size")) &&
>> + virStrToLong_uip(size_str, NULL, 10, &info->cipher_size) < 0) {
>> + virReportError(VIR_ERR_XML_ERROR,
>> + _("cannot parse cipher info size string '%s'"),
>
> "cannot parse cipher size: '%s'"
>
OK
>> + size_str);
>> + goto cleanup;
>> + }
>> +
>> + if (!size_str) {
>> + virReportError(VIR_ERR_XML_ERROR, "%s",
>> + _("cipher info missing 'size' attribute"));
>
> to share the string with this error.
>
OK
> Also, should we be validating these by converting them to an enum?
>
Good question! Unfortunately we have no way of knowing what any driver
supports so what are we validating them against? I thought of creating
a connection API that could/would fetch all the cipher/ivgen algorithm
information from the hypervisor that's going to be using them. Then I
investigated qemu to see what type of API was available only to find
nothing "obvious". So for now, I just left these as a string. I suppose
we could "mock up" a qemu response, but it's a lot more effort saved for
another day. If bad values are provided, qemu-img will fall over and
play dead during the volume create.
>> + goto cleanup;
>> + }
>> +
>
>> + /* Optional */
>
> Hence no error following the calls.
>
Gone.
>> + info->cipher_mode = virXMLPropString(info_node, "mode");
>> + info->cipher_hash = virXMLPropString(info_node, "hash");
>> +
>> + ret = 0;
>> +
>> + cleanup:
>> + VIR_FREE(size_str);
>> + return ret;
>> +}
>> +
>> +
>> +static int
>> +virStorageEncryptionInfoParseIvgen(xmlNodePtr info_node,
>> + virStorageEncryptionInfoDefPtr info)
>> +{
>> + if (!(info->ivgen_name = virXMLPropString(info_node, "name"))) {
>> + virReportError(VIR_ERR_XML_ERROR, "%s",
>> + _("missing ivgen info name string"));
>> + return -1;
>> + }
>> +
>
>> + /* Optional */
>
> Also redundant.
>
Gone
>> + info->ivgen_hash = virXMLPropString(info_node, "hash");
>> +
>> + return 0;
>> +}
>> +
>> +
>> static virStorageEncryptionPtr
>> virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
>> {
>> @@ -196,6 +286,28 @@ virStorageEncryptionParseXML(xmlXPathContextPtr
>> ctxt)
>> VIR_FREE(nodes);
>> }
>>
>> + if (ret->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
>> + xmlNodePtr tmpnode;
>> +
>> + if ((tmpnode = virXPathNode("./cipher[1]", ctxt))) {
>> + if (virStorageEncryptionInfoParseCipher(tmpnode,
>> &ret->encinfo) < 0)
>> + goto cleanup;
>> + }
>> +
>> + if ((tmpnode = virXPathNode("./ivgen[1]", ctxt))) {
>
>> + /* If no cipher node, then fail */
>
> Rather than putting it in this comment,
>
>> + if (!ret->encinfo.cipher_name) {
>> + virReportError(VIR_ERR_XML_ERROR, "%s",
>> + _("missing storage encryption cipher"));
>
> how about putting it in the error:
> "ivgen element found but cipher is missing"
>
OK, done.
>> + goto cleanup;
>> + }
>> +
>> + if (virStorageEncryptionInfoParseIvgen(tmpnode,
>> &ret->encinfo) < 0)
>> + goto cleanup;
>> + }
>> + }
>> +
>> +
>> return ret;
>>
>> cleanup:
>> @@ -250,6 +362,28 @@ virStorageEncryptionSecretFormat(virBufferPtr buf,
>> return 0;
>> }
>>
>> +
>> +static void
>> +virStorageEncryptionInfoDefFormat(virBufferPtr buf,
>> + const virStorageEncryptionInfoDef
>> *enc)
>> +{
>> + virBufferAsprintf(buf, "<cipher name='%s' size='%u'",
>> + enc->cipher_name, enc->cipher_size);
>> + if (enc->cipher_mode)
>> + virBufferAsprintf(buf, " mode='%s'", enc->cipher_mode);
>> + if (enc->cipher_hash)
>> + virBufferAsprintf(buf, " hash='%s'", enc->cipher_hash);
>> + virBufferAddLit(buf, "/>\n");
>> +
>> + if (enc->ivgen_name) {
>> + virBufferAsprintf(buf, "<ivgen name='%s'", enc->ivgen_name);
>> + if (enc->ivgen_hash)
>> + virBufferAsprintf(buf, " hash='%s'", enc->ivgen_hash);
>> + virBufferAddLit(buf, "/>\n");
>> + }
>
> The strings need to be escaped.
>
Done
>> +}
>> +
>> +
>> int
>> virStorageEncryptionFormat(virBufferPtr buf,
>> virStorageEncryptionPtr enc)
>
> ACK with the strings escaped.
Thanks for the look/time...
John
More information about the libvir-list
mailing list