From: James Bottomley <jejb@linux.ibm.com>
To: Brijesh Singh <brijesh.singh@amd.com>, Ard Biesheuvel <ardb@kernel.org>
Cc: kvm@vger.kernel.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Linux Doc Mailing List <linux-doc@vger.kernel.org>,
Tom Lendacky <Thomas.Lendacky@amd.com>,
David Rientjes <rientjes@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>,
Borislav Petkov <bp@alien8.de>, John Allen <john.allen@amd.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
Linux Crypto Mailing List <linux-crypto@vger.kernel.org>
Subject: Re: [PATCH] KVM/SVM: add support for SEV attestation command
Date: Sun, 13 Dec 2020 14:28:56 -0800 [thread overview]
Message-ID: <5d0085a960956ce8d9eae06465313012d448189c.camel@linux.ibm.com> (raw)
In-Reply-To: <78e18a3d-900b-fac5-19ca-c2defeb8d73a@amd.com>
On Wed, 2020-12-09 at 21:25 -0600, Brijesh Singh wrote:
> Noted, I will send v2 with these fixed.
I ran a test on this. It turns out for rome systems you need firmware
md_sev_fam17h_model3xh_0.24b0A (or later) installed to get this and the
QEMU patch with the base64 decoding fixed, but with that
Tested-by: James Bottomley <jejb@linux.ibm.com>
Attached is the test programme I used.
James
---
#!/usr/bin/python3
##
# Python script get an attestation and verify it with the PEK
#
# This assumes you've already exported the pek.cert with sev-tool
# from https://github.com/AMDESE/sev-tool.git
#
# sev-tool --export_cert_chain
#
# creates several files, the only one this script needs is pek.cert
#
# Tables and chapters refer to the amd 55766.pdf document
#
# https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf
##
import sys
import os
import base64
import hashlib
from argparse import ArgumentParser
from Crypto.PublicKey import ECC
from Crypto.Math.Numbers import Integer
from git.qemu.python.qemu import qmp
if __name__ == "__main__":
parser = ArgumentParser(description='Inject secret into SEV')
parser.add_argument('--pek-cert',
help='The Platform DH certificate in binary form',
default='pek.cert')
parser.add_argument('--socket',
help='Socket to connect to QMP on, defaults to localhost:6550',
default='localhost:6550')
args = parser.parse_args()
if (args.socket[0] == '/'):
socket = args.socket
elif (':' in args.socket):
s = args.socket.split(':')
socket = (s[0], int(s[1]))
else:
parse.error('--socket must be <host>:<port> or /path/to/unix')
fh = open(args.pek_cert, 'rb')
pek = bytearray(fh.read())
curve = int.from_bytes(pek[16:20], byteorder='little')
curves = {
1: 'p256',
2: 'p384'
}
Qx = int.from_bytes(bytes(pek[20:92]), byteorder='little')
Qy = int.from_bytes(bytes(pek[92:164]), byteorder='little')
pubkey = ECC.construct(point_x=Qx, point_y=Qy, curve=curves[curve])
Qmp = qmp.QEMUMonitorProtocol(address=socket);
Qmp.connect()
caps = Qmp.command('query-sev')
print('SEV query found API={api-major}.{api-minor} build={build-id} policy={policy}\n'.format(**caps))
nonce=os.urandom(16)
report = Qmp.command('query-sev-attestation-report',
mnonce=base64.b64encode(nonce).decode())
a = base64.b64decode(report['data'])
##
# returned data is formulated as Table 60. Attestation Report Buffer
##
rnonce = a[0:16]
rmeas = a[16:48]
if (nonce != rnonce):
sys.exit('returned nonce doesn\'t match input nonce')
policy = int.from_bytes(a[48:52], byteorder='little')
usage = int.from_bytes(a[52:56], byteorder='little')
algo = int.from_bytes(a[56:60], byteorder='little')
if (policy != caps['policy']):
sys.exit('Policy mismatch:', policy, '!=', caps['policy'])
if (usage != 0x1002):
sys.exit('error PEK is not specified in usage: ', usage)
if (algo == 0x2):
h = hashlib.sha256()
elif (algo == 0x102):
##
# The spec (6.8) says the signature must be ECDSA-SHA256 so this
# should be impossible, but it turns out to be the way our
# current test hardware produces its signature
##
h = hashlib.sha384()
else:
sys.exit('unrecognized signing algorithm: ', algo)
h.update(a[0:52])
sig = a[64:208]
r = int.from_bytes(sig[0:72],byteorder='little')
s = int.from_bytes(sig[72:144],byteorder='little')
##
# subtlety: r and s are little (AMD defined) z is big (crypto requirement)
##
z = int.from_bytes(h.digest(), byteorder='big')
##
# python crypto doesn't have a way of passing in r and s as
# integers and I'm not inclined to wrap them up as a big endian
# binary signature to have Signature.DSS unwrap them again, so
# call the _verify() private interface that does take integers
##
if (not pubkey._verify(Integer(z), (Integer(r), Integer(s)))):
sys.exit('returned signature did not verify')
print('usage={usage}, algorithm={algo}'.format(usage=hex(usage),
algo=hex(algo)))
print('ovmf-hash: ', rmeas.hex())
prev parent reply other threads:[~2020-12-13 22:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-04 21:28 [PATCH] KVM/SVM: add support for SEV attestation command Brijesh Singh
2020-12-08 16:43 ` Tom Lendacky
2020-12-09 7:51 ` Ard Biesheuvel
2020-12-10 3:25 ` Brijesh Singh
2020-12-10 23:28 ` David Rientjes
2020-12-13 22:28 ` James Bottomley [this message]
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=5d0085a960956ce8d9eae06465313012d448189c.camel@linux.ibm.com \
--to=jejb@linux.ibm.com \
--cc=Thomas.Lendacky@amd.com \
--cc=ardb@kernel.org \
--cc=bp@alien8.de \
--cc=brijesh.singh@amd.com \
--cc=herbert@gondor.apana.org.au \
--cc=john.allen@amd.com \
--cc=kvm@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=rientjes@google.com \
--cc=seanjc@google.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).