Public bug reported:

Description
===========

tl;dr hex(x) previously stripped leading 0's from individual hex numbers
while encoding the passphrase back to a hex string before use to
encrypt/decrypt a luks volume.

Prior to Newton the following method was used to encode passphrases when
attempting to use or create a luks volume :

    def _get_passphrase(self, key):
        """Convert raw key to string."""
        return ''.join(hex(x).replace('0x', '') for x in key)

https://github.com/openstack/nova/blob/82190bdd283dda37f7517fd9a268b5e55183f06c/nova/volume/encryptors/cryptsetup.py#L92-L94

This was replaced in Newton with the move to Castellan in the following
change that altered both the decoding and encoding steps :

Replace key manager with Castellan
https://review.openstack.org/#/c/309614/

The original method used the built-in hex() call to convert individual
unsigned ints back to hex. This would strip the leading 0 from each hex
digit pair, altering the eventual passphrase used to encrypt or decrypt
the volume.

For example, the following one liner represents both the initial decode
step preformed by ConfKeyManager and the step above to encode the
passphrase in the LuksEncryptor class :

>>> ''.join(hex(x).replace('0x', '') for x in array.array('B', 
>>> '752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'.decode('hex')).tolist())
'752523eb50c3bf2ba3ff639c2545805fd4e779894ef536e15e081696a'

Original string: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a
New string     : 752523eb50c3bf2ba3ff639c25 4 5805fd4e779894ef536 e15e081696a

The returned string is missing various 0's that have been stripped by
the hex() call :

>>> hex(14)
'0xe'

>>> int(0x0e)
14

>>> int(0xe)
14

>>> hex(4)
'0x4'

>>> int(0x04)
4

>>> int(0x4)
4

The following one liner represents the current decode and encode steps,
producing the same string as is entered :

>>> import binascii
>>> binascii.hexlify(bytes(binascii.unhexlify('752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'))).decode('utf-8')
u'752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'

Original string: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a
New string     : 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a

IMHO the way to handle this is to add a simple retry in master and
stable/newton when we fail due to a bad passphrase using the mangled
passphrase.

We should also improve the testing in this area as it appears all
previous testing used zero based passphrases, missing this issue when it
landed in Newton.

More notes available downstream in the following bug :

Nova encryption alters the key used
https://bugzilla.redhat.com/show_bug.cgi?id=1382415

Steps to reproduce
==================
- Encrypt a volume in Mitaka or earlier.
- Upgrade to Newton or later.
- Attempt to use the volume.

Expected result
===============
Volume is decrypted and usable.

Actual result
=============
Unable to decrypt the volume due to the use of an modified passphrase during 
initial formatting and use prior to Newton.

Environment
===========
1. Exact version of OpenStack you are running. See the following
  list for all releases: http://docs.openstack.org/releases/
   Newton and later.
   
2. Which hypervisor did you use?
   Libvirt

2. Which storage type did you use?
   N/A

3. Which networking type did you use?
   (For example: nova-network, Neutron with OpenVSwitch, ...)
   N/A

Logs & Configs
==============
N/A

** Affects: nova
     Importance: Undecided
         Status: New

** Summary changed:

- Passphrase change
+ The passphrase used to encrypt or decrypt volumes was mangled prior to Newton

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to OpenStack Compute (nova).
https://bugs.launchpad.net/bugs/1633518

Title:
  The passphrase used to encrypt or decrypt volumes was mangled prior to
  Newton

Status in OpenStack Compute (nova):
  New

Bug description:
  Description
  ===========

  tl;dr hex(x) previously stripped leading 0's from individual hex
  numbers while encoding the passphrase back to a hex string before use
  to encrypt/decrypt a luks volume.

  Prior to Newton the following method was used to encode passphrases
  when attempting to use or create a luks volume :

      def _get_passphrase(self, key):
          """Convert raw key to string."""
          return ''.join(hex(x).replace('0x', '') for x in key)

  
https://github.com/openstack/nova/blob/82190bdd283dda37f7517fd9a268b5e55183f06c/nova/volume/encryptors/cryptsetup.py#L92-L94

  This was replaced in Newton with the move to Castellan in the
  following change that altered both the decoding and encoding steps :

  Replace key manager with Castellan
  https://review.openstack.org/#/c/309614/

  The original method used the built-in hex() call to convert individual
  unsigned ints back to hex. This would strip the leading 0 from each
  hex digit pair, altering the eventual passphrase used to encrypt or
  decrypt the volume.

  For example, the following one liner represents both the initial
  decode step preformed by ConfKeyManager and the step above to encode
  the passphrase in the LuksEncryptor class :

  >>> ''.join(hex(x).replace('0x', '') for x in array.array('B', 
'752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'.decode('hex')).tolist())
  '752523eb50c3bf2ba3ff639c2545805fd4e779894ef536e15e081696a'

  Original string: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a
  New string     : 752523eb50c3bf2ba3ff639c25 4 5805fd4e779894ef536 e15e081696a

  The returned string is missing various 0's that have been stripped by
  the hex() call :

  >>> hex(14)
  '0xe'

  >>> int(0x0e)
  14

  >>> int(0xe)
  14

  >>> hex(4)
  '0x4'

  >>> int(0x04)
  4

  >>> int(0x4)
  4

  The following one liner represents the current decode and encode
  steps, producing the same string as is entered :

  >>> import binascii
  >>> 
binascii.hexlify(bytes(binascii.unhexlify('752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'))).decode('utf-8')
  u'752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'

  Original string: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a
  New string     : 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a

  IMHO the way to handle this is to add a simple retry in master and
  stable/newton when we fail due to a bad passphrase using the mangled
  passphrase.

  We should also improve the testing in this area as it appears all
  previous testing used zero based passphrases, missing this issue when
  it landed in Newton.

  More notes available downstream in the following bug :

  Nova encryption alters the key used
  https://bugzilla.redhat.com/show_bug.cgi?id=1382415

  Steps to reproduce
  ==================
  - Encrypt a volume in Mitaka or earlier.
  - Upgrade to Newton or later.
  - Attempt to use the volume.

  Expected result
  ===============
  Volume is decrypted and usable.

  Actual result
  =============
  Unable to decrypt the volume due to the use of an modified passphrase during 
initial formatting and use prior to Newton.

  Environment
  ===========
  1. Exact version of OpenStack you are running. See the following
    list for all releases: http://docs.openstack.org/releases/
     Newton and later.
     
  2. Which hypervisor did you use?
     Libvirt

  2. Which storage type did you use?
     N/A

  3. Which networking type did you use?
     (For example: nova-network, Neutron with OpenVSwitch, ...)
     N/A

  Logs & Configs
  ==============
  N/A

To manage notifications about this bug go to:
https://bugs.launchpad.net/nova/+bug/1633518/+subscriptions

-- 
Mailing list: https://launchpad.net/~yahoo-eng-team
Post to     : yahoo-eng-team@lists.launchpad.net
Unsubscribe : https://launchpad.net/~yahoo-eng-team
More help   : https://help.launchpad.net/ListHelp

Reply via email to