ipmi password storage
Vernon Mauery
vernon.mauery at linux.intel.com
Wed Apr 15 02:46:10 AEST 2020
On 14-Apr-2020 10:50 AM, Patrick Williams wrote:
>On Mon, Apr 13, 2020 at 04:00:15PM -0700, Vernon Mauery wrote:
>
>Vernon,
>
>Is there some background pointers on why IPMI needs to store passwords
>in a reverable way? I never understood that.
Sure. I think this is most clearly described in section 13.31 "RMCP+
Authenticated Key-Exchange Protocol (RAKP)" in the IPMI v2 1.1 spec.
Here is a high level overview though: It is baked into the RMCP+ key
exchange (RAKP). The password never goes across the wire in plaintext,
but it does get used during the session creation in RAKP messages as the
key to integrity and authentication HMACs.
Specifically, the RAKP3 message (User->BMC) contains an HMAC of the
various parts of the exchanged session (User random number, session ID, Role,
Username) using the password as the key for the HMAC. The BMC needs to
compute this same HMAC to compare (this is the main authentication
challenge).
Then, the session key is generated using an HMAC of similar
data (BMC random number, user random number, role, username) using
either the user password or the channel password. Almost nobody uses the
channel password, which is good because it allows for simple privilege
escalation and session hijacking.
Both sides use the same inputs and HMAC key, so the BMC needs to store
the user passwords in a way that they can be used as the key for an
HMAC. Ideally this would be stored in some sort of secure enclave or
HSM, but that is not yet available.
--Vernon
>> 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
>
>--
>Patrick Williams
More information about the openbmc
mailing list