Created attachment 1207974 [details] Script to simulate the key alteration and to get the one that can be used to open with cryptsetup Description of problem: Customer wanted to be able to use cryptsetup to prepare volumes pre-encrypted that could be loaded into OSP env (after injecting files) For using encryption, 'fixed_key' was set on cinder.conf and nova.conf Looking at the code for nova, the passphrase is given to the command but as the same fixed_key being used was not working, a debugging 'print' was used, yielding: fixed_key on config file: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a passphrase passed to cryptsetup: 752523eb50c3bf2ba3ff639c2545805fd4e779894ef536e15e081696a Once we used the passphrase passed to cryptsetup, we were able to open the device and access the contents. Version-Release number of selected component (if applicable): python-nova-2014.2.3-67.el7ost.noarch At: /usr/lib/python2.7/site-packages/nova/volume/encryptors cryptsetup.py: return ''.join(hex(x).replace('0x', '') for x in key) luks.py: passphrase = ''.join(hex(x).replace('0x', '') for x in key) How reproducible: Steps to Reproduce: 1. Define a passphrase by using fixed_key 2. Use that passphrase to open via cryptsetup the file Actual results: FAILS Expected results: Ability to open the encrypted volume Additional info: See attached script (to be executed on a server with nova libraries) and provide different keys like the one poster above Script output: [root@osp6 ~]# python cinder-volume-genkey.py Enter the fixed_key: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a ORIG: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a NEW : 752523eb50c3bf2ba3ff639c2545805fd4e779894ef536e15e081696a
Any fix on the key generation could lead to potential volumes no longer being accessible unless a fallback mechanism is provided for old-encrypted ones. The code has changed from OSP6 to upstream: git diff 8c0673d3 luks.py key = self._get_key(context).get_encoded() - # LUKS uses a passphrase rather than a raw key -- convert to string - passphrase = ''.join(hex(x).replace('0x', '') for x in key) + passphrase = self._get_passphrase(key) Initial: https://review.openstack.org/#/c/30976 Change: https://review.openstack.org/#/c/223315 If the 'conversion' code for the key has changed, in case any environment using the old schema (even if there's a log line saying that it's not secure) could face lot of issues on upgrade unless we mangle the key on the updated setup to get the same result from the functions.
hex(x) is stripping leading 0's in the individual hex number while we encode the passphrase back to a string via the join, leading to the differences between the original fixed_key hex string and the string used as the passphrase. As outlined in the attached script the following one liner reproducers the decode and encoding operations that we currently do in OSP 6 / Juno : >>> ''.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 >>> hex(14) '0xe' >>> int(0x0e) 14 >>> int(0xe) 14 >>> hex(4) '0x4' >>> int(0x04) 4 >>> int(0x4) 4 The change you listed above didn't change the implementation however it has recently changed in Newton via the following change : Replace key manager with Castellan https://review.openstack.org/#/c/309614/ This change introduces the use of the Castellan library and changes the way in which we encode the passphrase before use, again it breaks down to the following one liner : >>> import binascii >>> binascii.hexlify(bytes(binascii.unhexlify('752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a'))).decode('utf-8') u'752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a' Original string: 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a New string : 752523eb50c3bf2ba3ff639c250405805fd4e779894ef5360e15e081696a So any attempt to attach a volume encrypted prior to Newton with Newton or later is going to fail unless a) the shorter fixed_key is used b) we retry with the shorter key as a horrible workaround. I'm going to ask colleagues for advice here before pushing this upstream.
According to our records, this should be resolved by openstack-nova-14.0.2-7.el7ost. This build is available now.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2017-0319.html