From a1f478239d4dfd18331b311863758c71ce0a79f9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 17 Feb 2023 22:43:28 +0100 Subject: [PATCH] Added HMAC tests. Signed-off-by: Pol Henarejos --- tests/conftest.py | 23 ++++++++++++++--- tests/pico-hsm/test_060_mac.py | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 tests/pico-hsm/test_060_mac.py diff --git a/tests/conftest.py b/tests/conftest.py index ac4f743..cc94815 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -301,7 +301,7 @@ class Device: resp = self.send(cla=0x80, command=0x52, p1=0x0, p2=0x0, data=dkek) return resp - def import_key(self, pkey, dkek=None): + def import_key(self, pkey, dkek=None, purposes=None): data = b'' kcv = hashlib.sha256(dkek or b'\x00'*32).digest()[:8] kenc = hashlib.sha256((dkek or b'\x00'*32) + b'\x00\x00\x00\x01').digest() @@ -318,8 +318,10 @@ class Device: algo = b'\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01' data += algo - if (isinstance(pkey, bytes)): - data += b'\x00\x04\x10\x11\x18\x99' + b'\x00'*4 + if (not purposes and isinstance(pkey, bytes)): + purposes = [Algorithm.ALGO_AES_CBC_ENCRYPT.value, Algorithm.ALGO_AES_CBC_DECRYPT.value, Algorithm.ALGO_AES_CMAC.value, Algorithm.ALGO_AES_DERIVE.value, Algorithm.ALGO_EXT_CIPHER_ENCRYPT.value, Algorithm.ALGO_EXT_CIPHER_DECRYPT.value] + if (purposes): + data += b'\x00' + bytes([len(purposes)]) + bytes(purposes) + b'\x00'*4 else: data += b'\x00'*6 @@ -430,6 +432,21 @@ class Device: resp = self.send(cla=0x80, command=0x78, p1=keyid, p2=algo.value, data=data) return resp + def hmac(self, hash, keyid, data): + if (hash == hashes.SHA1): + algo = b'\x2A\x86\x48\x86\xF7\x0D\x02\x07' + elif (hash == hashes.SHA224): + algo = b'\x2A\x86\x48\x86\xF7\x0D\x02\x08' + elif (hash == hashes.SHA256): + algo = b'\x2A\x86\x48\x86\xF7\x0D\x02\x09' + elif (hash == hashes.SHA384): + algo = b'\x2A\x86\x48\x86\xF7\x0D\x02\x0A' + elif (hash == hashes.SHA512): + algo = b'\x2A\x86\x48\x86\xF7\x0D\x02\x0B' + data = [0x06, len(algo)] + list(algo) + [0x81, len(data)] + list(data) + resp = self.send(cla=0x80, command=0x78, p1=keyid, p2=0x51, data=data) + return resp + @pytest.fixture(scope="session") def device(): diff --git a/tests/pico-hsm/test_060_mac.py b/tests/pico-hsm/test_060_mac.py new file mode 100644 index 0000000..549e457 --- /dev/null +++ b/tests/pico-hsm/test_060_mac.py @@ -0,0 +1,46 @@ +""" +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * Copyright (c) 2022 Pol Henarejos. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +""" + +import pytest +import os +from cryptography.hazmat.primitives import hashes, hmac +from utils import Algorithm, DOPrefixes +from const import DEFAULT_DKEK_SHARES, DEFAULT_DKEK + +MESSAGE = b'a secret message' + +def test_prepare_aes(device): + device.initialize(dkek_shares=DEFAULT_DKEK_SHARES) + resp = device.import_dkek(DEFAULT_DKEK) + resp = device.import_dkek(DEFAULT_DKEK) + +@pytest.mark.parametrize( + "size", [128, 192, 256] +) +@pytest.mark.parametrize( + "algo", [hashes.SHA1, hashes.SHA224, hashes.SHA256, hashes.SHA384, hashes.SHA512] +) +def test_mac_hmac(device, size, algo): + pkey = os.urandom(size // 8) + keyid = device.import_key(pkey) + resA = device.hmac(algo, keyid, MESSAGE) + h = hmac.HMAC(pkey, algo()) + h.update(MESSAGE) + resB = h.finalize() + assert(bytes(resA) == resB)