qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Maxim Levitsky <mlevitsk@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: "Kevin Wolf" <kwolf@redhat.com>,
	"Daniel P.Berrangé" <berrange@redhat.com>,
	qemu-block@nongnu.org, qemu-devel@nongnu.org,
	"Max Reitz" <mreitz@redhat.com>, "John Snow" <jsnow@redhat.com>
Subject: Re: QAPI schema for desired state of LUKS keyslots (was: [PATCH 02/13] qcrypto-luks: implement encryption key management)
Date: Tue, 03 Mar 2020 11:18:36 +0200	[thread overview]
Message-ID: <6e42d2ac5a761548ed3b4fdf7382441646839a9b.camel@redhat.com> (raw)
In-Reply-To: <87lfp36gzh.fsf_-_@dusky.pond.sub.org>

On Sat, 2020-02-15 at 15:51 +0100, Markus Armbruster wrote:
> Review of this patch led to a lengthy QAPI schema design discussion.
> Let me try to condense it into a concrete proposal.
> 
> This is about the QAPI schema, and therefore about QMP.  The
> human-friendly interface is out of scope.  Not because it's not
> important (it clearly is!), only because we need to *focus* to have a
> chance at success.
> 
> I'm going to include a few design options.  I'll mark them "Option:".
> 
> The proposed "amend" interface takes a specification of desired state,
> and figures out how to get from here to there by itself.  LUKS keyslots
> are one part of desired state.
> 
> We commonly have eight LUKS keyslots.  Each keyslot is either active or
> inactive.  An active keyslot holds a secret.
> 
> Goal: a QAPI type for specifying desired state of LUKS keyslots.
> 
> Proposal:
> 
>     { 'enum': 'LUKSKeyslotState',
>       'data': [ 'active', 'inactive' ] }
> 
>     { 'struct': 'LUKSKeyslotActive',
>       'data': { 'secret': 'str',
>                 '*iter-time': 'int } }
> 
>     { 'struct': 'LUKSKeyslotInactive',
>       'data': { '*old-secret': 'str' } }
> 
>     { 'union': 'LUKSKeyslotAmend',
>       'base': { '*keyslot': 'int',
>                 'state': 'LUKSKeyslotState' }
>       'discriminator': 'state',
>       'data': { 'active': 'LUKSKeyslotActive',
>                 'inactive': 'LUKSKeyslotInactive' } }
> 
> LUKSKeyslotAmend specifies desired state for a set of keyslots.
> 
> Four cases:
> 
> * @state is "active"
> 
>   Desired state is active holding the secret given by @secret.  Optional
>   @iter-time tweaks key stretching.
> 
>   The keyslot is chosen either by the user or by the system, as follows:
> 
>   - @keyslot absent
> 
>     One inactive keyslot chosen by the system.  If none exists, error.
> 
>   - @keyslot present
> 
>     The keyslot given by @keyslot.
> 
>     If it's already active holding @secret, no-op.  Rationale: the
>     current state is the desired state.
> 
>     If it's already active holding another secret, error.  Rationale:
>     update in place is unsafe.
> 
>     Option: delete the "already active holding @secret" case.  Feels
>     inelegant to me.  Okay if it makes things substantially simpler.
> 
> * @state is "inactive"
> 
>   Desired state is inactive.
> 
>   Error if the current state has active keyslots, but the desired state
>   has none.
> 
>   The user choses the keyslot by number and/or by the secret it holds,
>   as follows:
> 
>   - @keyslot absent, @old-secret present
> 
>     All active keyslots holding @old-secret.  If none exists, error.
> 
>   - @keyslot present, @old-secret absent
> 
>     The keyslot given by @keyslot.
> 
>     If it's already inactive, no-op.  Rationale: the current state is
>     the desired state.
> 
>   - both @keyslot and @old-secret present
> 
>     The keyslot given by keyslot.
> 
>     If it's inactive or holds a secret other than @old-secret, error.
> 
>     Option: error regardless of @old-secret, if that makes things
>     simpler.
> 
>   - neither @keyslot not @old-secret present
> 
>     All keyslots.  Note that this will error out due to "desired state
>     has no active keyslots" unless the current state has none, either.
> 
>     Option: error out unconditionally.
> 
> Note that LUKSKeyslotAmend can specify only one desired state for
> commonly just one keyslot.  Rationale: this satisfies practical needs.
> An array of LUKSKeyslotAmend could specify desired state for all
> keyslots.  However, multiple array elements could then apply to the same
> slot.  We'd have to specify how to resolve such conflicts, and we'd have
> to code up conflict detection.  Not worth it.
> 
> Examples:
> 
> * Add a secret to some free keyslot:
> 
>   { "state": "active", "secret": "CIA/GRU/MI6" }
> 
> * Deactivate all keyslots holding a secret:
> 
>   { "state": "inactive", "old-secret": "CIA/GRU/MI6" }
> 
> * Add a secret to a specific keyslot:
> 
>   { "state": "active", "secret": "CIA/GRU/MI6", "keyslot": 0 }
> 
> * Deactivate a specific keyslot:
> 
>   { "state": "inactive", "keyslot": 0 }
> 
>   Possibly less dangerous:
> 
>   { "state": "inactive", "keyslot": 0, "old-secret": "CIA/GRU/MI6" }
> 
> Option: Make use of Max's patches to support optional union tag with
> default value to let us default @state to "active".  I doubt this makes
> much of a difference in QMP.  A human-friendly interface should probably
> be higher level anyway (Daniel pointed to cryptsetup).
> 
> Option: LUKSKeyslotInactive member @old-secret could also be named
> @secret.  I don't care.
> 
> Option: delete @keyslot.  It provides low-level slot access.
> Complicates the interface.  Fine if we need lov-level slot access.  Do
> we?
> 
> I apologize for the time it has taken me to write this.
> 
> Comments?

I tried today to implement this but I hit a very unpleasant roadblock:

Since QCrypto is generic (even though it only implements currently luks for raw/qcow2 usage,
and legacy qcow2 aes encryption), I still can't assume that this is always the case.
Thus I implemented the Qcrypto amend API in this way:

##
# @QCryptoBlockAmendOptions:
#
# The options that are available for all encryption formats
# when amending encryption settings
#
# Since: 5.0
##
{ 'union': 'QCryptoBlockAmendOptions',
  'base': 'QCryptoBlockOptionsBase',
  'discriminator': 'format',
  'data': {
          'luks': 'QCryptoBlockAmendOptionsLUKS' } }

However the QCryptoBlockAmendOptionsLUKS is a union too to be in line with the API proposal,
but that is not supported on QAPI level and after I and Markus talked about we are not sure
that it is worth it to implement this support only for this case.

So far I see the following solutions


1. Drop the QCryptoBlockAmendOptionsLUKS union for now.
This will bring the schema pretty much to be the same as my original proposal,
however the API will be the same thus once nested unions are implemented this union
can always be introduced again.

2. Drop the QCryptoBlockAmendOptions union. Strictly speaking this union is not needed
since it only has one member anyway, however this union is used both by qcow2 QAPI scheme,
so that it doesn't hardcode an encryption format for amend just like it doesn't for creation,
(this can be hardcoded for now as well for now as long as we don't have more amendable encryption formats).
However I also use the QCryptoBlockAmendOptions in C code in QCrypto API thus it will be ugly to use the 
QCryptoBlockAmendOptionsLUKS instead.


3. Make QCryptoBlockAmendOptionsLUKS a struct and add to it a nested member with new union type 
(say QCryptoBlockAmendOptionsLUKS1) which will be exactly as QCryptoBlockAmendOptionsLUKS was.

This IMHO is even uglier since it changes the API (which we can't later fix) and adds both a dummy struct
field and a dummy struct name.

I personally vote 1.

Best regards,
	Maxim Levitsky






  parent reply	other threads:[~2020-03-03  9:19 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-14 19:33 [PATCH 00/13] LUKS: encryption slot management using amend interface Maxim Levitsky
2020-01-14 19:33 ` [PATCH 01/13] qcrypto: add generic infrastructure for crypto options amendment Maxim Levitsky
2020-01-28 16:59   ` Daniel P. Berrangé
2020-01-29 17:49     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 02/13] qcrypto-luks: implement encryption key management Maxim Levitsky
2020-01-21  7:54   ` Markus Armbruster
2020-01-21 13:13     ` Maxim Levitsky
2020-01-28 17:11       ` Daniel P. Berrangé
2020-01-28 17:32         ` Daniel P. Berrangé
2020-01-29 17:54           ` Maxim Levitsky
2020-01-30 12:38           ` Kevin Wolf
2020-01-30 12:53             ` Daniel P. Berrangé
2020-01-30 14:23               ` Kevin Wolf
2020-01-30 14:30                 ` Daniel P. Berrangé
2020-01-30 14:53                 ` Markus Armbruster
2020-01-30 14:47               ` Markus Armbruster
2020-01-30 15:01                 ` Daniel P. Berrangé
2020-01-30 16:37                   ` Markus Armbruster
2020-02-05  8:24                     ` Markus Armbruster
2020-02-05  9:30                       ` Kevin Wolf
2020-02-05 10:03                         ` Markus Armbruster
2020-02-05 11:02                           ` Kevin Wolf
2020-02-05 14:31                             ` Markus Armbruster
2020-02-06 13:44                               ` Markus Armbruster
2020-02-06 13:49                                 ` Daniel P. Berrangé
2020-02-06 14:20                                   ` Max Reitz
2020-02-05 10:23                         ` Daniel P. Berrangé
2020-02-05 14:31                           ` Markus Armbruster
2020-02-06 13:20                             ` Markus Armbruster
2020-02-06 13:36                               ` Daniel P. Berrangé
2020-02-06 14:25                                 ` Kevin Wolf
2020-02-06 15:19                                   ` Markus Armbruster
2020-02-06 15:23                                     ` Maxim Levitsky
2020-01-30 15:45                 ` Maxim Levitsky
2020-01-28 17:21   ` Daniel P. Berrangé
2020-01-30 12:58     ` Maxim Levitsky
2020-02-15 14:51   ` QAPI schema for desired state of LUKS keyslots (was: [PATCH 02/13] qcrypto-luks: implement encryption key management) Markus Armbruster
2020-02-16  8:05     ` Maxim Levitsky
2020-02-17  6:45       ` QAPI schema for desired state of LUKS keyslots Markus Armbruster
2020-02-17  8:19         ` Maxim Levitsky
2020-02-17 10:37     ` QAPI schema for desired state of LUKS keyslots (was: [PATCH 02/13] qcrypto-luks: implement encryption key management) Kevin Wolf
2020-02-17 11:07       ` Maxim Levitsky
2020-02-24 14:46         ` Daniel P. Berrangé
2020-02-24 14:50           ` Maxim Levitsky
2020-02-17 12:28       ` QAPI schema for desired state of LUKS keyslots Markus Armbruster
2020-02-17 12:44         ` Eric Blake
2020-02-24 14:43         ` Daniel P. Berrangé
2020-02-24 14:45     ` QAPI schema for desired state of LUKS keyslots (was: [PATCH 02/13] qcrypto-luks: implement encryption key management) Daniel P. Berrangé
2020-02-25 12:15     ` Max Reitz
2020-02-25 16:48       ` QAPI schema for desired state of LUKS keyslots Markus Armbruster
2020-02-25 17:00         ` Max Reitz
2020-02-26  7:28           ` Markus Armbruster
2020-02-26  9:18             ` Maxim Levitsky
2020-02-25 17:18         ` Daniel P. Berrangé
2020-03-03  9:18     ` Maxim Levitsky [this message]
2020-03-05 12:15       ` QAPI schema for desired state of LUKS keyslots (was: [PATCH 02/13] qcrypto-luks: implement encryption key management) Maxim Levitsky
2020-01-14 19:33 ` [PATCH 03/13] block: amend: add 'force' option Maxim Levitsky
2020-01-14 19:33 ` [PATCH 04/13] block: amend: separate amend and create options for qemu-img Maxim Levitsky
2020-01-28 17:23   ` Daniel P. Berrangé
2020-01-30 15:54     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 05/13] block/crypto: rename two functions Maxim Levitsky
2020-01-14 19:33 ` [PATCH 06/13] block/crypto: implement the encryption key management Maxim Levitsky
2020-01-28 17:27   ` Daniel P. Berrangé
2020-01-30 16:08     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 07/13] qcow2: extend qemu-img amend interface with crypto options Maxim Levitsky
2020-01-28 17:30   ` Daniel P. Berrangé
2020-01-30 16:09     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 08/13] iotests: filter few more luks specific create options Maxim Levitsky
2020-01-28 17:36   ` Daniel P. Berrangé
2020-01-30 16:12     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 09/13] qemu-iotests: qemu-img tests for luks key management Maxim Levitsky
2020-01-14 19:33 ` [PATCH 10/13] block: add generic infrastructure for x-blockdev-amend qmp command Maxim Levitsky
2020-01-21  7:59   ` Markus Armbruster
2020-01-21 13:58     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 11/13] block/crypto: implement blockdev-amend Maxim Levitsky
2020-01-28 17:40   ` Daniel P. Berrangé
2020-01-30 16:24     ` Maxim Levitsky
2020-01-14 19:33 ` [PATCH 12/13] block/qcow2: " Maxim Levitsky
2020-01-28 17:41   ` Daniel P. Berrangé
2020-01-14 19:33 ` [PATCH 13/13] iotests: add tests for blockdev-amend Maxim Levitsky
2020-01-14 21:16 ` [PATCH 00/13] LUKS: encryption slot management using amend interface no-reply
2020-01-16 14:01   ` Maxim Levitsky
2020-01-14 21:17 ` no-reply
2020-01-16 14:19   ` Maxim Levitsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6e42d2ac5a761548ed3b4fdf7382441646839a9b.camel@redhat.com \
    --to=mlevitsk@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).