All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vernon Mauery <vernon.mauery@linux.intel.com>
To: Patrick Williams <patrick@stwcx.xyz>
Cc: OpenBMC Development <openbmc@lists.ozlabs.org>
Subject: Re: ipmi password storage
Date: Tue, 14 Apr 2020 09:46:10 -0700	[thread overview]
Message-ID: <20200414164610.GC9295@mauery.jf.intel.com> (raw)
In-Reply-To: <20200414155019.GB443018@heinlein.lan.stwcx.xyz>

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

  reply	other threads:[~2020-04-14 16:46 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-13 23:00 ipmi password storage Vernon Mauery
2020-04-14 15:50 ` Patrick Williams
2020-04-14 16:46   ` Vernon Mauery [this message]
2020-04-14 22:03     ` Joseph Reynolds
2020-04-14 22:42       ` Vernon Mauery
2020-04-16  6:04         ` Joel Stanley
2020-04-20 14:29           ` Vernon Mauery
2020-04-22 11:38     ` Patrick Williams
2020-04-22 22:19       ` Vernon Mauery
2020-04-24 15:15         ` Patrick Williams
2020-04-29 16:02           ` Alexander Tereschenko
2020-04-14 16:27 ` Alexander Tereschenko
2020-04-14 19:11   ` Vernon Mauery
2020-04-14 22:18     ` Joseph Reynolds
2020-04-14 22:44       ` Vernon Mauery
2020-04-14 22:48         ` Joseph Reynolds
2020-04-15 20:32           ` Joseph Reynolds
2020-04-14 18:04 ` Milton Miller II
2020-04-14 19:14   ` Vernon Mauery
2020-04-14 22:30     ` Joseph Reynolds
2020-04-14 22:47       ` Vernon Mauery

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200414164610.GC9295@mauery.jf.intel.com \
    --to=vernon.mauery@linux.intel.com \
    --cc=openbmc@lists.ozlabs.org \
    --cc=patrick@stwcx.xyz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.