From nobody Thu Oct 21 22:04:28 2021 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 1E2051801992; Thu, 21 Oct 2021 22:04:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Hb1jW2ndKz3tgX; Thu, 21 Oct 2021 22:04:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 524EC22E1F; Thu, 21 Oct 2021 22:04:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 19LM4Ska079782; Thu, 21 Oct 2021 22:04:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 19LM4SRc079781; Thu, 21 Oct 2021 22:04:28 GMT (envelope-from git) Date: Thu, 21 Oct 2021 22:04:28 GMT Message-Id: <202110212204.19LM4SRc079781@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: dffa7f13db78 - stable/13 - crypto: Test all of the AES-CCM KAT vectors. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: dffa7f13db7855941b270caa6fc5ec72becb07bc Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=dffa7f13db7855941b270caa6fc5ec72becb07bc commit dffa7f13db7855941b270caa6fc5ec72becb07bc Author: John Baldwin AuthorDate: 2021-10-06 21:08:48 +0000 Commit: John Baldwin CommitDate: 2021-10-21 21:19:24 +0000 crypto: Test all of the AES-CCM KAT vectors. Previously, only test vectors which used the default nonce and tag sizes (12 and 16, respectively) were tested. This now tests all of the vectors. This exposed some additional issues around requests with an empty payload (which wasn't supported) and an empty AAD (which falls back to CIOCCRYPT instead of CIOCCRYPTAEAD). - Make use of the 'ivlen' and 'maclen' fields for CIOGSESSION2 to test AES-CCM vectors with non-default nonce and tag lengths. - Permit requests with an empty payload. - Permit an input MAC for requests without AAD. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32121 (cherry picked from commit 668770dc7de2ec8b5f5edf71e09b8a404120f6fa) --- tests/sys/opencrypto/cryptodev.py | 54 +++++++++++++++++++++++++++----------- tests/sys/opencrypto/cryptotest.py | 41 ++++++++++++----------------- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/tests/sys/opencrypto/cryptodev.py b/tests/sys/opencrypto/cryptodev.py index 83d14fc2b205..d97a731d37ba 100644 --- a/tests/sys/opencrypto/cryptodev.py +++ b/tests/sys/opencrypto/cryptodev.py @@ -79,10 +79,10 @@ class SessionOp2(dpkt.Packet): ('mackey', 'P', 0), ('ses', 'I', 0), ('crid', 'i', 0), + ('ivlen', 'i', 0), + ('maclen', 'i', 0), ('pad0', 'i', 0), ('pad1', 'i', 0), - ('pad2', 'i', 0), - ('pad3', 'i', 0), ) class CryptOp(dpkt.Packet): @@ -159,6 +159,11 @@ def array_tobytes(array_obj): return array_obj.tobytes() return array_obj.tostring() +def empty_bytes(): + if sys.version_info[0] >= 3: + return b'' + return "" + class Crypto: @staticmethod def findcrid(name): @@ -169,7 +174,8 @@ class Crypto: return _findop(crid, '')[1] def __init__(self, cipher=0, key=None, mac=0, mackey=None, - crid=CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE, maclen=None): + crid=CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE, maclen=None, + ivlen=None): self._ses = None self._maclen = maclen ses = SessionOp2() @@ -191,6 +197,10 @@ class Crypto: if not cipher and not mac: raise ValueError('one of cipher or mac MUST be specified.') ses.crid = crid + if ivlen: + ses.ivlen = ivlen + if maclen: + ses.maclen = maclen #print(ses) s = array.array('B', ses.pack_hdr()) #print(s) @@ -209,16 +219,23 @@ class Crypto: pass self._ses = None - def _doop(self, op, src, iv): + def _doop(self, op, src, iv, mac=None): cop = CryptOp() cop.ses = self._ses cop.op = op cop.flags = 0 - cop.len = len(src) - s = array.array('B', src) - cop.src = cop.dst = s.buffer_info()[0] + if src is not None: + cop.len = len(src) + s = array.array('B', src) + cop.src = cop.dst = s.buffer_info()[0] + if mac is not None: + assert len(mac) == self._maclen, \ + '%d != %d' % (len(tag), self._maclen) if self._maclen is not None: - m = array.array('B', [0] * self._maclen) + if mac is None: + m = array.array('B', [0] * self._maclen) + else: + m = array.array('B', mac) cop.mac = m.buffer_info()[0] ivbuf = array.array('B', str_to_ascii(iv)) cop.iv = ivbuf.buffer_info()[0] @@ -226,7 +243,10 @@ class Crypto: #print('cop:', cop) ioctl(_cryptodev, CIOCCRYPT, bytes(cop)) - s = array_tobytes(s) + if src is not None: + s = array_tobytes(s) + else: + s = empty_bytes() if self._maclen is not None: return s, array_tobytes(m) @@ -238,10 +258,11 @@ class Crypto: caead.op = op caead.flags = CRD_F_IV_EXPLICIT caead.flags = 0 - src = str_to_ascii(src) - caead.len = len(src) - s = array.array('B', src) - caead.src = caead.dst = s.buffer_info()[0] + if src is not None and len(src) != 0: + src = str_to_ascii(src) + caead.len = len(src) + s = array.array('B', src) + caead.src = caead.dst = s.buffer_info()[0] aad = str_to_ascii(aad) caead.aadlen = len(aad) saad = array.array('B', aad) @@ -266,7 +287,10 @@ class Crypto: ioctl(_cryptodev, CIOCCRYPTAEAD, bytes(caead)) - s = array_tobytes(s) + if src is not None: + s = array_tobytes(s) + else: + s = empty_bytes() return s, array_tobytes(tag) @@ -320,7 +344,7 @@ class Crypto: def decrypt(self, data, iv, aad=None, tag=None): if aad is None: - return self._doop(COP_DECRYPT, data, iv) + return self._doop(COP_DECRYPT, data, iv, mac=tag) else: return self._doaead(COP_DECRYPT, data, aad, iv, tag=tag) diff --git a/tests/sys/opencrypto/cryptotest.py b/tests/sys/opencrypto/cryptotest.py index 2ef423ac1505..74ce62cee33d 100644 --- a/tests/sys/opencrypto/cryptotest.py +++ b/tests/sys/opencrypto/cryptotest.py @@ -243,25 +243,26 @@ def GenTestCase(cname): def runCCMEncryptWithParser(self, parser): for data in next(parser): Nlen = int(data['Nlen']) - if Nlen != 12: - # OCF only supports 12 byte IVs - continue + Tlen = int(data['Tlen']) key = binascii.unhexlify(data['Key']) nonce = binascii.unhexlify(data['Nonce']) Alen = int(data['Alen']) + Plen = int(data['Plen']) if Alen != 0: aad = binascii.unhexlify(data['Adata']) else: aad = None - payload = binascii.unhexlify(data['Payload']) + if Plen != 0: + payload = binascii.unhexlify(data['Payload']) + else: + payload = None ct = binascii.unhexlify(data['CT']) try: c = Crypto(crid=crid, cipher=cryptodev.CRYPTO_AES_CCM_16, key=key, - mac=cryptodev.CRYPTO_AES_CCM_CBC_MAC, - mackey=key, maclen=16) + mackey=key, maclen=Tlen, ivlen=Nlen) r, tag = Crypto.encrypt(c, payload, nonce, aad) except EnvironmentError as e: @@ -280,36 +281,29 @@ def GenTestCase(cname): self.runCCMDecryptWithParser(parser) def runCCMDecryptWithParser(self, parser): - # XXX: Note that all of the current CCM - # decryption test vectors use IV and tag sizes - # that aren't supported by OCF none of the - # tests are actually ran. for data in next(parser): Nlen = int(data['Nlen']) - if Nlen != 12: - # OCF only supports 12 byte IVs - continue Tlen = int(data['Tlen']) - if Tlen != 16: - # OCF only supports 16 byte tags - continue key = binascii.unhexlify(data['Key']) nonce = binascii.unhexlify(data['Nonce']) Alen = int(data['Alen']) + Plen = int(data['Plen']) if Alen != 0: aad = binascii.unhexlify(data['Adata']) else: aad = None ct = binascii.unhexlify(data['CT']) - tag = ct[-16:] - ct = ct[:-16] + tag = ct[-Tlen:] + if Plen != 0: + payload = ct[:-Tlen] + else: + payload = None try: c = Crypto(crid=crid, cipher=cryptodev.CRYPTO_AES_CCM_16, key=key, - mac=cryptodev.CRYPTO_AES_CCM_CBC_MAC, - mackey=key, maclen=16) + mackey=key, maclen=Tlen, ivlen=Nlen) except EnvironmentError as e: if e.errno != errno.EOPNOTSUPP: raise @@ -319,12 +313,11 @@ def GenTestCase(cname): self.assertRaises(IOError, c.decrypt, payload, nonce, aad, tag) else: - r = Crypto.decrypt(c, payload, nonce, - aad, tag) + r, tag = Crypto.decrypt(c, payload, nonce, + aad, tag) payload = binascii.unhexlify(data['Payload']) - plen = int(data('Plen')) - payload = payload[:plen] + payload = payload[:Plen] self.assertEqual(r, payload, "Count " + data['Count'] + \ " Actual: " + repr(binascii.hexlify(r)) + \