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