ipmi password storage
Vernon Mauery
vernon.mauery at linux.intel.com
Tue Apr 14 09:00:15 AEST 2020
Internally, an issue was raised that basically says that the mechanism
by which we are storing the IPMI passwords on the BMC is insufficiently
obfuscated. I have come up with a patch set that resolves this at the
expense of no downgrading the BMC without the side-effect of losing all
IPMI passwords. I would like to know what the community thinks about
usability vs. security in this scenario.
Current Implementation
======================
1) If the user is part of the ipmi group (/etc/group) then when the user
changes their password, pam-ipmisave.so intercepts the password as a one
of the PAM layers and saves it, encrypted, to /etc/ipmi_pass.
2) Encryption (obfuscation, because we don't really have a secure
mechanism of storing secret keys), is done like this:
a) read 8 bytes (S) from /etc/key_file (currently pre-loaded with "OPENBMC=")
b) create a random value H (read from /dev/urandom)
c) create the AES-CBC secret key K=HMAC-SHA256(S, H)
d) encrypt the list of username:password data using K
e) store H along with the encrypted data in /etc/ipmi_pass
3) reading the password (for establishing IPMI RMCP+ sessions)
a) read 8 bytes (S) from /etc/key_file
b) read H from /etc/ipmi_pass
c) compute the AES-CBC secret key K=HMAC-SHA256(S, H)
d) decrypt and verify the contents of /etc/key_file
There are many issues with this mechanism, but we cannot fix all of them
without some secure mechanism for storing secret keys. That is why
really, at best, this is obfuscation, not encryption. The data is not in
plain text, it takes some work to get to it. More than xor or rot13, but
not so much that a person could do it with a bash script.
1) the default /etc/key_file is the same for every BMC built with the
default settings (changing this requires a bbappend for pam-ipmi). This
means the /etc/key_file could basically not exist; all you need is the
algorithm and /etc/ipmi_pass.
2) the size of the /etc/key_file is also not really great. Even if it
was different on every machine, computing only 2^64 possibilities is not
so hard.
Possible Solution
=================
Migrate to a solution that uses a key that is longer that does not
get written directly to the flash
1) S is now computed instead of hard-coded. S=HMAC(MachineId, AppID)
2) S is longer (32 bytes instead of 8)
3) S is not written to flash, because it can be computed
4) S is different for every machine because it is a derivative of
/etc/machine-id
The migration from the old mechanism to the new could be done simply by
using the new key on the next write to the /etc/ipmi_pass file. After a
firmware update to this new code, a password change would trigger a
decrypt of the /etc/ipmi_pass file, a modification of the plain text,
and a re-encryption of the data. If it reads the 'legacy' key in and
writes out the data using the new key mechanism and deletes the legacy
key, it would use the new key mechanism from that point onward. However,
this would cause any downgrades to prior versions to fail to decrypt the
/etc/ipmi_pass file, thereby losing all the ipmi passwords. This is not
ideal, but could possibly be mitigating by truncating the new machine-id
derivative password to 8 bytes and storing it in the /etc/key_file
instead of just deleting it. This might improve security only slightly
at for the price of a better user experience.
I know that some companies using OpenBMC have products with users out in
the field, so it is not great to make changes like this. Also, it is not
great to have low-grade security. So here I am, writing to ask for
opinions and options.
--Vernon
More information about the openbmc
mailing list